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/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 3101885..e9e13ef 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -29,7 +29,6 @@
#include <cutils/atomic.h>
#include <cutils/compiler.h>
#include <ftl/future.h>
-#include <ftl/small_map.h>
#include <gui/BufferQueue.h>
#include <gui/CompositorTiming.h>
#include <gui/FrameTimestamps.h>
@@ -59,6 +58,8 @@
#include <ui/FenceResult.h>
#include "ClientCache.h"
+#include "Display/DisplayMap.h"
+#include "Display/PhysicalDisplay.h"
#include "DisplayDevice.h"
#include "DisplayHardware/HWC2.h"
#include "DisplayHardware/PowerAdvisor.h"
@@ -515,7 +516,7 @@
status_t getDisplayNativePrimaries(const sp<IBinder>& displayToken, ui::DisplayPrimaries&);
status_t setActiveColorMode(const sp<IBinder>& displayToken, ui::ColorMode colorMode);
status_t getBootDisplayModeSupport(bool* outSupport) const;
- status_t setBootDisplayMode(const sp<IBinder>& displayToken, ui::DisplayModeId id);
+ status_t setBootDisplayMode(const sp<display::DisplayToken>&, DisplayModeId);
status_t clearBootDisplayMode(const sp<IBinder>& displayToken);
void setAutoLowLatencyMode(const sp<IBinder>& displayToken, bool on);
void setGameContentType(const sp<IBinder>& displayToken, bool on);
@@ -651,7 +652,7 @@
void onInitializeDisplays() REQUIRES(mStateLock);
// Sets the desired active mode bit. It obtains the lock, and sets mDesiredActiveMode.
void setDesiredActiveMode(const ActiveModeInfo& info) REQUIRES(mStateLock);
- status_t setActiveModeFromBackdoor(const sp<IBinder>& displayToken, int id);
+ status_t setActiveModeFromBackdoor(const sp<display::DisplayToken>&, DisplayModeId);
// Sets the active mode and a new refresh rate in SF.
void updateInternalStateWithChangedMode() REQUIRES(mStateLock);
// Calls to setActiveMode on the main thread if there is a pending mode change
@@ -820,6 +821,10 @@
// called when starting, or restarting after system_server death
void initializeDisplays();
+ bool isDisplayActiveLocked(const sp<const DisplayDevice>& display) const REQUIRES(mStateLock) {
+ return display->getDisplayToken() == mActiveDisplayToken;
+ }
+
sp<const DisplayDevice> getDisplayDeviceLocked(const wp<IBinder>& displayToken) const
REQUIRES(mStateLock) {
return const_cast<SurfaceFlinger*>(this)->getDisplayDeviceLocked(displayToken);
@@ -867,6 +872,21 @@
return getDefaultDisplayDeviceLocked();
}
+ using DisplayDeviceAndSnapshot =
+ std::pair<sp<DisplayDevice>, display::PhysicalDisplay::SnapshotRef>;
+
+ // Combinator for ftl::Optional<PhysicalDisplay>::and_then.
+ auto getDisplayDeviceAndSnapshot() REQUIRES(mStateLock) {
+ return [this](const display::PhysicalDisplay& display) REQUIRES(
+ mStateLock) -> ftl::Optional<DisplayDeviceAndSnapshot> {
+ if (auto device = getDisplayDeviceLocked(display.snapshot().displayId())) {
+ return std::make_pair(std::move(device), display.snapshotRef());
+ }
+
+ return {};
+ };
+ }
+
// Returns the first display that matches a `bool(const DisplayDevice&)` predicate.
template <typename Predicate>
sp<DisplayDevice> findDisplay(Predicate p) const REQUIRES(mStateLock) {
@@ -882,8 +902,13 @@
// region of all screens presenting this layer stack.
void invalidateLayerStack(const sp<const Layer>& layer, const Region& dirty);
- bool isDisplayActiveLocked(const sp<const DisplayDevice>& display) const REQUIRES(mStateLock) {
- return display->getDisplayToken() == mActiveDisplayToken;
+ ui::LayerFilter makeLayerFilterForDisplay(DisplayId displayId, ui::LayerStack layerStack)
+ REQUIRES(mStateLock) {
+ return {layerStack,
+ PhysicalDisplayId::tryCast(displayId)
+ .and_then(display::getPhysicalDisplay(mPhysicalDisplays))
+ .transform(&display::PhysicalDisplay::isInternal)
+ .value_or(false)};
}
/*
@@ -959,21 +984,16 @@
/*
* Display identification
*/
- sp<IBinder> getPhysicalDisplayTokenLocked(PhysicalDisplayId displayId) const
+ sp<display::DisplayToken> getPhysicalDisplayTokenLocked(PhysicalDisplayId displayId) const
REQUIRES(mStateLock) {
- const sp<IBinder> nullToken;
- return mPhysicalDisplayTokens.get(displayId).value_or(std::cref(nullToken));
+ const sp<display::DisplayToken> nullToken;
+ return mPhysicalDisplays.get(displayId)
+ .transform([](const display::PhysicalDisplay& display) { return display.token(); })
+ .value_or(std::cref(nullToken));
}
std::optional<PhysicalDisplayId> getPhysicalDisplayIdLocked(
- const sp<IBinder>& displayToken) const REQUIRES(mStateLock) {
- for (const auto& [id, token] : mPhysicalDisplayTokens) {
- if (token == displayToken) {
- return id;
- }
- }
- return {};
- }
+ const sp<display::DisplayToken>&) const REQUIRES(mStateLock);
// Returns the first display connected at boot.
//
@@ -1063,7 +1083,7 @@
/*
* Misc
*/
- std::vector<ui::ColorMode> getDisplayColorModes(const DisplayDevice&) REQUIRES(mStateLock);
+ std::vector<ui::ColorMode> getDisplayColorModes(PhysicalDisplayId) REQUIRES(mStateLock);
static int calculateMaxAcquiredBufferCount(Fps refreshRate,
std::chrono::nanoseconds presentLatency);
@@ -1164,12 +1184,10 @@
// Displays are composited in `mDisplays` order. Internal displays are inserted at boot and
// never removed, so take precedence over external and virtual displays.
//
- // The static capacities were chosen to exceed a typical number of physical/virtual displays.
- //
// May be read from any thread, but must only be written from the main thread.
- ftl::SmallMap<wp<IBinder>, const sp<DisplayDevice>, 5> mDisplays GUARDED_BY(mStateLock);
- ftl::SmallMap<PhysicalDisplayId, const sp<IBinder>, 3> mPhysicalDisplayTokens
- GUARDED_BY(mStateLock);
+ display::DisplayMap<wp<IBinder>, const sp<DisplayDevice>> mDisplays GUARDED_BY(mStateLock);
+
+ display::PhysicalDisplays mPhysicalDisplays GUARDED_BY(mStateLock);
struct {
DisplayIdGenerator<GpuVirtualDisplayId> gpu;