SF: Introduce DisplaySnapshot
DisplaySnapshot stores the immutable state of a physical display,
captured on hotplug. The SurfaceFlinger class stores a map from
PhysicalDisplayId to PhysicalDisplay, a new class that augments
this state with the sp<DisplayToken>.
Later, DisplayDevice will be removed, and SF::mDisplays will map
wp<DisplayToken> to compositionengine::Display.
Bug: 241285876
Test: libsurfaceflinger_unittest
Test: dumpsys SurfaceFlinger --displays
Change-Id: I172df87c4a7a9cf64659ff9cfbd6df195ee4bc8d
diff --git a/services/surfaceflinger/tests/unittests/CompositionTest.cpp b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
index 77625b3..e546c2f 100644
--- a/services/surfaceflinger/tests/unittests/CompositionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
@@ -309,16 +309,20 @@
compositionengine::impl::createDisplay(test->mFlinger.getCompositionEngine(),
ceDisplayArgs);
+ constexpr auto kDisplayConnectionType = ui::DisplayConnectionType::Internal;
+ constexpr bool kIsPrimary = true;
+
test->mDisplay = FakeDisplayDeviceInjector(test->mFlinger, compositionDisplay,
- ui::DisplayConnectionType::Internal, HWC_DISPLAY,
- true /* isPrimary */)
+ kDisplayConnectionType, HWC_DISPLAY, kIsPrimary)
.setDisplaySurface(test->mDisplaySurface)
.setNativeWindow(test->mNativeWindow)
.setSecure(Derived::IS_SECURE)
.setPowerMode(Derived::INIT_POWER_MODE)
.inject();
Mock::VerifyAndClear(test->mNativeWindow.get());
- test->mDisplay->setLayerStack(LAYER_STACK);
+
+ constexpr bool kIsInternal = kDisplayConnectionType == ui::DisplayConnectionType::Internal;
+ test->mDisplay->setLayerFilter({LAYER_STACK, kIsInternal});
}
template <typename Case>
diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_DisplayTransactionCommitTest.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_DisplayTransactionCommitTest.cpp
index 71f1a2b..73f654b 100644
--- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_DisplayTransactionCommitTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SurfaceFlinger_DisplayTransactionCommitTest.cpp
@@ -118,9 +118,7 @@
ASSERT_TRUE(displayId);
const auto hwcDisplayId = Case::Display::HWC_DISPLAY_ID_OPT::value;
ASSERT_TRUE(hwcDisplayId);
- expectedPhysical = {.id = *displayId,
- .type = *connectionType,
- .hwcDisplayId = *hwcDisplayId};
+ expectedPhysical = {.id = *displayId, .hwcDisplayId = *hwcDisplayId};
}
// The display should have been set up in the current display state
@@ -145,10 +143,13 @@
const auto displayId = Case::Display::DISPLAY_ID::get();
ASSERT_TRUE(PhysicalDisplayId::tryCast(displayId));
- const auto displayTokenOpt = mFlinger.mutablePhysicalDisplayTokens().get(displayId);
- ASSERT_TRUE(displayTokenOpt);
+ const auto displayOpt = mFlinger.mutablePhysicalDisplays().get(displayId);
+ ASSERT_TRUE(displayOpt);
- verifyDisplayIsConnected<Case>(displayTokenOpt->get());
+ const auto& display = displayOpt->get();
+ EXPECT_EQ(Case::Display::CONNECTION_TYPE::value, display.snapshot().connectionType());
+
+ verifyDisplayIsConnected<Case>(display.token());
}
void DisplayTransactionCommitTest::verifyDisplayIsNotConnected(const sp<IBinder>& displayToken) {
@@ -247,10 +248,10 @@
// HWComposer should not have an entry for the display
EXPECT_FALSE(hasPhysicalHwcDisplay(Case::Display::HWC_DISPLAY_ID));
- // SF should not have a display token.
+ // SF should not have a PhysicalDisplay.
const auto displayId = Case::Display::DISPLAY_ID::get();
ASSERT_TRUE(PhysicalDisplayId::tryCast(displayId));
- ASSERT_FALSE(mFlinger.mutablePhysicalDisplayTokens().contains(displayId));
+ ASSERT_FALSE(mFlinger.mutablePhysicalDisplays().contains(displayId));
// The existing token should have been removed.
verifyDisplayIsNotConnected(existing.token());
@@ -329,10 +330,10 @@
// HWComposer should not have an entry for the display
EXPECT_FALSE(hasPhysicalHwcDisplay(Case::Display::HWC_DISPLAY_ID));
- // SF should not have a display token.
+ // SF should not have a PhysicalDisplay.
const auto displayId = Case::Display::DISPLAY_ID::get();
ASSERT_TRUE(PhysicalDisplayId::tryCast(displayId));
- ASSERT_FALSE(mFlinger.mutablePhysicalDisplayTokens().contains(displayId));
+ ASSERT_FALSE(mFlinger.mutablePhysicalDisplays().contains(displayId));
}(),
testing::KilledBySignal(SIGABRT), "Primary display cannot be disconnected.");
}
@@ -376,9 +377,9 @@
const auto displayId = Case::Display::DISPLAY_ID::get();
ASSERT_TRUE(PhysicalDisplayId::tryCast(displayId));
- const auto displayTokenOpt = mFlinger.mutablePhysicalDisplayTokens().get(displayId);
- ASSERT_TRUE(displayTokenOpt);
- EXPECT_NE(existing.token(), displayTokenOpt->get());
+ const auto displayOpt = mFlinger.mutablePhysicalDisplays().get(displayId);
+ ASSERT_TRUE(displayOpt);
+ EXPECT_NE(existing.token(), displayOpt->get().token());
// A new display should be connected in its place.
verifyPhysicalDisplayIsConnected<Case>();
diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetPowerModeInternalTest.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetPowerModeInternalTest.cpp
index 1756368..9e54083 100644
--- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetPowerModeInternalTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetPowerModeInternalTest.cpp
@@ -253,14 +253,16 @@
using DispSync = DispSyncVariant;
using Transition = TransitionVariant;
- static auto injectDisplayWithInitialPowerMode(DisplayTransactionTest* test, PowerMode mode) {
+ static sp<DisplayDevice> injectDisplayWithInitialPowerMode(DisplayTransactionTest* test,
+ PowerMode mode) {
Display::injectHwcDisplayWithNoDefaultCapabilities(test);
- auto display = Display::makeFakeExistingDisplayInjector(test);
- display.inject();
- display.mutableDisplayDevice()->setPowerMode(mode);
- if (display.mutableDisplayDevice()->isInternal()) {
- test->mFlinger.mutableActiveDisplayToken() =
- display.mutableDisplayDevice()->getDisplayToken();
+ auto injector = Display::makeFakeExistingDisplayInjector(test);
+ const auto display = injector.inject();
+ display->setPowerMode(mode);
+ if (injector.physicalDisplay()
+ .transform(&display::PhysicalDisplay::isInternal)
+ .value_or(false)) {
+ test->mFlinger.mutableActiveDisplayToken() = display->getDisplayToken();
}
return display;
@@ -353,8 +355,7 @@
// --------------------------------------------------------------------
// Invocation
- mFlinger.setPowerModeInternal(display.mutableDisplayDevice(),
- Case::Transition::TARGET_POWER_MODE);
+ mFlinger.setPowerModeInternal(display, Case::Transition::TARGET_POWER_MODE);
// --------------------------------------------------------------------
// Postconditions
diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetupNewDisplayDeviceInternalTest.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetupNewDisplayDeviceInternalTest.cpp
index 6aeb3fe..ec2c2b4 100644
--- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetupNewDisplayDeviceInternalTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetupNewDisplayDeviceInternalTest.cpp
@@ -246,11 +246,14 @@
.setDpiY(DEFAULT_DPI)
.setGroup(0)
.build();
+
state.physical = {.id = *displayId,
- .type = *connectionType,
.hwcDisplayId = *hwcDisplayId,
- .supportedModes = makeModes(activeMode),
- .activeMode = std::move(activeMode)};
+ .activeMode = activeMode};
+
+ mFlinger.mutablePhysicalDisplays().emplace_or_replace(*displayId, displayToken, *displayId,
+ *connectionType,
+ makeModes(activeMode), std::nullopt);
}
state.isSecure = static_cast<bool>(Case::Display::SECURE);
@@ -264,7 +267,6 @@
ASSERT_TRUE(device != nullptr);
EXPECT_EQ(Case::Display::DISPLAY_ID::get(), device->getId());
- EXPECT_EQ(Case::Display::CONNECTION_TYPE::value, device->getConnectionType());
EXPECT_EQ(static_cast<bool>(Case::Display::VIRTUAL), device->isVirtual());
EXPECT_EQ(static_cast<bool>(Case::Display::SECURE), device->isSecure());
EXPECT_EQ(static_cast<bool>(Case::Display::PRIMARY), device->isPrimary());
@@ -280,7 +282,6 @@
device->receivesInput());
if constexpr (Case::Display::CONNECTION_TYPE::value) {
- EXPECT_EQ(1, device->getSupportedModes().size());
EXPECT_NE(nullptr, device->getActiveMode());
EXPECT_EQ(Case::Display::HWC_ACTIVE_CONFIG_ID, device->getActiveMode()->getHwcId());
}
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index 6c6c9aa..a6b3f7c 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -503,6 +503,7 @@
*/
const auto& displays() const { return mFlinger->mDisplays; }
+ const auto& physicalDisplays() const { return mFlinger->mPhysicalDisplays; }
const auto& currentState() const { return mFlinger->mCurrentState; }
const auto& drawingState() const { return mFlinger->mDrawingState; }
const auto& transactionFlags() const { return mFlinger->mTransactionFlags; }
@@ -515,12 +516,12 @@
auto& mutableCurrentState() { return mFlinger->mCurrentState; }
auto& mutableDisplayColorSetting() { return mFlinger->mDisplayColorSetting; }
auto& mutableDisplays() { return mFlinger->mDisplays; }
+ auto& mutablePhysicalDisplays() { return mFlinger->mPhysicalDisplays; }
auto& mutableDrawingState() { return mFlinger->mDrawingState; }
auto& mutableGeometryDirty() { return mFlinger->mGeometryDirty; }
auto& mutableInterceptor() { return mFlinger->mInterceptor; }
auto& mutableMainThreadId() { return mFlinger->mMainThreadId; }
auto& mutablePendingHotplugEvents() { return mFlinger->mPendingHotplugEvents; }
- auto& mutablePhysicalDisplayTokens() { return mFlinger->mPhysicalDisplayTokens; }
auto& mutableTexturePool() { return mFlinger->mTexturePool; }
auto& mutableTransactionFlags() { return mFlinger->mTransactionFlags; }
auto& mutableDebugDisableHWC() { return mFlinger->mDebugDisableHWC; }
@@ -725,14 +726,20 @@
: mFlinger(flinger),
mCreationArgs(flinger.mFlinger, flinger.mFlinger->getHwComposer(), mDisplayToken,
display),
+ mConnectionType(connectionType),
mHwcDisplayId(hwcDisplayId) {
- mCreationArgs.connectionType = connectionType;
mCreationArgs.isPrimary = isPrimary;
mCreationArgs.initialPowerMode = hal::PowerMode::ON;
}
sp<IBinder> token() const { return mDisplayToken; }
+ auto physicalDisplay() const {
+ return ftl::Optional(mCreationArgs.compositionDisplay->getDisplayId())
+ .and_then(&PhysicalDisplayId::tryCast)
+ .and_then(display::getPhysicalDisplay(mFlinger.physicalDisplays()));
+ }
+
DisplayDeviceState& mutableDrawingDisplayState() {
return mFlinger.mutableDrawingState().displays.editValueFor(mDisplayToken);
}
@@ -760,7 +767,7 @@
// the `configs` parameter in favor of an alternative setRefreshRateConfigs API.
auto& setDisplayModes(DisplayModes modes, DisplayModeId activeModeId,
std::shared_ptr<scheduler::RefreshRateConfigs> configs = nullptr) {
- mCreationArgs.supportedModes = std::move(modes);
+ mDisplayModes = std::move(modes);
mCreationArgs.activeModeId = activeModeId;
mCreationArgs.refreshRateConfigs = std::move(configs);
return *this;
@@ -806,7 +813,7 @@
sp<DisplayDevice> inject() NO_THREAD_SAFETY_ANALYSIS {
const auto displayId = mCreationArgs.compositionDisplay->getDisplayId();
- auto& modes = mCreationArgs.supportedModes;
+ auto& modes = mDisplayModes;
auto& activeModeId = mCreationArgs.activeModeId;
if (displayId && !mCreationArgs.refreshRateConfigs) {
@@ -834,8 +841,13 @@
}
}
+ sp<DisplayDevice> display = sp<DisplayDevice>::make(mCreationArgs);
+ mFlinger.mutableDisplays().emplace_or_replace(mDisplayToken, display);
+
DisplayDeviceState state;
- if (const auto type = mCreationArgs.connectionType) {
+ state.isSecure = mCreationArgs.isSecure;
+
+ if (mConnectionType) {
LOG_ALWAYS_FATAL_IF(!displayId);
const auto physicalId = PhysicalDisplayId::tryCast(*displayId);
LOG_ALWAYS_FATAL_IF(!physicalId);
@@ -845,29 +857,21 @@
LOG_ALWAYS_FATAL_IF(!activeMode);
state.physical = {.id = *physicalId,
- .type = *type,
.hwcDisplayId = *mHwcDisplayId,
- .deviceProductInfo = {},
- .supportedModes = modes,
.activeMode = activeMode->get()};
- }
- state.isSecure = mCreationArgs.isSecure;
+ const auto it = mFlinger.mutablePhysicalDisplays()
+ .emplace_or_replace(*physicalId, mDisplayToken, *physicalId,
+ *mConnectionType, std::move(modes),
+ std::nullopt)
+ .first;
- sp<DisplayDevice> display = sp<DisplayDevice>::make(mCreationArgs);
- if (!display->isVirtual()) {
- display->setActiveMode(activeModeId);
+ display->setActiveMode(activeModeId, it->second.snapshot());
}
- mFlinger.mutableDisplays().emplace_or_replace(mDisplayToken, display);
mFlinger.mutableCurrentState().displays.add(mDisplayToken, state);
mFlinger.mutableDrawingState().displays.add(mDisplayToken, state);
- if (const auto& physical = state.physical) {
- mFlinger.mutablePhysicalDisplayTokens().emplace_or_replace(physical->id,
- mDisplayToken);
- }
-
return display;
}
@@ -875,6 +879,8 @@
TestableSurfaceFlinger& mFlinger;
sp<BBinder> mDisplayToken = sp<BBinder>::make();
DisplayDeviceCreationArgs mCreationArgs;
+ DisplayModes mDisplayModes;
+ const std::optional<ui::DisplayConnectionType> mConnectionType;
const std::optional<hal::HWDisplayId> mHwcDisplayId;
};