SF: Parametrize display lookup
The predicate will match not only on layer stack in the next CL.
Bug: 182939859
Test: screencap -d <id or layer stack>
Change-Id: I3d30b282fdf2b80faaedd732f4ff6f032c62ca3d
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index 68846d3..9976e1e 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -282,4 +282,16 @@
DisplayModes supportedModes;
};
+// Predicates for display lookup.
+
+struct WithLayerStack {
+ explicit WithLayerStack(ui::LayerStack layerStack) : layerStack(layerStack) {}
+
+ bool operator()(const DisplayDevice& display) const {
+ return display.getLayerStack() == layerStack;
+ }
+
+ ui::LayerStack layerStack;
+};
+
} // namespace android
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 2da8ed4..548aa32 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -2175,11 +2175,10 @@
mFpsReporter->dispatchLayerFps();
}
hdrInfoListeners.reserve(mHdrLayerInfoListeners.size());
- for (auto& [key, value] : mHdrLayerInfoListeners) {
- if (value && value->hasListeners()) {
- auto listenersDisplay = getDisplayById(key);
- if (listenersDisplay) {
- hdrInfoListeners.emplace_back(listenersDisplay->getCompositionDisplay(), value);
+ for (const auto& [displayId, reporter] : mHdrLayerInfoListeners) {
+ if (reporter && reporter->hasListeners()) {
+ if (const auto display = getDisplayDeviceLocked(displayId)) {
+ hdrInfoListeners.emplace_back(display->getCompositionDisplay(), reporter);
}
}
}
@@ -5708,34 +5707,6 @@
return NO_ERROR;
}
-sp<DisplayDevice> SurfaceFlinger::getDisplayByIdOrLayerStack(uint64_t displayOrLayerStack) {
- if (const sp<IBinder> displayToken =
- getPhysicalDisplayTokenLocked(PhysicalDisplayId{displayOrLayerStack})) {
- return getDisplayDeviceLocked(displayToken);
- }
- // Couldn't find display by displayId. Try to get display by layerStack since virtual displays
- // may not have a displayId.
- return getDisplayByLayerStack(displayOrLayerStack);
-}
-
-sp<DisplayDevice> SurfaceFlinger::getDisplayById(DisplayId displayId) const {
- for (const auto& [token, display] : mDisplays) {
- if (display->getId() == displayId) {
- return display;
- }
- }
- return nullptr;
-}
-
-sp<DisplayDevice> SurfaceFlinger::getDisplayByLayerStack(uint64_t layerStack) {
- for (const auto& [token, display] : mDisplays) {
- if (display->getLayerStack() == layerStack) {
- return display;
- }
- }
- return nullptr;
-}
-
status_t SurfaceFlinger::captureDisplay(const DisplayCaptureArgs& args,
const sp<IScreenCaptureListener>& captureListener) {
ATRACE_CALL();
@@ -5747,7 +5718,7 @@
if (!args.displayToken) return BAD_VALUE;
- wp<DisplayDevice> displayWeak;
+ wp<const DisplayDevice> displayWeak;
ui::LayerStack layerStack;
ui::Size reqSize(args.width, args.height);
ui::Dataspace dataspace;
@@ -5788,18 +5759,26 @@
captureListener);
}
-status_t SurfaceFlinger::captureDisplay(uint64_t displayOrLayerStack,
+status_t SurfaceFlinger::captureDisplay(uint64_t displayIdOrLayerStack,
const sp<IScreenCaptureListener>& captureListener) {
ui::LayerStack layerStack;
- wp<DisplayDevice> displayWeak;
+ wp<const DisplayDevice> displayWeak;
ui::Size size;
ui::Dataspace dataspace;
{
Mutex::Autolock lock(mStateLock);
- sp<DisplayDevice> display = getDisplayByIdOrLayerStack(displayOrLayerStack);
+ auto display = getDisplayDeviceLocked(PhysicalDisplayId{displayIdOrLayerStack});
+
+ // Fall back to first display whose layer stack matches.
+ if (!display) {
+ const auto layerStack = static_cast<ui::LayerStack>(displayIdOrLayerStack);
+ display = findDisplay(WithLayerStack(layerStack));
+ }
+
if (!display) {
return NAME_NOT_FOUND;
}
+
layerStack = display->getLayerStack();
displayWeak = display;
@@ -5884,7 +5863,7 @@
}
}
- const auto display = getDisplayByLayerStack(parent->getLayerStack());
+ const auto display = findDisplay(WithLayerStack(parent->getLayerStack()));
if (!display) {
return NAME_NOT_FOUND;
}
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index cf1a545..fb82b3e 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -907,10 +907,6 @@
bool forSystem, bool regionSampling, bool grayscale,
ScreenCaptureResults&);
- sp<DisplayDevice> getDisplayByIdOrLayerStack(uint64_t displayOrLayerStack) REQUIRES(mStateLock);
- sp<DisplayDevice> getDisplayById(DisplayId displayId) const REQUIRES(mStateLock);
- sp<DisplayDevice> getDisplayByLayerStack(uint64_t layerStack) REQUIRES(mStateLock);
-
// If the uid provided is not UNSET_UID, the traverse will skip any layers that don't have a
// matching ownerUid
void traverseLayersInLayerStack(ui::LayerStack, const int32_t uid, const LayerVector::Visitor&);
@@ -936,6 +932,14 @@
return it == mDisplays.end() ? nullptr : it->second;
}
+ sp<const DisplayDevice> getDisplayDeviceLocked(PhysicalDisplayId id) const
+ REQUIRES(mStateLock) {
+ if (const auto token = getPhysicalDisplayTokenLocked(id)) {
+ return getDisplayDeviceLocked(token);
+ }
+ return nullptr;
+ }
+
sp<const DisplayDevice> getDefaultDisplayDeviceLocked() const REQUIRES(mStateLock) {
return const_cast<SurfaceFlinger*>(this)->getDefaultDisplayDeviceLocked();
}
@@ -952,6 +956,20 @@
return getDefaultDisplayDeviceLocked();
}
+ // Returns the first display that matches a `bool(const DisplayDevice&)` predicate.
+ template <typename Predicate>
+ sp<DisplayDevice> findDisplay(Predicate p) const REQUIRES(mStateLock) {
+ const auto it = std::find_if(mDisplays.begin(), mDisplays.end(),
+ [&](const auto& pair) { return p(*pair.second); });
+
+ return it == mDisplays.end() ? nullptr : it->second;
+ }
+
+ sp<const DisplayDevice> getDisplayDeviceLocked(DisplayId id) const REQUIRES(mStateLock) {
+ // TODO(b/182939859): Replace tokens with IDs for display lookup.
+ return findDisplay([id](const auto& display) { return display.getId() == id; });
+ }
+
// mark a region of a layer stack dirty. this updates the dirty
// region of all screens presenting this layer stack.
void invalidateLayerStack(const sp<const Layer>& layer, const Region& dirty);