Merge "SurfaceFlinger: decouple EventThread from SF wakeup"
diff --git a/cmds/surfacereplayer/replayer/Replayer.cpp b/cmds/surfacereplayer/replayer/Replayer.cpp
index 2b5667d..86e4f5d 100644
--- a/cmds/surfacereplayer/replayer/Replayer.cpp
+++ b/cmds/surfacereplayer/replayer/Replayer.cpp
@@ -584,9 +584,7 @@
return;
}
- auto handle = mLayers[dtc.layer_id()]->getHandle();
-
- t.deferTransactionUntil_legacy(mLayers[id], handle, dtc.frame_number());
+ t.deferTransactionUntil_legacy(mLayers[id], mLayers[dtc.layer_id()], dtc.frame_number());
}
void Replayer::setDisplaySurface(SurfaceComposerClient::Transaction& t,
@@ -706,11 +704,11 @@
void Replayer::setReparentChange(SurfaceComposerClient::Transaction& t,
layer_id id, const ReparentChange& c) {
- sp<IBinder> newParentHandle = nullptr;
+ sp<SurfaceControl> newSurfaceControl = nullptr;
if (mLayers.count(c.parent_id()) != 0 && mLayers[c.parent_id()] != nullptr) {
- newParentHandle = mLayers[c.parent_id()]->getHandle();
+ newSurfaceControl = mLayers[c.parent_id()];
}
- t.reparent(mLayers[id], newParentHandle);
+ t.reparent(mLayers[id], newSurfaceControl);
}
void Replayer::setRelativeParentChange(SurfaceComposerClient::Transaction& t,
@@ -719,7 +717,7 @@
ALOGE("Layer %d not found in set relative parent transaction", c.relative_parent_id());
return;
}
- t.setRelativeLayer(mLayers[id], mLayers[c.relative_parent_id()]->getHandle(), c.z());
+ t.setRelativeLayer(mLayers[id], mLayers[c.relative_parent_id()], c.z());
}
void Replayer::setDetachChildrenChange(SurfaceComposerClient::Transaction& t,
@@ -733,7 +731,7 @@
ALOGE("Layer %d not found in reparent children transaction", c.parent_id());
return;
}
- t.reparentChildren(mLayers[id], mLayers[c.parent_id()]->getHandle());
+ t.reparentChildren(mLayers[id], mLayers[c.parent_id()]);
}
void Replayer::setShadowRadiusChange(SurfaceComposerClient::Transaction& t,
diff --git a/include/binder/Enum.h b/include/binder/Enum.h
new file mode 100644
index 0000000..4c25654
--- /dev/null
+++ b/include/binder/Enum.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#error Do not rely on global include files. All Android cc_* programs are given access to \
+ include_dirs for frameworks/native/include via global configuration, but this is legacy \
+ configuration. Instead, you should have a direct dependency on libbinder OR one of your \
+ dependencies should re-export libbinder headers with export_shared_lib_headers.
diff --git a/include/input/Flags.h b/include/input/Flags.h
index 4ad9056..072dd18 100644
--- a/include/input/Flags.h
+++ b/include/input/Flags.h
@@ -22,6 +22,7 @@
#include <string>
#include <type_traits>
+#include "NamedEnum.h"
#include "utils/BitSet.h"
#ifndef __UI_INPUT_FLAGS_H
@@ -30,38 +31,6 @@
namespace android {
namespace details {
-template <typename F, F V>
-constexpr std::optional<std::string_view> enum_value_name() {
- // Should look something like (but all on one line):
- // std::optional<std::string_view>
- // android::details::enum_value_name()
- // [F = android::test::TestFlags, V = android::test::TestFlags::ONE]
- std::string_view view = __PRETTY_FUNCTION__;
- size_t templateStart = view.rfind("[");
- size_t templateEnd = view.rfind("]");
- if (templateStart == std::string::npos || templateEnd == std::string::npos) {
- return std::nullopt;
- }
-
- // Extract the template parameters without the enclosing braces.
- // Example (cont'd): F = android::test::TestFlags, V = android::test::TestFlags::ONE
- view = view.substr(templateStart + 1, templateEnd - templateStart - 1);
- size_t valStart = view.rfind("V = ");
- if (valStart == std::string::npos) {
- return std::nullopt;
- }
-
- // Example (cont'd): V = android::test::TestFlags::ONE
- view = view.substr(valStart);
- size_t nameStart = view.rfind("::");
- if (nameStart == std::string::npos) {
- return std::nullopt;
- }
-
- // Chop off the initial "::"
- nameStart += 2;
- return view.substr(nameStart);
-}
template <typename F>
inline constexpr auto flag_count = sizeof(F) * __CHAR_BIT__;
diff --git a/include/input/NamedEnum.h b/include/input/NamedEnum.h
new file mode 100644
index 0000000..42cfb12
--- /dev/null
+++ b/include/input/NamedEnum.h
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/stringprintf.h>
+
+#include <array>
+#include <cstdint>
+#include <optional>
+#include <string>
+
+#ifndef __UI_INPUT_NAMEDENUM_H
+#define __UI_INPUT_NAMEDENUM_H
+
+namespace android {
+
+namespace details {
+template <typename E, E V>
+constexpr std::optional<std::string_view> enum_value_name() {
+ // Should look something like (but all on one line):
+ // std::optional<std::string_view>
+ // android::details::enum_value_name()
+ // [E = android::test::TestEnums, V = android::test::TestEnums::ONE]
+ std::string_view view = __PRETTY_FUNCTION__;
+ size_t templateStart = view.rfind("[");
+ size_t templateEnd = view.rfind("]");
+ if (templateStart == std::string::npos || templateEnd == std::string::npos) {
+ return std::nullopt;
+ }
+
+ // Extract the template parameters without the enclosing braces.
+ // Example (cont'd): E = android::test::TestEnums, V = android::test::TestEnums::ONE
+ view = view.substr(templateStart + 1, templateEnd - templateStart - 1);
+ size_t valStart = view.rfind("V = ");
+ if (valStart == std::string::npos) {
+ return std::nullopt;
+ }
+
+ // Example (cont'd): V = android::test::TestEnums::ONE
+ view = view.substr(valStart);
+ size_t nameStart = view.rfind("::");
+ if (nameStart == std::string::npos) {
+ return std::nullopt;
+ }
+
+ // Chop off the initial "::"
+ nameStart += 2;
+ return view.substr(nameStart);
+}
+
+template <typename E, typename T, T... I>
+constexpr auto generate_enum_values(std::integer_sequence<T, I...> seq) {
+ constexpr size_t count = seq.size();
+
+ std::array<E, count> values{};
+ for (size_t i = 0, v = 0; v < count; ++i) {
+ values[v++] = static_cast<E>(T{0} + i);
+ }
+
+ return values;
+}
+
+template <typename E, std::size_t N>
+inline constexpr auto enum_values =
+ generate_enum_values<E>(std::make_integer_sequence<std::underlying_type_t<E>, N>{});
+
+template <typename E, std::size_t N, std::size_t... I>
+constexpr auto generate_enum_names(std::index_sequence<I...>) noexcept {
+ return std::array<std::optional<std::string_view>, sizeof...(I)>{
+ {enum_value_name<E, enum_values<E, N>[I]>()...}};
+}
+
+template <typename E, std::size_t N>
+inline constexpr auto enum_names = generate_enum_names<E, N>(std::make_index_sequence<N>{});
+
+} // namespace details
+
+class NamedEnum {
+public:
+ // By default allowed enum value range is 0 ~ 7.
+ template <typename E>
+ static constexpr size_t max = 8;
+
+ template <auto V>
+ static constexpr auto enum_name() {
+ using E = decltype(V);
+ return details::enum_value_name<E, V>();
+ }
+
+ template <typename E>
+ static constexpr std::optional<std::string_view> enum_name(E val) {
+ auto idx = static_cast<size_t>(val);
+ return idx < max<E> ? details::enum_names<E, max<E>>[idx] : std::nullopt;
+ }
+
+ // Helper function for parsing enum value to string.
+ // Example : enum class TestEnums { ZERO = 0x0 };
+ // NamedEnum::string(TestEnums::ZERO) returns string of "ZERO".
+ // Note the default maximum enum is 8, if the enum ID to be parsed if greater than 8 like 16,
+ // it should be declared to specialized the maximum enum by below:
+ // template <> constexpr size_t NamedEnum::max<TestEnums> = 16;
+ // If the enum class definition is sparse and contains enum values starting from a large value,
+ // Do not specialize it to a large number to avoid performance issues.
+ // The recommended maximum enum number to specialize is 64.
+ template <typename E>
+ static const std::string string(E val) {
+ std::string result;
+ std::optional<std::string_view> enumString = enum_name(val);
+ result += enumString ? enumString.value() : base::StringPrintf("0x%08x", val);
+ return result;
+ }
+};
+
+} // namespace android
+
+#endif // __UI_INPUT_NAMEDENUM_H
\ No newline at end of file
diff --git a/libs/binder/rust/src/binder.rs b/libs/binder/rust/src/binder.rs
index 81a5f02..6d0a369 100644
--- a/libs/binder/rust/src/binder.rs
+++ b/libs/binder/rust/src/binder.rs
@@ -532,7 +532,17 @@
}
fn on_transact(&self, code: $crate::TransactionCode, data: &$crate::Parcel, reply: &mut $crate::Parcel) -> $crate::Result<()> {
- $on_transact(&*self.0, code, data, reply)
+ match $on_transact(&*self.0, code, data, reply) {
+ // The C++ backend converts UNEXPECTED_NULL into an exception
+ Err($crate::StatusCode::UNEXPECTED_NULL) => {
+ let status = $crate::Status::new_exception(
+ $crate::ExceptionCode::NULL_POINTER,
+ None,
+ );
+ reply.write(&status)
+ },
+ result => result
+ }
}
fn get_class() -> $crate::InterfaceClass {
diff --git a/libs/binder/rust/src/proxy.rs b/libs/binder/rust/src/proxy.rs
index 82212d8..5002fc6 100644
--- a/libs/binder/rust/src/proxy.rs
+++ b/libs/binder/rust/src/proxy.rs
@@ -352,7 +352,10 @@
impl Deserialize for SpIBinder {
fn deserialize(parcel: &Parcel) -> Result<SpIBinder> {
- parcel.read_binder().transpose().unwrap()
+ parcel
+ .read_binder()
+ .transpose()
+ .unwrap_or(Err(StatusCode::UNEXPECTED_NULL))
}
}
diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp
index ba72f9b..cce434a 100644
--- a/libs/gui/BLASTBufferQueue.cpp
+++ b/libs/gui/BLASTBufferQueue.cpp
@@ -166,8 +166,8 @@
const std::vector<SurfaceControlStats>& stats) {
std::unique_lock _lock{mMutex};
ATRACE_CALL();
-
BQA_LOGV("transactionCallback");
+ mInitialCallbackReceived = true;
if (!stats.empty()) {
mTransformHint = stats[0].transformHint;
@@ -185,7 +185,7 @@
if (!stats.empty()) {
mPendingReleaseItem.releaseFence = stats[0].previousReleaseFence;
} else {
- ALOGE("Warning: no SurfaceControlStats returned in BLASTBufferQueue callback");
+ BQA_LOGE("Warning: no SurfaceControlStats returned in BLASTBufferQueue callback");
mPendingReleaseItem.releaseFence = nullptr;
}
mBufferItemConsumer->releaseBuffer(mPendingReleaseItem.item,
@@ -198,7 +198,7 @@
}
if (mSubmitted.empty()) {
- ALOGE("ERROR: callback with no corresponding submitted buffer item");
+ BQA_LOGE("ERROR: callback with no corresponding submitted buffer item");
}
mPendingReleaseItem.item = std::move(mSubmitted.front());
mSubmitted.pop();
@@ -213,12 +213,18 @@
ATRACE_CALL();
BQA_LOGV("processNextBufferLocked useNextTransaction=%s", toString(useNextTransaction));
- if (mNumFrameAvailable == 0 || mNumAcquired == MAX_ACQUIRED_BUFFERS + 1) {
+ // Wait to acquire a buffer if there are no frames available or we have acquired the maximum
+ // number of buffers.
+ // As a special case, we wait for the first callback before acquiring the second buffer so we
+ // can ensure the first buffer is presented if multiple buffers are queued in succession.
+ if (mNumFrameAvailable == 0 || mNumAcquired == MAX_ACQUIRED_BUFFERS + 1 ||
+ (!mInitialCallbackReceived && mNumAcquired == 1)) {
+ BQA_LOGV("processNextBufferLocked waiting for frame available or callback");
return;
}
if (mSurfaceControl == nullptr) {
- ALOGE("ERROR : surface control is null");
+ BQA_LOGE("ERROR : surface control is null");
return;
}
@@ -245,6 +251,13 @@
return;
}
+ if (rejectBuffer(bufferItem)) {
+ BQA_LOGE("rejecting buffer: configured width=%d, height=%d, buffer{w=%d, h=%d}", mWidth,
+ mHeight, buffer->getWidth(), buffer->getHeight());
+ mBufferItemConsumer->releaseBuffer(bufferItem, Fence::NO_FENCE);
+ return;
+ }
+
mNumAcquired++;
mSubmitted.push(bufferItem);
@@ -311,4 +324,13 @@
mNextTransaction = t;
}
+bool BLASTBufferQueue::rejectBuffer(const BufferItem& item) const {
+ if (item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE) {
+ // Only reject buffers if scaling mode is freeze.
+ return false;
+ }
+
+ // reject buffers if the buffer size doesn't match.
+ return item.mGraphicBuffer->getWidth() != mWidth || item.mGraphicBuffer->getHeight() != mHeight;
+}
} // namespace android
diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp
index 4a57b1b..bde73ba 100644
--- a/libs/gui/LayerState.cpp
+++ b/libs/gui/LayerState.cpp
@@ -18,16 +18,55 @@
#include <inttypes.h>
-#include <utils/Errors.h>
#include <binder/Parcel.h>
-#include <gui/ISurfaceComposerClient.h>
#include <gui/IGraphicBufferProducer.h>
+#include <gui/ISurfaceComposerClient.h>
#include <gui/LayerState.h>
+#include <utils/Errors.h>
#include <cmath>
namespace android {
+layer_state_t::layer_state_t()
+ : what(0),
+ x(0),
+ y(0),
+ z(0),
+ w(0),
+ h(0),
+ layerStack(0),
+ alpha(0),
+ flags(0),
+ mask(0),
+ reserved(0),
+ crop_legacy(Rect::INVALID_RECT),
+ cornerRadius(0.0f),
+ backgroundBlurRadius(0),
+ barrierFrameNumber(0),
+ overrideScalingMode(-1),
+ transform(0),
+ transformToDisplayInverse(false),
+ crop(Rect::INVALID_RECT),
+ orientedDisplaySpaceRect(Rect::INVALID_RECT),
+ dataspace(ui::Dataspace::UNKNOWN),
+ surfaceDamageRegion(),
+ api(-1),
+ colorTransform(mat4()),
+ bgColorAlpha(0),
+ bgColorDataspace(ui::Dataspace::UNKNOWN),
+ colorSpaceAgnostic(false),
+ shadowRadius(0.0f),
+ frameRateSelectionPriority(-1),
+ frameRate(0.0f),
+ frameRateCompatibility(ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT),
+ fixedTransformHint(ui::Transform::ROT_INVALID),
+ frameNumber(0) {
+ matrix.dsdx = matrix.dtdy = 1.0f;
+ matrix.dsdy = matrix.dtdx = 0.0f;
+ hdrMetadata.validTypes = 0;
+}
+
status_t layer_state_t::write(Parcel& output) const
{
SAFE_PARCEL(output.writeStrongBinder, surface);
@@ -44,13 +83,12 @@
SAFE_PARCEL(output.writeUint32, mask);
SAFE_PARCEL(matrix.write, output);
SAFE_PARCEL(output.write, crop_legacy);
- SAFE_PARCEL(output.writeStrongBinder, barrierHandle_legacy);
- SAFE_PARCEL(output.writeStrongBinder, reparentHandle);
+ SAFE_PARCEL(SurfaceControl::writeNullableToParcel, output, barrierSurfaceControl_legacy);
+ SAFE_PARCEL(SurfaceControl::writeNullableToParcel, output, reparentSurfaceControl);
SAFE_PARCEL(output.writeUint64, barrierFrameNumber);
SAFE_PARCEL(output.writeInt32, overrideScalingMode);
- SAFE_PARCEL(output.writeStrongBinder, IInterface::asBinder(barrierGbp_legacy));
- SAFE_PARCEL(output.writeStrongBinder, relativeLayerHandle);
- SAFE_PARCEL(output.writeStrongBinder, parentHandleForChild);
+ SAFE_PARCEL(SurfaceControl::writeNullableToParcel, output, relativeLayerSurfaceControl);
+ SAFE_PARCEL(SurfaceControl::writeNullableToParcel, output, parentSurfaceControlForChild);
SAFE_PARCEL(output.writeFloat, color.r);
SAFE_PARCEL(output.writeFloat, color.g);
SAFE_PARCEL(output.writeFloat, color.b);
@@ -135,18 +173,15 @@
SAFE_PARCEL(matrix.read, input);
SAFE_PARCEL(input.read, crop_legacy);
- SAFE_PARCEL(input.readNullableStrongBinder, &barrierHandle_legacy);
- SAFE_PARCEL(input.readNullableStrongBinder, &reparentHandle);
+ SAFE_PARCEL(SurfaceControl::readNullableFromParcel, input, &barrierSurfaceControl_legacy);
+ SAFE_PARCEL(SurfaceControl::readNullableFromParcel, input, &reparentSurfaceControl);
SAFE_PARCEL(input.readUint64, &barrierFrameNumber);
SAFE_PARCEL(input.readInt32, &overrideScalingMode);
- sp<IBinder> tmpBinder;
- SAFE_PARCEL(input.readNullableStrongBinder, &tmpBinder);
- barrierGbp_legacy = interface_cast<IGraphicBufferProducer>(tmpBinder);
+ SAFE_PARCEL(SurfaceControl::readNullableFromParcel, input, &relativeLayerSurfaceControl);
+ SAFE_PARCEL(SurfaceControl::readNullableFromParcel, input, &parentSurfaceControlForChild);
float tmpFloat = 0;
- SAFE_PARCEL(input.readNullableStrongBinder, &relativeLayerHandle);
- SAFE_PARCEL(input.readNullableStrongBinder, &parentHandleForChild);
SAFE_PARCEL(input.readFloat, &tmpFloat);
color.r = tmpFloat;
SAFE_PARCEL(input.readFloat, &tmpFloat);
@@ -190,6 +225,7 @@
SAFE_PARCEL(input.read, &colorTransform, 16 * sizeof(float));
SAFE_PARCEL(input.readFloat, &cornerRadius);
SAFE_PARCEL(input.readUint32, &backgroundBlurRadius);
+ sp<IBinder> tmpBinder;
SAFE_PARCEL(input.readNullableStrongBinder, &tmpBinder);
cachedBuffer.token = tmpBinder;
SAFE_PARCEL(input.readUint64, &cachedBuffer.id);
@@ -342,8 +378,7 @@
}
if (other.what & eDeferTransaction_legacy) {
what |= eDeferTransaction_legacy;
- barrierHandle_legacy = other.barrierHandle_legacy;
- barrierGbp_legacy = other.barrierGbp_legacy;
+ barrierSurfaceControl_legacy = other.barrierSurfaceControl_legacy;
barrierFrameNumber = other.barrierFrameNumber;
}
if (other.what & eOverrideScalingModeChanged) {
@@ -352,7 +387,7 @@
}
if (other.what & eReparentChildren) {
what |= eReparentChildren;
- reparentHandle = other.reparentHandle;
+ reparentSurfaceControl = other.reparentSurfaceControl;
}
if (other.what & eDetachChildren) {
what |= eDetachChildren;
@@ -361,11 +396,11 @@
what |= eRelativeLayerChanged;
what &= ~eLayerChanged;
z = other.z;
- relativeLayerHandle = other.relativeLayerHandle;
+ relativeLayerSurfaceControl = other.relativeLayerSurfaceControl;
}
if (other.what & eReparent) {
what |= eReparent;
- parentHandleForChild = other.parentHandleForChild;
+ parentSurfaceControlForChild = other.parentSurfaceControlForChild;
}
if (other.what & eDestroySurface) {
what |= eDestroySurface;
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 2f6a34b..0068ccf 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -875,8 +875,8 @@
return *this;
}
-SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setRelativeLayer(const sp<SurfaceControl>& sc, const sp<IBinder>& relativeTo,
- int32_t z) {
+SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setRelativeLayer(
+ const sp<SurfaceControl>& sc, const sp<SurfaceControl>& relativeTo, int32_t z) {
layer_state_t* s = getLayerState(sc);
if (!s) {
mStatus = BAD_INDEX;
@@ -884,7 +884,7 @@
}
s->what |= layer_state_t::eRelativeLayerChanged;
s->what &= ~layer_state_t::eLayerChanged;
- s->relativeLayerHandle = relativeTo;
+ s->relativeLayerSurfaceControl = relativeTo;
s->z = z;
registerSurfaceControlForCallback(sc);
@@ -1028,33 +1028,16 @@
}
SurfaceComposerClient::Transaction&
-SurfaceComposerClient::Transaction::deferTransactionUntil_legacy(const sp<SurfaceControl>& sc,
- const sp<IBinder>& handle,
- uint64_t frameNumber) {
+SurfaceComposerClient::Transaction::deferTransactionUntil_legacy(
+ const sp<SurfaceControl>& sc, const sp<SurfaceControl>& barrierSurfaceControl,
+ uint64_t frameNumber) {
layer_state_t* s = getLayerState(sc);
if (!s) {
mStatus = BAD_INDEX;
return *this;
}
s->what |= layer_state_t::eDeferTransaction_legacy;
- s->barrierHandle_legacy = handle;
- s->barrierFrameNumber = frameNumber;
-
- registerSurfaceControlForCallback(sc);
- return *this;
-}
-
-SurfaceComposerClient::Transaction&
-SurfaceComposerClient::Transaction::deferTransactionUntil_legacy(const sp<SurfaceControl>& sc,
- const sp<Surface>& barrierSurface,
- uint64_t frameNumber) {
- layer_state_t* s = getLayerState(sc);
- if (!s) {
- mStatus = BAD_INDEX;
- return *this;
- }
- s->what |= layer_state_t::eDeferTransaction_legacy;
- s->barrierGbp_legacy = barrierSurface->getIGraphicBufferProducer();
+ s->barrierSurfaceControl_legacy = barrierSurfaceControl;
s->barrierFrameNumber = frameNumber;
registerSurfaceControlForCallback(sc);
@@ -1062,30 +1045,28 @@
}
SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::reparentChildren(
- const sp<SurfaceControl>& sc,
- const sp<IBinder>& newParentHandle) {
+ const sp<SurfaceControl>& sc, const sp<SurfaceControl>& newParent) {
layer_state_t* s = getLayerState(sc);
if (!s) {
mStatus = BAD_INDEX;
return *this;
}
s->what |= layer_state_t::eReparentChildren;
- s->reparentHandle = newParentHandle;
+ s->reparentSurfaceControl = newParent;
registerSurfaceControlForCallback(sc);
return *this;
}
SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::reparent(
- const sp<SurfaceControl>& sc,
- const sp<IBinder>& newParentHandle) {
+ const sp<SurfaceControl>& sc, const sp<SurfaceControl>& newParent) {
layer_state_t* s = getLayerState(sc);
if (!s) {
mStatus = BAD_INDEX;
return *this;
}
s->what |= layer_state_t::eReparent;
- s->parentHandleForChild = newParentHandle;
+ s->parentSurfaceControlForChild = newParent;
registerSurfaceControlForCallback(sc);
return *this;
diff --git a/libs/gui/SurfaceControl.cpp b/libs/gui/SurfaceControl.cpp
index e37ff89..e842382 100644
--- a/libs/gui/SurfaceControl.cpp
+++ b/libs/gui/SurfaceControl.cpp
@@ -24,6 +24,7 @@
#include <android/native_window.h>
#include <utils/Errors.h>
+#include <utils/KeyedVector.h>
#include <utils/Log.h>
#include <utils/threads.h>
diff --git a/libs/gui/include/gui/BLASTBufferQueue.h b/libs/gui/include/gui/BLASTBufferQueue.h
index 35c656a..5b1a018 100644
--- a/libs/gui/include/gui/BLASTBufferQueue.h
+++ b/libs/gui/include/gui/BLASTBufferQueue.h
@@ -94,6 +94,8 @@
void processNextBufferLocked(bool useNextTransaction) REQUIRES(mMutex);
Rect computeCrop(const BufferItem& item);
+ // Return true if we need to reject the buffer based on the scaling mode and the buffer size.
+ bool rejectBuffer(const BufferItem& item) const;
std::string mName;
sp<SurfaceControl> mSurfaceControl;
@@ -107,6 +109,7 @@
int32_t mNumFrameAvailable GUARDED_BY(mMutex);
int32_t mNumAcquired GUARDED_BY(mMutex);
+ bool mInitialCallbackReceived GUARDED_BY(mMutex) = false;
struct PendingReleaseItem {
BufferItem item;
sp<Fence> releaseFence;
diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h
index 65fd9ab..fed0ef3 100644
--- a/libs/gui/include/gui/LayerState.h
+++ b/libs/gui/include/gui/LayerState.h
@@ -49,6 +49,7 @@
#include <gui/ISurfaceComposer.h>
#include <gui/LayerMetadata.h>
+#include <gui/SurfaceControl.h>
#include <math/vec3.h>
#include <ui/GraphicTypes.h>
#include <ui/Rect.h>
@@ -128,44 +129,7 @@
eFrameNumberChanged = 0x400'00000000,
};
- layer_state_t()
- : what(0),
- x(0),
- y(0),
- z(0),
- w(0),
- h(0),
- layerStack(0),
- alpha(0),
- flags(0),
- mask(0),
- reserved(0),
- crop_legacy(Rect::INVALID_RECT),
- cornerRadius(0.0f),
- backgroundBlurRadius(0),
- barrierFrameNumber(0),
- overrideScalingMode(-1),
- transform(0),
- transformToDisplayInverse(false),
- crop(Rect::INVALID_RECT),
- orientedDisplaySpaceRect(Rect::INVALID_RECT),
- dataspace(ui::Dataspace::UNKNOWN),
- surfaceDamageRegion(),
- api(-1),
- colorTransform(mat4()),
- bgColorAlpha(0),
- bgColorDataspace(ui::Dataspace::UNKNOWN),
- colorSpaceAgnostic(false),
- shadowRadius(0.0f),
- frameRateSelectionPriority(-1),
- frameRate(0.0f),
- frameRateCompatibility(ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT),
- fixedTransformHint(ui::Transform::ROT_INVALID),
- frameNumber(0) {
- matrix.dsdx = matrix.dtdy = 1.0f;
- matrix.dsdy = matrix.dtdx = 0.0f;
- hdrMetadata.validTypes = 0;
- }
+ layer_state_t();
void merge(const layer_state_t& other);
status_t write(Parcel& output) const;
@@ -196,16 +160,14 @@
Rect crop_legacy;
float cornerRadius;
uint32_t backgroundBlurRadius;
- sp<IBinder> barrierHandle_legacy;
- sp<IBinder> reparentHandle;
+ sp<SurfaceControl> barrierSurfaceControl_legacy;
+ sp<SurfaceControl> reparentSurfaceControl;
uint64_t barrierFrameNumber;
int32_t overrideScalingMode;
- sp<IGraphicBufferProducer> barrierGbp_legacy;
+ sp<SurfaceControl> relativeLayerSurfaceControl;
- sp<IBinder> relativeLayerHandle;
-
- sp<IBinder> parentHandleForChild;
+ sp<SurfaceControl> parentSurfaceControlForChild;
half3 color;
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index cc82502..277060f 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -424,7 +424,7 @@
// If the relative is removed, the Surface will have no layer and be
// invisible, until the next time set(Relative)Layer is called.
Transaction& setRelativeLayer(const sp<SurfaceControl>& sc,
- const sp<IBinder>& relativeTo, int32_t z);
+ const sp<SurfaceControl>& relativeTo, int32_t z);
Transaction& setFlags(const sp<SurfaceControl>& sc,
uint32_t flags, uint32_t mask);
Transaction& setTransparentRegionHint(const sp<SurfaceControl>& sc,
@@ -444,22 +444,16 @@
// by handle is removed, then we will apply this transaction regardless of
// what frame number has been reached.
Transaction& deferTransactionUntil_legacy(const sp<SurfaceControl>& sc,
- const sp<IBinder>& handle, uint64_t frameNumber);
- // A variant of deferTransactionUntil_legacy which identifies the Layer we wait for by
- // Surface instead of Handle. Useful for clients which may not have the
- // SurfaceControl for some of their Surfaces. Otherwise behaves identically.
- Transaction& deferTransactionUntil_legacy(const sp<SurfaceControl>& sc,
- const sp<Surface>& barrierSurface,
+ const sp<SurfaceControl>& barrierSurfaceControl,
uint64_t frameNumber);
// Reparents all children of this layer to the new parent handle.
Transaction& reparentChildren(const sp<SurfaceControl>& sc,
- const sp<IBinder>& newParentHandle);
+ const sp<SurfaceControl>& newParent);
/// Reparents the current layer to the new parent handle. The new parent must not be null.
// This can be used instead of reparentChildren if the caller wants to
// only re-parent a specific child.
- Transaction& reparent(const sp<SurfaceControl>& sc,
- const sp<IBinder>& newParentHandle);
+ Transaction& reparent(const sp<SurfaceControl>& sc, const sp<SurfaceControl>& newParent);
Transaction& setColor(const sp<SurfaceControl>& sc, const half3& color);
diff --git a/libs/gui/include/gui/SurfaceControl.h b/libs/gui/include/gui/SurfaceControl.h
index c0dfcdb..35bdfc1 100644
--- a/libs/gui/include/gui/SurfaceControl.h
+++ b/libs/gui/include/gui/SurfaceControl.h
@@ -20,7 +20,6 @@
#include <stdint.h>
#include <sys/types.h>
-#include <utils/KeyedVector.h>
#include <utils/RefBase.h>
#include <utils/threads.h>
diff --git a/libs/gui/tests/EndToEndNativeInputTest.cpp b/libs/gui/tests/EndToEndNativeInputTest.cpp
index ef4d870..483f171 100644
--- a/libs/gui/tests/EndToEndNativeInputTest.cpp
+++ b/libs/gui/tests/EndToEndNativeInputTest.cpp
@@ -381,7 +381,7 @@
childSurface->doTransaction([&](auto &t, auto &sc) {
t.setPosition(sc, -5, -5);
- t.reparent(sc, parentSurface->mSurfaceControl->getHandle());
+ t.reparent(sc, parentSurface->mSurfaceControl);
});
injectTap(106, 106);
diff --git a/libs/input/InputEventLabels.cpp b/libs/input/InputEventLabels.cpp
index dee240c..c0aa2e2 100644
--- a/libs/input/InputEventLabels.cpp
+++ b/libs/input/InputEventLabels.cpp
@@ -348,6 +348,9 @@
DEFINE_AXIS(SCROLL), \
DEFINE_AXIS(RELATIVE_X), \
DEFINE_AXIS(RELATIVE_Y), \
+ {"RESERVED_29", 29}, \
+ {"RESERVED_30", 30}, \
+ {"RESERVED_31", 31}, \
DEFINE_AXIS(GENERIC_1), \
DEFINE_AXIS(GENERIC_2), \
DEFINE_AXIS(GENERIC_3), \
diff --git a/libs/input/tests/Android.bp b/libs/input/tests/Android.bp
index 7ff5ab6..44147a5 100644
--- a/libs/input/tests/Android.bp
+++ b/libs/input/tests/Android.bp
@@ -2,6 +2,7 @@
cc_test {
name: "libinput_tests",
srcs: [
+ "NamedEnum_test.cpp",
"Flags_test.cpp",
"IdGenerator_test.cpp",
"InputChannel_test.cpp",
diff --git a/libs/input/tests/NamedEnum_test.cpp b/libs/input/tests/NamedEnum_test.cpp
new file mode 100644
index 0000000..4e93f71
--- /dev/null
+++ b/libs/input/tests/NamedEnum_test.cpp
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gtest/gtest.h>
+#include <input/NamedEnum.h>
+
+namespace android {
+
+// Test enum class maximum enum value smaller than default maximum of 8.
+enum class TestEnums { ZERO = 0x0, ONE = 0x1, TWO = 0x2, THREE = 0x3, SEVEN = 0x7 };
+// Big enum contains enum values greater than default maximum of 8.
+enum class TestBigEnums { ZERO = 0x0, FIFTEEN = 0xF };
+
+// Declared to specialize the maximum enum since the enum size exceeds 8 by default.
+template <>
+constexpr size_t NamedEnum::max<TestBigEnums> = 16;
+
+namespace test {
+using android::TestBigEnums;
+using android::TestEnums;
+
+TEST(NamedEnum, RuntimeNamedEnum) {
+ TestEnums e = TestEnums::ZERO;
+ ASSERT_EQ(NamedEnum::enum_name(e), "ZERO");
+
+ e = TestEnums::ONE;
+ ASSERT_EQ(NamedEnum::enum_name(e), "ONE");
+
+ e = TestEnums::THREE;
+ ASSERT_EQ(NamedEnum::enum_name(e), "THREE");
+
+ e = TestEnums::SEVEN;
+ ASSERT_EQ(NamedEnum::enum_name(e), "SEVEN");
+}
+
+// Test big enum
+TEST(NamedEnum, RuntimeBigNamedEnum) {
+ TestBigEnums e = TestBigEnums::ZERO;
+ ASSERT_EQ(NamedEnum::enum_name(e), "ZERO");
+
+ e = TestBigEnums::FIFTEEN;
+ ASSERT_EQ(NamedEnum::enum_name(e), "FIFTEEN");
+}
+
+TEST(NamedEnum, RuntimeNamedEnumAsString) {
+ TestEnums e = TestEnums::ZERO;
+ ASSERT_EQ(NamedEnum::string(e), "ZERO");
+
+ e = TestEnums::ONE;
+ ASSERT_EQ(NamedEnum::string(e), "ONE");
+
+ e = TestEnums::THREE;
+ ASSERT_EQ(NamedEnum::string(e), "THREE");
+
+ e = TestEnums::SEVEN;
+ ASSERT_EQ(NamedEnum::string(e), "SEVEN");
+}
+
+TEST(NamedEnum, RuntimeBigNamedEnumAsString) {
+ TestBigEnums e = TestBigEnums::ZERO;
+ ASSERT_EQ(NamedEnum::string(e), "ZERO");
+
+ e = TestBigEnums::FIFTEEN;
+ ASSERT_EQ(NamedEnum::string(e), "FIFTEEN");
+}
+
+TEST(NamedEnum, RuntimeUnknownNamedEnum) {
+ TestEnums e = static_cast<TestEnums>(0x5);
+ ASSERT_EQ(NamedEnum::enum_name(e), std::nullopt);
+ e = static_cast<TestEnums>(0x9);
+ ASSERT_EQ(NamedEnum::enum_name(e), std::nullopt);
+}
+
+TEST(NamedEnum, RuntimeUnknownNamedEnumAsString) {
+ TestEnums e = static_cast<TestEnums>(0x5);
+ ASSERT_EQ(NamedEnum::string(e), "0x00000005");
+ e = static_cast<TestEnums>(0x9);
+ ASSERT_EQ(NamedEnum::string(e), "0x00000009");
+}
+
+TEST(NamedEnum, CompileTimeFlagName) {
+ static_assert(NamedEnum::enum_name<TestEnums::TWO>() == "TWO");
+ static_assert(NamedEnum::enum_name<TestEnums::THREE>() == "THREE");
+}
+
+} // namespace test
+
+} // namespace android
diff --git a/libs/renderengine/include/renderengine/DisplaySettings.h b/libs/renderengine/include/renderengine/DisplaySettings.h
index ca16d2c..a637796 100644
--- a/libs/renderengine/include/renderengine/DisplaySettings.h
+++ b/libs/renderengine/include/renderengine/DisplaySettings.h
@@ -47,8 +47,8 @@
// DataSpace::UNKNOWN otherwise.
ui::Dataspace outputDataspace = ui::Dataspace::UNKNOWN;
- // Additional color transform to apply in linear space after transforming
- // to the output dataspace.
+ // Additional color transform to apply after transforming to the output
+ // dataspace, in non-linear space.
mat4 colorTransform = mat4();
// Region that will be cleared to (0, 0, 0, 1) prior to rendering.
diff --git a/libs/renderengine/skia/SkiaGLRenderEngine.cpp b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
index afedd48..69ad189 100644
--- a/libs/renderengine/skia/SkiaGLRenderEngine.cpp
+++ b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
@@ -15,17 +15,18 @@
*/
//#define LOG_NDEBUG 0
+#include <cstdint>
#undef LOG_TAG
#define LOG_TAG "RenderEngine"
#define ATRACE_TAG ATRACE_TAG_GRAPHICS
-#include "SkiaGLRenderEngine.h"
-
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <GLES2/gl2.h>
#include <GrContextOptions.h>
#include <SkCanvas.h>
+#include <SkColorFilter.h>
+#include <SkColorMatrix.h>
#include <SkColorSpace.h>
#include <SkImage.h>
#include <SkImageFilters.h>
@@ -39,6 +40,7 @@
#include <cmath>
#include "../gl/GLExtensions.h"
+#include "SkiaGLRenderEngine.h"
#include "filters/BlurFilter.h"
extern "C" EGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name);
@@ -381,6 +383,26 @@
return !!(desc.usage & usage);
}
+static float toDegrees(uint32_t transform) {
+ switch (transform) {
+ case ui::Transform::ROT_90:
+ return 90.0;
+ case ui::Transform::ROT_180:
+ return 180.0;
+ case ui::Transform::ROT_270:
+ return 270.0;
+ default:
+ return 0.0;
+ }
+}
+
+static SkColorMatrix toSkColorMatrix(const mat4& matrix) {
+ return SkColorMatrix(matrix[0][0], matrix[1][0], matrix[2][0], matrix[3][0], 0, matrix[0][1],
+ matrix[1][1], matrix[2][1], matrix[3][1], 0, matrix[0][2], matrix[1][2],
+ matrix[2][2], matrix[3][2], 0, matrix[0][3], matrix[1][3], matrix[2][3],
+ matrix[3][3], 0);
+}
+
void SkiaGLRenderEngine::unbindExternalTextureBuffer(uint64_t bufferId) {
std::lock_guard<std::mutex> lock(mRenderingMutex);
mImageCache.erase(bufferId);
@@ -441,20 +463,39 @@
ALOGE("Failed to make surface");
return BAD_VALUE;
}
+
auto canvas = surface->getCanvas();
+ // Clear the entire canvas with a transparent black to prevent ghost images.
+ canvas->clear(SK_ColorTRANSPARENT);
canvas->save();
// Before doing any drawing, let's make sure that we'll start at the origin of the display.
// Some displays don't start at 0,0 for example when we're mirroring the screen. Also, virtual
// displays might have different scaling when compared to the physical screen.
+
+ canvas->clipRect(getSkRect(display.physicalDisplay));
canvas->translate(display.physicalDisplay.left, display.physicalDisplay.top);
+
+ const auto clipWidth = display.clip.width();
+ const auto clipHeight = display.clip.height();
+ auto rotatedClipWidth = clipWidth;
+ auto rotatedClipHeight = clipHeight;
+ // Scale is contingent on the rotation result.
+ if (display.orientation & ui::Transform::ROT_90) {
+ std::swap(rotatedClipWidth, rotatedClipHeight);
+ }
const auto scaleX = static_cast<SkScalar>(display.physicalDisplay.width()) /
- static_cast<SkScalar>(display.clip.width());
+ static_cast<SkScalar>(rotatedClipWidth);
const auto scaleY = static_cast<SkScalar>(display.physicalDisplay.height()) /
- static_cast<SkScalar>(display.clip.height());
+ static_cast<SkScalar>(rotatedClipHeight);
canvas->scale(scaleX, scaleY);
- canvas->clipRect(getSkRect(display.clip));
- canvas->drawColor(0, SkBlendMode::kSrc);
+
+ // Canvas rotation is done by centering the clip window at the origin, rotating, translating
+ // back so that the top left corner of the clip is at (0, 0).
+ canvas->translate(rotatedClipWidth / 2, rotatedClipHeight / 2);
+ canvas->rotate(toDegrees(display.orientation));
+ canvas->translate(-clipWidth / 2, -clipHeight / 2);
+ canvas->translate(-display.clip.left, -display.clip.top);
for (const auto& layer : layers) {
SkPaint paint;
const auto& bounds = layer->geometry.boundaries;
@@ -468,6 +509,8 @@
if (layer->source.buffer.buffer) {
ATRACE_NAME("DrawImage");
const auto& item = layer->source.buffer;
+ const auto bufferWidth = item.buffer->getBounds().width();
+ const auto bufferHeight = item.buffer->getBounds().height();
sk_sp<SkImage> image;
auto iter = mImageCache.find(item.buffer->getId());
if (iter != mImageCache.end()) {
@@ -492,6 +535,38 @@
} else {
matrix.setIdentity();
}
+
+ auto texMatrix = getSkM44(item.textureTransform).asM33();
+ // textureTansform was intended to be passed directly into a shader, so when
+ // building the total matrix with the textureTransform we need to first
+ // normalize it, then apply the textureTransform, then scale back up.
+ matrix.postScale(1.0f / bufferWidth, 1.0f / bufferHeight);
+
+ auto rotatedBufferWidth = bufferWidth;
+ auto rotatedBufferHeight = bufferHeight;
+
+ // Swap the buffer width and height if we're rotating, so that we
+ // scale back up by the correct factors post-rotation.
+ if (texMatrix.getSkewX() <= -0.5f || texMatrix.getSkewX() >= 0.5f) {
+ std::swap(rotatedBufferWidth, rotatedBufferHeight);
+ // TODO: clean this up.
+ // GLESRenderEngine specifies its texture coordinates in
+ // CW orientation under OpenGL conventions, when they probably should have
+ // been CCW instead. The net result is that orientation
+ // transforms are applied in the reverse
+ // direction to render the correct result, because SurfaceFlinger uses the inverse
+ // of the display transform to correct for that. But this means that
+ // the tex transform passed by SkiaGLRenderEngine will rotate
+ // individual layers in the reverse orientation. Hack around it
+ // by injected a 180 degree rotation, but ultimately this is
+ // a bug in how SurfaceFlinger invokes the RenderEngine
+ // interface, so the proper fix should live there, and GLESRenderEngine
+ // should be fixed accordingly.
+ matrix.postRotate(180, 0.5, 0.5);
+ }
+
+ matrix.postConcat(texMatrix);
+ matrix.postScale(rotatedBufferWidth, rotatedBufferHeight);
paint.setShader(image->makeShader(matrix));
} else {
ATRACE_NAME("DrawColor");
@@ -499,6 +574,8 @@
paint.setColor(SkColor4f{.fR = color.r, .fG = color.g, .fB = color.b, layer->alpha});
}
+ paint.setColorFilter(SkColorFilters::Matrix(toSkColorMatrix(display.colorTransform)));
+
// Layers have a local transform matrix that should be applied to them.
canvas->save();
canvas->concat(getSkM44(layer->geometry.positionTransform));
diff --git a/libs/ui/include/ui/DisplayId.h b/libs/ui/include/ui/DisplayId.h
index 9eb5483..f196ab9 100644
--- a/libs/ui/include/ui/DisplayId.h
+++ b/libs/ui/include/ui/DisplayId.h
@@ -17,13 +17,20 @@
#pragma once
#include <cstdint>
-#include <functional>
+#include <optional>
#include <string>
namespace android {
// ID of a physical or a virtual display. This class acts as a type safe wrapper around uint64_t.
+// The encoding of the ID is type-specific for bits 0 to 61.
struct DisplayId {
+ // Flag indicating that the display is virtual.
+ static constexpr uint64_t FLAG_VIRTUAL = 1ULL << 63;
+
+ // Flag indicating that the ID is stable across reboots.
+ static constexpr uint64_t FLAG_STABLE = 1ULL << 62;
+
// TODO(b/162612135) Remove default constructor
DisplayId() = default;
constexpr DisplayId(const DisplayId&) = default;
@@ -51,8 +58,12 @@
// DisplayId of a physical display, such as the internal display or externally connected display.
struct PhysicalDisplayId : DisplayId {
- // Flag indicating that the ID is stable across reboots.
- static constexpr uint64_t FLAG_STABLE = 1ULL << 62;
+ static constexpr std::optional<PhysicalDisplayId> tryCast(DisplayId id) {
+ if (id.value & FLAG_VIRTUAL) {
+ return std::nullopt;
+ }
+ return {PhysicalDisplayId(id)};
+ }
// Returns a stable ID based on EDID information.
static constexpr PhysicalDisplayId fromEdid(uint8_t port, uint16_t manufacturerId,
@@ -69,8 +80,8 @@
// TODO(b/162612135) Remove default constructor
PhysicalDisplayId() = default;
+ // TODO(b/162612135) Remove constructor
explicit constexpr PhysicalDisplayId(uint64_t id) : DisplayId(id) {}
- explicit constexpr PhysicalDisplayId(DisplayId other) : DisplayId(other.value) {}
constexpr uint16_t getManufacturerId() const { return static_cast<uint16_t>(value >> 40); }
@@ -81,10 +92,82 @@
uint32_t modelHash)
: DisplayId(flags | (static_cast<uint64_t>(manufacturerId) << 40) |
(static_cast<uint64_t>(modelHash) << 8) | port) {}
+
+ explicit constexpr PhysicalDisplayId(DisplayId other) : DisplayId(other) {}
};
static_assert(sizeof(PhysicalDisplayId) == sizeof(uint64_t));
+struct VirtualDisplayId : DisplayId {
+ using BaseId = uint32_t;
+ // Flag indicating that this virtual display is backed by the GPU.
+ static constexpr uint64_t FLAG_GPU = 1ULL << 61;
+
+ static constexpr std::optional<VirtualDisplayId> tryCast(DisplayId id) {
+ if (id.value & FLAG_VIRTUAL) {
+ return {VirtualDisplayId(id)};
+ }
+ return std::nullopt;
+ }
+
+protected:
+ constexpr VirtualDisplayId(uint64_t flags, BaseId baseId)
+ : DisplayId(DisplayId::FLAG_VIRTUAL | flags | baseId) {}
+
+ explicit constexpr VirtualDisplayId(DisplayId other) : DisplayId(other) {}
+};
+
+struct HalVirtualDisplayId : VirtualDisplayId {
+ explicit constexpr HalVirtualDisplayId(BaseId baseId) : VirtualDisplayId(0, baseId) {}
+
+ static constexpr std::optional<HalVirtualDisplayId> tryCast(DisplayId id) {
+ if ((id.value & FLAG_VIRTUAL) && !(id.value & VirtualDisplayId::FLAG_GPU)) {
+ return {HalVirtualDisplayId(id)};
+ }
+ return std::nullopt;
+ }
+
+private:
+ explicit constexpr HalVirtualDisplayId(DisplayId other) : VirtualDisplayId(other) {}
+};
+
+struct GpuVirtualDisplayId : VirtualDisplayId {
+ explicit constexpr GpuVirtualDisplayId(BaseId baseId)
+ : VirtualDisplayId(VirtualDisplayId::FLAG_GPU, baseId) {}
+
+ static constexpr std::optional<GpuVirtualDisplayId> tryCast(DisplayId id) {
+ if ((id.value & FLAG_VIRTUAL) && (id.value & VirtualDisplayId::FLAG_GPU)) {
+ return {GpuVirtualDisplayId(id)};
+ }
+ return std::nullopt;
+ }
+
+private:
+ explicit constexpr GpuVirtualDisplayId(DisplayId other) : VirtualDisplayId(other) {}
+};
+
+// HalDisplayId is the ID of a display which is managed by HWC.
+// PhysicalDisplayId and HalVirtualDisplayId are implicitly convertible to HalDisplayId.
+struct HalDisplayId : DisplayId {
+ constexpr HalDisplayId(HalVirtualDisplayId other) : DisplayId(other) {}
+ constexpr HalDisplayId(PhysicalDisplayId other) : DisplayId(other) {}
+
+ static constexpr std::optional<HalDisplayId> tryCast(DisplayId id) {
+ if (GpuVirtualDisplayId::tryCast(id)) {
+ return std::nullopt;
+ }
+ return {HalDisplayId(id)};
+ }
+
+private:
+ explicit constexpr HalDisplayId(DisplayId other) : DisplayId(other) {}
+};
+
+static_assert(sizeof(VirtualDisplayId) == sizeof(uint64_t));
+static_assert(sizeof(HalVirtualDisplayId) == sizeof(uint64_t));
+static_assert(sizeof(GpuVirtualDisplayId) == sizeof(uint64_t));
+static_assert(sizeof(HalDisplayId) == sizeof(uint64_t));
+
} // namespace android
namespace std {
@@ -99,4 +182,13 @@
template <>
struct hash<android::PhysicalDisplayId> : hash<android::DisplayId> {};
+template <>
+struct hash<android::HalVirtualDisplayId> : hash<android::DisplayId> {};
+
+template <>
+struct hash<android::GpuVirtualDisplayId> : hash<android::DisplayId> {};
+
+template <>
+struct hash<android::HalDisplayId> : hash<android::DisplayId> {};
+
} // namespace std
diff --git a/libs/ui/tests/Android.bp b/libs/ui/tests/Android.bp
index 032dd4c..d005ce8 100644
--- a/libs/ui/tests/Android.bp
+++ b/libs/ui/tests/Android.bp
@@ -29,6 +29,13 @@
}
cc_test {
+ name: "DisplayId_test",
+ shared_libs: ["libui"],
+ srcs: ["DisplayId_test.cpp"],
+ cflags: ["-Wall", "-Werror"],
+}
+
+cc_test {
name: "FlattenableHelpers_test",
shared_libs: ["libui"],
srcs: ["FlattenableHelpers_test.cpp"],
diff --git a/libs/ui/tests/DisplayId_test.cpp b/libs/ui/tests/DisplayId_test.cpp
new file mode 100644
index 0000000..1d908b8
--- /dev/null
+++ b/libs/ui/tests/DisplayId_test.cpp
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <ui/DisplayId.h>
+
+#include <gtest/gtest.h>
+
+namespace android::ui {
+
+TEST(DisplayIdTest, createPhysicalIdFromEdid) {
+ constexpr uint8_t port = 1;
+ constexpr uint16_t manufacturerId = 13;
+ constexpr uint32_t modelHash = 42;
+ PhysicalDisplayId id = PhysicalDisplayId::fromEdid(port, manufacturerId, modelHash);
+ EXPECT_EQ(port, id.getPort());
+ EXPECT_EQ(manufacturerId, id.getManufacturerId());
+ EXPECT_FALSE(VirtualDisplayId::tryCast(id));
+ EXPECT_FALSE(HalVirtualDisplayId::tryCast(id));
+ EXPECT_FALSE(GpuVirtualDisplayId::tryCast(id));
+ EXPECT_TRUE(PhysicalDisplayId::tryCast(id));
+ EXPECT_TRUE(HalDisplayId::tryCast(id));
+}
+
+TEST(DisplayIdTest, createPhysicalIdFromPort) {
+ constexpr uint8_t port = 3;
+ PhysicalDisplayId id = PhysicalDisplayId::fromPort(port);
+ EXPECT_EQ(port, id.getPort());
+ EXPECT_FALSE(VirtualDisplayId::tryCast(id));
+ EXPECT_FALSE(HalVirtualDisplayId::tryCast(id));
+ EXPECT_FALSE(GpuVirtualDisplayId::tryCast(id));
+ EXPECT_TRUE(PhysicalDisplayId::tryCast(id));
+ EXPECT_TRUE(HalDisplayId::tryCast(id));
+}
+
+TEST(DisplayIdTest, createGpuVirtualId) {
+ GpuVirtualDisplayId id(42);
+ EXPECT_TRUE(VirtualDisplayId::tryCast(id));
+ EXPECT_TRUE(GpuVirtualDisplayId::tryCast(id));
+ EXPECT_FALSE(HalVirtualDisplayId::tryCast(id));
+ EXPECT_FALSE(PhysicalDisplayId::tryCast(id));
+ EXPECT_FALSE(HalDisplayId::tryCast(id));
+}
+
+TEST(DisplayIdTest, createHalVirtualId) {
+ HalVirtualDisplayId id(42);
+ EXPECT_TRUE(VirtualDisplayId::tryCast(id));
+ EXPECT_TRUE(HalVirtualDisplayId::tryCast(id));
+ EXPECT_FALSE(GpuVirtualDisplayId::tryCast(id));
+ EXPECT_FALSE(PhysicalDisplayId::tryCast(id));
+ EXPECT_TRUE(HalDisplayId::tryCast(id));
+}
+
+} // namespace android::ui
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 3ccb0c9..efe2bb1 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -2109,9 +2109,9 @@
auto otherInfo = otherHandle->getInfo();
if (!otherInfo->visible) {
return false;
- } else if (info->ownerPid == otherInfo->ownerPid) {
- // If ownerPid is the same we don't generate occlusion events as there
- // is no in-process security boundary.
+ } else if (info->ownerUid == otherInfo->ownerUid) {
+ // If ownerUid is the same we don't generate occlusion events as there
+ // is no security boundary within an uid.
return false;
} else if (otherInfo->trustedOverlay) {
return false;
diff --git a/services/inputflinger/reader/mapper/TouchInputMapper.cpp b/services/inputflinger/reader/mapper/TouchInputMapper.cpp
index e957826..ea84835 100644
--- a/services/inputflinger/reader/mapper/TouchInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/TouchInputMapper.cpp
@@ -18,6 +18,7 @@
#include "../Macros.h"
// clang-format on
+#include <input/NamedEnum.h>
#include "TouchInputMapper.h"
#include "CursorButtonAccumulator.h"
@@ -257,7 +258,8 @@
}
void TouchInputMapper::dump(std::string& dump) {
- dump += StringPrintf(INDENT2 "Touch Input Mapper (mode - %s):\n", modeToString(mDeviceMode));
+ dump += StringPrintf(INDENT2 "Touch Input Mapper (mode - %s):\n",
+ NamedEnum::string(mDeviceMode).c_str());
dumpParameters(dump);
dumpVirtualKeys(dump);
dumpRawPointerAxes(dump);
@@ -345,22 +347,6 @@
}
}
-const char* TouchInputMapper::modeToString(DeviceMode deviceMode) {
- switch (deviceMode) {
- case DeviceMode::DISABLED:
- return "disabled";
- case DeviceMode::DIRECT:
- return "direct";
- case DeviceMode::UNSCALED:
- return "unscaled";
- case DeviceMode::NAVIGATION:
- return "navigation";
- case DeviceMode::POINTER:
- return "pointer";
- }
- return "unknown";
-}
-
void TouchInputMapper::configure(nsecs_t when, const InputReaderConfiguration* config,
uint32_t changes) {
InputMapper::configure(when, config, changes);
@@ -512,33 +498,9 @@
void TouchInputMapper::dumpParameters(std::string& dump) {
dump += INDENT3 "Parameters:\n";
- switch (mParameters.gestureMode) {
- case Parameters::GestureMode::SINGLE_TOUCH:
- dump += INDENT4 "GestureMode: single-touch\n";
- break;
- case Parameters::GestureMode::MULTI_TOUCH:
- dump += INDENT4 "GestureMode: multi-touch\n";
- break;
- default:
- assert(false);
- }
+ dump += INDENT4 "GestureMode: " + NamedEnum::string(mParameters.gestureMode) + "\n";
- switch (mParameters.deviceType) {
- case Parameters::DeviceType::TOUCH_SCREEN:
- dump += INDENT4 "DeviceType: touchScreen\n";
- break;
- case Parameters::DeviceType::TOUCH_PAD:
- dump += INDENT4 "DeviceType: touchPad\n";
- break;
- case Parameters::DeviceType::TOUCH_NAVIGATION:
- dump += INDENT4 "DeviceType: touchNavigation\n";
- break;
- case Parameters::DeviceType::POINTER:
- dump += INDENT4 "DeviceType: pointer\n";
- break;
- default:
- ALOG_ASSERT(false);
- }
+ dump += INDENT4 "DeviceType: " + NamedEnum::string(mParameters.deviceType) + "\n";
dump += StringPrintf(INDENT4 "AssociatedDisplay: hasAssociatedDisplay=%s, isExternal=%s, "
"displayId='%s'\n",
diff --git a/services/sensorservice/SensorEventConnection.cpp b/services/sensorservice/SensorEventConnection.cpp
index d14a301..3cccaf9 100644
--- a/services/sensorservice/SensorEventConnection.cpp
+++ b/services/sensorservice/SensorEventConnection.cpp
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include <log/log.h>
#include <sys/socket.h>
#include <utils/threads.h>
@@ -53,20 +54,13 @@
SensorService::SensorEventConnection::~SensorEventConnection() {
ALOGD_IF(DEBUG_CONNECTIONS, "~SensorEventConnection(%p)", this);
destroy();
-}
-
-void SensorService::SensorEventConnection::destroy() {
- Mutex::Autolock _l(mDestroyLock);
-
- // destroy once only
- if (mDestroyed) {
- return;
- }
-
mService->cleanupConnection(this);
if (mEventCache != nullptr) {
delete[] mEventCache;
}
+}
+
+void SensorService::SensorEventConnection::destroy() {
mDestroyed = true;
}
@@ -679,6 +673,11 @@
int handle, bool enabled, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs,
int reservedFlags)
{
+ if (mDestroyed) {
+ android_errorWriteLog(0x534e4554, "168211968");
+ return DEAD_OBJECT;
+ }
+
status_t err;
if (enabled) {
err = mService->enable(this, handle, samplingPeriodNs, maxBatchReportLatencyNs,
@@ -693,10 +692,19 @@
status_t SensorService::SensorEventConnection::setEventRate(
int handle, nsecs_t samplingPeriodNs)
{
+ if (mDestroyed) {
+ android_errorWriteLog(0x534e4554, "168211968");
+ return DEAD_OBJECT;
+ }
+
return mService->setEventRate(this, handle, samplingPeriodNs, mOpPackageName);
}
status_t SensorService::SensorEventConnection::flush() {
+ if (mDestroyed) {
+ return DEAD_OBJECT;
+ }
+
return mService->flushSensor(this, mOpPackageName);
}
diff --git a/services/sensorservice/SensorEventConnection.h b/services/sensorservice/SensorEventConnection.h
index 8f2d5db..9487a39 100644
--- a/services/sensorservice/SensorEventConnection.h
+++ b/services/sensorservice/SensorEventConnection.h
@@ -17,6 +17,7 @@
#ifndef ANDROID_SENSOR_EVENT_CONNECTION_H
#define ANDROID_SENSOR_EVENT_CONNECTION_H
+#include <atomic>
#include <stdint.h>
#include <sys/types.h>
#include <unordered_map>
@@ -182,8 +183,8 @@
int mTotalAcksNeeded, mTotalAcksReceived;
#endif
- mutable Mutex mDestroyLock;
- bool mDestroyed;
+ // Used to track if this object was inappropriately used after destroy().
+ std::atomic_bool mDestroyed;
// Store a mapping of sensor handles to required AppOp for a sensor. This map only contains a
// valid mapping for sensors that require a permission in order to reduce the lookup time.
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp
index cf60b71..c77298e 100644
--- a/services/surfaceflinger/BufferLayer.cpp
+++ b/services/surfaceflinger/BufferLayer.cpp
@@ -366,7 +366,7 @@
mFrameTracker.setActualPresentFence(std::shared_ptr<FenceTime>(presentFence));
} else if (!display) {
// Do nothing.
- } else if (const auto displayId = display->getId();
+ } else if (const auto displayId = PhysicalDisplayId::tryCast(display->getId());
displayId && mFlinger->getHwComposer().isConnected(*displayId)) {
// The HWC doesn't support present fences, so use the refresh
// timestamp instead.
diff --git a/services/surfaceflinger/BufferQueueLayer.cpp b/services/surfaceflinger/BufferQueueLayer.cpp
index a574549..0863a22 100644
--- a/services/surfaceflinger/BufferQueueLayer.cpp
+++ b/services/surfaceflinger/BufferQueueLayer.cpp
@@ -340,7 +340,7 @@
FrameTracer::FrameEvent::LATCH);
if (mQueueItems[0].surfaceFrame) {
- mQueueItems[0].surfaceFrame->setActualEndTime(
+ mQueueItems[0].surfaceFrame->setAcquireFenceTime(
mQueueItems[0].item.mFenceTime->getSignalTime());
mFlinger->mFrameTimeline->addSurfaceFrame(std::move(mQueueItems[0].surfaceFrame),
PresentState::Presented);
diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp
index 2033f8e..361c1f3 100644
--- a/services/surfaceflinger/BufferStateLayer.cpp
+++ b/services/surfaceflinger/BufferStateLayer.cpp
@@ -162,8 +162,8 @@
mCurrentStateModified = mCurrentState.modified;
bool stateUpdateAvailable = Layer::applyPendingStates(stateToCommit);
if (stateUpdateAvailable && mCallbackHandleAcquireTime != -1) {
- // Update the actual end time if we have a buffer
- mSurfaceFrame->setActualEndTime(mCallbackHandleAcquireTime);
+ // Update the acquire fence time if we have a buffer
+ mSurfaceFrame->setAcquireFenceTime(mCallbackHandleAcquireTime);
}
mCurrentStateModified = stateUpdateAvailable && mCurrentStateModified;
mCurrentState.modified = false;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/Display.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/Display.h
index a38d1f3..01dd534 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/Display.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/Display.h
@@ -34,8 +34,8 @@
*/
class Display : public virtual Output {
public:
- // Gets the HWC DisplayId for the display if there is one
- virtual const std::optional<DisplayId>& getId() const = 0;
+ // Gets the DisplayId for the display
+ virtual DisplayId getId() const = 0;
// True if the display is secure
virtual bool isSecure() const = 0;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplayCreationArgs.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplayCreationArgs.h
index 6bc677d..95ba9f0 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplayCreationArgs.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplayCreationArgs.h
@@ -20,12 +20,14 @@
#include <optional>
#include <string>
+#include <ui/DisplayId.h>
#include <ui/DisplayInfo.h>
#include <ui/PixelFormat.h>
#include <ui/Size.h>
#include "DisplayHardware/DisplayIdentification.h"
#include "DisplayHardware/PowerAdvisor.h"
+#include "DisplayIdGenerator.h"
namespace android::compositionengine {
@@ -65,6 +67,9 @@
// Debugging. Human readable name for the display.
std::string name;
+
+ // Generator for IDs of virtual displays, which are backed by the GPU.
+ DisplayIdGenerator<GpuVirtualDisplayId>* gpuVirtualDisplayIdGenerator;
};
/**
@@ -95,6 +100,12 @@
return *this;
}
+ DisplayCreationArgsBuilder& setGpuVirtualDisplayIdGenerator(
+ DisplayIdGenerator<GpuVirtualDisplayId>& generator) {
+ mArgs.gpuVirtualDisplayIdGenerator = &generator;
+ return *this;
+ }
+
DisplayCreationArgsBuilder& setIsSecure(bool isSecure) {
mArgs.isSecure = isSecure;
return *this;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h
index 7a4f738..54e91ae 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h
@@ -57,7 +57,7 @@
void finishFrame(const CompositionRefreshArgs&) override;
// compositionengine::Display overrides
- const std::optional<DisplayId>& getId() const override;
+ DisplayId getId() const override;
bool isSecure() const override;
bool isVirtual() const override;
void disconnect() override;
@@ -85,12 +85,14 @@
std::unique_ptr<compositionengine::OutputLayer> createOutputLayer(const sp<LayerFE>&) const;
// Testing
- void setDisplayIdForTesting(std::optional<DisplayId> displayId);
+ void setDisplayIdForTesting(DisplayId displayId);
private:
bool mIsVirtual = false;
- std::optional<DisplayId> mId;
+ bool mIsDisconnected = false;
+ DisplayId mId;
Hwc2::PowerAdvisor* mPowerAdvisor = nullptr;
+ DisplayIdGenerator<GpuVirtualDisplayId>* mGpuVirtualDisplayIdGenerator;
};
// This template factory function standardizes the implementation details of the
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Display.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Display.h
index 3a4c70f..08a8b84 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Display.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Display.h
@@ -32,7 +32,7 @@
Display();
virtual ~Display();
- MOCK_CONST_METHOD0(getId, const std::optional<DisplayId>&());
+ MOCK_CONST_METHOD0(getId, DisplayId());
MOCK_CONST_METHOD0(isSecure, bool());
MOCK_CONST_METHOD0(isVirtual, bool());
diff --git a/services/surfaceflinger/CompositionEngine/src/Display.cpp b/services/surfaceflinger/CompositionEngine/src/Display.cpp
index 5459861..0b0b8d5 100644
--- a/services/surfaceflinger/CompositionEngine/src/Display.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Display.cpp
@@ -51,19 +51,26 @@
void Display::setConfiguration(const compositionengine::DisplayCreationArgs& args) {
mIsVirtual = !args.physical;
- mId = args.physical ? std::make_optional(args.physical->id) : std::nullopt;
mPowerAdvisor = args.powerAdvisor;
-
editState().isSecure = args.isSecure;
editState().displaySpace.bounds = Rect(args.pixels);
-
setLayerStackFilter(args.layerStackId,
- args.physical ? args.physical->type == DisplayConnectionType::Internal
- : false);
+ args.physical && args.physical->type == DisplayConnectionType::Internal);
setName(args.name);
+ mGpuVirtualDisplayIdGenerator = args.gpuVirtualDisplayIdGenerator;
- if (!args.physical && args.useHwcVirtualDisplays) {
- mId = maybeAllocateDisplayIdForVirtualDisplay(args.pixels, args.pixelFormat);
+ if (args.physical) {
+ mId = args.physical->id;
+ } else {
+ std::optional<DisplayId> id;
+ if (args.useHwcVirtualDisplays) {
+ id = maybeAllocateDisplayIdForVirtualDisplay(args.pixels, args.pixelFormat);
+ }
+ if (!id) {
+ id = mGpuVirtualDisplayIdGenerator->nextId();
+ }
+ LOG_ALWAYS_FATAL_IF(!id, "Failed to generate display ID");
+ mId = *id;
}
}
@@ -78,7 +85,7 @@
return Output::isValid() && mPowerAdvisor;
}
-const std::optional<DisplayId>& Display::getId() const {
+DisplayId Display::getId() const {
return mId;
}
@@ -94,31 +101,36 @@
return mId;
}
-void Display::setDisplayIdForTesting(std::optional<DisplayId> displayId) {
+void Display::setDisplayIdForTesting(DisplayId displayId) {
mId = displayId;
}
void Display::disconnect() {
- if (!mId) {
+ if (mIsDisconnected) {
return;
}
- auto& hwc = getCompositionEngine().getHwComposer();
- hwc.disconnectDisplay(*mId);
- mId.reset();
+ mIsDisconnected = true;
+ if (const auto id = GpuVirtualDisplayId::tryCast(mId)) {
+ mGpuVirtualDisplayIdGenerator->markUnused(*id);
+ return;
+ }
+ const auto halDisplayId = HalDisplayId::tryCast(mId);
+ LOG_FATAL_IF(!halDisplayId);
+ getCompositionEngine().getHwComposer().disconnectDisplay(*halDisplayId);
}
void Display::setColorTransform(const compositionengine::CompositionRefreshArgs& args) {
Output::setColorTransform(args);
-
- if (!mId || CC_LIKELY(!args.colorTransformMatrix)) {
+ const auto halDisplayId = HalDisplayId::tryCast(mId);
+ if (mIsDisconnected || !halDisplayId || CC_LIKELY(!args.colorTransformMatrix)) {
return;
}
auto& hwc = getCompositionEngine().getHwComposer();
- status_t result = hwc.setColorTransform(*mId, *args.colorTransformMatrix);
+ status_t result = hwc.setColorTransform(*halDisplayId, *args.colorTransformMatrix);
ALOGE_IF(result != NO_ERROR, "Failed to set color transform on display \"%s\": %d",
- mId ? to_string(*mId).c_str() : "", result);
+ to_string(mId).c_str(), result);
}
void Display::setColorProfile(const ColorProfile& colorProfile) {
@@ -140,8 +152,10 @@
Output::setColorProfile(colorProfile);
- auto& hwc = getCompositionEngine().getHwComposer();
- hwc.setActiveColorMode(*mId, colorProfile.mode, colorProfile.renderIntent);
+ const auto physicalId = PhysicalDisplayId::tryCast(mId);
+ LOG_FATAL_IF(!physicalId);
+ getCompositionEngine().getHwComposer().setActiveColorMode(*physicalId, colorProfile.mode,
+ colorProfile.renderIntent);
}
void Display::dump(std::string& out) const {
@@ -150,14 +164,8 @@
StringAppendF(&out, " Composition Display State: [\"%s\"]", getName().c_str());
out.append("\n ");
-
dumpVal(out, "isVirtual", mIsVirtual);
- if (mId) {
- dumpVal(out, "hwcId", to_string(*mId));
- } else {
- StringAppendF(&out, "no hwcId, ");
- }
-
+ dumpVal(out, "DisplayId", to_string(mId));
out.append("\n");
Output::dumpBase(out);
@@ -178,31 +186,33 @@
std::unique_ptr<compositionengine::OutputLayer> Display::createOutputLayer(
const sp<compositionengine::LayerFE>& layerFE) const {
- auto result = impl::createOutputLayer(*this, layerFE);
+ auto outputLayer = impl::createOutputLayer(*this, layerFE);
- if (result && mId) {
+ if (const auto halDisplayId = HalDisplayId::tryCast(mId);
+ outputLayer && !mIsDisconnected && halDisplayId) {
auto& hwc = getCompositionEngine().getHwComposer();
- auto displayId = *mId;
// Note: For the moment we ensure it is safe to take a reference to the
// HWComposer implementation by destroying all the OutputLayers (and
// hence the HWC2::Layers they own) before setting a new HWComposer. See
// for example SurfaceFlinger::updateVrFlinger().
// TODO(b/121291683): Make this safer.
- auto hwcLayer = std::shared_ptr<HWC2::Layer>(hwc.createLayer(displayId),
- [&hwc, displayId](HWC2::Layer* layer) {
- hwc.destroyLayer(displayId, layer);
- });
+ auto hwcLayer =
+ std::shared_ptr<HWC2::Layer>(hwc.createLayer(*halDisplayId),
+ [&hwc, id = *halDisplayId](HWC2::Layer* layer) {
+ hwc.destroyLayer(id, layer);
+ });
ALOGE_IF(!hwcLayer, "Failed to create a HWC layer for a HWC supported display %s",
getName().c_str());
- result->setHwcLayer(std::move(hwcLayer));
+ outputLayer->setHwcLayer(std::move(hwcLayer));
}
- return result;
+ return outputLayer;
}
void Display::setReleasedLayers(const compositionengine::CompositionRefreshArgs& refreshArgs) {
Output::setReleasedLayers(refreshArgs);
- if (!mId || refreshArgs.layersWithQueuedFrames.empty()) {
+ if (mIsDisconnected || GpuVirtualDisplayId::tryCast(mId) ||
+ refreshArgs.layersWithQueuedFrames.empty()) {
return;
}
@@ -238,19 +248,25 @@
ATRACE_CALL();
ALOGV(__FUNCTION__);
+ if (mIsDisconnected) {
+ return;
+ }
+
// Default to the base settings -- client composition only.
Output::chooseCompositionStrategy();
- // If we don't have a HWC display, then we are done
- if (!mId) {
+ // If we don't have a HWC display, then we are done.
+ const auto halDisplayId = HalDisplayId::tryCast(mId);
+ if (!halDisplayId) {
return;
}
// Get any composition changes requested by the HWC device, and apply them.
std::optional<android::HWComposer::DeviceRequestedChanges> changes;
auto& hwc = getCompositionEngine().getHwComposer();
- if (status_t result = hwc.getDeviceCompositionChanges(*mId, anyLayersRequireClientComposition(),
- &changes);
+ if (status_t result =
+ hwc.getDeviceCompositionChanges(*halDisplayId, anyLayersRequireClientComposition(),
+ &changes);
result != NO_ERROR) {
ALOGE("chooseCompositionStrategy failed for %s: %d (%s)", getName().c_str(), result,
strerror(-result));
@@ -271,8 +287,12 @@
bool Display::getSkipColorTransform() const {
const auto& hwc = getCompositionEngine().getHwComposer();
- return mId ? hwc.hasDisplayCapability(*mId, hal::DisplayCapability::SKIP_CLIENT_COLOR_TRANSFORM)
- : hwc.hasCapability(hal::Capability::SKIP_CLIENT_COLOR_TRANSFORM);
+ if (const auto halDisplayId = HalDisplayId::tryCast(mId)) {
+ return hwc.hasDisplayCapability(*halDisplayId,
+ hal::DisplayCapability::SKIP_CLIENT_COLOR_TRANSFORM);
+ }
+
+ return hwc.hasCapability(hal::Capability::SKIP_CLIENT_COLOR_TRANSFORM);
}
bool Display::anyLayersRequireClientComposition() const {
@@ -339,16 +359,17 @@
}
compositionengine::Output::FrameFences Display::presentAndGetFrameFences() {
- auto result = impl::Output::presentAndGetFrameFences();
+ auto fences = impl::Output::presentAndGetFrameFences();
- if (!mId) {
- return result;
+ const auto halDisplayIdOpt = HalDisplayId::tryCast(mId);
+ if (mIsDisconnected || !halDisplayIdOpt) {
+ return fences;
}
auto& hwc = getCompositionEngine().getHwComposer();
- hwc.presentAndGetReleaseFences(*mId);
+ hwc.presentAndGetReleaseFences(*halDisplayIdOpt);
- result.presentFence = hwc.getPresentFence(*mId);
+ fences.presentFence = hwc.getPresentFence(*halDisplayIdOpt);
// TODO(b/121291683): Change HWComposer call to return entire map
for (const auto* layer : getOutputLayersOrderedByZ()) {
@@ -357,19 +378,19 @@
continue;
}
- result.layerFences.emplace(hwcLayer, hwc.getLayerReleaseFence(*mId, hwcLayer));
+ fences.layerFences.emplace(hwcLayer, hwc.getLayerReleaseFence(*halDisplayIdOpt, hwcLayer));
}
- hwc.clearReleaseFences(*mId);
+ hwc.clearReleaseFences(*halDisplayIdOpt);
- return result;
+ return fences;
}
void Display::setExpensiveRenderingExpected(bool enabled) {
Output::setExpensiveRenderingExpected(enabled);
- if (mPowerAdvisor && mId) {
- mPowerAdvisor->setExpensiveRenderingExpected(*mId, enabled);
+ if (mPowerAdvisor && !GpuVirtualDisplayId::tryCast(mId)) {
+ mPowerAdvisor->setExpensiveRenderingExpected(mId, enabled);
}
}
@@ -378,11 +399,10 @@
// 1) It is being handled by hardware composer, which may need this to
// keep its virtual display state machine in sync, or
// 2) There is work to be done (the dirty region isn't empty)
- if (!mId) {
- if (getDirtyRegion(refreshArgs.repaintEverything).isEmpty()) {
- ALOGV("Skipping display composition");
- return;
- }
+ if (GpuVirtualDisplayId::tryCast(mId) &&
+ getDirtyRegion(refreshArgs.repaintEverything).isEmpty()) {
+ ALOGV("Skipping display composition");
+ return;
}
impl::Output::finishFrame(refreshArgs);
diff --git a/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp b/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
index 4519a9d..6d01bf1 100644
--- a/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
@@ -176,6 +176,7 @@
DisplayCreationArgs getDisplayCreationArgsForNonHWCVirtualDisplay() {
return DisplayCreationArgsBuilder()
.setUseHwcVirtualDisplays(false)
+ .setGpuVirtualDisplayIdGenerator(mGpuDisplayIdGenerator)
.setPixels({DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT})
.setPixelFormat(static_cast<ui::PixelFormat>(PIXEL_FORMAT_RGBA_8888))
.setIsSecure(false)
@@ -189,6 +190,7 @@
StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
StrictMock<mock::CompositionEngine> mCompositionEngine;
sp<mock::NativeWindow> mNativeWindow = new StrictMock<mock::NativeWindow>();
+ RandomDisplayIdGenerator<GpuVirtualDisplayId> mGpuDisplayIdGenerator;
};
struct PartialMockDisplayTestCommon : public DisplayTestCommon {
@@ -245,7 +247,7 @@
getDisplayCreationArgsForNonHWCVirtualDisplay());
EXPECT_FALSE(display->isSecure());
EXPECT_TRUE(display->isVirtual());
- EXPECT_EQ(std::nullopt, display->getId());
+ EXPECT_TRUE(GpuVirtualDisplayId::tryCast(display->getId()));
}
/*
@@ -332,6 +334,7 @@
mDisplay->setConfiguration(
DisplayCreationArgsBuilder()
.setUseHwcVirtualDisplays(true)
+ .setGpuVirtualDisplayIdGenerator(mGpuDisplayIdGenerator)
.setPixels(ui::Size(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_WIDTH))
.setPixelFormat(static_cast<ui::PixelFormat>(PIXEL_FORMAT_RGBA_8888))
.setIsSecure(false)
@@ -340,7 +343,7 @@
.setName(getDisplayNameFromCurrentTest())
.build());
- EXPECT_EQ(std::nullopt, mDisplay->getId());
+ EXPECT_TRUE(GpuVirtualDisplayId::tryCast(mDisplay->getId()));
EXPECT_FALSE(mDisplay->isSecure());
EXPECT_TRUE(mDisplay->isVirtual());
EXPECT_EQ(DEFAULT_LAYER_STACK, mDisplay->getState().layerStackId);
@@ -352,6 +355,7 @@
mDisplay->setConfiguration(
DisplayCreationArgsBuilder()
.setUseHwcVirtualDisplays(false)
+ .setGpuVirtualDisplayIdGenerator(mGpuDisplayIdGenerator)
.setPixels(ui::Size(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_WIDTH))
.setPixelFormat(static_cast<ui::PixelFormat>(PIXEL_FORMAT_RGBA_8888))
.setIsSecure(false)
@@ -360,7 +364,7 @@
.setName(getDisplayNameFromCurrentTest())
.build());
- EXPECT_EQ(std::nullopt, mDisplay->getId());
+ EXPECT_TRUE(GpuVirtualDisplayId::tryCast(mDisplay->getId()));
EXPECT_FALSE(mDisplay->isSecure());
EXPECT_TRUE(mDisplay->isVirtual());
EXPECT_EQ(DEFAULT_LAYER_STACK, mDisplay->getState().layerStackId);
@@ -375,16 +379,13 @@
using DisplayDisconnectTest = PartialMockDisplayTestCommon;
TEST_F(DisplayDisconnectTest, disconnectsDisplay) {
- // The first call to disconnect will disconnect the display with the HWC and
- // set mHwcId to -1.
- EXPECT_CALL(mHwComposer, disconnectDisplay(DEFAULT_DISPLAY_ID)).Times(1);
+ // The first call to disconnect will disconnect the display with the HWC.
+ EXPECT_CALL(mHwComposer, disconnectDisplay(HalDisplayId(DEFAULT_DISPLAY_ID))).Times(1);
mDisplay->disconnect();
- EXPECT_FALSE(mDisplay->getId());
// Subsequent calls will do nothing,
- EXPECT_CALL(mHwComposer, disconnectDisplay(DEFAULT_DISPLAY_ID)).Times(0);
+ EXPECT_CALL(mHwComposer, disconnectDisplay(HalDisplayId(DEFAULT_DISPLAY_ID))).Times(0);
mDisplay->disconnect();
- EXPECT_FALSE(mDisplay->getId());
}
/*
@@ -402,7 +403,8 @@
// Identity matrix sets an identity state value
const mat4 kIdentity;
- EXPECT_CALL(mHwComposer, setColorTransform(DEFAULT_DISPLAY_ID, kIdentity)).Times(1);
+ EXPECT_CALL(mHwComposer, setColorTransform(HalDisplayId(DEFAULT_DISPLAY_ID), kIdentity))
+ .Times(1);
refreshArgs.colorTransformMatrix = kIdentity;
mDisplay->setColorTransform(refreshArgs);
@@ -410,7 +412,8 @@
// Non-identity matrix sets a non-identity state value
const mat4 kNonIdentity = mat4() * 2;
- EXPECT_CALL(mHwComposer, setColorTransform(DEFAULT_DISPLAY_ID, kNonIdentity)).Times(1);
+ EXPECT_CALL(mHwComposer, setColorTransform(HalDisplayId(DEFAULT_DISPLAY_ID), kNonIdentity))
+ .Times(1);
refreshArgs.colorTransformMatrix = kNonIdentity;
mDisplay->setColorTransform(refreshArgs);
@@ -527,13 +530,14 @@
sp<mock::LayerFE> layerFE = new StrictMock<mock::LayerFE>();
StrictMock<HWC2::mock::Layer> hwcLayer;
- EXPECT_CALL(mHwComposer, createLayer(DEFAULT_DISPLAY_ID)).WillOnce(Return(&hwcLayer));
+ EXPECT_CALL(mHwComposer, createLayer(HalDisplayId(DEFAULT_DISPLAY_ID)))
+ .WillOnce(Return(&hwcLayer));
auto outputLayer = mDisplay->createOutputLayer(layerFE);
EXPECT_EQ(&hwcLayer, outputLayer->getHwcLayer());
- EXPECT_CALL(mHwComposer, destroyLayer(DEFAULT_DISPLAY_ID, &hwcLayer));
+ EXPECT_CALL(mHwComposer, destroyLayer(HalDisplayId(DEFAULT_DISPLAY_ID), &hwcLayer));
outputLayer.reset();
}
@@ -606,7 +610,7 @@
auto args = getDisplayCreationArgsForNonHWCVirtualDisplay();
std::shared_ptr<Display> nonHwcDisplay =
createPartialMockDisplay<Display>(mCompositionEngine, args);
- EXPECT_FALSE(nonHwcDisplay->getId());
+ EXPECT_TRUE(GpuVirtualDisplayId::tryCast(nonHwcDisplay->getId()));
nonHwcDisplay->chooseCompositionStrategy();
@@ -617,7 +621,8 @@
TEST_F(DisplayChooseCompositionStrategyTest, takesEarlyOutOnHwcError) {
EXPECT_CALL(*mDisplay, anyLayersRequireClientComposition()).WillOnce(Return(false));
- EXPECT_CALL(mHwComposer, getDeviceCompositionChanges(DEFAULT_DISPLAY_ID, false, _))
+ EXPECT_CALL(mHwComposer,
+ getDeviceCompositionChanges(HalDisplayId(DEFAULT_DISPLAY_ID), false, _))
.WillOnce(Return(INVALID_OPERATION));
mDisplay->chooseCompositionStrategy();
@@ -639,7 +644,7 @@
.InSequence(s)
.WillOnce(Return(false));
- EXPECT_CALL(mHwComposer, getDeviceCompositionChanges(DEFAULT_DISPLAY_ID, true, _))
+ EXPECT_CALL(mHwComposer, getDeviceCompositionChanges(HalDisplayId(DEFAULT_DISPLAY_ID), true, _))
.WillOnce(Return(NO_ERROR));
EXPECT_CALL(*mDisplay, allLayersRequireClientComposition()).WillOnce(Return(false));
@@ -669,7 +674,7 @@
.InSequence(s)
.WillOnce(Return(false));
- EXPECT_CALL(mHwComposer, getDeviceCompositionChanges(DEFAULT_DISPLAY_ID, true, _))
+ EXPECT_CALL(mHwComposer, getDeviceCompositionChanges(HalDisplayId(DEFAULT_DISPLAY_ID), true, _))
.WillOnce(DoAll(SetArgPointee<2>(changes), Return(NO_ERROR)));
EXPECT_CALL(*mDisplay, applyChangedTypesToLayers(changes.changedTypes)).Times(1);
EXPECT_CALL(*mDisplay, applyDisplayRequests(changes.displayRequests)).Times(1);
@@ -699,7 +704,7 @@
TEST_F(DisplayGetSkipColorTransformTest, checksDisplayCapability) {
EXPECT_CALL(mHwComposer,
- hasDisplayCapability(DEFAULT_DISPLAY_ID,
+ hasDisplayCapability(HalDisplayId(DEFAULT_DISPLAY_ID),
hal::DisplayCapability::SKIP_CLIENT_COLOR_TRANSFORM))
.WillOnce(Return(true));
EXPECT_TRUE(mDisplay->getSkipColorTransform());
@@ -857,13 +862,16 @@
sp<Fence> layer1Fence = new Fence();
sp<Fence> layer2Fence = new Fence();
- EXPECT_CALL(mHwComposer, presentAndGetReleaseFences(DEFAULT_DISPLAY_ID)).Times(1);
- EXPECT_CALL(mHwComposer, getPresentFence(DEFAULT_DISPLAY_ID)).WillOnce(Return(presentFence));
- EXPECT_CALL(mHwComposer, getLayerReleaseFence(DEFAULT_DISPLAY_ID, &mLayer1.hwc2Layer))
+ EXPECT_CALL(mHwComposer, presentAndGetReleaseFences(HalDisplayId(DEFAULT_DISPLAY_ID))).Times(1);
+ EXPECT_CALL(mHwComposer, getPresentFence(HalDisplayId(DEFAULT_DISPLAY_ID)))
+ .WillOnce(Return(presentFence));
+ EXPECT_CALL(mHwComposer,
+ getLayerReleaseFence(HalDisplayId(DEFAULT_DISPLAY_ID), &mLayer1.hwc2Layer))
.WillOnce(Return(layer1Fence));
- EXPECT_CALL(mHwComposer, getLayerReleaseFence(DEFAULT_DISPLAY_ID, &mLayer2.hwc2Layer))
+ EXPECT_CALL(mHwComposer,
+ getLayerReleaseFence(HalDisplayId(DEFAULT_DISPLAY_ID), &mLayer2.hwc2Layer))
.WillOnce(Return(layer2Fence));
- EXPECT_CALL(mHwComposer, clearReleaseFences(DEFAULT_DISPLAY_ID)).Times(1);
+ EXPECT_CALL(mHwComposer, clearReleaseFences(HalDisplayId(DEFAULT_DISPLAY_ID))).Times(1);
auto result = mDisplay->presentAndGetFrameFences();
diff --git a/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
index 1dd5df4..b5cda68 100644
--- a/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
+++ b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
@@ -42,63 +42,68 @@
MOCK_CONST_METHOD3(getDisplayIdentificationData,
bool(hal::HWDisplayId, uint8_t*, DisplayIdentificationData*));
MOCK_CONST_METHOD1(hasCapability, bool(hal::Capability));
- MOCK_CONST_METHOD2(hasDisplayCapability, bool(DisplayId, hal::DisplayCapability));
+ MOCK_CONST_METHOD2(hasDisplayCapability, bool(HalDisplayId, hal::DisplayCapability));
MOCK_METHOD3(allocateVirtualDisplay,
std::optional<DisplayId>(uint32_t, uint32_t, ui::PixelFormat*));
MOCK_METHOD2(allocatePhysicalDisplay, void(hal::HWDisplayId, PhysicalDisplayId));
- MOCK_METHOD1(createLayer, HWC2::Layer*(DisplayId));
- MOCK_METHOD2(destroyLayer, void(DisplayId, HWC2::Layer*));
+ MOCK_METHOD1(createLayer, HWC2::Layer*(HalDisplayId));
+ MOCK_METHOD2(destroyLayer, void(HalDisplayId, HWC2::Layer*));
MOCK_METHOD3(getDeviceCompositionChanges,
- status_t(DisplayId, bool,
+ status_t(HalDisplayId, bool,
std::optional<android::HWComposer::DeviceRequestedChanges>*));
MOCK_METHOD5(setClientTarget,
- status_t(DisplayId, uint32_t, const sp<Fence>&, const sp<GraphicBuffer>&,
+ status_t(HalDisplayId, uint32_t, const sp<Fence>&, const sp<GraphicBuffer>&,
ui::Dataspace));
- MOCK_METHOD1(presentAndGetReleaseFences, status_t(DisplayId));
- MOCK_METHOD2(setPowerMode, status_t(DisplayId, hal::PowerMode));
- MOCK_METHOD2(setActiveConfig, status_t(DisplayId, size_t));
- MOCK_METHOD2(setColorTransform, status_t(DisplayId, const mat4&));
- MOCK_METHOD1(disconnectDisplay, void(DisplayId));
+ MOCK_METHOD1(presentAndGetReleaseFences, status_t(HalDisplayId));
+ MOCK_METHOD2(setPowerMode, status_t(PhysicalDisplayId, hal::PowerMode));
+ MOCK_METHOD2(setActiveConfig, status_t(HalDisplayId, size_t));
+ MOCK_METHOD2(setColorTransform, status_t(HalDisplayId, const mat4&));
+ MOCK_METHOD1(disconnectDisplay, void(HalDisplayId));
MOCK_CONST_METHOD1(hasDeviceComposition, bool(const std::optional<DisplayId>&));
- MOCK_CONST_METHOD1(getPresentFence, sp<Fence>(DisplayId));
- MOCK_CONST_METHOD2(getLayerReleaseFence, sp<Fence>(DisplayId, HWC2::Layer*));
- MOCK_METHOD3(setOutputBuffer, status_t(DisplayId, const sp<Fence>&, const sp<GraphicBuffer>&));
- MOCK_METHOD1(clearReleaseFences, void(DisplayId));
- MOCK_METHOD2(getHdrCapabilities, status_t(DisplayId, HdrCapabilities*));
- MOCK_CONST_METHOD1(getSupportedPerFrameMetadata, int32_t(DisplayId));
- MOCK_CONST_METHOD2(getRenderIntents, std::vector<ui::RenderIntent>(DisplayId, ui::ColorMode));
- MOCK_METHOD2(getDataspaceSaturationMatrix, mat4(DisplayId, ui::Dataspace));
+ MOCK_CONST_METHOD1(getPresentFence, sp<Fence>(HalDisplayId));
+ MOCK_CONST_METHOD2(getLayerReleaseFence, sp<Fence>(HalDisplayId, HWC2::Layer*));
+ MOCK_METHOD3(setOutputBuffer,
+ status_t(HalVirtualDisplayId, const sp<Fence>&, const sp<GraphicBuffer>&));
+ MOCK_METHOD1(clearReleaseFences, void(HalDisplayId));
+ MOCK_METHOD2(getHdrCapabilities, status_t(HalDisplayId, HdrCapabilities*));
+ MOCK_CONST_METHOD1(getSupportedPerFrameMetadata, int32_t(HalDisplayId));
+ MOCK_CONST_METHOD2(getRenderIntents,
+ std::vector<ui::RenderIntent>(HalDisplayId, ui::ColorMode));
+ MOCK_METHOD2(getDataspaceSaturationMatrix, mat4(HalDisplayId, ui::Dataspace));
MOCK_METHOD4(getDisplayedContentSamplingAttributes,
- status_t(DisplayId, ui::PixelFormat*, ui::Dataspace*, uint8_t*));
- MOCK_METHOD4(setDisplayContentSamplingEnabled, status_t(DisplayId, bool, uint8_t, uint64_t));
+ status_t(HalDisplayId, ui::PixelFormat*, ui::Dataspace*, uint8_t*));
+ MOCK_METHOD4(setDisplayContentSamplingEnabled, status_t(HalDisplayId, bool, uint8_t, uint64_t));
MOCK_METHOD4(getDisplayedContentSample,
- status_t(DisplayId, uint64_t, uint64_t, DisplayedFrameStats*));
- MOCK_METHOD2(setDisplayBrightness, std::future<status_t>(DisplayId, float));
- MOCK_METHOD2(getDisplayBrightnessSupport, status_t(DisplayId, bool*));
+ status_t(HalDisplayId, uint64_t, uint64_t, DisplayedFrameStats*));
+ MOCK_METHOD2(setDisplayBrightness, std::future<status_t>(PhysicalDisplayId, float));
+ MOCK_METHOD2(getDisplayBrightnessSupport, status_t(PhysicalDisplayId, bool*));
MOCK_METHOD2(onHotplug,
std::optional<DisplayIdentificationInfo>(hal::HWDisplayId, hal::Connection));
MOCK_METHOD2(onVsync, bool(hal::HWDisplayId, int64_t));
- MOCK_METHOD2(setVsyncEnabled, void(DisplayId, hal::Vsync));
- MOCK_CONST_METHOD1(getRefreshTimestamp, nsecs_t(DisplayId));
- MOCK_CONST_METHOD1(isConnected, bool(DisplayId));
- MOCK_CONST_METHOD1(getConfigs,
- std::vector<std::shared_ptr<const HWC2::Display::Config>>(DisplayId));
- MOCK_CONST_METHOD1(getActiveConfig, std::shared_ptr<const HWC2::Display::Config>(DisplayId));
- MOCK_CONST_METHOD1(getActiveConfigIndex, int(DisplayId));
- MOCK_CONST_METHOD1(getColorModes, std::vector<ui::ColorMode>(DisplayId));
- MOCK_METHOD3(setActiveColorMode, status_t(DisplayId, ui::ColorMode, ui::RenderIntent));
+ MOCK_METHOD2(setVsyncEnabled, void(PhysicalDisplayId, hal::Vsync));
+ MOCK_CONST_METHOD1(getRefreshTimestamp, nsecs_t(PhysicalDisplayId));
+ MOCK_CONST_METHOD1(isConnected, bool(PhysicalDisplayId));
+ MOCK_CONST_METHOD1(
+ getConfigs,
+ std::vector<std::shared_ptr<const HWC2::Display::Config>>(PhysicalDisplayId));
+ MOCK_CONST_METHOD1(getActiveConfig,
+ std::shared_ptr<const HWC2::Display::Config>(PhysicalDisplayId));
+ MOCK_CONST_METHOD1(getActiveConfigIndex, int(PhysicalDisplayId));
+ MOCK_CONST_METHOD1(getColorModes, std::vector<ui::ColorMode>(PhysicalDisplayId));
+ MOCK_METHOD3(setActiveColorMode, status_t(PhysicalDisplayId, ui::ColorMode, ui::RenderIntent));
MOCK_CONST_METHOD0(isUsingVrComposer, bool());
- MOCK_CONST_METHOD1(getDisplayConnectionType, DisplayConnectionType(DisplayId));
- MOCK_CONST_METHOD1(isVsyncPeriodSwitchSupported, bool(DisplayId));
- MOCK_CONST_METHOD1(getDisplayVsyncPeriod, nsecs_t(DisplayId));
+ MOCK_CONST_METHOD1(getDisplayConnectionType, DisplayConnectionType(PhysicalDisplayId));
+ MOCK_CONST_METHOD1(isVsyncPeriodSwitchSupported, bool(PhysicalDisplayId));
+ MOCK_CONST_METHOD1(getDisplayVsyncPeriod, nsecs_t(PhysicalDisplayId));
MOCK_METHOD4(setActiveConfigWithConstraints,
- status_t(DisplayId, size_t, const hal::VsyncPeriodChangeConstraints&,
+ status_t(PhysicalDisplayId, size_t, const hal::VsyncPeriodChangeConstraints&,
hal::VsyncPeriodChangeTimeline*));
- MOCK_METHOD2(setAutoLowLatencyMode, status_t(DisplayId, bool));
- MOCK_METHOD2(getSupportedContentTypes, status_t(DisplayId, std::vector<hal::ContentType>*));
- MOCK_METHOD2(setContentType, status_t(DisplayId, hal::ContentType));
+ MOCK_METHOD2(setAutoLowLatencyMode, status_t(PhysicalDisplayId, bool));
+ MOCK_METHOD2(getSupportedContentTypes,
+ status_t(PhysicalDisplayId, std::vector<hal::ContentType>*));
+ MOCK_METHOD2(setContentType, status_t(PhysicalDisplayId, hal::ContentType));
MOCK_CONST_METHOD0(getSupportedLayerGenericMetadata,
const std::unordered_map<std::string, bool>&());
diff --git a/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp b/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp
index 8d1eb36..6ce8a6b 100644
--- a/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp
@@ -33,7 +33,7 @@
constexpr int32_t DEFAULT_DISPLAY_WIDTH = 1920;
constexpr int32_t DEFAULT_DISPLAY_HEIGHT = 1080;
-constexpr std::optional<DisplayId> DEFAULT_DISPLAY_ID = {PhysicalDisplayId(123u)};
+constexpr DisplayId DEFAULT_DISPLAY_ID = PhysicalDisplayId(123u);
const std::string DEFAULT_DISPLAY_NAME = "Mock Display";
using testing::_;
@@ -48,7 +48,7 @@
class RenderSurfaceTest : public testing::Test {
public:
RenderSurfaceTest() {
- EXPECT_CALL(mDisplay, getId()).WillRepeatedly(ReturnRef(DEFAULT_DISPLAY_ID));
+ EXPECT_CALL(mDisplay, getId()).WillRepeatedly(Return(DEFAULT_DISPLAY_ID));
EXPECT_CALL(mDisplay, getName()).WillRepeatedly(ReturnRef(DEFAULT_DISPLAY_NAME));
EXPECT_CALL(mCompositionEngine, getRenderEngine).WillRepeatedly(ReturnRef(mRenderEngine));
EXPECT_CALL(*mNativeWindow, disconnect(NATIVE_WINDOW_API_EGL))
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index a1ccaad..5bd7a1f 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -168,22 +168,16 @@
sPrimaryDisplayRotationFlags = ui::Transform::toRotationFlags(orientation);
}
- const Rect& displayBounds = getCompositionDisplay()->getState().displaySpace.bounds;
- const int displayWidth = displayBounds.width();
- const int displayHeight = displayBounds.height();
-
if (!orientedDisplaySpaceRect.isValid()) {
- // the destination frame can be invalid if it has never been set,
- // in that case we assume the whole display frame.
- orientedDisplaySpaceRect = Rect(displayWidth, displayHeight);
+ // The destination frame can be invalid if it has never been set,
+ // in that case we assume the whole display size.
+ orientedDisplaySpaceRect = getCompositionDisplay()->getState().displaySpace.bounds;
}
if (layerStackSpaceRect.isEmpty()) {
- // layerStackSpaceRect can be invalid if it has never been set, in that case
- // we assume the whole display size.
- // It's also invalid to have an empty layerStackSpaceRect, so we handle that
- // case in the same way.
- layerStackSpaceRect = Rect(displayWidth, displayHeight);
+ // The layerStackSpaceRect can be invalid if it has never been set, in that case
+ // we assume the whole framebuffer size.
+ layerStackSpaceRect = getCompositionDisplay()->getState().framebufferSpace.bounds;
if (orientation == ui::ROTATION_90 || orientation == ui::ROTATION_270) {
std::swap(layerStackSpaceRect.right, layerStackSpaceRect.bottom);
}
@@ -201,17 +195,12 @@
}
std::string DisplayDevice::getDebugName() const {
- std::string displayId;
- if (const auto id = getId()) {
- displayId = to_string(*id) + ", ";
- }
-
const char* type = "virtual";
if (mConnectionType) {
type = *mConnectionType == DisplayConnectionType::Internal ? "internal" : "external";
}
- return base::StringPrintf("DisplayDevice{%s%s%s, \"%s\"}", displayId.c_str(), type,
+ return base::StringPrintf("DisplayDevice{%s, %s%s, \"%s\"}", to_string(getId()).c_str(), type,
isPrimary() ? ", primary" : "", mDisplayName.c_str());
}
@@ -235,9 +224,7 @@
return mCompositionDisplay->getDisplayColorProfile()->hasRenderIntent(intent);
}
-// ----------------------------------------------------------------------------
-
-const std::optional<DisplayId>& DisplayDevice::getId() const {
+DisplayId DisplayDevice::getId() const {
return mCompositionDisplay->getId();
}
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index 35a8b62..fa684c0 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -27,6 +27,7 @@
#include <math/mat4.h>
#include <renderengine/RenderEngine.h>
#include <system/window.h>
+#include <ui/DisplayId.h>
#include <ui/DisplayInfo.h>
#include <ui/DisplayState.h>
#include <ui/GraphicTypes.h>
@@ -104,7 +105,15 @@
bool needsFiltering() const;
ui::LayerStack getLayerStack() const;
- const std::optional<DisplayId>& getId() const;
+ // Returns the physical ID of this display. This function asserts the ID is physical and it
+ // shouldn't be called for other display types, e.g. virtual.
+ PhysicalDisplayId getPhysicalId() const {
+ const auto displayIdOpt = PhysicalDisplayId::tryCast(getId());
+ LOG_FATAL_IF(!displayIdOpt);
+ return *displayIdOpt;
+ }
+
+ DisplayId getId() const;
const wp<IBinder>& getDisplayToken() const { return mDisplayToken; }
int32_t getSequenceId() const { return mSequenceId; }
diff --git a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
index 4c3b3e5..14b54cd 100644
--- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
+++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
@@ -56,7 +56,7 @@
*
*/
-FramebufferSurface::FramebufferSurface(HWComposer& hwc, DisplayId displayId,
+FramebufferSurface::FramebufferSurface(HWComposer& hwc, PhysicalDisplayId displayId,
const sp<IGraphicBufferConsumer>& consumer,
uint32_t maxWidth, uint32_t maxHeight)
: ConsumerBase(consumer),
diff --git a/services/surfaceflinger/DisplayHardware/FramebufferSurface.h b/services/surfaceflinger/DisplayHardware/FramebufferSurface.h
index a1859f3..759943a 100644
--- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.h
+++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.h
@@ -23,6 +23,7 @@
#include <compositionengine/DisplaySurface.h>
#include <compositionengine/impl/HwcBufferCache.h>
#include <gui/ConsumerBase.h>
+#include <ui/DisplayId.h>
#include <ui/Size.h>
#include "DisplayIdentification.h"
@@ -39,7 +40,7 @@
class FramebufferSurface : public ConsumerBase, public compositionengine::DisplaySurface {
public:
- FramebufferSurface(HWComposer& hwc, DisplayId displayId,
+ FramebufferSurface(HWComposer& hwc, PhysicalDisplayId displayId,
const sp<IGraphicBufferConsumer>& consumer, uint32_t maxWidth,
uint32_t maxHeight);
@@ -69,7 +70,7 @@
status_t nextBuffer(uint32_t& outSlot, sp<GraphicBuffer>& outBuffer,
sp<Fence>& outFence, ui::Dataspace& outDataspace);
- const DisplayId mDisplayId;
+ const PhysicalDisplayId mDisplayId;
// Framebuffer size has a dimension limitation in pixels based on the graphics capabilities of
// the device.
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.h b/services/surfaceflinger/DisplayHardware/HWC2.h
index 1f03787..89df84b 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.h
+++ b/services/surfaceflinger/DisplayHardware/HWC2.h
@@ -240,15 +240,14 @@
class Display : public HWC2::Display {
public:
- Display(android::Hwc2::Composer& composer,
- const std::unordered_set<hal::Capability>& capabilities, hal::HWDisplayId id,
- hal::DisplayType type);
+ Display(android::Hwc2::Composer&, const std::unordered_set<hal::Capability>&, hal::HWDisplayId,
+ hal::DisplayType);
~Display() override;
// Required by HWC2
hal::Error acceptChanges() override;
hal::Error createLayer(Layer** outLayer) override;
- hal::Error destroyLayer(Layer* layer) override;
+ hal::Error destroyLayer(Layer*) override;
hal::Error getActiveConfig(std::shared_ptr<const Config>* outConfig) const override;
hal::Error getActiveConfigIndex(int* outIndex) const override;
hal::Error getChangedCompositionTypes(
@@ -258,8 +257,7 @@
int32_t getSupportedPerFrameMetadata() const override;
hal::Error getRenderIntents(hal::ColorMode colorMode,
std::vector<hal::RenderIntent>* outRenderIntents) const override;
- hal::Error getDataspaceSaturationMatrix(hal::Dataspace dataspace,
- android::mat4* outMatrix) override;
+ hal::Error getDataspaceSaturationMatrix(hal::Dataspace, android::mat4* outMatrix) override;
// Doesn't call into the HWC2 device, so no errors are possible
std::vector<std::shared_ptr<const Config>> getConfigs() const override;
@@ -285,11 +283,11 @@
hal::Error setClientTarget(uint32_t slot, const android::sp<android::GraphicBuffer>& target,
const android::sp<android::Fence>& acquireFence,
hal::Dataspace dataspace) override;
- hal::Error setColorMode(hal::ColorMode mode, hal::RenderIntent renderIntent) override;
+ hal::Error setColorMode(hal::ColorMode, hal::RenderIntent) override;
hal::Error setColorTransform(const android::mat4& matrix, hal::ColorTransform hint) override;
- hal::Error setOutputBuffer(const android::sp<android::GraphicBuffer>& buffer,
+ hal::Error setOutputBuffer(const android::sp<android::GraphicBuffer>&,
const android::sp<android::Fence>& releaseFence) override;
- hal::Error setPowerMode(hal::PowerMode mode) override;
+ hal::Error setPowerMode(hal::PowerMode) override;
hal::Error setVsyncEnabled(hal::Vsync enabled) override;
hal::Error validate(uint32_t* outNumTypes, uint32_t* outNumRequests) override;
hal::Error presentOrValidate(uint32_t* outNumTypes, uint32_t* outNumRequests,
@@ -317,13 +315,13 @@
virtual bool isVsyncPeriodSwitchSupported() const override;
private:
- int32_t getAttribute(hal::HWConfigId configId, hal::Attribute attribute);
- void loadConfig(hal::HWConfigId configId);
+ int32_t getAttribute(hal::HWConfigId, hal::Attribute);
+ void loadConfig(hal::HWConfigId);
void loadConfigs();
// This may fail (and return a null pointer) if no layer with this ID exists
// on this display
- Layer* getLayerById(hal::HWLayerId id) const;
+ Layer* getLayerById(hal::HWLayerId) const;
friend android::TestableSurfaceFlinger;
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 195182a..2379e6e 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -186,7 +186,7 @@
return mCapabilities.count(capability) > 0;
}
-bool HWComposer::hasDisplayCapability(DisplayId displayId,
+bool HWComposer::hasDisplayCapability(HalDisplayId displayId,
hal::DisplayCapability capability) const {
RETURN_IF_INVALID_DISPLAY(displayId, false);
return mDisplayData.at(displayId).hwcDisplay->getCapabilities().count(capability) > 0;
@@ -214,10 +214,8 @@
RETURN_IF_INVALID_DISPLAY(*displayId, false);
auto& displayData = mDisplayData[*displayId];
- if (displayData.isVirtual) {
- LOG_DISPLAY_ERROR(*displayId, "Invalid operation on virtual display");
- return false;
- }
+ LOG_FATAL_IF(displayData.isVirtual, "%s: Invalid operation on virtual display with ID %s",
+ __FUNCTION__, to_string(*displayId));
{
std::lock_guard lock(displayData.lastHwVsyncLock);
@@ -244,11 +242,6 @@
std::optional<DisplayId> HWComposer::allocateVirtualDisplay(uint32_t width, uint32_t height,
ui::PixelFormat* format) {
- if (mRemainingHwcVirtualDisplays == 0) {
- ALOGE("%s: No remaining virtual displays", __FUNCTION__);
- return {};
- }
-
if (SurfaceFlinger::maxVirtualDisplaySize != 0 &&
(width > SurfaceFlinger::maxVirtualDisplaySize ||
height > SurfaceFlinger::maxVirtualDisplaySize)) {
@@ -256,31 +249,28 @@
height, SurfaceFlinger::maxVirtualDisplaySize);
return {};
}
+
+ const auto displayId = mVirtualIdGenerator.nextId();
+ if (!displayId) {
+ ALOGE("%s: No remaining virtual displays", __FUNCTION__);
+ return {};
+ }
+
hal::HWDisplayId hwcDisplayId = 0;
const auto error = static_cast<hal::Error>(
mComposer->createVirtualDisplay(width, height, format, &hwcDisplayId));
if (error != hal::Error::NONE) {
ALOGE("%s: Failed to create HWC virtual display", __FUNCTION__);
+ mVirtualIdGenerator.markUnused(*displayId);
return {};
}
auto display = std::make_unique<HWC2::impl::Display>(*mComposer.get(), mCapabilities,
hwcDisplayId, hal::DisplayType::VIRTUAL);
display->setConnected(true);
-
- DisplayId displayId;
- if (mFreeVirtualDisplayIds.empty()) {
- displayId = getVirtualDisplayId(mNextVirtualDisplayId++);
- } else {
- displayId = *mFreeVirtualDisplayIds.begin();
- mFreeVirtualDisplayIds.erase(displayId);
- }
-
- auto& displayData = mDisplayData[displayId];
+ auto& displayData = mDisplayData[*displayId];
displayData.hwcDisplay = std::move(display);
displayData.isVirtual = true;
-
- --mRemainingHwcVirtualDisplays;
return displayId;
}
@@ -301,7 +291,7 @@
mPhysicalDisplayIdMap[hwcDisplayId] = displayId;
}
-HWC2::Layer* HWComposer::createLayer(DisplayId displayId) {
+HWC2::Layer* HWComposer::createLayer(HalDisplayId displayId) {
RETURN_IF_INVALID_DISPLAY(displayId, nullptr);
HWC2::Layer* layer;
@@ -310,14 +300,14 @@
return layer;
}
-void HWComposer::destroyLayer(DisplayId displayId, HWC2::Layer* layer) {
+void HWComposer::destroyLayer(HalDisplayId displayId, HWC2::Layer* layer) {
RETURN_IF_INVALID_DISPLAY(displayId);
auto error = mDisplayData[displayId].hwcDisplay->destroyLayer(layer);
RETURN_IF_HWC_ERROR(error, displayId);
}
-nsecs_t HWComposer::getRefreshTimestamp(DisplayId displayId) const {
+nsecs_t HWComposer::getRefreshTimestamp(PhysicalDisplayId displayId) const {
RETURN_IF_INVALID_DISPLAY(displayId, 0);
const auto& displayData = mDisplayData.at(displayId);
// this returns the last refresh timestamp.
@@ -329,13 +319,13 @@
return now - ((now - displayData.lastHwVsync) % vsyncPeriodNanos);
}
-bool HWComposer::isConnected(DisplayId displayId) const {
+bool HWComposer::isConnected(PhysicalDisplayId displayId) const {
RETURN_IF_INVALID_DISPLAY(displayId, false);
return mDisplayData.at(displayId).hwcDisplay->isConnected();
}
std::vector<std::shared_ptr<const HWC2::Display::Config>> HWComposer::getConfigs(
- DisplayId displayId) const {
+ PhysicalDisplayId displayId) const {
RETURN_IF_INVALID_DISPLAY(displayId, {});
const auto& displayData = mDisplayData.at(displayId);
@@ -349,7 +339,7 @@
}
std::shared_ptr<const HWC2::Display::Config> HWComposer::getActiveConfig(
- DisplayId displayId) const {
+ PhysicalDisplayId displayId) const {
RETURN_IF_INVALID_DISPLAY(displayId, nullptr);
std::shared_ptr<const HWC2::Display::Config> config;
@@ -371,7 +361,7 @@
// Composer 2.4
-DisplayConnectionType HWComposer::getDisplayConnectionType(DisplayId displayId) const {
+DisplayConnectionType HWComposer::getDisplayConnectionType(PhysicalDisplayId displayId) const {
RETURN_IF_INVALID_DISPLAY(displayId, DisplayConnectionType::Internal);
const auto& hwcDisplay = mDisplayData.at(displayId).hwcDisplay;
@@ -386,12 +376,12 @@
return type;
}
-bool HWComposer::isVsyncPeriodSwitchSupported(DisplayId displayId) const {
+bool HWComposer::isVsyncPeriodSwitchSupported(PhysicalDisplayId displayId) const {
RETURN_IF_INVALID_DISPLAY(displayId, false);
return mDisplayData.at(displayId).hwcDisplay->isVsyncPeriodSwitchSupported();
}
-nsecs_t HWComposer::getDisplayVsyncPeriod(DisplayId displayId) const {
+nsecs_t HWComposer::getDisplayVsyncPeriod(PhysicalDisplayId displayId) const {
RETURN_IF_INVALID_DISPLAY(displayId, 0);
nsecs_t vsyncPeriodNanos;
@@ -400,7 +390,7 @@
return vsyncPeriodNanos;
}
-int HWComposer::getActiveConfigIndex(DisplayId displayId) const {
+int HWComposer::getActiveConfigIndex(PhysicalDisplayId displayId) const {
RETURN_IF_INVALID_DISPLAY(displayId, -1);
int index;
@@ -420,7 +410,7 @@
return index;
}
-std::vector<ui::ColorMode> HWComposer::getColorModes(DisplayId displayId) const {
+std::vector<ui::ColorMode> HWComposer::getColorModes(PhysicalDisplayId displayId) const {
RETURN_IF_INVALID_DISPLAY(displayId, {});
std::vector<ui::ColorMode> modes;
@@ -429,7 +419,7 @@
return modes;
}
-status_t HWComposer::setActiveColorMode(DisplayId displayId, ui::ColorMode mode,
+status_t HWComposer::setActiveColorMode(PhysicalDisplayId displayId, ui::ColorMode mode,
ui::RenderIntent renderIntent) {
RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
@@ -443,14 +433,12 @@
return NO_ERROR;
}
-void HWComposer::setVsyncEnabled(DisplayId displayId, hal::Vsync enabled) {
+void HWComposer::setVsyncEnabled(PhysicalDisplayId displayId, hal::Vsync enabled) {
RETURN_IF_INVALID_DISPLAY(displayId);
auto& displayData = mDisplayData[displayId];
- if (displayData.isVirtual) {
- LOG_DISPLAY_ERROR(displayId, "Invalid operation on virtual display");
- return;
- }
+ LOG_FATAL_IF(displayData.isVirtual, "%s: Invalid operation on virtual display with ID %s",
+ __FUNCTION__, to_string(*displayId));
// NOTE: we use our own internal lock here because we have to call
// into the HWC with the lock held, and we want to make sure
@@ -471,7 +459,7 @@
ATRACE_INT(tag.c_str(), enabled == hal::Vsync::ENABLE ? 1 : 0);
}
-status_t HWComposer::setClientTarget(DisplayId displayId, uint32_t slot,
+status_t HWComposer::setClientTarget(HalDisplayId displayId, uint32_t slot,
const sp<Fence>& acquireFence, const sp<GraphicBuffer>& target,
ui::Dataspace dataspace) {
RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
@@ -484,7 +472,7 @@
}
status_t HWComposer::getDeviceCompositionChanges(
- DisplayId displayId, bool frameUsesClientComposition,
+ HalDisplayId displayId, bool frameUsesClientComposition,
std::optional<android::HWComposer::DeviceRequestedChanges>* outChanges) {
ATRACE_CALL();
@@ -554,12 +542,12 @@
return NO_ERROR;
}
-sp<Fence> HWComposer::getPresentFence(DisplayId displayId) const {
+sp<Fence> HWComposer::getPresentFence(HalDisplayId displayId) const {
RETURN_IF_INVALID_DISPLAY(displayId, Fence::NO_FENCE);
return mDisplayData.at(displayId).lastPresentFence;
}
-sp<Fence> HWComposer::getLayerReleaseFence(DisplayId displayId, HWC2::Layer* layer) const {
+sp<Fence> HWComposer::getLayerReleaseFence(HalDisplayId displayId, HWC2::Layer* layer) const {
RETURN_IF_INVALID_DISPLAY(displayId, Fence::NO_FENCE);
const auto& displayFences = mDisplayData.at(displayId).releaseFences;
auto fence = displayFences.find(layer);
@@ -570,7 +558,7 @@
return fence->second;
}
-status_t HWComposer::presentAndGetReleaseFences(DisplayId displayId) {
+status_t HWComposer::presentAndGetReleaseFences(HalDisplayId displayId) {
ATRACE_CALL();
RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
@@ -598,14 +586,12 @@
return NO_ERROR;
}
-status_t HWComposer::setPowerMode(DisplayId displayId, hal::PowerMode mode) {
+status_t HWComposer::setPowerMode(PhysicalDisplayId displayId, hal::PowerMode mode) {
RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
const auto& displayData = mDisplayData[displayId];
- if (displayData.isVirtual) {
- LOG_DISPLAY_ERROR(displayId, "Invalid operation on virtual display");
- return INVALID_OPERATION;
- }
+ LOG_FATAL_IF(displayData.isVirtual, "%s: Invalid operation on virtual display with ID %s",
+ __FUNCTION__, to_string(*displayId));
if (mode == hal::PowerMode::OFF) {
setVsyncEnabled(displayId, hal::Vsync::DISABLE);
@@ -654,7 +640,8 @@
}
status_t HWComposer::setActiveConfigWithConstraints(
- DisplayId displayId, size_t configId, const hal::VsyncPeriodChangeConstraints& constraints,
+ PhysicalDisplayId displayId, size_t configId,
+ const hal::VsyncPeriodChangeConstraints& constraints,
hal::VsyncPeriodChangeTimeline* outTimeline) {
RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
@@ -671,7 +658,7 @@
return NO_ERROR;
}
-status_t HWComposer::setColorTransform(DisplayId displayId, const mat4& transform) {
+status_t HWComposer::setColorTransform(HalDisplayId displayId, const mat4& transform) {
RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
auto& displayData = mDisplayData[displayId];
@@ -684,15 +671,14 @@
return NO_ERROR;
}
-void HWComposer::disconnectDisplay(DisplayId displayId) {
+void HWComposer::disconnectDisplay(HalDisplayId displayId) {
RETURN_IF_INVALID_DISPLAY(displayId);
auto& displayData = mDisplayData[displayId];
// If this was a virtual display, add its slot back for reuse by future
// virtual displays
if (displayData.isVirtual) {
- mFreeVirtualDisplayIds.insert(displayId);
- ++mRemainingHwcVirtualDisplays;
+ mVirtualIdGenerator.markUnused(*HalVirtualDisplayId::tryCast(displayId));
}
const auto hwcDisplayId = displayData.hwcDisplay->getId();
@@ -707,27 +693,25 @@
mDisplayData.erase(displayId);
}
-status_t HWComposer::setOutputBuffer(DisplayId displayId, const sp<Fence>& acquireFence,
+status_t HWComposer::setOutputBuffer(HalVirtualDisplayId displayId, const sp<Fence>& acquireFence,
const sp<GraphicBuffer>& buffer) {
RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
const auto& displayData = mDisplayData[displayId];
- if (!displayData.isVirtual) {
- LOG_DISPLAY_ERROR(displayId, "Invalid operation on physical display");
- return INVALID_OPERATION;
- }
+ LOG_FATAL_IF(!displayData.isVirtual, "%s: Invalid operation on physical display with ID %s",
+ __FUNCTION__, to_string(*displayId));
auto error = displayData.hwcDisplay->setOutputBuffer(buffer, acquireFence);
RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
return NO_ERROR;
}
-void HWComposer::clearReleaseFences(DisplayId displayId) {
+void HWComposer::clearReleaseFences(HalDisplayId displayId) {
RETURN_IF_INVALID_DISPLAY(displayId);
mDisplayData[displayId].releaseFences.clear();
}
-status_t HWComposer::getHdrCapabilities(DisplayId displayId, HdrCapabilities* outCapabilities) {
+status_t HWComposer::getHdrCapabilities(HalDisplayId displayId, HdrCapabilities* outCapabilities) {
RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
auto& hwcDisplay = mDisplayData[displayId].hwcDisplay;
@@ -736,12 +720,12 @@
return NO_ERROR;
}
-int32_t HWComposer::getSupportedPerFrameMetadata(DisplayId displayId) const {
+int32_t HWComposer::getSupportedPerFrameMetadata(HalDisplayId displayId) const {
RETURN_IF_INVALID_DISPLAY(displayId, 0);
return mDisplayData.at(displayId).hwcDisplay->getSupportedPerFrameMetadata();
}
-std::vector<ui::RenderIntent> HWComposer::getRenderIntents(DisplayId displayId,
+std::vector<ui::RenderIntent> HWComposer::getRenderIntents(HalDisplayId displayId,
ui::ColorMode colorMode) const {
RETURN_IF_INVALID_DISPLAY(displayId, {});
@@ -751,7 +735,7 @@
return renderIntents;
}
-mat4 HWComposer::getDataspaceSaturationMatrix(DisplayId displayId, ui::Dataspace dataspace) {
+mat4 HWComposer::getDataspaceSaturationMatrix(HalDisplayId displayId, ui::Dataspace dataspace) {
RETURN_IF_INVALID_DISPLAY(displayId, {});
mat4 matrix;
@@ -761,7 +745,7 @@
return matrix;
}
-status_t HWComposer::getDisplayedContentSamplingAttributes(DisplayId displayId,
+status_t HWComposer::getDisplayedContentSamplingAttributes(HalDisplayId displayId,
ui::PixelFormat* outFormat,
ui::Dataspace* outDataspace,
uint8_t* outComponentMask) {
@@ -775,7 +759,7 @@
return NO_ERROR;
}
-status_t HWComposer::setDisplayContentSamplingEnabled(DisplayId displayId, bool enabled,
+status_t HWComposer::setDisplayContentSamplingEnabled(HalDisplayId displayId, bool enabled,
uint8_t componentMask, uint64_t maxFrames) {
RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
const auto error =
@@ -789,7 +773,7 @@
return NO_ERROR;
}
-status_t HWComposer::getDisplayedContentSample(DisplayId displayId, uint64_t maxFrames,
+status_t HWComposer::getDisplayedContentSample(HalDisplayId displayId, uint64_t maxFrames,
uint64_t timestamp, DisplayedFrameStats* outStats) {
RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
const auto error =
@@ -799,7 +783,8 @@
return NO_ERROR;
}
-std::future<status_t> HWComposer::setDisplayBrightness(DisplayId displayId, float brightness) {
+std::future<status_t> HWComposer::setDisplayBrightness(PhysicalDisplayId displayId,
+ float brightness) {
RETURN_IF_INVALID_DISPLAY(displayId, promise::yield<status_t>(BAD_INDEX));
auto& display = mDisplayData[displayId].hwcDisplay;
@@ -816,7 +801,7 @@
});
}
-status_t HWComposer::setAutoLowLatencyMode(DisplayId displayId, bool on) {
+status_t HWComposer::setAutoLowLatencyMode(PhysicalDisplayId displayId, bool on) {
RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
const auto error = mDisplayData[displayId].hwcDisplay->setAutoLowLatencyMode(on);
if (error == hal::Error::UNSUPPORTED) {
@@ -830,7 +815,7 @@
}
status_t HWComposer::getSupportedContentTypes(
- DisplayId displayId, std::vector<hal::ContentType>* outSupportedContentTypes) {
+ PhysicalDisplayId displayId, std::vector<hal::ContentType>* outSupportedContentTypes) {
RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
const auto error =
mDisplayData[displayId].hwcDisplay->getSupportedContentTypes(outSupportedContentTypes);
@@ -840,7 +825,7 @@
return NO_ERROR;
}
-status_t HWComposer::setContentType(DisplayId displayId, hal::ContentType contentType) {
+status_t HWComposer::setContentType(PhysicalDisplayId displayId, hal::ContentType contentType) {
RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
const auto error = mDisplayData[displayId].hwcDisplay->setContentType(contentType);
if (error == hal::Error::UNSUPPORTED) {
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index 488cdc5..028a9a4 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -38,6 +38,7 @@
#include <utils/StrongPointer.h>
#include <utils/Timers.h>
+#include "DisplayIdGenerator.h"
#include "DisplayIdentification.h"
#include "HWC2.h"
#include "Hal.h"
@@ -88,7 +89,7 @@
DisplayIdentificationData* outData) const = 0;
virtual bool hasCapability(hal::Capability) const = 0;
- virtual bool hasDisplayCapability(DisplayId, hal::DisplayCapability) const = 0;
+ virtual bool hasDisplayCapability(HalDisplayId, hal::DisplayCapability) const = 0;
// Attempts to allocate a virtual display and returns its ID if created on the HWC device.
virtual std::optional<DisplayId> allocateVirtualDisplay(uint32_t width, uint32_t height,
@@ -97,9 +98,9 @@
virtual void allocatePhysicalDisplay(hal::HWDisplayId, PhysicalDisplayId) = 0;
// Attempts to create a new layer on this display
- virtual HWC2::Layer* createLayer(DisplayId) = 0;
+ virtual HWC2::Layer* createLayer(HalDisplayId) = 0;
// Destroy a previously created layer
- virtual void destroyLayer(DisplayId, HWC2::Layer*) = 0;
+ virtual void destroyLayer(HalDisplayId, HWC2::Layer*) = 0;
// Gets any required composition change requests from the HWC device.
//
@@ -109,61 +110,60 @@
// with fewer handshakes, but this does not work if client composition is
// expected.
virtual status_t getDeviceCompositionChanges(
- DisplayId, bool frameUsesClientComposition,
+ HalDisplayId, bool frameUsesClientComposition,
std::optional<DeviceRequestedChanges>* outChanges) = 0;
- virtual status_t setClientTarget(DisplayId, uint32_t slot, const sp<Fence>& acquireFence,
+ virtual status_t setClientTarget(HalDisplayId, uint32_t slot, const sp<Fence>& acquireFence,
const sp<GraphicBuffer>& target, ui::Dataspace) = 0;
// Present layers to the display and read releaseFences.
- virtual status_t presentAndGetReleaseFences(DisplayId) = 0;
+ virtual status_t presentAndGetReleaseFences(HalDisplayId) = 0;
// set power mode
- virtual status_t setPowerMode(DisplayId, hal::PowerMode) = 0;
+ virtual status_t setPowerMode(PhysicalDisplayId, hal::PowerMode) = 0;
// Sets a color transform to be applied to the result of composition
- virtual status_t setColorTransform(DisplayId, const mat4& transform) = 0;
+ virtual status_t setColorTransform(HalDisplayId, const mat4& transform) = 0;
- // reset state when an external, non-virtual display is disconnected
- virtual void disconnectDisplay(DisplayId) = 0;
+ // reset state when a display is disconnected
+ virtual void disconnectDisplay(HalDisplayId) = 0;
// get the present fence received from the last call to present.
- virtual sp<Fence> getPresentFence(DisplayId) const = 0;
+ virtual sp<Fence> getPresentFence(HalDisplayId) const = 0;
// Get last release fence for the given layer
- virtual sp<Fence> getLayerReleaseFence(DisplayId, HWC2::Layer*) const = 0;
+ virtual sp<Fence> getLayerReleaseFence(HalDisplayId, HWC2::Layer*) const = 0;
// Set the output buffer and acquire fence for a virtual display.
- // Returns INVALID_OPERATION if displayId is not a virtual display.
- virtual status_t setOutputBuffer(DisplayId, const sp<Fence>& acquireFence,
+ virtual status_t setOutputBuffer(HalVirtualDisplayId, const sp<Fence>& acquireFence,
const sp<GraphicBuffer>& buffer) = 0;
// After SurfaceFlinger has retrieved the release fences for all the frames,
// it can call this to clear the shared pointers in the release fence map
- virtual void clearReleaseFences(DisplayId) = 0;
+ virtual void clearReleaseFences(HalDisplayId) = 0;
// Fetches the HDR capabilities of the given display
- virtual status_t getHdrCapabilities(DisplayId, HdrCapabilities* outCapabilities) = 0;
+ virtual status_t getHdrCapabilities(HalDisplayId, HdrCapabilities* outCapabilities) = 0;
- virtual int32_t getSupportedPerFrameMetadata(DisplayId) const = 0;
+ virtual int32_t getSupportedPerFrameMetadata(HalDisplayId) const = 0;
// Returns the available RenderIntent of the given display.
- virtual std::vector<ui::RenderIntent> getRenderIntents(DisplayId, ui::ColorMode) const = 0;
+ virtual std::vector<ui::RenderIntent> getRenderIntents(HalDisplayId, ui::ColorMode) const = 0;
- virtual mat4 getDataspaceSaturationMatrix(DisplayId, ui::Dataspace) = 0;
+ virtual mat4 getDataspaceSaturationMatrix(HalDisplayId, ui::Dataspace) = 0;
// Returns the attributes of the color sampling engine.
- virtual status_t getDisplayedContentSamplingAttributes(DisplayId, ui::PixelFormat* outFormat,
+ virtual status_t getDisplayedContentSamplingAttributes(HalDisplayId, ui::PixelFormat* outFormat,
ui::Dataspace* outDataspace,
uint8_t* outComponentMask) = 0;
- virtual status_t setDisplayContentSamplingEnabled(DisplayId, bool enabled,
+ virtual status_t setDisplayContentSamplingEnabled(HalDisplayId, bool enabled,
uint8_t componentMask,
uint64_t maxFrames) = 0;
- virtual status_t getDisplayedContentSample(DisplayId, uint64_t maxFrames, uint64_t timestamp,
+ virtual status_t getDisplayedContentSample(HalDisplayId, uint64_t maxFrames, uint64_t timestamp,
DisplayedFrameStats* outStats) = 0;
// Sets the brightness of a display.
- virtual std::future<status_t> setDisplayBrightness(DisplayId, float brightness) = 0;
+ virtual std::future<status_t> setDisplayBrightness(PhysicalDisplayId, float brightness) = 0;
// Events handling ---------------------------------------------------------
@@ -174,33 +174,35 @@
hal::Connection) = 0;
virtual bool onVsync(hal::HWDisplayId, int64_t timestamp) = 0;
- virtual void setVsyncEnabled(DisplayId, hal::Vsync enabled) = 0;
+ virtual void setVsyncEnabled(PhysicalDisplayId, hal::Vsync enabled) = 0;
- virtual nsecs_t getRefreshTimestamp(DisplayId) const = 0;
- virtual bool isConnected(DisplayId) const = 0;
+ virtual nsecs_t getRefreshTimestamp(PhysicalDisplayId) const = 0;
+ virtual bool isConnected(PhysicalDisplayId) const = 0;
// Non-const because it can update configMap inside of mDisplayData
virtual std::vector<std::shared_ptr<const HWC2::Display::Config>> getConfigs(
- DisplayId) const = 0;
+ PhysicalDisplayId) const = 0;
- virtual std::shared_ptr<const HWC2::Display::Config> getActiveConfig(DisplayId) const = 0;
- virtual int getActiveConfigIndex(DisplayId) const = 0;
+ virtual std::shared_ptr<const HWC2::Display::Config> getActiveConfig(
+ PhysicalDisplayId) const = 0;
+ virtual int getActiveConfigIndex(PhysicalDisplayId) const = 0;
- virtual std::vector<ui::ColorMode> getColorModes(DisplayId) const = 0;
+ virtual std::vector<ui::ColorMode> getColorModes(PhysicalDisplayId) const = 0;
- virtual status_t setActiveColorMode(DisplayId, ui::ColorMode mode, ui::RenderIntent) = 0;
+ virtual status_t setActiveColorMode(PhysicalDisplayId, ui::ColorMode mode,
+ ui::RenderIntent) = 0;
// Composer 2.4
- virtual DisplayConnectionType getDisplayConnectionType(DisplayId) const = 0;
- virtual bool isVsyncPeriodSwitchSupported(DisplayId) const = 0;
- virtual nsecs_t getDisplayVsyncPeriod(DisplayId) const = 0;
+ virtual DisplayConnectionType getDisplayConnectionType(PhysicalDisplayId) const = 0;
+ virtual bool isVsyncPeriodSwitchSupported(PhysicalDisplayId) const = 0;
+ virtual nsecs_t getDisplayVsyncPeriod(PhysicalDisplayId) const = 0;
virtual status_t setActiveConfigWithConstraints(
- DisplayId, size_t configId, const hal::VsyncPeriodChangeConstraints&,
+ PhysicalDisplayId, size_t configId, const hal::VsyncPeriodChangeConstraints&,
hal::VsyncPeriodChangeTimeline* outTimeline) = 0;
- virtual status_t setAutoLowLatencyMode(DisplayId, bool on) = 0;
+ virtual status_t setAutoLowLatencyMode(PhysicalDisplayId, bool on) = 0;
virtual status_t getSupportedContentTypes(
- DisplayId, std::vector<hal::ContentType>* outSupportedContentTypes) = 0;
- virtual status_t setContentType(DisplayId, hal::ContentType) = 0;
+ PhysicalDisplayId, std::vector<hal::ContentType>* outSupportedContentTypes) = 0;
+ virtual status_t setContentType(PhysicalDisplayId, hal::ContentType) = 0;
virtual const std::unordered_map<std::string, bool>& getSupportedLayerGenericMetadata()
const = 0;
@@ -232,7 +234,7 @@
DisplayIdentificationData* outData) const override;
bool hasCapability(hal::Capability) const override;
- bool hasDisplayCapability(DisplayId, hal::DisplayCapability) const override;
+ bool hasDisplayCapability(HalDisplayId, hal::DisplayCapability) const override;
// Attempts to allocate a virtual display and returns its ID if created on the HWC device.
std::optional<DisplayId> allocateVirtualDisplay(uint32_t width, uint32_t height,
@@ -242,63 +244,62 @@
void allocatePhysicalDisplay(hal::HWDisplayId, PhysicalDisplayId) override;
// Attempts to create a new layer on this display
- HWC2::Layer* createLayer(DisplayId) override;
+ HWC2::Layer* createLayer(HalDisplayId) override;
// Destroy a previously created layer
- void destroyLayer(DisplayId, HWC2::Layer*) override;
+ void destroyLayer(HalDisplayId, HWC2::Layer*) override;
status_t getDeviceCompositionChanges(
- DisplayId, bool frameUsesClientComposition,
+ HalDisplayId, bool frameUsesClientComposition,
std::optional<DeviceRequestedChanges>* outChanges) override;
- status_t setClientTarget(DisplayId, uint32_t slot, const sp<Fence>& acquireFence,
+ status_t setClientTarget(HalDisplayId, uint32_t slot, const sp<Fence>& acquireFence,
const sp<GraphicBuffer>& target, ui::Dataspace) override;
// Present layers to the display and read releaseFences.
- status_t presentAndGetReleaseFences(DisplayId) override;
+ status_t presentAndGetReleaseFences(HalDisplayId) override;
// set power mode
- status_t setPowerMode(DisplayId, hal::PowerMode mode) override;
+ status_t setPowerMode(PhysicalDisplayId, hal::PowerMode mode) override;
// Sets a color transform to be applied to the result of composition
- status_t setColorTransform(DisplayId, const mat4& transform) override;
+ status_t setColorTransform(HalDisplayId, const mat4& transform) override;
- // reset state when an external, non-virtual display is disconnected
- void disconnectDisplay(DisplayId) override;
+ // reset state when a display is disconnected
+ void disconnectDisplay(HalDisplayId) override;
// get the present fence received from the last call to present.
- sp<Fence> getPresentFence(DisplayId) const override;
+ sp<Fence> getPresentFence(HalDisplayId) const override;
// Get last release fence for the given layer
- sp<Fence> getLayerReleaseFence(DisplayId, HWC2::Layer*) const override;
+ sp<Fence> getLayerReleaseFence(HalDisplayId, HWC2::Layer*) const override;
// Set the output buffer and acquire fence for a virtual display.
- // Returns INVALID_OPERATION if displayId is not a virtual display.
- status_t setOutputBuffer(DisplayId, const sp<Fence>& acquireFence,
+ status_t setOutputBuffer(HalVirtualDisplayId, const sp<Fence>& acquireFence,
const sp<GraphicBuffer>& buffer) override;
// After SurfaceFlinger has retrieved the release fences for all the frames,
// it can call this to clear the shared pointers in the release fence map
- void clearReleaseFences(DisplayId) override;
+ void clearReleaseFences(HalDisplayId) override;
// Fetches the HDR capabilities of the given display
- status_t getHdrCapabilities(DisplayId, HdrCapabilities* outCapabilities) override;
+ status_t getHdrCapabilities(HalDisplayId, HdrCapabilities* outCapabilities) override;
- int32_t getSupportedPerFrameMetadata(DisplayId) const override;
+ int32_t getSupportedPerFrameMetadata(HalDisplayId) const override;
// Returns the available RenderIntent of the given display.
- std::vector<ui::RenderIntent> getRenderIntents(DisplayId, ui::ColorMode) const override;
+ std::vector<ui::RenderIntent> getRenderIntents(HalDisplayId, ui::ColorMode) const override;
- mat4 getDataspaceSaturationMatrix(DisplayId, ui::Dataspace) override;
+ mat4 getDataspaceSaturationMatrix(HalDisplayId, ui::Dataspace) override;
// Returns the attributes of the color sampling engine.
- status_t getDisplayedContentSamplingAttributes(DisplayId, ui::PixelFormat* outFormat,
+ status_t getDisplayedContentSamplingAttributes(HalDisplayId, ui::PixelFormat* outFormat,
ui::Dataspace* outDataspace,
uint8_t* outComponentMask) override;
- status_t setDisplayContentSamplingEnabled(DisplayId, bool enabled, uint8_t componentMask,
+ status_t setDisplayContentSamplingEnabled(HalDisplayId, bool enabled, uint8_t componentMask,
uint64_t maxFrames) override;
- status_t getDisplayedContentSample(DisplayId, uint64_t maxFrames, uint64_t timestamp,
+ status_t getDisplayedContentSample(HalDisplayId, uint64_t maxFrames, uint64_t timestamp,
DisplayedFrameStats* outStats) override;
- std::future<status_t> setDisplayBrightness(DisplayId, float brightness) override;
+ std::future<status_t> setDisplayBrightness(PhysicalDisplayId, float brightness) override;
// Events handling ---------------------------------------------------------
@@ -307,31 +308,32 @@
std::optional<DisplayIdentificationInfo> onHotplug(hal::HWDisplayId, hal::Connection) override;
bool onVsync(hal::HWDisplayId, int64_t timestamp) override;
- void setVsyncEnabled(DisplayId, hal::Vsync enabled) override;
+ void setVsyncEnabled(PhysicalDisplayId, hal::Vsync enabled) override;
- nsecs_t getRefreshTimestamp(DisplayId) const override;
- bool isConnected(DisplayId) const override;
+ nsecs_t getRefreshTimestamp(PhysicalDisplayId) const override;
+ bool isConnected(PhysicalDisplayId) const override;
// Non-const because it can update configMap inside of mDisplayData
- std::vector<std::shared_ptr<const HWC2::Display::Config>> getConfigs(DisplayId) const override;
+ std::vector<std::shared_ptr<const HWC2::Display::Config>> getConfigs(
+ PhysicalDisplayId) const override;
- std::shared_ptr<const HWC2::Display::Config> getActiveConfig(DisplayId) const override;
- int getActiveConfigIndex(DisplayId) const override;
+ std::shared_ptr<const HWC2::Display::Config> getActiveConfig(PhysicalDisplayId) const override;
+ int getActiveConfigIndex(PhysicalDisplayId) const override;
- std::vector<ui::ColorMode> getColorModes(DisplayId) const override;
+ std::vector<ui::ColorMode> getColorModes(PhysicalDisplayId) const override;
- status_t setActiveColorMode(DisplayId, ui::ColorMode, ui::RenderIntent) override;
+ status_t setActiveColorMode(PhysicalDisplayId, ui::ColorMode, ui::RenderIntent) override;
// Composer 2.4
- DisplayConnectionType getDisplayConnectionType(DisplayId) const override;
- bool isVsyncPeriodSwitchSupported(DisplayId) const override;
- nsecs_t getDisplayVsyncPeriod(DisplayId) const override;
- status_t setActiveConfigWithConstraints(DisplayId, size_t configId,
+ DisplayConnectionType getDisplayConnectionType(PhysicalDisplayId) const override;
+ bool isVsyncPeriodSwitchSupported(PhysicalDisplayId) const override;
+ nsecs_t getDisplayVsyncPeriod(PhysicalDisplayId) const override;
+ status_t setActiveConfigWithConstraints(PhysicalDisplayId, size_t configId,
const hal::VsyncPeriodChangeConstraints&,
hal::VsyncPeriodChangeTimeline* outTimeline) override;
- status_t setAutoLowLatencyMode(DisplayId, bool) override;
- status_t getSupportedContentTypes(DisplayId, std::vector<hal::ContentType>*) override;
- status_t setContentType(DisplayId, hal::ContentType) override;
+ status_t setAutoLowLatencyMode(PhysicalDisplayId, bool) override;
+ status_t getSupportedContentTypes(PhysicalDisplayId, std::vector<hal::ContentType>*) override;
+ status_t setContentType(PhysicalDisplayId, hal::ContentType) override;
const std::unordered_map<std::string, bool>& getSupportedLayerGenericMetadata() const override;
@@ -385,7 +387,7 @@
nsecs_t lastHwVsync GUARDED_BY(lastHwVsyncLock) = 0;
};
- std::unordered_map<DisplayId, DisplayData> mDisplayData;
+ std::unordered_map<HalDisplayId, DisplayData> mDisplayData;
std::unique_ptr<android::Hwc2::Composer> mComposer;
std::unordered_set<hal::Capability> mCapabilities;
@@ -397,9 +399,7 @@
std::optional<hal::HWDisplayId> mExternalHwcDisplayId;
bool mHasMultiDisplaySupport = false;
- std::unordered_set<DisplayId> mFreeVirtualDisplayIds;
- uint32_t mNextVirtualDisplayId = 0;
- uint32_t mRemainingHwcVirtualDisplays{getMaxVirtualDisplayCount()};
+ RandomDisplayIdGenerator<HalVirtualDisplayId> mVirtualIdGenerator{getMaxVirtualDisplayCount()};
};
} // namespace impl
diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
index fba3261..247ee23 100644
--- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
+++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
@@ -57,8 +57,7 @@
}
}
-VirtualDisplaySurface::VirtualDisplaySurface(HWComposer& hwc,
- const std::optional<DisplayId>& displayId,
+VirtualDisplaySurface::VirtualDisplaySurface(HWComposer& hwc, VirtualDisplayId displayId,
const sp<IGraphicBufferProducer>& sink,
const sp<IGraphicBufferProducer>& bqProducer,
const sp<IGraphicBufferConsumer>& bqConsumer,
@@ -125,7 +124,7 @@
}
status_t VirtualDisplaySurface::beginFrame(bool mustRecompose) {
- if (!mDisplayId) {
+ if (GpuVirtualDisplayId::tryCast(mDisplayId)) {
return NO_ERROR;
}
@@ -139,7 +138,7 @@
}
status_t VirtualDisplaySurface::prepareFrame(CompositionType compositionType) {
- if (!mDisplayId) {
+ if (GpuVirtualDisplayId::tryCast(mDisplayId)) {
return NO_ERROR;
}
@@ -187,7 +186,7 @@
}
status_t VirtualDisplaySurface::advanceFrame() {
- if (!mDisplayId) {
+ if (GpuVirtualDisplayId::tryCast(mDisplayId)) {
return NO_ERROR;
}
@@ -219,9 +218,11 @@
mFbProducerSlot, fbBuffer.get(),
mOutputProducerSlot, outBuffer.get());
+ const auto halDisplayId = HalVirtualDisplayId::tryCast(mDisplayId);
+ LOG_FATAL_IF(!halDisplayId);
// At this point we know the output buffer acquire fence,
// so update HWC state with it.
- mHwc.setOutputBuffer(*mDisplayId, mOutputFence, outBuffer);
+ mHwc.setOutputBuffer(*halDisplayId, mOutputFence, outBuffer);
status_t result = NO_ERROR;
if (fbBuffer != nullptr) {
@@ -230,7 +231,7 @@
mHwcBufferCache.getHwcBuffer(mFbProducerSlot, fbBuffer, &hwcSlot, &hwcBuffer);
// TODO: Correctly propagate the dataspace from GL composition
- result = mHwc.setClientTarget(*mDisplayId, hwcSlot, mFbFence, hwcBuffer,
+ result = mHwc.setClientTarget(*halDisplayId, hwcSlot, mFbFence, hwcBuffer,
ui::Dataspace::UNKNOWN);
}
@@ -238,7 +239,8 @@
}
void VirtualDisplaySurface::onFrameCommitted() {
- if (!mDisplayId) {
+ const auto halDisplayId = HalVirtualDisplayId::tryCast(mDisplayId);
+ if (!halDisplayId) {
return;
}
@@ -246,7 +248,7 @@
"Unexpected onFrameCommitted() in %s state", dbgStateStr());
mDbgState = DBG_STATE_IDLE;
- sp<Fence> retireFence = mHwc.getPresentFence(*mDisplayId);
+ sp<Fence> retireFence = mHwc.getPresentFence(*halDisplayId);
if (mCompositionType == COMPOSITION_MIXED && mFbProducerSlot >= 0) {
// release the scratch buffer back to the pool
Mutex::Autolock lock(mMutex);
@@ -301,7 +303,7 @@
status_t VirtualDisplaySurface::requestBuffer(int pslot,
sp<GraphicBuffer>* outBuf) {
- if (!mDisplayId) {
+ if (GpuVirtualDisplayId::tryCast(mDisplayId)) {
return mSource[SOURCE_SINK]->requestBuffer(pslot, outBuf);
}
@@ -323,7 +325,7 @@
status_t VirtualDisplaySurface::dequeueBuffer(Source source,
PixelFormat format, uint64_t usage, int* sslot, sp<Fence>* fence) {
- LOG_FATAL_IF(!mDisplayId);
+ LOG_FATAL_IF(GpuVirtualDisplayId::tryCast(mDisplayId));
status_t result =
mSource[source]->dequeueBuffer(sslot, fence, mSinkBufferWidth, mSinkBufferHeight,
@@ -369,7 +371,7 @@
PixelFormat format, uint64_t usage,
uint64_t* outBufferAge,
FrameEventHistoryDelta* outTimestamps) {
- if (!mDisplayId) {
+ if (GpuVirtualDisplayId::tryCast(mDisplayId)) {
return mSource[SOURCE_SINK]->dequeueBuffer(pslot, fence, w, h, format, usage, outBufferAge,
outTimestamps);
}
@@ -456,7 +458,7 @@
status_t VirtualDisplaySurface::queueBuffer(int pslot,
const QueueBufferInput& input, QueueBufferOutput* output) {
- if (!mDisplayId) {
+ if (GpuVirtualDisplayId::tryCast(mDisplayId)) {
return mSource[SOURCE_SINK]->queueBuffer(pslot, input, output);
}
@@ -514,7 +516,7 @@
status_t VirtualDisplaySurface::cancelBuffer(int pslot,
const sp<Fence>& fence) {
- if (!mDisplayId) {
+ if (GpuVirtualDisplayId::tryCast(mDisplayId)) {
return mSource[SOURCE_SINK]->cancelBuffer(mapProducer2SourceSlot(SOURCE_SINK, pslot), fence);
}
@@ -626,7 +628,7 @@
}
status_t VirtualDisplaySurface::refreshOutputBuffer() {
- LOG_FATAL_IF(!mDisplayId);
+ LOG_FATAL_IF(GpuVirtualDisplayId::tryCast(mDisplayId));
if (mOutputProducerSlot >= 0) {
mSource[SOURCE_SINK]->cancelBuffer(
@@ -645,7 +647,9 @@
// until after GPU calls queueBuffer(). So here we just set the buffer
// (for use in HWC prepare) but not the fence; we'll call this again with
// the proper fence once we have it.
- result = mHwc.setOutputBuffer(*mDisplayId, Fence::NO_FENCE,
+ const auto halDisplayId = HalVirtualDisplayId::tryCast(mDisplayId);
+ LOG_FATAL_IF(!halDisplayId);
+ result = mHwc.setOutputBuffer(*halDisplayId, Fence::NO_FENCE,
mProducerBuffers[mOutputProducerSlot]);
return result;
diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
index 3cbad8f..1974625 100644
--- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
+++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
@@ -24,6 +24,7 @@
#include <compositionengine/impl/HwcBufferCache.h>
#include <gui/ConsumerBase.h>
#include <gui/IGraphicBufferProducer.h>
+#include <ui/DisplayId.h>
#include "DisplayIdentification.h"
@@ -77,8 +78,7 @@
public BnGraphicBufferProducer,
private ConsumerBase {
public:
- VirtualDisplaySurface(HWComposer& hwc, const std::optional<DisplayId>& displayId,
- const sp<IGraphicBufferProducer>& sink,
+ VirtualDisplaySurface(HWComposer&, VirtualDisplayId, const sp<IGraphicBufferProducer>& sink,
const sp<IGraphicBufferProducer>& bqProducer,
const sp<IGraphicBufferConsumer>& bqConsumer, const std::string& name);
@@ -86,7 +86,7 @@
// DisplaySurface interface
//
virtual status_t beginFrame(bool mustRecompose);
- virtual status_t prepareFrame(CompositionType compositionType);
+ virtual status_t prepareFrame(CompositionType);
virtual status_t advanceFrame();
virtual void onFrameCommitted();
virtual void dumpAsString(String8& result) const;
@@ -104,25 +104,22 @@
virtual status_t requestBuffer(int pslot, sp<GraphicBuffer>* outBuf);
virtual status_t setMaxDequeuedBufferCount(int maxDequeuedBuffers);
virtual status_t setAsyncMode(bool async);
- virtual status_t dequeueBuffer(int* pslot, sp<Fence>* fence, uint32_t w, uint32_t h,
- PixelFormat format, uint64_t usage, uint64_t* outBufferAge,
+ virtual status_t dequeueBuffer(int* pslot, sp<Fence>*, uint32_t w, uint32_t h, PixelFormat,
+ uint64_t usage, uint64_t* outBufferAge,
FrameEventHistoryDelta* outTimestamps);
virtual status_t detachBuffer(int slot);
- virtual status_t detachNextBuffer(sp<GraphicBuffer>* outBuffer,
- sp<Fence>* outFence);
- virtual status_t attachBuffer(int* slot, const sp<GraphicBuffer>& buffer);
- virtual status_t queueBuffer(int pslot,
- const QueueBufferInput& input, QueueBufferOutput* output);
- virtual status_t cancelBuffer(int pslot, const sp<Fence>& fence);
+ virtual status_t detachNextBuffer(sp<GraphicBuffer>* outBuffer, sp<Fence>* outFence);
+ virtual status_t attachBuffer(int* slot, const sp<GraphicBuffer>&);
+ virtual status_t queueBuffer(int pslot, const QueueBufferInput&, QueueBufferOutput*);
+ virtual status_t cancelBuffer(int pslot, const sp<Fence>&);
virtual int query(int what, int* value);
- virtual status_t connect(const sp<IProducerListener>& listener,
- int api, bool producerControlledByApp, QueueBufferOutput* output);
- virtual status_t disconnect(int api, DisconnectMode mode);
+ virtual status_t connect(const sp<IProducerListener>&, int api, bool producerControlledByApp,
+ QueueBufferOutput*);
+ virtual status_t disconnect(int api, DisconnectMode);
virtual status_t setSidebandStream(const sp<NativeHandle>& stream);
- virtual void allocateBuffers(uint32_t width, uint32_t height,
- PixelFormat format, uint64_t usage);
+ virtual void allocateBuffers(uint32_t width, uint32_t height, PixelFormat, uint64_t usage);
virtual status_t allowAllocation(bool allow);
- virtual status_t setGenerationNumber(uint32_t generationNumber);
+ virtual status_t setGenerationNumber(uint32_t);
virtual String8 getConsumerName() const override;
virtual status_t setSharedBufferMode(bool sharedBufferMode) override;
virtual status_t setAutoRefresh(bool autoRefresh) override;
@@ -135,10 +132,9 @@
//
// Utility methods
//
- static Source fbSourceForCompositionType(CompositionType type);
- status_t dequeueBuffer(Source source, PixelFormat format, uint64_t usage,
- int* sslot, sp<Fence>* fence);
- void updateQueueBufferOutput(QueueBufferOutput&& qbo);
+ static Source fbSourceForCompositionType(CompositionType);
+ status_t dequeueBuffer(Source, PixelFormat, uint64_t usage, int* sslot, sp<Fence>*);
+ void updateQueueBufferOutput(QueueBufferOutput&&);
void resetPerFrameState();
status_t refreshOutputBuffer();
@@ -148,14 +144,14 @@
// internally in the VirtualDisplaySurface. To minimize the number of times
// a producer slot switches which source it comes from, we map source slot
// numbers to producer slot numbers differently for each source.
- static int mapSource2ProducerSlot(Source source, int sslot);
- static int mapProducer2SourceSlot(Source source, int pslot);
+ static int mapSource2ProducerSlot(Source, int sslot);
+ static int mapProducer2SourceSlot(Source, int pslot);
//
// Immutable after construction
//
HWComposer& mHwc;
- const std::optional<DisplayId> mDisplayId;
+ const VirtualDisplayId mDisplayId;
const std::string mDisplayName;
sp<IGraphicBufferProducer> mSource[2]; // indexed by SOURCE_*
uint32_t mDefaultOutputFormat;
diff --git a/services/surfaceflinger/DisplayIdGenerator.h b/services/surfaceflinger/DisplayIdGenerator.h
new file mode 100644
index 0000000..e7c69a8
--- /dev/null
+++ b/services/surfaceflinger/DisplayIdGenerator.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <ui/DisplayId.h>
+
+#include <limits>
+#include <optional>
+#include <random>
+#include <unordered_set>
+
+#include <log/log.h>
+
+namespace android {
+
+template <typename T>
+class DisplayIdGenerator {
+public:
+ virtual std::optional<T> nextId() = 0;
+ virtual void markUnused(T id) = 0;
+
+protected:
+ ~DisplayIdGenerator() {}
+};
+
+template <typename T>
+class RandomDisplayIdGenerator final : public DisplayIdGenerator<T> {
+public:
+ explicit RandomDisplayIdGenerator(size_t maxIdsCount = std::numeric_limits<size_t>::max())
+ : mMaxIdsCount(maxIdsCount) {}
+
+ std::optional<T> nextId() override {
+ if (mUsedIds.size() >= mMaxIdsCount) {
+ return std::nullopt;
+ }
+
+ constexpr int kMaxAttempts = 1000;
+
+ for (int attempts = 0; attempts < kMaxAttempts; attempts++) {
+ const auto baseId = mDistribution(mGenerator);
+ const T id(baseId);
+ if (mUsedIds.count(id) == 0) {
+ mUsedIds.insert(id);
+ return id;
+ }
+ }
+
+ LOG_ALWAYS_FATAL("Couldn't generate ID after %d attempts", kMaxAttempts);
+ }
+
+ void markUnused(T id) override { mUsedIds.erase(id); }
+
+private:
+ const size_t mMaxIdsCount;
+
+ std::unordered_set<T> mUsedIds;
+ std::default_random_engine mGenerator{std::random_device()()};
+ std::uniform_int_distribution<typename T::BaseId> mDistribution;
+};
+
+} // namespace android
\ No newline at end of file
diff --git a/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp b/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp
index a12f4c7..9985253 100644
--- a/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp
+++ b/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp
@@ -20,6 +20,7 @@
#include "FrameTimeline.h"
#include <android-base/stringprintf.h>
+#include <utils/Log.h>
#include <utils/Trace.h>
#include <cinttypes>
@@ -104,9 +105,9 @@
std::lock_guard<std::mutex> lock(mMutex);
mActualQueueTime = actualQueueTime;
}
-void SurfaceFrame::setActualEndTime(nsecs_t actualEndTime) {
+void SurfaceFrame::setAcquireFenceTime(nsecs_t acquireFenceTime) {
std::lock_guard<std::mutex> lock(mMutex);
- mActuals.endTime = actualEndTime;
+ mActuals.endTime = std::max(acquireFenceTime, mActualQueueTime);
}
void SurfaceFrame::setActualPresentTime(nsecs_t presentTime) {
diff --git a/services/surfaceflinger/FrameTimeline/FrameTimeline.h b/services/surfaceflinger/FrameTimeline/FrameTimeline.h
index 9d7b540..6d1bb73 100644
--- a/services/surfaceflinger/FrameTimeline/FrameTimeline.h
+++ b/services/surfaceflinger/FrameTimeline/FrameTimeline.h
@@ -92,10 +92,10 @@
// Actual timestamps of the app are set individually at different functions.
// Start time (if the app provides) and Queue time are accessible after queueing the frame,
- // whereas End time is available only during latch.
+ // whereas Acquire Fence time is available only during latch.
virtual void setActualStartTime(nsecs_t actualStartTime) = 0;
virtual void setActualQueueTime(nsecs_t actualQueueTime) = 0;
- virtual void setActualEndTime(nsecs_t actualEndTime) = 0;
+ virtual void setAcquireFenceTime(nsecs_t acquireFenceTime) = 0;
};
/*
@@ -170,7 +170,7 @@
void setActualStartTime(nsecs_t actualStartTime) override;
void setActualQueueTime(nsecs_t actualQueueTime) override;
- void setActualEndTime(nsecs_t actualEndTime) override;
+ void setAcquireFenceTime(nsecs_t acquireFenceTime) override;
void setPresentState(PresentState state) override;
void setActualPresentTime(nsecs_t presentTime);
void dump(std::string& result);
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index df2ef80..08801c9 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -894,7 +894,10 @@
auto surfaceFrame =
mFlinger->mFrameTimeline->createSurfaceFrameForToken(mTransactionName, vsyncId);
surfaceFrame->setActualQueueTime(stateToCommit->postTime);
- surfaceFrame->setActualEndTime(stateToCommit->postTime);
+ // For transactions we set the acquire fence time to the post time as we
+ // don't have a buffer. For BufferStateLayer it is overridden in
+ // BufferStateLayer::applyPendingStates
+ surfaceFrame->setAcquireFenceTime(stateToCommit->postTime);
mSurfaceFrame = std::move(surfaceFrame);
}
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 1b15164..363d29e 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -328,7 +328,7 @@
SurfaceFlinger::SurfaceFlinger(Factory& factory, SkipInitializationTag)
: mFactory(factory),
- mInterceptor(mFactory.createSurfaceInterceptor(this)),
+ mInterceptor(mFactory.createSurfaceInterceptor()),
mTimeStats(std::make_shared<impl::TimeStats>()),
mFrameTracer(std::make_unique<FrameTracer>()),
mFrameTimeline(std::make_unique<frametimeline::impl::FrameTimeline>()),
@@ -717,7 +717,8 @@
processDisplayHotplugEventsLocked();
const auto display = getDefaultDisplayDeviceLocked();
LOG_ALWAYS_FATAL_IF(!display, "Missing internal display after registering composer callback.");
- LOG_ALWAYS_FATAL_IF(!getHwComposer().isConnected(*display->getId()),
+ const auto displayId = display->getPhysicalId();
+ LOG_ALWAYS_FATAL_IF(!getHwComposer().isConnected(displayId),
"Internal display is disconnected.");
// initialize our drawing state
@@ -1078,8 +1079,8 @@
const nsecs_t vsyncPeriod =
mRefreshRateConfigs->getRefreshRateFromConfigId(mUpcomingActiveConfig.configId)
.getVsyncPeriod();
- mScheduler->onPrimaryDisplayConfigChanged(mAppConnectionHandle,
- static_cast<PhysicalDisplayId>(*display->getId()),
+ const auto physicalId = display->getPhysicalId();
+ mScheduler->onPrimaryDisplayConfigChanged(mAppConnectionHandle, physicalId,
mUpcomingActiveConfig.configId, vsyncPeriod);
}
}
@@ -1128,8 +1129,7 @@
}
mUpcomingActiveConfig = *desiredActiveConfig;
- const auto displayId = display->getId();
- LOG_ALWAYS_FATAL_IF(!displayId);
+ const auto displayId = display->getPhysicalId();
ATRACE_INT("ActiveConfigFPS_HWC", refreshRate.getFps());
@@ -1140,7 +1140,7 @@
hal::VsyncPeriodChangeTimeline outTimeline;
auto status =
- getHwComposer().setActiveConfigWithConstraints(*displayId,
+ getHwComposer().setActiveConfigWithConstraints(displayId,
mUpcomingActiveConfig.configId.value(),
constraints, &outTimeline);
if (status != NO_ERROR) {
@@ -1665,7 +1665,7 @@
if (const auto display = getDefaultDisplayDeviceLocked();
display && display->isPoweredOn()) {
- getHwComposer().setVsyncEnabled(*display->getId(), mHWCVsyncPendingState);
+ getHwComposer().setVsyncEnabled(display->getPhysicalId(), mHWCVsyncPendingState);
}
}));
}
@@ -2120,7 +2120,7 @@
getBE().mDisplayTimeline.updateSignalTimes();
mPreviousPresentFences[1] = mPreviousPresentFences[0];
mPreviousPresentFences[0] =
- display ? getHwComposer().getPresentFence(*display->getId()) : Fence::NO_FENCE;
+ display ? getHwComposer().getPresentFence(display->getPhysicalId()) : Fence::NO_FENCE;
auto presentFenceTime = std::make_shared<FenceTime>(mPreviousPresentFences[0]);
getBE().mDisplayTimeline.push(presentFenceTime);
@@ -2154,7 +2154,8 @@
mScheduler->addPresentFence(presentFenceTime);
}
- const bool isDisplayConnected = display && getHwComposer().isConnected(*display->getId());
+ const bool isDisplayConnected =
+ display && getHwComposer().isConnected(display->getPhysicalId());
if (!hasSyncFramework) {
if (isDisplayConnected && display->isPoweredOn()) {
@@ -2171,7 +2172,8 @@
} else if (isDisplayConnected) {
// The HWC doesn't support present fences, so use the refresh
// timestamp instead.
- const nsecs_t presentTime = getHwComposer().getRefreshTimestamp(*display->getId());
+ const nsecs_t presentTime =
+ getHwComposer().getRefreshTimestamp(display->getPhysicalId());
mAnimFrameTracker.setActualPresentTime(presentTime);
}
mAnimFrameTracker.advanceFrame();
@@ -2273,7 +2275,7 @@
void SurfaceFlinger::postFrame() {
const auto display = ON_MAIN_THREAD(getDefaultDisplayDeviceLocked());
- if (display && getHwComposer().isConnected(*display->getId())) {
+ if (display && getHwComposer().isConnected(display->getPhysicalId())) {
uint32_t flipCount = display->getPageFlipCount();
if (flipCount % LOG_FRAME_STATS_PERIOD == 0) {
logFrameStats();
@@ -2378,7 +2380,6 @@
const DisplayDeviceState& state,
const sp<compositionengine::DisplaySurface>& displaySurface,
const sp<IGraphicBufferProducer>& producer) {
- auto displayId = compositionDisplay->getDisplayId();
DisplayDeviceCreationArgs creationArgs(this, displayToken, compositionDisplay);
creationArgs.sequenceId = state.sequenceId;
creationArgs.isSecure = state.isSecure;
@@ -2390,26 +2391,26 @@
creationArgs.connectionType = physical->type;
}
- const bool isInternalDisplay = displayId && displayId == getInternalDisplayIdLocked();
- creationArgs.isPrimary = isInternalDisplay;
+ if (const auto id = PhysicalDisplayId::tryCast(compositionDisplay->getId())) {
+ creationArgs.isPrimary = id == getInternalDisplayIdLocked();
- if (useColorManagement && displayId) {
- std::vector<ColorMode> modes = getHwComposer().getColorModes(*displayId);
- for (ColorMode colorMode : modes) {
- if (isWideColorMode(colorMode)) {
- creationArgs.hasWideColorGamut = true;
+ if (useColorManagement) {
+ std::vector<ColorMode> modes = getHwComposer().getColorModes(*id);
+ for (ColorMode colorMode : modes) {
+ if (isWideColorMode(colorMode)) {
+ creationArgs.hasWideColorGamut = true;
+ }
+
+ std::vector<RenderIntent> renderIntents =
+ getHwComposer().getRenderIntents(*id, colorMode);
+ creationArgs.hwcColorModes.emplace(colorMode, renderIntents);
}
-
- std::vector<RenderIntent> renderIntents =
- getHwComposer().getRenderIntents(*displayId, colorMode);
- creationArgs.hwcColorModes.emplace(colorMode, renderIntents);
}
}
- if (displayId) {
- getHwComposer().getHdrCapabilities(*displayId, &creationArgs.hdrCapabilities);
- creationArgs.supportedPerFrameMetadata =
- getHwComposer().getSupportedPerFrameMetadata(*displayId);
+ if (const auto id = HalDisplayId::tryCast(compositionDisplay->getId())) {
+ getHwComposer().getHdrCapabilities(*id, &creationArgs.hdrCapabilities);
+ creationArgs.supportedPerFrameMetadata = getHwComposer().getSupportedPerFrameMetadata(*id);
}
auto nativeWindowSurface = getFactory().createNativeWindowSurface(producer);
@@ -2424,7 +2425,7 @@
}
creationArgs.physicalOrientation =
- isInternalDisplay ? internalDisplayOrientation : ui::ROTATION_0;
+ creationArgs.isPrimary ? internalDisplayOrientation : ui::ROTATION_0;
// virtual displays are always considered enabled
creationArgs.initialPowerMode = state.isVirtual() ? hal::PowerMode::ON : hal::PowerMode::OFF;
@@ -2446,8 +2447,8 @@
RenderIntent::COLORIMETRIC,
Dataspace::UNKNOWN});
if (!state.isVirtual()) {
- LOG_ALWAYS_FATAL_IF(!displayId);
- auto activeConfigId = HwcConfigIndexType(getHwComposer().getActiveConfigIndex(*displayId));
+ const auto physicalId = display->getPhysicalId();
+ auto activeConfigId = HwcConfigIndexType(getHwComposer().getActiveConfigIndex(physicalId));
display->setActiveConfig(activeConfigId);
display->setDeviceProductInfo(state.physical->deviceProductInfo);
}
@@ -2497,6 +2498,7 @@
builder.setLayerStackId(state.layerStack);
builder.setPowerAdvisor(&mPowerAdvisor);
builder.setUseHwcVirtualDisplays(mUseHwcVirtualDisplays);
+ builder.setGpuVirtualDisplayIdGenerator(mGpuVirtualDisplayIdGenerator);
builder.setName(state.displayName);
const auto compositionDisplay = getCompositionEngine().createDisplay(builder.build());
@@ -2506,11 +2508,13 @@
sp<IGraphicBufferConsumer> bqConsumer;
getFactory().createBufferQueue(&bqProducer, &bqConsumer, /*consumerIsSurfaceFlinger =*/false);
- std::optional<DisplayId> displayId = compositionDisplay->getId();
+ DisplayId displayId = compositionDisplay->getId();
if (state.isVirtual()) {
+ const auto virtualId = VirtualDisplayId::tryCast(displayId);
+ LOG_FATAL_IF(!virtualId);
sp<VirtualDisplaySurface> vds =
- new VirtualDisplaySurface(getHwComposer(), displayId, state.surface, bqProducer,
+ new VirtualDisplaySurface(getHwComposer(), *virtualId, state.surface, bqProducer,
bqConsumer, state.displayName);
displaySurface = vds;
@@ -2520,9 +2524,9 @@
"adding a supported display, but rendering "
"surface is provided (%p), ignoring it",
state.surface.get());
-
- LOG_ALWAYS_FATAL_IF(!displayId);
- displaySurface = new FramebufferSurface(getHwComposer(), *displayId, bqConsumer,
+ const auto physicalId = PhysicalDisplayId::tryCast(displayId);
+ LOG_FATAL_IF(!physicalId);
+ displaySurface = new FramebufferSurface(getHwComposer(), *physicalId, bqConsumer,
maxGraphicsWidth, maxGraphicsHeight);
producer = bqProducer;
}
@@ -2532,8 +2536,7 @@
displaySurface, producer);
mDisplays.emplace(displayToken, display);
if (!state.isVirtual()) {
- LOG_FATAL_IF(!displayId);
- dispatchDisplayHotplugEvent(static_cast<PhysicalDisplayId>(*displayId), true);
+ dispatchDisplayHotplugEvent(display->getPhysicalId(), true);
}
if (display->isPrimary()) {
@@ -2543,13 +2546,9 @@
void SurfaceFlinger::processDisplayRemoved(const wp<IBinder>& displayToken) {
if (const auto display = getDisplayDeviceLocked(displayToken)) {
- // Save display ID before disconnecting.
- const auto displayId = display->getId();
display->disconnect();
-
if (!display->isVirtual()) {
- LOG_FATAL_IF(!displayId);
- dispatchDisplayHotplugEvent(static_cast<PhysicalDisplayId>(*displayId), false);
+ dispatchDisplayHotplugEvent(display->getPhysicalId(), false);
}
}
@@ -2825,7 +2824,7 @@
void SurfaceFlinger::updateCursorAsync() {
compositionengine::CompositionRefreshArgs refreshArgs;
for (const auto& [_, display] : ON_MAIN_THREAD(mDisplays)) {
- if (display->getId()) {
+ if (HalDisplayId::tryCast(display->getId())) {
refreshArgs.outputs.push_back(display->getCompositionDisplay());
}
}
@@ -3303,7 +3302,7 @@
applyTransactionState(frameTimelineVsyncId, states, displays, flags, inputWindowCommands,
desiredPresentTime, uncacheBuffer, postTime, privileged,
hasListenerCallbacks, listenerCallbacks, originPid, originUid,
- /*isMainThread*/ false);
+ transactionId, /*isMainThread*/ false);
return NO_ERROR;
}
@@ -3596,7 +3595,8 @@
const auto& p = layer->getParent();
if (p == nullptr) {
ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
- if (layer->setRelativeLayer(s.relativeLayerHandle, s.z) && idx >= 0) {
+ if (layer->setRelativeLayer(s.relativeLayerSurfaceControl->getHandle(), s.z) &&
+ idx >= 0) {
mCurrentState.layersSortedByZ.removeAt(idx);
mCurrentState.layersSortedByZ.add(layer);
// we need traversal (state changed)
@@ -3604,7 +3604,7 @@
flags |= eTransactionNeeded|eTraversalNeeded;
}
} else {
- if (p->setChildRelativeLayer(layer, s.relativeLayerHandle, s.z)) {
+ if (p->setChildRelativeLayer(layer, s.relativeLayerSurfaceControl->getHandle(), s.z)) {
flags |= eTransactionNeeded|eTraversalNeeded;
}
}
@@ -3690,24 +3690,13 @@
}
}
if (what & layer_state_t::eDeferTransaction_legacy) {
- if (s.barrierHandle_legacy != nullptr) {
- layer->deferTransactionUntil_legacy(s.barrierHandle_legacy, s.barrierFrameNumber);
- } else if (s.barrierGbp_legacy != nullptr) {
- const sp<IGraphicBufferProducer>& gbp = s.barrierGbp_legacy;
- if (authenticateSurfaceTextureLocked(gbp)) {
- const auto& otherLayer =
- (static_cast<MonitoredProducer*>(gbp.get()))->getLayer();
- layer->deferTransactionUntil_legacy(otherLayer, s.barrierFrameNumber);
- } else {
- ALOGE("Attempt to defer transaction to to an"
- " unrecognized GraphicBufferProducer");
- }
- }
+ layer->deferTransactionUntil_legacy(s.barrierSurfaceControl_legacy->getHandle(),
+ s.barrierFrameNumber);
// We don't trigger a traversal here because if no other state is
// changed, we don't want this to cause any more work
}
if (what & layer_state_t::eReparentChildren) {
- if (layer->reparentChildren(s.reparentHandle)) {
+ if (layer->reparentChildren(s.reparentSurfaceControl->getHandle())) {
flags |= eTransactionNeeded|eTraversalNeeded;
}
}
@@ -3794,7 +3783,10 @@
// lose its relative z order.
if (what & layer_state_t::eReparent) {
bool hadParent = layer->hasParent();
- if (layer->reparent(s.parentHandleForChild)) {
+ auto parentHandle = (s.parentSurfaceControlForChild)
+ ? s.parentSurfaceControlForChild->getHandle()
+ : nullptr;
+ if (layer->reparent(parentHandle)) {
if (!hadParent) {
mCurrentState.layersSortedByZ.remove(layer);
}
@@ -4132,10 +4124,8 @@
return;
}
- const auto displayId = display->getId();
- LOG_ALWAYS_FATAL_IF(!displayId);
-
- ALOGD("Setting power mode %d on display %s", mode, to_string(*displayId).c_str());
+ const auto displayId = display->getPhysicalId();
+ ALOGD("Setting power mode %d on display %s", mode, to_string(displayId).c_str());
const hal::PowerMode currentMode = display->getPowerMode();
if (mode == currentMode) {
@@ -4152,9 +4142,9 @@
if (SurfaceFlinger::setSchedFifo(true) != NO_ERROR) {
ALOGW("Couldn't set SCHED_FIFO on display on: %s\n", strerror(errno));
}
- getHwComposer().setPowerMode(*displayId, mode);
+ getHwComposer().setPowerMode(displayId, mode);
if (display->isPrimary() && mode != hal::PowerMode::DOZE_SUSPEND) {
- getHwComposer().setVsyncEnabled(*displayId, mHWCVsyncPendingState);
+ getHwComposer().setVsyncEnabled(displayId, mHWCVsyncPendingState);
mScheduler->onScreenAcquired(mAppConnectionHandle);
mScheduler->resyncToHardwareVsync(true, vsyncPeriod);
}
@@ -4173,14 +4163,14 @@
}
// Make sure HWVsync is disabled before turning off the display
- getHwComposer().setVsyncEnabled(*displayId, hal::Vsync::DISABLE);
+ getHwComposer().setVsyncEnabled(displayId, hal::Vsync::DISABLE);
- getHwComposer().setPowerMode(*displayId, mode);
+ getHwComposer().setPowerMode(displayId, mode);
mVisibleRegionsDirty = true;
// from this point on, SF will stop drawing on this display
} else if (mode == hal::PowerMode::DOZE || mode == hal::PowerMode::ON) {
// Update display while dozing
- getHwComposer().setPowerMode(*displayId, mode);
+ getHwComposer().setPowerMode(displayId, mode);
if (display->isPrimary() && currentMode == hal::PowerMode::DOZE_SUSPEND) {
mScheduler->onScreenAcquired(mAppConnectionHandle);
mScheduler->resyncToHardwareVsync(true, vsyncPeriod);
@@ -4191,10 +4181,10 @@
mScheduler->disableHardwareVsync(true);
mScheduler->onScreenReleased(mAppConnectionHandle);
}
- getHwComposer().setPowerMode(*displayId, mode);
+ getHwComposer().setPowerMode(displayId, mode);
} else {
ALOGE("Attempting to set unknown power mode: %d\n", mode);
- getHwComposer().setPowerMode(*displayId, mode);
+ getHwComposer().setPowerMode(displayId, mode);
}
if (display->isPrimary()) {
@@ -4203,7 +4193,7 @@
mScheduler->setDisplayPowerState(mode == hal::PowerMode::ON);
}
- ALOGD("Finished setting power mode %d on display %s", mode, to_string(*displayId).c_str());
+ ALOGD("Finished setting power mode %d on display %s", mode, to_string(displayId).c_str());
}
void SurfaceFlinger::setPowerMode(const sp<IBinder>& displayToken, int mode) {
@@ -4462,12 +4452,11 @@
void SurfaceFlinger::dumpDisplayIdentificationData(std::string& result) const {
for (const auto& [token, display] : mDisplays) {
- const auto displayId = display->getId();
+ const auto displayId = PhysicalDisplayId::tryCast(display->getId());
if (!displayId) {
continue;
}
- const auto hwcDisplayId =
- getHwComposer().fromPhysicalDisplayId(static_cast<PhysicalDisplayId>(*displayId));
+ const auto hwcDisplayId = getHwComposer().fromPhysicalDisplayId(*displayId);
if (!hwcDisplayId) {
continue;
}
@@ -4520,7 +4509,7 @@
// TODO: print out if wide-color mode is active or not
for (const auto& [token, display] : mDisplays) {
- const auto displayId = display->getId();
+ const auto displayId = PhysicalDisplayId::tryCast(display->getId());
if (!displayId) {
continue;
}
@@ -4734,7 +4723,7 @@
* HWC layer minidump
*/
for (const auto& [token, display] : mDisplays) {
- const auto displayId = display->getId();
+ const auto displayId = HalDisplayId::tryCast(display->getId());
if (!displayId) {
continue;
}
@@ -5253,18 +5242,12 @@
// Inject a hotplug connected event for the primary display. This will deallocate and
// reallocate the display state including framebuffers.
case 1037: {
- const auto token = getInternalDisplayToken();
-
- sp<DisplayDevice> display;
+ std::optional<hal::HWDisplayId> hwcId;
{
Mutex::Autolock lock(mStateLock);
- display = getDisplayDeviceLocked(token);
+ hwcId = getHwComposer().getInternalHwcDisplayId();
}
- const auto hwcId =
- getHwComposer().fromPhysicalDisplayId(PhysicalDisplayId(*display->getId()));
-
onHotplugReceived(getBE().mComposerSequenceId, *hwcId, hal::Connection::CONNECTED);
-
return NO_ERROR;
}
}
@@ -5871,16 +5854,14 @@
// as well. For now, just call directly to setActiveConfigWithConstraints but ideally
// it should go thru setDesiredActiveConfig, similar to primary display.
ALOGV("setAllowedDisplayConfigsInternal for non-primary display");
- const auto displayId = display->getId();
- LOG_ALWAYS_FATAL_IF(!displayId);
+ const auto displayId = display->getPhysicalId();
hal::VsyncPeriodChangeConstraints constraints;
constraints.desiredTimeNanos = systemTime();
constraints.seamlessRequired = false;
hal::VsyncPeriodChangeTimeline timeline = {0, 0, 0};
- if (getHwComposer().setActiveConfigWithConstraints(*displayId,
- policy->defaultConfig.value(),
+ if (getHwComposer().setActiveConfigWithConstraints(displayId, policy->defaultConfig.value(),
constraints, &timeline) < 0) {
return BAD_VALUE;
}
@@ -5890,11 +5871,9 @@
display->setActiveConfig(policy->defaultConfig);
const nsecs_t vsyncPeriod = getHwComposer()
- .getConfigs(*displayId)[policy->defaultConfig.value()]
+ .getConfigs(displayId)[policy->defaultConfig.value()]
->getVsyncPeriod();
- mScheduler->onNonPrimaryDisplayConfigChanged(mAppConnectionHandle,
- static_cast<PhysicalDisplayId>(
- *display->getId()),
+ mScheduler->onNonPrimaryDisplayConfigChanged(mAppConnectionHandle, displayId,
policy->defaultConfig, vsyncPeriod);
return NO_ERROR;
}
@@ -5926,8 +5905,8 @@
const nsecs_t vsyncPeriod =
mRefreshRateConfigs->getRefreshRateFromConfigId(display->getActiveConfig())
.getVsyncPeriod();
- mScheduler->onPrimaryDisplayConfigChanged(mAppConnectionHandle,
- static_cast<PhysicalDisplayId>(*display->getId()),
+ const auto physicalId = display->getPhysicalId();
+ mScheduler->onPrimaryDisplayConfigChanged(mAppConnectionHandle, physicalId,
display->getActiveConfig(), vsyncPeriod);
toggleKernelIdleTimer();
@@ -6018,11 +5997,9 @@
} else if (display->isVirtual()) {
return INVALID_OPERATION;
} else {
- const auto displayId = display->getId();
- LOG_FATAL_IF(!displayId);
-
- *outDefaultConfig = getHwComposer().getActiveConfigIndex(*displayId);
- auto vsyncPeriod = getHwComposer().getActiveConfig(*displayId)->getVsyncPeriod();
+ const auto displayId = display->getPhysicalId();
+ *outDefaultConfig = getHwComposer().getActiveConfigIndex(displayId);
+ auto vsyncPeriod = getHwComposer().getActiveConfig(displayId)->getVsyncPeriod();
*outPrimaryRefreshRateMin = 1e9f / vsyncPeriod;
*outPrimaryRefreshRateMax = 1e9f / vsyncPeriod;
*outAppRequestRefreshRateMin = 1e9f / vsyncPeriod;
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 66acde0..aba07b7 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -52,6 +52,7 @@
#include "DisplayDevice.h"
#include "DisplayHardware/HWC2.h"
#include "DisplayHardware/PowerAdvisor.h"
+#include "DisplayIdGenerator.h"
#include "Effects/Daltonizer.h"
#include "FrameTracker.h"
#include "LayerVector.h"
@@ -948,8 +949,8 @@
return it != mPhysicalDisplayTokens.end() ? it->second : nullptr;
}
- std::optional<DisplayId> getPhysicalDisplayIdLocked(const sp<IBinder>& displayToken) const
- REQUIRES(mStateLock) {
+ std::optional<PhysicalDisplayId> getPhysicalDisplayIdLocked(
+ const sp<IBinder>& displayToken) const REQUIRES(mStateLock) {
for (const auto& [id, token] : mPhysicalDisplayTokens) {
if (token == displayToken) {
return id;
@@ -1112,6 +1113,8 @@
std::unordered_map<PhysicalDisplayId, sp<IBinder>> mPhysicalDisplayTokens
GUARDED_BY(mStateLock);
+ RandomDisplayIdGenerator<GpuVirtualDisplayId> mGpuVirtualDisplayIdGenerator;
+
std::unordered_map<BBinder*, wp<Layer>> mLayersByLocalBinderToken GUARDED_BY(mStateLock);
// don't use a lock for these, we don't care
diff --git a/services/surfaceflinger/SurfaceFlingerDefaultFactory.cpp b/services/surfaceflinger/SurfaceFlingerDefaultFactory.cpp
index 93d36a6..9a8deae 100644
--- a/services/surfaceflinger/SurfaceFlingerDefaultFactory.cpp
+++ b/services/surfaceflinger/SurfaceFlingerDefaultFactory.cpp
@@ -68,8 +68,8 @@
return std::make_unique<Scheduler>(configs, callback);
}
-sp<SurfaceInterceptor> DefaultFactory::createSurfaceInterceptor(SurfaceFlinger* flinger) {
- return new android::impl::SurfaceInterceptor(flinger);
+sp<SurfaceInterceptor> DefaultFactory::createSurfaceInterceptor() {
+ return new android::impl::SurfaceInterceptor();
}
sp<StartPropertySetThread> DefaultFactory::createStartPropertySetThread(
diff --git a/services/surfaceflinger/SurfaceFlingerDefaultFactory.h b/services/surfaceflinger/SurfaceFlingerDefaultFactory.h
index e06c2f4..40774ef 100644
--- a/services/surfaceflinger/SurfaceFlingerDefaultFactory.h
+++ b/services/surfaceflinger/SurfaceFlingerDefaultFactory.h
@@ -32,7 +32,7 @@
const scheduler::RefreshRateConfigs&) override;
std::unique_ptr<Scheduler> createScheduler(const scheduler::RefreshRateConfigs&,
ISchedulerCallback&) override;
- sp<SurfaceInterceptor> createSurfaceInterceptor(SurfaceFlinger*) override;
+ sp<SurfaceInterceptor> createSurfaceInterceptor() override;
sp<StartPropertySetThread> createStartPropertySetThread(bool timestampPropertyValue) override;
sp<DisplayDevice> createDisplayDevice(DisplayDeviceCreationArgs&) override;
sp<GraphicBuffer> createGraphicBuffer(uint32_t width, uint32_t height, PixelFormat format,
diff --git a/services/surfaceflinger/SurfaceFlingerFactory.h b/services/surfaceflinger/SurfaceFlingerFactory.h
index 41ccc10..2dd563b 100644
--- a/services/surfaceflinger/SurfaceFlingerFactory.h
+++ b/services/surfaceflinger/SurfaceFlingerFactory.h
@@ -73,7 +73,7 @@
const scheduler::RefreshRateConfigs&) = 0;
virtual std::unique_ptr<Scheduler> createScheduler(const scheduler::RefreshRateConfigs&,
ISchedulerCallback&) = 0;
- virtual sp<SurfaceInterceptor> createSurfaceInterceptor(SurfaceFlinger*) = 0;
+ virtual sp<SurfaceInterceptor> createSurfaceInterceptor() = 0;
virtual sp<StartPropertySetThread> createStartPropertySetThread(
bool timestampPropertyValue) = 0;
diff --git a/services/surfaceflinger/SurfaceInterceptor.cpp b/services/surfaceflinger/SurfaceInterceptor.cpp
index 4407f4c..da58d4e 100644
--- a/services/surfaceflinger/SurfaceInterceptor.cpp
+++ b/services/surfaceflinger/SurfaceInterceptor.cpp
@@ -40,11 +40,6 @@
namespace impl {
-SurfaceInterceptor::SurfaceInterceptor(SurfaceFlinger* flinger)
- : mFlinger(flinger)
-{
-}
-
void SurfaceInterceptor::addTransactionTraceListener(
const sp<gui::ITransactionTraceListener>& listener) {
sp<IBinder> asBinder = IInterface::asBinder(listener);
@@ -472,16 +467,10 @@
}
if (state.what & layer_state_t::eDeferTransaction_legacy) {
sp<Layer> otherLayer = nullptr;
- if (state.barrierHandle_legacy != nullptr) {
- otherLayer =
- static_cast<Layer::Handle*>(state.barrierHandle_legacy.get())->owner.promote();
- } else if (state.barrierGbp_legacy != nullptr) {
- auto const& gbp = state.barrierGbp_legacy;
- if (mFlinger->authenticateSurfaceTextureLocked(gbp)) {
- otherLayer = (static_cast<MonitoredProducer*>(gbp.get()))->getLayer();
- } else {
- ALOGE("Attempt to defer transaction to to an unrecognized GraphicBufferProducer");
- }
+ if (state.barrierSurfaceControl_legacy != nullptr) {
+ otherLayer = static_cast<Layer::Handle*>(
+ state.barrierSurfaceControl_legacy->getHandle().get())
+ ->owner.promote();
}
addDeferTransactionLocked(transaction, layerId, otherLayer, state.barrierFrameNumber);
}
@@ -489,17 +478,23 @@
addOverrideScalingModeLocked(transaction, layerId, state.overrideScalingMode);
}
if (state.what & layer_state_t::eReparent) {
- addReparentLocked(transaction, layerId, getLayerIdFromHandle(state.parentHandleForChild));
+ auto parentHandle = (state.parentSurfaceControlForChild)
+ ? state.parentSurfaceControlForChild->getHandle()
+ : nullptr;
+ addReparentLocked(transaction, layerId, getLayerIdFromHandle(parentHandle));
}
if (state.what & layer_state_t::eReparentChildren) {
- addReparentChildrenLocked(transaction, layerId, getLayerIdFromHandle(state.reparentHandle));
+ addReparentChildrenLocked(transaction, layerId,
+ getLayerIdFromHandle(state.reparentSurfaceControl->getHandle()));
}
if (state.what & layer_state_t::eDetachChildren) {
addDetachChildrenLocked(transaction, layerId, true);
}
if (state.what & layer_state_t::eRelativeLayerChanged) {
addRelativeParentLocked(transaction, layerId,
- getLayerIdFromHandle(state.relativeLayerHandle), state.z);
+ getLayerIdFromHandle(
+ state.relativeLayerSurfaceControl->getHandle()),
+ state.z);
}
if (state.what & layer_state_t::eShadowRadiusChanged) {
addShadowRadiusLocked(transaction, layerId, state.shadowRadius);
diff --git a/services/surfaceflinger/SurfaceInterceptor.h b/services/surfaceflinger/SurfaceInterceptor.h
index 46284df..9ac189a 100644
--- a/services/surfaceflinger/SurfaceInterceptor.h
+++ b/services/surfaceflinger/SurfaceInterceptor.h
@@ -92,7 +92,7 @@
*/
class SurfaceInterceptor final : public android::SurfaceInterceptor {
public:
- explicit SurfaceInterceptor(SurfaceFlinger* const flinger);
+ SurfaceInterceptor() = default;
~SurfaceInterceptor() override = default;
// Both vectors are used to capture the current state of SF as the initial snapshot in the trace
@@ -202,7 +202,6 @@
std::string mOutputFileName {DEFAULT_FILENAME};
std::mutex mTraceMutex {};
Trace mTrace {};
- SurfaceFlinger* const mFlinger;
std::mutex mListenersMutex;
std::map<wp<IBinder>, sp<gui::ITransactionTraceListener>> mTraceToggledListeners
GUARDED_BY(mListenersMutex);
diff --git a/services/surfaceflinger/tests/DetachChildren_test.cpp b/services/surfaceflinger/tests/DetachChildren_test.cpp
index 3261308..9c7b1fc 100644
--- a/services/surfaceflinger/tests/DetachChildren_test.cpp
+++ b/services/surfaceflinger/tests/DetachChildren_test.cpp
@@ -61,7 +61,7 @@
TransactionUtils::fillSurfaceRGBA8(relative, relativeColor);
Transaction{}
- .setRelativeLayer(relative, mMainSurface->getHandle(), 1)
+ .setRelativeLayer(relative, mMainSurface, 1)
.setPosition(relative, relBounds.left, relBounds.top)
.apply();
@@ -204,7 +204,7 @@
.setLayer(newParentSurface, INT32_MAX - 1)
.show(newParentSurface)
.setPosition(newParentSurface, newParentBounds.left, newParentBounds.top)
- .reparent(childNewClient, newParentSurface->getHandle())
+ .reparent(childNewClient, newParentSurface)
.apply();
{
mCapture = screenshot();
@@ -238,7 +238,7 @@
}
Transaction()
- .deferTransactionUntil_legacy(childNewClient, mMainSurface->getHandle(),
+ .deferTransactionUntil_legacy(childNewClient, mMainSurface,
mMainSurface->getSurface()->getNextFrameNumber())
.apply();
Transaction().detachChildren(mMainSurface).apply();
@@ -290,7 +290,7 @@
Transaction().detachChildren(mMainSurface).apply();
Transaction()
.setCrop_legacy(childNewClient, {0, 0, childBounds.width(), childBounds.height()})
- .deferTransactionUntil_legacy(childNewClient, mMainSurface->getHandle(),
+ .deferTransactionUntil_legacy(childNewClient, mMainSurface,
mMainSurface->getSurface()->getNextFrameNumber())
.apply();
@@ -352,7 +352,7 @@
mCapture->expectColor(mMainSurfaceBounds, Color::BLACK);
}
- Transaction().reparent(mMainSurface, mBlackBgSurface->getHandle()).apply();
+ Transaction().reparent(mMainSurface, mBlackBgSurface).apply();
{
mCapture = screenshot();
mCapture->expectBorder(childBounds, mMainSurfaceColor);
diff --git a/services/surfaceflinger/tests/LayerRenderTypeTransaction_test.cpp b/services/surfaceflinger/tests/LayerRenderTypeTransaction_test.cpp
index 83e5060..4947289 100644
--- a/services/surfaceflinger/tests/LayerRenderTypeTransaction_test.cpp
+++ b/services/surfaceflinger/tests/LayerRenderTypeTransaction_test.cpp
@@ -211,16 +211,13 @@
switch (layerType) {
case ISurfaceComposerClient::eFXSurfaceBufferQueue:
- Transaction()
- .setPosition(layerG, 16, 16)
- .setRelativeLayer(layerG, layerR->getHandle(), 1)
- .apply();
+ Transaction().setPosition(layerG, 16, 16).setRelativeLayer(layerG, layerR, 1).apply();
break;
case ISurfaceComposerClient::eFXSurfaceBufferState:
Transaction()
.setFrame(layerR, Rect(0, 0, 32, 32))
.setFrame(layerG, Rect(16, 16, 48, 48))
- .setRelativeLayer(layerG, layerR->getHandle(), 1)
+ .setRelativeLayer(layerG, layerR, 1)
.apply();
break;
default:
@@ -233,7 +230,7 @@
shot->expectColor(Rect(16, 16, 48, 48), Color::GREEN);
}
- Transaction().setRelativeLayer(layerG, layerR->getHandle(), -1).apply();
+ Transaction().setRelativeLayer(layerG, layerR, -1).apply();
{
SCOPED_TRACE("layerG below");
auto shot = getScreenCapture();
@@ -266,7 +263,7 @@
case ISurfaceComposerClient::eFXSurfaceBufferQueue:
Transaction()
.setPosition(layerG, 8, 8)
- .setRelativeLayer(layerG, layerR->getHandle(), 3)
+ .setRelativeLayer(layerG, layerR, 3)
.setPosition(layerB, 16, 16)
.setLayer(layerB, mLayerZBase + 2)
.apply();
@@ -275,7 +272,7 @@
Transaction()
.setFrame(layerR, Rect(0, 0, 32, 32))
.setFrame(layerG, Rect(8, 8, 40, 40))
- .setRelativeLayer(layerG, layerR->getHandle(), 3)
+ .setRelativeLayer(layerG, layerR, 3)
.setFrame(layerB, Rect(16, 16, 48, 48))
.setLayer(layerB, mLayerZBase + 2)
.apply();
@@ -303,7 +300,7 @@
}
// layerR = 4, layerG = layerR - 3, layerB = 2
- Transaction().setRelativeLayer(layerG, layerR->getHandle(), -3).apply();
+ Transaction().setRelativeLayer(layerG, layerR, -3).apply();
{
SCOPED_TRACE("layerB < (layerG < layerR)");
auto shot = getScreenCapture();
@@ -810,7 +807,7 @@
// channel) should be less than one
const uint8_t tolerance = 1;
Transaction()
- .reparent(colorLayer, parentLayer->getHandle())
+ .reparent(colorLayer, parentLayer)
.setColor(colorLayer, color)
.setAlpha(parentLayer, alpha)
.setLayer(parentLayer, mLayerZBase + 1)
@@ -1225,7 +1222,7 @@
child = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState));
ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(child, Color::BLUE, 10, 10));
- Transaction().reparent(child, parent->getHandle()).apply();
+ Transaction().reparent(child, parent).apply();
// A layer will default to the frame of its parent
auto shot = getScreenCapture();
@@ -1242,7 +1239,7 @@
child = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState));
ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(child, Color::BLUE, 10, 10));
- Transaction().reparent(child, parent->getHandle()).apply();
+ Transaction().reparent(child, parent).apply();
// A layer will default to the frame of its parent
auto shot = getScreenCapture();
@@ -1272,7 +1269,7 @@
parent = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState));
ASSERT_NO_FATAL_FAILURE(
child = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState));
- Transaction().reparent(child, parent->getHandle()).apply();
+ Transaction().reparent(child, parent).apply();
ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(parent, Color::RED, 32, 32));
Transaction().setFrame(parent, Rect(0, 0, 32, 32)).apply();
diff --git a/services/surfaceflinger/tests/LayerTransaction_test.cpp b/services/surfaceflinger/tests/LayerTransaction_test.cpp
index 8d715e1..ef992d6 100644
--- a/services/surfaceflinger/tests/LayerTransaction_test.cpp
+++ b/services/surfaceflinger/tests/LayerTransaction_test.cpp
@@ -50,7 +50,7 @@
sp<SurfaceControl> layer;
ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32));
ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 32, 32));
- Transaction().reparent(layer, layer->getHandle()).apply();
+ Transaction().reparent(layer, layer).apply();
{
// We expect the transaction to be silently dropped, but for SurfaceFlinger
diff --git a/services/surfaceflinger/tests/LayerTypeAndRenderTypeTransaction_test.cpp b/services/surfaceflinger/tests/LayerTypeAndRenderTypeTransaction_test.cpp
index 7d4314f..c57ad43 100644
--- a/services/surfaceflinger/tests/LayerTypeAndRenderTypeTransaction_test.cpp
+++ b/services/surfaceflinger/tests/LayerTypeAndRenderTypeTransaction_test.cpp
@@ -87,10 +87,7 @@
ASSERT_NO_FATAL_FAILURE(layerG = createLayer("test G", 32, 32));
ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerG, Color::GREEN, 32, 32));
- Transaction()
- .setPosition(layerG, 16, 16)
- .setRelativeLayer(layerG, layerR->getHandle(), 1)
- .apply();
+ Transaction().setPosition(layerG, 16, 16).setRelativeLayer(layerG, layerR, 1).apply();
Transaction().reparent(layerG, nullptr).apply();
@@ -154,10 +151,7 @@
ASSERT_NO_FATAL_FAILURE(layerG = createLayer("test G", 32, 32));
ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerG, Color::GREEN, 32, 32));
- Transaction()
- .reparent(layerR, parent->getHandle())
- .reparent(layerG, parent->getHandle())
- .apply();
+ Transaction().reparent(layerR, parent).reparent(layerG, parent).apply();
Transaction().setLayer(layerR, -1).setLayer(layerG, -2).apply();
{
SCOPED_TRACE("layerR");
@@ -241,7 +235,7 @@
auto transaction = Transaction()
.setCornerRadius(parent, cornerRadius)
.setCrop_legacy(parent, Rect(0, 0, size, size))
- .reparent(child, parent->getHandle())
+ .reparent(child, parent)
.setPosition(child, 0, size)
// Rotate by half PI
.setMatrix(child, 0.0f, -1.0f, 1.0f, 0.0f);
@@ -283,14 +277,14 @@
Transaction()
.setCornerRadius(parent, cornerRadius)
.setCrop_legacy(parent, Rect(0, 0, size, size))
- .reparent(child, parent->getHandle())
+ .reparent(child, parent)
.setPosition(child, 0, size / 2)
.apply();
} else {
Transaction()
.setCornerRadius(parent, cornerRadius)
.setFrame(parent, Rect(0, 0, size, size))
- .reparent(child, parent->getHandle())
+ .reparent(child, parent)
.setFrame(child, Rect(0, size / 2, size, size))
.apply();
}
diff --git a/services/surfaceflinger/tests/LayerTypeTransaction_test.cpp b/services/surfaceflinger/tests/LayerTypeTransaction_test.cpp
index ab74c50..f8a0bc1 100644
--- a/services/surfaceflinger/tests/LayerTypeTransaction_test.cpp
+++ b/services/surfaceflinger/tests/LayerTypeTransaction_test.cpp
@@ -54,10 +54,10 @@
ASSERT_NO_FATAL_FAILURE(layerB = createLayer("test B", 32, 32));
ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerB, Color::BLUE, 32, 32));
- Transaction().reparent(layerB, parent->getHandle()).apply();
+ Transaction().reparent(layerB, parent).apply();
// layerR = mLayerZBase, layerG = layerR - 1, layerB = -2
- Transaction().setRelativeLayer(layerG, layerR->getHandle(), -1).setLayer(layerB, -2).apply();
+ Transaction().setRelativeLayer(layerG, layerR, -1).setLayer(layerB, -2).apply();
std::unique_ptr<ScreenCapture> screenshot;
// only layerB is in this range
@@ -88,10 +88,7 @@
.setCrop_legacy(childLayer, Rect(0, 0, 20, 30))
.apply();
- Transaction()
- .setRelativeLayer(childLayer, parent->getHandle(), -1)
- .setLayer(childLayer, 1)
- .apply();
+ Transaction().setRelativeLayer(childLayer, parent, -1).setLayer(childLayer, 1).apply();
{
SCOPED_TRACE("setLayer above");
@@ -101,10 +98,7 @@
screenshot->expectColor(Rect(0, 0, 20, 30), Color::RED);
}
- Transaction()
- .setLayer(childLayer, 1)
- .setRelativeLayer(childLayer, parent->getHandle(), -1)
- .apply();
+ Transaction().setLayer(childLayer, 1).setRelativeLayer(childLayer, parent, -1).apply();
{
SCOPED_TRACE("setRelative below");
@@ -141,7 +135,7 @@
.setLayer(relativeParent, mLayerZBase)
.apply();
- Transaction().setRelativeLayer(childLayer, relativeParent->getHandle(), 1).apply();
+ Transaction().setRelativeLayer(childLayer, relativeParent, 1).apply();
{
SCOPED_TRACE("setLayer above");
diff --git a/services/surfaceflinger/tests/LayerUpdate_test.cpp b/services/surfaceflinger/tests/LayerUpdate_test.cpp
index c56d473..38da0b1 100644
--- a/services/surfaceflinger/tests/LayerUpdate_test.cpp
+++ b/services/surfaceflinger/tests/LayerUpdate_test.cpp
@@ -173,13 +173,13 @@
// set up two deferred transactions on different frames
asTransaction([&](Transaction& t) {
t.setAlpha(mFGSurfaceControl, 0.75);
- t.deferTransactionUntil_legacy(mFGSurfaceControl, mSyncSurfaceControl->getHandle(),
+ t.deferTransactionUntil_legacy(mFGSurfaceControl, mSyncSurfaceControl,
mSyncSurfaceControl->getSurface()->getNextFrameNumber());
});
asTransaction([&](Transaction& t) {
t.setPosition(mFGSurfaceControl, 128, 128);
- t.deferTransactionUntil_legacy(mFGSurfaceControl, mSyncSurfaceControl->getHandle(),
+ t.deferTransactionUntil_legacy(mFGSurfaceControl, mSyncSurfaceControl,
mSyncSurfaceControl->getSurface()->getNextFrameNumber() + 1);
});
@@ -480,9 +480,8 @@
mCapture->expectFGColor(84, 84);
}
- asTransaction([&](Transaction& t) {
- t.reparentChildren(mFGSurfaceControl, mBGSurfaceControl->getHandle());
- });
+ asTransaction(
+ [&](Transaction& t) { t.reparentChildren(mFGSurfaceControl, mBGSurfaceControl); });
{
mCapture = screenshot();
@@ -516,7 +515,7 @@
mCapture->expectFGColor(64, 64);
}
- asTransaction([&](Transaction& t) { t.reparent(mGrandChild, mFGSurfaceControl->getHandle()); });
+ asTransaction([&](Transaction& t) { t.reparent(mGrandChild, mFGSurfaceControl); });
{
SCOPED_TRACE("After reparenting grandchild");
@@ -531,9 +530,7 @@
TransactionUtils::fillSurfaceRGBA8(mGrandChild, 111, 111, 111);
// draw grand child behind the foreground surface
- asTransaction([&](Transaction& t) {
- t.setRelativeLayer(mGrandChild, mFGSurfaceControl->getHandle(), -1);
- });
+ asTransaction([&](Transaction& t) { t.setRelativeLayer(mGrandChild, mFGSurfaceControl, -1); });
{
SCOPED_TRACE("Child visible");
@@ -543,7 +540,7 @@
asTransaction([&](Transaction& t) {
t.reparent(mChild, nullptr);
- t.reparentChildren(mChild, mFGSurfaceControl->getHandle());
+ t.reparentChildren(mChild, mFGSurfaceControl);
});
{
@@ -739,7 +736,7 @@
// Show the child layer in a deferred transaction
asTransaction([&](Transaction& t) {
- t.deferTransactionUntil_legacy(mChild, mFGSurfaceControl->getHandle(),
+ t.deferTransactionUntil_legacy(mChild, mFGSurfaceControl,
mFGSurfaceControl->getSurface()->getNextFrameNumber());
t.show(mChild);
});
@@ -776,7 +773,7 @@
mCapture->expectFGColor(84, 84);
}
- asTransaction([&](Transaction& t) { t.reparent(mChild, mBGSurfaceControl->getHandle()); });
+ asTransaction([&](Transaction& t) { t.reparent(mChild, mBGSurfaceControl); });
{
mCapture = screenshot();
@@ -838,7 +835,7 @@
mCapture->checkPixel(10, 10, 63, 195, 63);
}
- asTransaction([&](Transaction& t) { t.reparent(newSurface, mFGSurfaceControl->getHandle()); });
+ asTransaction([&](Transaction& t) { t.reparent(newSurface, mFGSurfaceControl); });
{
mCapture = screenshot();
@@ -869,7 +866,7 @@
Transaction t;
t.setLayer(relative, INT32_MAX)
- .setRelativeLayer(mChild, relative->getHandle(), 1)
+ .setRelativeLayer(mChild, relative, 1)
.setPosition(mFGSurfaceControl, 0, 0)
.apply(true);
diff --git a/services/surfaceflinger/tests/MirrorLayer_test.cpp b/services/surfaceflinger/tests/MirrorLayer_test.cpp
index b49bd54..16826c1 100644
--- a/services/surfaceflinger/tests/MirrorLayer_test.cpp
+++ b/services/surfaceflinger/tests/MirrorLayer_test.cpp
@@ -68,7 +68,7 @@
// Add mirrorLayer as child of mParentLayer so it's shown on the display
Transaction()
- .reparent(mirrorLayer, mParentLayer->getHandle())
+ .reparent(mirrorLayer, mParentLayer)
.setPosition(mirrorLayer, 500, 500)
.show(mirrorLayer)
.apply();
@@ -127,7 +127,7 @@
}
// Add grandchild layer to offscreen layer
- Transaction().reparent(grandchild, mChildLayer->getHandle()).apply();
+ Transaction().reparent(grandchild, mChildLayer).apply();
{
SCOPED_TRACE("Added Grandchild Layer");
auto shot = screenshot();
@@ -138,7 +138,7 @@
}
// Add child layer
- Transaction().reparent(mChildLayer, mParentLayer->getHandle()).apply();
+ Transaction().reparent(mChildLayer, mParentLayer).apply();
{
SCOPED_TRACE("Added Child Layer");
auto shot = screenshot();
@@ -157,7 +157,7 @@
sp<SurfaceControl> mirrorLayer = mClient->mirrorSurface(mChildLayer.get());
Transaction()
- .reparent(mirrorLayer, mParentLayer->getHandle())
+ .reparent(mirrorLayer, mParentLayer)
.setPosition(mirrorLayer, 500, 500)
.show(mirrorLayer)
.apply();
diff --git a/services/surfaceflinger/tests/RelativeZ_test.cpp b/services/surfaceflinger/tests/RelativeZ_test.cpp
index 3e0b3c6..fde6e6e 100644
--- a/services/surfaceflinger/tests/RelativeZ_test.cpp
+++ b/services/surfaceflinger/tests/RelativeZ_test.cpp
@@ -70,10 +70,7 @@
sp<SurfaceControl> childLayer =
createColorLayer("Child layer", Color::BLUE, mBackgroundLayer.get());
- Transaction{}
- .setRelativeLayer(childLayer, mForegroundLayer->getHandle(), 1)
- .show(childLayer)
- .apply();
+ Transaction{}.setRelativeLayer(childLayer, mForegroundLayer, 1).show(childLayer).apply();
{
// The childLayer should be in front of the FG control.
@@ -88,7 +85,7 @@
// Background layer (RED)
// Child layer (WHITE)
// Foregroud layer (GREEN)
- Transaction{}.reparent(childLayer, mBackgroundLayer->getHandle()).apply();
+ Transaction{}.reparent(childLayer, mBackgroundLayer).apply();
{
// The relative z info for child layer should be reset, leaving FG control on top.
@@ -118,7 +115,7 @@
createColorLayer("child level 3", Color::GREEN, childLevel2a.get());
Transaction{}
- .setRelativeLayer(childLevel3, childLevel2b->getHandle(), 1)
+ .setRelativeLayer(childLevel3, childLevel2b, 1)
.show(childLevel2a)
.show(childLevel2b)
.show(childLevel3)
@@ -140,7 +137,7 @@
// child level 2 back (BLUE)
// child level 3 (GREEN) (relative to child level 2b)
// child level 2 front (BLACK)
- Transaction{}.reparent(childLevel1, mForegroundLayer->getHandle()).apply();
+ Transaction{}.reparent(childLevel1, mForegroundLayer).apply();
{
// Nothing should change at this point since relative z info was preserved.
@@ -162,7 +159,7 @@
createColorLayer("Relative layer", Color::WHITE, mForegroundLayer.get());
Transaction{}
- .setRelativeLayer(childLayer, relativeToLayer->getHandle(), 1)
+ .setRelativeLayer(childLayer, relativeToLayer, 1)
.show(childLayer)
.show(relativeToLayer)
.apply();
@@ -199,7 +196,7 @@
// Background layer (RED)
// Foregroud layer (GREEN)
// Child layer (BLUE)
- Transaction{}.reparent(childLayer, mForegroundLayer->getHandle()).apply();
+ Transaction{}.reparent(childLayer, mForegroundLayer).apply();
{
// The relative z info for child layer should be reset, leaving the child layer on top.
@@ -230,7 +227,7 @@
createColorLayer("child level 2b", Color::BLACK, childLevel1b.get());
Transaction{}
- .setRelativeLayer(childLevel1a, childLevel2b->getHandle(), 1)
+ .setRelativeLayer(childLevel1a, childLevel2b, 1)
.show(childLevel1a)
.show(childLevel1b)
.show(childLevel2a)
@@ -250,7 +247,7 @@
// // Background layer (RED)
// // Foregroud layer (GREEN)
- Transaction{}.reparent(childLevel1a, childLevel2a->getHandle()).apply();
+ Transaction{}.reparent(childLevel1a, childLevel2a).apply();
{
// The childLevel1a and childLevel1b are no longer on screen
@@ -264,7 +261,7 @@
// child level 2a (BLUE)
// child level 1a (testLayerColor) (relative to child level 2b)
// child level 2b (BLACK)
- Transaction{}.reparent(childLevel1b, mForegroundLayer->getHandle()).apply();
+ Transaction{}.reparent(childLevel1b, mForegroundLayer).apply();
{
// Nothing should change at this point since relative z info was preserved.
diff --git a/services/surfaceflinger/tests/ScreenCapture_test.cpp b/services/surfaceflinger/tests/ScreenCapture_test.cpp
index 3ab2ad1..e173996 100644
--- a/services/surfaceflinger/tests/ScreenCapture_test.cpp
+++ b/services/surfaceflinger/tests/ScreenCapture_test.cpp
@@ -239,7 +239,7 @@
SurfaceComposerClient::Transaction()
.show(child)
// Set relative layer above fg layer so should be shown above when computing all layers.
- .setRelativeLayer(relative, mFGSurfaceControl->getHandle(), 1)
+ .setRelativeLayer(relative, mFGSurfaceControl, 1)
.show(relative)
.apply(true);
@@ -264,7 +264,7 @@
// Set relative layer below fg layer but relative to child layer so it should be shown
// above child layer.
.setLayer(relative, -1)
- .setRelativeLayer(relative, child->getHandle(), 1)
+ .setRelativeLayer(relative, child, 1)
.show(relative)
.apply(true);
@@ -707,7 +707,7 @@
.setLayer(layerWithFakeUid, INT32_MAX)
.setPosition(layerWithFakeUid, 128, 128)
// reparent a layer that was created with a different uid to the new layer.
- .reparent(layer, layerWithFakeUid->getHandle())
+ .reparent(layer, layerWithFakeUid)
.apply();
// Screenshot from the fakeUid caller with the uid requested allows the layer
diff --git a/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp b/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp
index 8570032..104d919 100644
--- a/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp
+++ b/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp
@@ -397,16 +397,15 @@
}
void SurfaceInterceptorTest::deferredTransactionUpdate(Transaction& t) {
- t.deferTransactionUntil_legacy(mBGSurfaceControl, mBGSurfaceControl->getHandle(),
- DEFERRED_UPDATE);
+ t.deferTransactionUntil_legacy(mBGSurfaceControl, mBGSurfaceControl, DEFERRED_UPDATE);
}
void SurfaceInterceptorTest::reparentUpdate(Transaction& t) {
- t.reparent(mBGSurfaceControl, mFGSurfaceControl->getHandle());
+ t.reparent(mBGSurfaceControl, mFGSurfaceControl);
}
void SurfaceInterceptorTest::relativeParentUpdate(Transaction& t) {
- t.setRelativeLayer(mBGSurfaceControl, mFGSurfaceControl->getHandle(), RELATIVE_Z);
+ t.setRelativeLayer(mBGSurfaceControl, mFGSurfaceControl, RELATIVE_Z);
}
void SurfaceInterceptorTest::detachChildrenUpdate(Transaction& t) {
@@ -414,7 +413,7 @@
}
void SurfaceInterceptorTest::reparentChildrenUpdate(Transaction& t) {
- t.reparentChildren(mBGSurfaceControl, mFGSurfaceControl->getHandle());
+ t.reparentChildren(mBGSurfaceControl, mFGSurfaceControl);
}
void SurfaceInterceptorTest::shadowRadiusUpdate(Transaction& t) {
diff --git a/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp b/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp
index 87fc08a..07c558f 100644
--- a/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp
+++ b/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp
@@ -1322,7 +1322,7 @@
{
TransactionScope ts(*sFakeComposer);
ts.setAlpha(mFGSurfaceControl, 0.75);
- ts.deferTransactionUntil_legacy(mFGSurfaceControl, syncSurfaceControl->getHandle(),
+ ts.deferTransactionUntil_legacy(mFGSurfaceControl, syncSurfaceControl,
syncSurfaceControl->getSurface()->getNextFrameNumber());
}
EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame()));
@@ -1330,7 +1330,7 @@
{
TransactionScope ts(*sFakeComposer);
ts.setPosition(mFGSurfaceControl, 128, 128);
- ts.deferTransactionUntil_legacy(mFGSurfaceControl, syncSurfaceControl->getHandle(),
+ ts.deferTransactionUntil_legacy(mFGSurfaceControl, syncSurfaceControl,
syncSurfaceControl->getSurface()->getNextFrameNumber() +
1);
}
@@ -1376,7 +1376,7 @@
TransactionScope ts(*sFakeComposer);
ts.setPosition(relativeSurfaceControl, 64, 64);
ts.show(relativeSurfaceControl);
- ts.setRelativeLayer(relativeSurfaceControl, mFGSurfaceControl->getHandle(), 1);
+ ts.setRelativeLayer(relativeSurfaceControl, mFGSurfaceControl, 1);
}
auto referenceFrame = mBaseFrame;
// NOTE: All three layers will be visible as the surfaces are
@@ -1606,7 +1606,7 @@
{
TransactionScope ts(*Base::sFakeComposer);
- ts.reparentChildren(Base::mFGSurfaceControl, Base::mBGSurfaceControl->getHandle());
+ ts.reparentChildren(Base::mFGSurfaceControl, Base::mBGSurfaceControl);
}
auto referenceFrame2 = referenceFrame;
@@ -1761,7 +1761,7 @@
// Show the child layer in a deferred transaction
{
TransactionScope ts(*Base::sFakeComposer);
- ts.deferTransactionUntil_legacy(mChild, Base::mFGSurfaceControl->getHandle(),
+ ts.deferTransactionUntil_legacy(mChild, Base::mFGSurfaceControl,
Base::mFGSurfaceControl->getSurface()
->getNextFrameNumber());
ts.show(mChild);
diff --git a/services/surfaceflinger/tests/unittests/Android.bp b/services/surfaceflinger/tests/unittests/Android.bp
index cf3a4c2..9655cf3 100644
--- a/services/surfaceflinger/tests/unittests/Android.bp
+++ b/services/surfaceflinger/tests/unittests/Android.bp
@@ -39,6 +39,7 @@
"CompositionTest.cpp",
"DispSyncSourceTest.cpp",
"DisplayIdentificationTest.cpp",
+ "DisplayIdGeneratorTest.cpp",
"DisplayTransactionTest.cpp",
"EventThreadTest.cpp",
"FrameTimelineTest.cpp",
diff --git a/services/surfaceflinger/tests/unittests/DisplayIdGeneratorTest.cpp b/services/surfaceflinger/tests/unittests/DisplayIdGeneratorTest.cpp
new file mode 100644
index 0000000..be7609a
--- /dev/null
+++ b/services/surfaceflinger/tests/unittests/DisplayIdGeneratorTest.cpp
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gtest/gtest.h>
+
+#include <vector>
+
+#include <ui/DisplayId.h>
+#include "DisplayIdGenerator.h"
+
+namespace android {
+
+template <typename T>
+void testNextId(DisplayIdGenerator<T>& generator) {
+ constexpr int kNumIds = 5;
+ std::vector<T> ids;
+ for (int i = 0; i < kNumIds; i++) {
+ const auto id = generator.nextId();
+ ASSERT_TRUE(id);
+ ids.push_back(*id);
+ }
+
+ // All IDs should be different.
+ for (size_t i = 0; i < kNumIds; i++) {
+ for (size_t j = i + 1; j < kNumIds; j++) {
+ EXPECT_NE(ids[i], ids[j]);
+ }
+ }
+}
+
+TEST(DisplayIdGeneratorTest, nextIdGpuVirtual) {
+ RandomDisplayIdGenerator<GpuVirtualDisplayId> generator;
+ testNextId(generator);
+}
+
+TEST(DisplayIdGeneratorTest, nextIdHalVirtual) {
+ RandomDisplayIdGenerator<HalVirtualDisplayId> generator;
+ testNextId(generator);
+}
+
+TEST(DisplayIdGeneratorTest, markUnused) {
+ constexpr size_t kMaxIdsCount = 5;
+ RandomDisplayIdGenerator<GpuVirtualDisplayId> generator(kMaxIdsCount);
+
+ const auto id = generator.nextId();
+ EXPECT_TRUE(id);
+
+ for (int i = 1; i < kMaxIdsCount; i++) {
+ EXPECT_TRUE(generator.nextId());
+ }
+
+ EXPECT_FALSE(generator.nextId());
+
+ generator.markUnused(*id);
+ EXPECT_TRUE(generator.nextId());
+}
+
+TEST(DisplayIdGeneratorTest, maxIdsCount) {
+ constexpr size_t kMaxIdsCount = 5;
+ RandomDisplayIdGenerator<GpuVirtualDisplayId> generator(kMaxIdsCount);
+
+ for (int i = 0; i < kMaxIdsCount; i++) {
+ EXPECT_TRUE(generator.nextId());
+ }
+
+ EXPECT_FALSE(generator.nextId());
+}
+
+} // namespace android
diff --git a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
index 5864d02..e055e95 100644
--- a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
@@ -338,9 +338,9 @@
struct PhysicalDisplayIdType {};
template <uint64_t displayId>
-using VirtualDisplayIdType = std::integral_constant<uint64_t, displayId>;
+using HalVirtualDisplayIdType = std::integral_constant<uint64_t, displayId>;
-struct NoDisplayId {};
+struct GpuVirtualDisplayIdType {};
template <typename>
struct IsPhysicalDisplayId : std::bool_constant<false> {};
@@ -353,7 +353,7 @@
template <typename PhysicalDisplay>
struct DisplayIdGetter<PhysicalDisplayIdType<PhysicalDisplay>> {
- static std::optional<PhysicalDisplayId> get() {
+ static PhysicalDisplayId get() {
if (!PhysicalDisplay::HAS_IDENTIFICATION_DATA) {
return PhysicalDisplayId::fromPort(static_cast<bool>(PhysicalDisplay::PRIMARY)
? LEGACY_DISPLAY_TYPE_PRIMARY
@@ -363,19 +363,18 @@
const auto info =
parseDisplayIdentificationData(PhysicalDisplay::PORT,
PhysicalDisplay::GET_IDENTIFICATION_DATA());
- return info ? std::make_optional(info->id) : std::nullopt;
+ return info ? info->id : PhysicalDisplayId::fromPort(PhysicalDisplay::PORT);
}
};
template <uint64_t displayId>
-struct DisplayIdGetter<VirtualDisplayIdType<displayId>> {
- // TODO(b/160679868) Use VirtualDisplayId
- static std::optional<PhysicalDisplayId> get() { return PhysicalDisplayId{displayId}; }
+struct DisplayIdGetter<HalVirtualDisplayIdType<displayId>> {
+ static HalVirtualDisplayId get() { return HalVirtualDisplayId(displayId); }
};
template <>
-struct DisplayIdGetter<NoDisplayId> {
- static std::optional<DisplayId> get() { return {}; }
+struct DisplayIdGetter<GpuVirtualDisplayIdType> {
+ static GpuVirtualDisplayId get() { return GpuVirtualDisplayId(0); }
};
template <typename>
@@ -396,7 +395,7 @@
constexpr HWDisplayId HWC_VIRTUAL_DISPLAY_HWC_DISPLAY_ID = 1010;
template <uint64_t displayId>
-struct HwcDisplayIdGetter<VirtualDisplayIdType<displayId>> {
+struct HwcDisplayIdGetter<HalVirtualDisplayIdType<displayId>> {
static constexpr std::optional<HWDisplayId> value = HWC_VIRTUAL_DISPLAY_HWC_DISPLAY_ID;
};
@@ -407,8 +406,8 @@
// DisplayIdType can be:
// 1) PhysicalDisplayIdType<...> for generated ID of physical display backed by HWC.
-// 2) VirtualDisplayIdType<...> for hard-coded ID of virtual display backed by HWC.
-// 3) NoDisplayId for virtual display without HWC backing.
+// 2) HalVirtualDisplayIdType<...> for hard-coded ID of virtual display backed by HWC.
+// 3) GpuVirtualDisplayIdType for virtual display without HWC backing.
template <typename DisplayIdType, int width, int height, Critical critical, Async async,
Secure secure, Primary primary, int grallocUsage>
struct DisplayVariant {
@@ -440,17 +439,36 @@
static auto makeFakeExistingDisplayInjector(DisplayTransactionTest* test) {
auto ceDisplayArgs = compositionengine::DisplayCreationArgsBuilder();
- if (auto displayId = DISPLAY_ID::get()) {
+ if (auto displayId = PhysicalDisplayId::tryCast(DISPLAY_ID::get())) {
ceDisplayArgs.setPhysical({*displayId, DisplayConnectionType::Internal});
} else {
+ // We turn off the use of HwcVirtualDisplays, to prevent Composition Engine
+ // from calling into HWComposer. This way all virtual displays will get
+ // a GpuVirtualDisplayId, even if we are in the HwcVirtualDisplayVariant.
+ // In this case we later override it by calling display.setDisplayIdForTesting().
ceDisplayArgs.setUseHwcVirtualDisplays(false);
+
+ GpuVirtualDisplayId desiredDisplayId = GpuVirtualDisplayId::tryCast(DISPLAY_ID::get())
+ .value_or(GpuVirtualDisplayId(0));
+
+ ON_CALL(test->mFlinger.gpuVirtualDisplayIdGenerator(), nextId())
+ .WillByDefault(Return(desiredDisplayId));
+
+ auto& generator = test->mFlinger.gpuVirtualDisplayIdGenerator();
+ ceDisplayArgs.setGpuVirtualDisplayIdGenerator(generator);
}
- ceDisplayArgs.setPixels({WIDTH, HEIGHT}).setPowerAdvisor(&test->mPowerAdvisor).build();
+ ceDisplayArgs.setPixels({WIDTH, HEIGHT}).setPowerAdvisor(&test->mPowerAdvisor);
auto compositionDisplay =
compositionengine::impl::createDisplay(test->mFlinger.getCompositionEngine(),
ceDisplayArgs.build());
+ if (HalVirtualDisplayId::tryCast(DISPLAY_ID::get())) {
+ // CompositionEngine has assigned a placeholder GpuVirtualDisplayId and we need to
+ // override it with the correct HalVirtualDisplayId.
+ compositionDisplay->setDisplayIdForTesting(DISPLAY_ID::get());
+ }
+
auto injector = FakeDisplayDeviceInjector(test->mFlinger, compositionDisplay,
CONNECTION_TYPE::value, HWC_DISPLAY_ID_OPT::value,
static_cast<bool>(PRIMARY));
@@ -532,8 +550,8 @@
// Called by tests to inject a HWC display setup
static void injectHwcDisplayWithNoDefaultCapabilities(DisplayTransactionTest* test) {
const auto displayId = DisplayVariant::DISPLAY_ID::get();
- ASSERT_TRUE(displayId);
- FakeHwcDisplayInjector(*displayId, HWC_DISPLAY_TYPE,
+ ASSERT_FALSE(GpuVirtualDisplayId::tryCast(displayId));
+ FakeHwcDisplayInjector(displayId, HWC_DISPLAY_TYPE,
static_cast<bool>(DisplayVariant::PRIMARY))
.setHwcDisplayId(HWC_DISPLAY_ID)
.setWidth(DisplayVariant::WIDTH)
@@ -559,7 +577,7 @@
::testing::UnitTest::GetInstance()->current_test_info();
auto ceDisplayArgs = compositionengine::DisplayCreationArgsBuilder()
- .setPhysical({*DisplayVariant::DISPLAY_ID::get(),
+ .setPhysical({DisplayVariant::DISPLAY_ID::get(),
PhysicalDisplay::CONNECTION_TYPE})
.setPixels({DisplayVariant::WIDTH, DisplayVariant::HEIGHT})
.setIsSecure(static_cast<bool>(DisplayVariant::SECURE))
@@ -686,10 +704,11 @@
template <int width, int height, Secure secure>
struct NonHwcVirtualDisplayVariant
- : DisplayVariant<NoDisplayId, width, height, Critical::FALSE, Async::TRUE, secure,
+ : DisplayVariant<GpuVirtualDisplayIdType, width, height, Critical::FALSE, Async::TRUE, secure,
Primary::FALSE, GRALLOC_USAGE_NONHWC_VIRTUAL_DISPLAY> {
- using Base = DisplayVariant<NoDisplayId, width, height, Critical::FALSE, Async::TRUE, secure,
- Primary::FALSE, GRALLOC_USAGE_NONHWC_VIRTUAL_DISPLAY>;
+ using Base =
+ DisplayVariant<GpuVirtualDisplayIdType, width, height, Critical::FALSE, Async::TRUE,
+ secure, Primary::FALSE, GRALLOC_USAGE_NONHWC_VIRTUAL_DISPLAY>;
static void injectHwcDisplay(DisplayTransactionTest*) {}
@@ -698,12 +717,17 @@
const ::testing::TestInfo* const test_info =
::testing::UnitTest::GetInstance()->current_test_info();
+ ON_CALL(test->mFlinger.gpuVirtualDisplayIdGenerator(), nextId())
+ .WillByDefault(Return(Base::DISPLAY_ID::get()));
+
auto ceDisplayArgs = compositionengine::DisplayCreationArgsBuilder()
.setPixels({Base::WIDTH, Base::HEIGHT})
.setIsSecure(static_cast<bool>(Base::SECURE))
.setPowerAdvisor(&test->mPowerAdvisor)
.setName(std::string("Injected display for ") +
test_info->test_case_name() + "." + test_info->name())
+ .setGpuVirtualDisplayIdGenerator(
+ test->mFlinger.gpuVirtualDisplayIdGenerator())
.build();
return compositionengine::impl::createDisplay(test->mFlinger.getCompositionEngine(),
@@ -725,13 +749,13 @@
template <int width, int height, Secure secure>
struct HwcVirtualDisplayVariant
- : DisplayVariant<VirtualDisplayIdType<42>, width, height, Critical::FALSE, Async::TRUE,
+ : DisplayVariant<HalVirtualDisplayIdType<42>, width, height, Critical::FALSE, Async::TRUE,
secure, Primary::FALSE, GRALLOC_USAGE_HWC_VIRTUAL_DISPLAY>,
HwcDisplayVariant<HWC_VIRTUAL_DISPLAY_HWC_DISPLAY_ID, DisplayType::VIRTUAL,
- DisplayVariant<VirtualDisplayIdType<42>, width, height, Critical::FALSE,
- Async::TRUE, secure, Primary::FALSE,
+ DisplayVariant<HalVirtualDisplayIdType<42>, width, height,
+ Critical::FALSE, Async::TRUE, secure, Primary::FALSE,
GRALLOC_USAGE_HWC_VIRTUAL_DISPLAY>> {
- using Base = DisplayVariant<VirtualDisplayIdType<42>, width, height, Critical::FALSE,
+ using Base = DisplayVariant<HalVirtualDisplayIdType<42>, width, height, Critical::FALSE,
Async::TRUE, secure, Primary::FALSE, GRALLOC_USAGE_HW_COMPOSER>;
using Self = HwcVirtualDisplayVariant<width, height, secure>;
@@ -740,6 +764,14 @@
const ::testing::TestInfo* const test_info =
::testing::UnitTest::GetInstance()->current_test_info();
+ // In order to prevent compostition engine calling into HWComposer, we
+ // 1. turn off the use of HWC virtual displays,
+ // 2. provide a GpuVirtualDisplayIdGenerator which always returns some fake ID
+ // 3. override the ID by calling setDisplayIdForTesting()
+
+ ON_CALL(test->mFlinger.gpuVirtualDisplayIdGenerator(), nextId())
+ .WillByDefault(Return(GpuVirtualDisplayId(0)));
+
auto ceDisplayArgs = compositionengine::DisplayCreationArgsBuilder()
.setUseHwcVirtualDisplays(false)
.setPixels({Base::WIDTH, Base::HEIGHT})
@@ -747,6 +779,8 @@
.setPowerAdvisor(&test->mPowerAdvisor)
.setName(std::string("Injected display for ") +
test_info->test_case_name() + "." + test_info->name())
+ .setGpuVirtualDisplayIdGenerator(
+ test->mFlinger.gpuVirtualDisplayIdGenerator())
.build();
auto compositionDisplay =
@@ -755,8 +789,9 @@
compositionDisplay->setDisplayIdForTesting(Base::DISPLAY_ID::get());
// Insert display data so that the HWC thinks it created the virtual display.
- if (const auto displayId = Base::DISPLAY_ID::get()) {
- test->mFlinger.mutableHwcDisplayData().try_emplace(*displayId);
+ if (const auto displayId = Base::DISPLAY_ID::get();
+ HalVirtualDisplayId::tryCast(displayId)) {
+ test->mFlinger.mutableHwcDisplayData().try_emplace(displayId);
}
return compositionDisplay;
@@ -1776,13 +1811,11 @@
DisplayDeviceState state;
if (const auto connectionType = Case::Display::CONNECTION_TYPE::value) {
- const auto displayId = Case::Display::DISPLAY_ID::get();
+ const auto displayId = PhysicalDisplayId::tryCast(Case::Display::DISPLAY_ID::get());
ASSERT_TRUE(displayId);
const auto hwcDisplayId = Case::Display::HWC_DISPLAY_ID_OPT::value;
ASSERT_TRUE(hwcDisplayId);
- state.physical = {.id = static_cast<PhysicalDisplayId>(*displayId),
- .type = *connectionType,
- .hwcDisplayId = *hwcDisplayId};
+ state.physical = {.id = *displayId, .type = *connectionType, .hwcDisplayId = *hwcDisplayId};
}
state.isSecure = static_cast<bool>(Case::Display::SECURE);
@@ -1954,11 +1987,11 @@
std::optional<DisplayDeviceState::Physical> expectedPhysical;
if (const auto connectionType = Case::Display::CONNECTION_TYPE::value) {
- const auto displayId = Case::Display::DISPLAY_ID::get();
+ const auto displayId = PhysicalDisplayId::tryCast(Case::Display::DISPLAY_ID::get());
ASSERT_TRUE(displayId);
const auto hwcDisplayId = Case::Display::HWC_DISPLAY_ID_OPT::value;
ASSERT_TRUE(hwcDisplayId);
- expectedPhysical = {.id = static_cast<PhysicalDisplayId>(*displayId),
+ expectedPhysical = {.id = *displayId,
.type = *connectionType,
.hwcDisplayId = *hwcDisplayId};
}
@@ -1983,9 +2016,9 @@
// SF should have a display token.
const auto displayId = Case::Display::DISPLAY_ID::get();
- ASSERT_TRUE(displayId);
- ASSERT_TRUE(mFlinger.mutablePhysicalDisplayTokens().count(*displayId) == 1);
- auto& displayToken = mFlinger.mutablePhysicalDisplayTokens()[*displayId];
+ ASSERT_TRUE(PhysicalDisplayId::tryCast(displayId));
+ ASSERT_TRUE(mFlinger.mutablePhysicalDisplayTokens().count(displayId) == 1);
+ auto& displayToken = mFlinger.mutablePhysicalDisplayTokens()[displayId];
verifyDisplayIsConnected<Case>(displayToken);
}
@@ -2088,8 +2121,8 @@
// SF should not have a display token.
const auto displayId = Case::Display::DISPLAY_ID::get();
- ASSERT_TRUE(displayId);
- ASSERT_TRUE(mFlinger.mutablePhysicalDisplayTokens().count(*displayId) == 0);
+ ASSERT_TRUE(PhysicalDisplayId::tryCast(displayId));
+ ASSERT_TRUE(mFlinger.mutablePhysicalDisplayTokens().count(displayId) == 0);
// The existing token should have been removed
verifyDisplayIsNotConnected(existing.token());
@@ -2174,8 +2207,8 @@
// SF should not have a display token.
const auto displayId = Case::Display::DISPLAY_ID::get();
- ASSERT_TRUE(displayId);
- ASSERT_TRUE(mFlinger.mutablePhysicalDisplayTokens().count(*displayId) == 0);
+ ASSERT_TRUE(PhysicalDisplayId::tryCast(displayId));
+ ASSERT_TRUE(mFlinger.mutablePhysicalDisplayTokens().count(displayId) == 0);
}
TEST_F(HandleTransactionLockedTest, processesHotplugDisconnectThenConnectPrimary) {
@@ -2213,9 +2246,9 @@
// The existing token should have been removed
verifyDisplayIsNotConnected(existing.token());
const auto displayId = Case::Display::DISPLAY_ID::get();
- ASSERT_TRUE(displayId);
- ASSERT_TRUE(mFlinger.mutablePhysicalDisplayTokens().count(*displayId) == 1);
- EXPECT_NE(existing.token(), mFlinger.mutablePhysicalDisplayTokens()[*displayId]);
+ ASSERT_TRUE(PhysicalDisplayId::tryCast(displayId));
+ ASSERT_TRUE(mFlinger.mutablePhysicalDisplayTokens().count(displayId) == 1);
+ EXPECT_NE(existing.token(), mFlinger.mutablePhysicalDisplayTokens()[displayId]);
// A new display should be connected in its place
@@ -2349,8 +2382,8 @@
// A virtual display is set up but is removed from the current state.
const auto displayId = Case::Display::DISPLAY_ID::get();
- ASSERT_TRUE(displayId);
- mFlinger.mutableHwcDisplayData().try_emplace(*displayId);
+ ASSERT_TRUE(HalVirtualDisplayId::tryCast(displayId));
+ mFlinger.mutableHwcDisplayData().try_emplace(displayId);
Case::Display::injectHwcDisplay(this);
auto existing = Case::Display::makeFakeExistingDisplayInjector(this);
existing.inject();
@@ -3485,8 +3518,8 @@
// Insert display data so that the HWC thinks it created the virtual display.
const auto displayId = Case::Display::DISPLAY_ID::get();
- ASSERT_TRUE(displayId);
- mFlinger.mutableHwcDisplayData().try_emplace(*displayId);
+ ASSERT_TRUE(HalVirtualDisplayId::tryCast(displayId));
+ mFlinger.mutableHwcDisplayData().try_emplace(displayId);
// A virtual display device is set up
Case::Display::injectHwcDisplay(this);
diff --git a/services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp b/services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp
index 85d2834..617f95a 100644
--- a/services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp
+++ b/services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp
@@ -217,4 +217,20 @@
true);
}
+TEST_F(FrameTimelineTest, surfaceFrameEndTimeAcquireFenceAfterQueue) {
+ auto surfaceFrame =
+ mFrameTimeline->createSurfaceFrameForToken("acquireFenceAfterQueue", std::nullopt);
+ surfaceFrame->setActualQueueTime(123);
+ surfaceFrame->setAcquireFenceTime(456);
+ EXPECT_EQ(surfaceFrame->getActuals().endTime, 456);
+}
+
+TEST_F(FrameTimelineTest, surfaceFrameEndTimeAcquireFenceBeforeQueue) {
+ auto surfaceFrame =
+ mFrameTimeline->createSurfaceFrameForToken("acquireFenceAfterQueue", std::nullopt);
+ surfaceFrame->setActualQueueTime(456);
+ surfaceFrame->setAcquireFenceTime(123);
+ EXPECT_EQ(surfaceFrame->getActuals().endTime, 456);
+}
+
} // namespace android::frametimeline
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index 8c12e94..9ff8f4e 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -40,6 +40,7 @@
#include "SurfaceInterceptor.h"
#include "TestableScheduler.h"
#include "mock/DisplayHardware/MockDisplay.h"
+#include "mock/MockDisplayIdGenerator.h"
namespace android {
@@ -83,8 +84,8 @@
return nullptr;
}
- sp<SurfaceInterceptor> createSurfaceInterceptor(SurfaceFlinger* flinger) override {
- return new android::impl::SurfaceInterceptor(flinger);
+ sp<SurfaceInterceptor> createSurfaceInterceptor() override {
+ return new android::impl::SurfaceInterceptor();
}
sp<StartPropertySetThread> createStartPropertySetThread(bool timestampPropertyValue) override {
@@ -171,6 +172,9 @@
SurfaceFlinger* flinger() { return mFlinger.get(); }
TestableScheduler* scheduler() { return mScheduler; }
+ mock::DisplayIdGenerator<GpuVirtualDisplayId>& gpuVirtualDisplayIdGenerator() {
+ return mGpuVirtualDisplayIdGenerator;
+ }
// Extend this as needed for accessing SurfaceFlinger private (and public)
// functions.
@@ -463,7 +467,8 @@
static constexpr hal::HWConfigId DEFAULT_ACTIVE_CONFIG = 0;
static constexpr hal::PowerMode DEFAULT_POWER_MODE = hal::PowerMode::ON;
- FakeHwcDisplayInjector(DisplayId displayId, hal::DisplayType hwcDisplayType, bool isPrimary)
+ FakeHwcDisplayInjector(HalDisplayId displayId, hal::DisplayType hwcDisplayType,
+ bool isPrimary)
: mDisplayId(displayId), mHwcDisplayType(hwcDisplayType), mIsPrimary(isPrimary) {}
auto& setHwcDisplayId(hal::HWDisplayId displayId) {
@@ -536,14 +541,16 @@
flinger->mutableHwcDisplayData()[mDisplayId].hwcDisplay = std::move(display);
if (mHwcDisplayType == hal::DisplayType::PHYSICAL) {
- flinger->mutableHwcPhysicalDisplayIdMap().emplace(mHwcDisplayId, mDisplayId);
+ const auto physicalId = PhysicalDisplayId::tryCast(mDisplayId);
+ LOG_ALWAYS_FATAL_IF(!physicalId);
+ flinger->mutableHwcPhysicalDisplayIdMap().emplace(mHwcDisplayId, *physicalId);
(mIsPrimary ? flinger->mutableInternalHwcDisplayId()
: flinger->mutableExternalHwcDisplayId()) = mHwcDisplayId;
}
}
private:
- const DisplayId mDisplayId;
+ const HalDisplayId mDisplayId;
const hal::DisplayType mHwcDisplayType;
const bool mIsPrimary;
@@ -635,10 +642,10 @@
DisplayDeviceState state;
if (const auto type = mCreationArgs.connectionType) {
LOG_ALWAYS_FATAL_IF(!displayId);
+ const auto physicalId = PhysicalDisplayId::tryCast(*displayId);
+ LOG_ALWAYS_FATAL_IF(!physicalId);
LOG_ALWAYS_FATAL_IF(!mHwcDisplayId);
- state.physical = {.id = static_cast<PhysicalDisplayId>(*displayId),
- .type = *type,
- .hwcDisplayId = *mHwcDisplayId};
+ state.physical = {.id = *physicalId, .type = *type, .hwcDisplayId = *mHwcDisplayId};
}
state.isSecure = mCreationArgs.isSecure;
@@ -672,6 +679,7 @@
sp<SurfaceFlinger> mFlinger = new SurfaceFlinger(mFactory, SurfaceFlinger::SkipInitialization);
TestableScheduler* mScheduler = nullptr;
Hwc2::mock::Display mDisplay;
+ mock::DisplayIdGenerator<GpuVirtualDisplayId> mGpuVirtualDisplayIdGenerator;
};
} // namespace android
diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.cpp b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.cpp
index 0780af1..251ab36 100644
--- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.cpp
+++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.cpp
@@ -20,17 +20,13 @@
#include "mock/DisplayHardware/MockComposer.h"
-namespace android {
-namespace Hwc2 {
-namespace mock {
+namespace android::Hwc2::mock {
// Explicit default instantiation is recommended.
Composer::Composer() = default;
Composer::~Composer() = default;
-} // namespace mock
-} // namespace Hwc2
-} // namespace android
+} // namespace android::Hwc2::mock
// TODO(b/129481165): remove the #pragma below and fix conversion issues
#pragma clang diagnostic pop // ignored "-Wconversion"
diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h
index cd9b87a..1ba3c0f 100644
--- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h
+++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h
@@ -24,8 +24,7 @@
class GraphicBuffer;
-namespace Hwc2 {
-namespace mock {
+namespace Hwc2::mock {
using android::hardware::graphics::common::V1_0::ColorTransform;
using android::hardware::graphics::common::V1_0::Transform;
@@ -140,6 +139,5 @@
MOCK_METHOD2(getClientTargetProperty, Error(Display, IComposerClient::ClientTargetProperty*));
};
-} // namespace mock
-} // namespace Hwc2
+} // namespace Hwc2::mock
} // namespace android
diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplay.cpp b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplay.cpp
index 2ec37c1..c9788af 100644
--- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplay.cpp
+++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplay.cpp
@@ -16,14 +16,10 @@
#include "mock/DisplayHardware/MockDisplay.h"
-namespace android {
-namespace Hwc2 {
-namespace mock {
+namespace android::Hwc2::mock {
// Explicit default instantiation is recommended.
Display::Display() = default;
Display::~Display() = default;
-} // namespace mock
-} // namespace Hwc2
-} // namespace android
\ No newline at end of file
+} // namespace android::Hwc2::mock
\ No newline at end of file
diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplay.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplay.h
index fe99e77..a96d9db 100644
--- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplay.h
+++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplay.h
@@ -22,9 +22,7 @@
using android::HWC2::Layer;
-namespace android {
-namespace Hwc2 {
-namespace mock {
+namespace android::Hwc2::mock {
namespace hal = android::hardware::graphics::composer::hal;
@@ -98,6 +96,4 @@
MOCK_CONST_METHOD0(isVsyncPeriodSwitchSupported, bool());
};
-} // namespace mock
-} // namespace Hwc2
-} // namespace android
+} // namespace android::Hwc2::mock
diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerAdvisor.cpp b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerAdvisor.cpp
index 8be7077..1ba38a8 100644
--- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerAdvisor.cpp
+++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerAdvisor.cpp
@@ -16,14 +16,10 @@
#include "MockPowerAdvisor.h"
-namespace android {
-namespace Hwc2 {
-namespace mock {
+namespace android::Hwc2::mock {
// Explicit default instantiation is recommended.
PowerAdvisor::PowerAdvisor() = default;
PowerAdvisor::~PowerAdvisor() = default;
-} // namespace mock
-} // namespace Hwc2
-} // namespace android
+} // namespace android::Hwc2::mock
diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerAdvisor.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerAdvisor.h
index e22d0cf..7450b5d 100644
--- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerAdvisor.h
+++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerAdvisor.h
@@ -20,9 +20,7 @@
#include "DisplayHardware/PowerAdvisor.h"
-namespace android {
-namespace Hwc2 {
-namespace mock {
+namespace android::Hwc2::mock {
class PowerAdvisor : public android::Hwc2::PowerAdvisor {
public:
@@ -34,6 +32,4 @@
MOCK_METHOD0(notifyDisplayUpdateImminent, void());
};
-} // namespace mock
-} // namespace Hwc2
-} // namespace android
+} // namespace android::Hwc2::mock
diff --git a/services/surfaceflinger/tests/unittests/mock/MockDisplayIdGenerator.h b/services/surfaceflinger/tests/unittests/mock/MockDisplayIdGenerator.h
new file mode 100644
index 0000000..cfc37ea
--- /dev/null
+++ b/services/surfaceflinger/tests/unittests/mock/MockDisplayIdGenerator.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <gmock/gmock.h>
+
+#include "DisplayIdGenerator.h"
+
+namespace android::mock {
+
+template <typename T>
+class DisplayIdGenerator : public android::DisplayIdGenerator<T> {
+public:
+ // Explicit default instantiation is recommended.
+ DisplayIdGenerator() = default;
+ virtual ~DisplayIdGenerator() = default;
+
+ MOCK_METHOD0(nextId, std::optional<T>());
+ MOCK_METHOD1(markUnused, void(T));
+};
+
+} // namespace android::mock
diff --git a/services/surfaceflinger/tests/unittests/mock/MockEventThread.cpp b/services/surfaceflinger/tests/unittests/mock/MockEventThread.cpp
index 408cd35..302dc01 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockEventThread.cpp
+++ b/services/surfaceflinger/tests/unittests/mock/MockEventThread.cpp
@@ -16,12 +16,10 @@
#include "mock/MockEventThread.h"
-namespace android {
-namespace mock {
+namespace android::mock {
// Explicit default instantiation is recommended.
EventThread::EventThread() = default;
EventThread::~EventThread() = default;
-} // namespace mock
-} // namespace android
+} // namespace android::mock
diff --git a/services/surfaceflinger/tests/unittests/mock/MockEventThread.h b/services/surfaceflinger/tests/unittests/mock/MockEventThread.h
index eefdec1..b4594c1 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockEventThread.h
+++ b/services/surfaceflinger/tests/unittests/mock/MockEventThread.h
@@ -20,8 +20,7 @@
#include "Scheduler/EventThread.h"
-namespace android {
-namespace mock {
+namespace android::mock {
class EventThread : public android::EventThread {
public:
@@ -47,5 +46,4 @@
MOCK_METHOD0(getEventThreadConnectionCount, size_t());
};
-} // namespace mock
-} // namespace android
+} // namespace android::mock
diff --git a/services/surfaceflinger/tests/unittests/mock/MockFrameTracer.cpp b/services/surfaceflinger/tests/unittests/mock/MockFrameTracer.cpp
index 358dfdb..417dcb0 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockFrameTracer.cpp
+++ b/services/surfaceflinger/tests/unittests/mock/MockFrameTracer.cpp
@@ -16,12 +16,10 @@
#include "mock/MockFrameTracer.h"
-namespace android {
-namespace mock {
+namespace android::mock {
// Explicit default instantiation is recommended.
FrameTracer::FrameTracer() = default;
FrameTracer::~FrameTracer() = default;
-} // namespace mock
-} // namespace android
+} // namespace android::mock
diff --git a/services/surfaceflinger/tests/unittests/mock/MockFrameTracer.h b/services/surfaceflinger/tests/unittests/mock/MockFrameTracer.h
index f768b81..305cb1c 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockFrameTracer.h
+++ b/services/surfaceflinger/tests/unittests/mock/MockFrameTracer.h
@@ -20,8 +20,7 @@
#include "FrameTracer/FrameTracer.h"
-namespace android {
-namespace mock {
+namespace android::mock {
class FrameTracer : public android::FrameTracer {
public:
@@ -39,5 +38,4 @@
MOCK_METHOD0(miniDump, std::string());
};
-} // namespace mock
-} // namespace android
+} // namespace android::mock
diff --git a/services/surfaceflinger/tests/unittests/mock/MockSurfaceInterceptor.cpp b/services/surfaceflinger/tests/unittests/mock/MockSurfaceInterceptor.cpp
index 7e925b9..0a0e7b5 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockSurfaceInterceptor.cpp
+++ b/services/surfaceflinger/tests/unittests/mock/MockSurfaceInterceptor.cpp
@@ -20,15 +20,13 @@
#include "mock/MockSurfaceInterceptor.h"
-namespace android {
-namespace mock {
+namespace android::mock {
// Explicit default instantiation is recommended.
SurfaceInterceptor::SurfaceInterceptor() = default;
SurfaceInterceptor::~SurfaceInterceptor() = default;
-} // namespace mock
-} // namespace android
+} // namespace android::mock
// TODO(b/129481165): remove the #pragma below and fix conversion issues
#pragma clang diagnostic pop // ignored "-Wconversion"
diff --git a/services/surfaceflinger/tests/unittests/mock/MockSurfaceInterceptor.h b/services/surfaceflinger/tests/unittests/mock/MockSurfaceInterceptor.h
index 03a04a9..b085027 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockSurfaceInterceptor.h
+++ b/services/surfaceflinger/tests/unittests/mock/MockSurfaceInterceptor.h
@@ -20,8 +20,7 @@
#include "SurfaceInterceptor.h"
-namespace android {
-namespace mock {
+namespace android::mock {
class SurfaceInterceptor : public android::SurfaceInterceptor {
public:
@@ -48,5 +47,4 @@
MOCK_METHOD1(saveVSyncEvent, void(nsecs_t));
};
-} // namespace mock
-} // namespace android
+} // namespace android::mock
diff --git a/services/surfaceflinger/tests/unittests/mock/MockTimeStats.cpp b/services/surfaceflinger/tests/unittests/mock/MockTimeStats.cpp
index d686939..f8e76b2 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockTimeStats.cpp
+++ b/services/surfaceflinger/tests/unittests/mock/MockTimeStats.cpp
@@ -16,12 +16,10 @@
#include "mock/MockTimeStats.h"
-namespace android {
-namespace mock {
+namespace android::mock {
// Explicit default instantiation is recommended.
TimeStats::TimeStats() = default;
TimeStats::~TimeStats() = default;
-} // namespace mock
-} // namespace android
+} // namespace android::mock
diff --git a/services/surfaceflinger/tests/unittests/mock/MockTimeStats.h b/services/surfaceflinger/tests/unittests/mock/MockTimeStats.h
index 4186e2b..ff37ec8 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockTimeStats.h
+++ b/services/surfaceflinger/tests/unittests/mock/MockTimeStats.h
@@ -20,8 +20,7 @@
#include "TimeStats/TimeStats.h"
-namespace android {
-namespace mock {
+namespace android::mock {
class TimeStats : public android::TimeStats {
public:
@@ -59,5 +58,4 @@
MOCK_METHOD1(setPresentFenceGlobal, void(const std::shared_ptr<FenceTime>&));
};
-} // namespace mock
-} // namespace android
+} // namespace android::mock
diff --git a/services/surfaceflinger/tests/unittests/mock/MockVSyncTracker.cpp b/services/surfaceflinger/tests/unittests/mock/MockVSyncTracker.cpp
index 8a18123..bcccae5 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockVSyncTracker.cpp
+++ b/services/surfaceflinger/tests/unittests/mock/MockVSyncTracker.cpp
@@ -15,15 +15,11 @@
*/
#include "mock/MockVSyncTracker.h"
-#include <thread>
-using namespace std::chrono_literals;
-namespace android {
-namespace mock {
+namespace android::mock {
// Explicit default instantiation is recommended.
VSyncTracker::VSyncTracker() = default;
VSyncTracker::~VSyncTracker() = default;
-} // namespace mock
-} // namespace android
+} // namespace android::mock
diff --git a/services/surfaceflinger/tests/unittests/mock/MockVsyncController.h b/services/surfaceflinger/tests/unittests/mock/MockVsyncController.h
index 1d87546..94d9966 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockVsyncController.h
+++ b/services/surfaceflinger/tests/unittests/mock/MockVsyncController.h
@@ -20,8 +20,7 @@
#include "Scheduler/VsyncController.h"
-namespace android {
-namespace mock {
+namespace android::mock {
class VsyncController : public android::scheduler::VsyncController {
public:
@@ -36,5 +35,4 @@
MOCK_CONST_METHOD1(dump, void(std::string&));
};
-} // namespace mock
-} // namespace android
+} // namespace android::mock