SF: Generalize display management
This CL enables SF to manage an arbitrary number of physical displays.
Previously, displays were identified by 32-bit IDs, where 0 is the
internal display, 1 is the external display, [2, INT32_MAX] are HWC
virtual displays, and -1 represents an invalid display or a non-HWC
virtual display.
If the HWC provides display identification data, SF now allocates 64-bit
display IDs for physical and HWC virtual displays. The IDs are expressed
using an option type, where the null value represents an invalid display
or non-HWC virtual display. Without HWC support, SF falls back to legacy
behavior with at most two physical displays.
The dynamic display IDs are translated to the legacy constants at the
SF/DMS boundary, as a stopgap until the framework is generalized.
Bug: 74619554
Test: Connect 3 displays and create virtual displays on HWC 2.2 and 2.3
Test: libsurfaceflinger_unittest
Test: SurfaceFlinger_test
Change-Id: I0a4a57b6ab7de2dbcf719a4eb1a19a133694012e
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 51168a6..36bb62c 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -76,10 +76,11 @@
#include <map>
#include <mutex>
#include <queue>
+#include <set>
#include <string>
#include <thread>
+#include <unordered_map>
#include <utility>
-#include "RenderArea.h"
#include <layerproto/LayerProtoHeader.h>
@@ -348,7 +349,7 @@
// enable/disable h/w composer event
// TODO: this should be made accessible only to EventThread
- void setVsyncEnabled(int disp, int enabled);
+ void setVsyncEnabled(EventThread::DisplayType displayType, bool enabled);
// called on the main thread by MessageQueue when an internal message
// is received
@@ -357,7 +358,7 @@
// for debugging only
// TODO: this should be made accessible only to HWComposer
- const Vector< sp<Layer> >& getLayerSortedByZForHwcDisplay(int id);
+ const Vector<sp<Layer>>& getLayerSortedByZForHwcDisplay(DisplayId displayId);
renderengine::RenderEngine& getRenderEngine() const { return *getBE().mRenderEngine; }
@@ -659,7 +660,10 @@
}
sp<DisplayDevice> getDefaultDisplayDeviceLocked() {
- return getDisplayDeviceLocked(mDisplayTokens[DisplayDevice::DISPLAY_PRIMARY]);
+ if (const auto token = getInternalDisplayToken()) {
+ return getDisplayDeviceLocked(token);
+ }
+ return nullptr;
}
// mark a region of a layer stack dirty. this updates the dirty
@@ -724,10 +728,8 @@
/* ------------------------------------------------------------------------
* Display management
*/
- DisplayDevice::DisplayType determineDisplayType(hwc2_display_t hwcDisplayId,
- HWC2::Connection connection) const;
sp<DisplayDevice> setupNewDisplayDeviceInternal(const wp<IBinder>& displayToken,
- int32_t displayId,
+ const std::optional<DisplayId>& displayId,
const DisplayDeviceState& state,
const sp<DisplaySurface>& dispSurface,
const sp<IGraphicBufferProducer>& producer);
@@ -759,6 +761,37 @@
}
private:
+ sp<IBinder> getPhysicalDisplayToken(DisplayId displayId) const {
+ const auto it = mPhysicalDisplayTokens.find(displayId);
+ return it != mPhysicalDisplayTokens.end() ? it->second : nullptr;
+ }
+
+ std::optional<DisplayId> getPhysicalDisplayId(const sp<IBinder>& displayToken) const {
+ for (const auto& [id, token] : mPhysicalDisplayTokens) {
+ if (token == displayToken) {
+ return id;
+ }
+ }
+ return {};
+ }
+
+ // TODO(b/74619554): Remove special cases for primary display.
+ sp<IBinder> getInternalDisplayToken() const {
+ const auto displayId = getInternalDisplayId();
+ return displayId ? getPhysicalDisplayToken(*displayId) : nullptr;
+ }
+
+ std::optional<DisplayId> getInternalDisplayId() const {
+ const auto hwcDisplayId = getHwComposer().getInternalHwcDisplayId();
+ return hwcDisplayId ? getHwComposer().toPhysicalDisplayId(*hwcDisplayId) : std::nullopt;
+ }
+
+ // TODO(b/74619554): Remove special cases for external display.
+ std::optional<DisplayId> getExternalDisplayId() const {
+ const auto hwcDisplayId = getHwComposer().getExternalHwcDisplayId();
+ return hwcDisplayId ? getHwComposer().toPhysicalDisplayId(*hwcDisplayId) : std::nullopt;
+ }
+
void listLayersLocked(const Vector<String16>& args, size_t& index, String8& result) const;
void dumpStatsLocked(const Vector<String16>& args, size_t& index, String8& result) const;
void clearStatsLocked(const Vector<String16>& args, size_t& index, String8& result);
@@ -836,7 +869,7 @@
std::unique_ptr<VSyncSource> mSfEventThreadSource;
std::unique_ptr<InjectVSyncSource> mVSyncInjector;
std::unique_ptr<EventControlThread> mEventControlThread;
- sp<IBinder> mDisplayTokens[DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES];
+ std::unordered_map<DisplayId, sp<IBinder>> mPhysicalDisplayTokens;
VSyncModulator mVsyncModulator;