SF: Extract virtual display allocation from CE
Allocate HAL virtual display and generate HAL/GPU virtual display ID in
SF rather than CE. This centralizes the HAL vs. GPU decision as a first
step in isolating display configuration (e.g. hotplug, modeset) to be a
distinct stage from invalidate/refresh.
Rework SF backend hooks for screen capture. Plumb the PhysicalDisplayId
to be mirrored by the virtual display to Composer::createVirtualDisplay.
This enables the ARC backend to know which display to mirror (instead of
making assumptions about the layer stack) or error out if not mirroring
(previously done through maybeAllocateDisplayIdForVirtualDisplay), such
that SF falls back to creating a GPU virtual display.
Bug: 182939859
Bug: 129481165
Test: Enable overlay display and toggle HAL/GPU
Test: libsurfaceflinger_unittest
Test: libcompositionengine_test
Change-Id: I209b245966e544d5ff55d5d118140cfcfa85db15
Merged-In: I209b245966e544d5ff55d5d118140cfcfa85db15
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 36876dc..b7bb924 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -38,7 +38,6 @@
#include <utils/Trace.h>
#include "../Layer.h" // needed only for debugging
-#include "../SurfaceFlinger.h"
#include "../SurfaceFlingerProperties.h"
#include "ComposerHal.h"
#include "HWC2.h"
@@ -145,8 +144,9 @@
HWComposer::HWComposer(std::unique_ptr<Hwc2::Composer> composer)
: mComposer(std::move(composer)),
+ mMaxVirtualDisplayDimension(static_cast<size_t>(sysprop::max_virtual_display_dimension(0))),
mUpdateDeviceProductInfoOnHotplugReconnect(
- android::sysprop::update_device_product_info_on_hotplug_reconnect(false)) {}
+ sysprop::update_device_product_info_on_hotplug_reconnect(false)) {}
HWComposer::HWComposer(const std::string& composerServiceName)
: HWComposer(std::make_unique<Hwc2::impl::Composer>(composerServiceName)) {}
@@ -243,38 +243,49 @@
return true;
}
-std::optional<DisplayId> HWComposer::allocateVirtualDisplay(uint32_t width, uint32_t height,
- ui::PixelFormat* format) {
- if (SurfaceFlinger::maxVirtualDisplaySize != 0 &&
- (width > SurfaceFlinger::maxVirtualDisplaySize ||
- height > SurfaceFlinger::maxVirtualDisplaySize)) {
- ALOGE("%s: Display size %ux%u exceeds maximum dimension of %" PRIu64, __FUNCTION__, width,
- height, SurfaceFlinger::maxVirtualDisplaySize);
- return {};
+size_t HWComposer::getMaxVirtualDisplayCount() const {
+ return mComposer->getMaxVirtualDisplayCount();
+}
+
+size_t HWComposer::getMaxVirtualDisplayDimension() const {
+ return mMaxVirtualDisplayDimension;
+}
+
+bool HWComposer::allocateVirtualDisplay(HalVirtualDisplayId displayId, ui::Size resolution,
+ ui::PixelFormat* format,
+ std::optional<PhysicalDisplayId> mirror) {
+ if (!resolution.isValid()) {
+ ALOGE("%s: Invalid resolution %dx%d", __func__, resolution.width, resolution.height);
+ return false;
}
- const auto displayId = mVirtualIdGenerator.nextId();
- if (!displayId) {
- ALOGE("%s: No remaining virtual displays", __FUNCTION__);
- return {};
+ const uint32_t width = static_cast<uint32_t>(resolution.width);
+ const uint32_t height = static_cast<uint32_t>(resolution.height);
+
+ if (mMaxVirtualDisplayDimension > 0 &&
+ (width > mMaxVirtualDisplayDimension || height > mMaxVirtualDisplayDimension)) {
+ ALOGE("%s: Resolution %ux%u exceeds maximum dimension %zu", __func__, width, height,
+ mMaxVirtualDisplayDimension);
+ return false;
}
- hal::HWDisplayId hwcDisplayId = 0;
+ std::optional<hal::HWDisplayId> hwcMirrorId;
+ if (mirror) {
+ hwcMirrorId = fromPhysicalDisplayId(*mirror);
+ }
+
+ hal::HWDisplayId hwcDisplayId;
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 {};
- }
+ mComposer->createVirtualDisplay(width, height, format, hwcMirrorId, &hwcDisplayId));
+ RETURN_IF_HWC_ERROR_FOR("createVirtualDisplay", error, displayId, false);
auto display = std::make_unique<HWC2::impl::Display>(*mComposer.get(), mCapabilities,
hwcDisplayId, hal::DisplayType::VIRTUAL);
display->setConnected(true);
- auto& displayData = mDisplayData[*displayId];
+ auto& displayData = mDisplayData[displayId];
displayData.hwcDisplay = std::move(display);
displayData.isVirtual = true;
- return displayId;
+ return true;
}
void HWComposer::allocatePhysicalDisplay(hal::HWDisplayId hwcDisplayId,
@@ -670,13 +681,6 @@
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) {
- mVirtualIdGenerator.markUnused(*HalVirtualDisplayId::tryCast(displayId));
- }
-
const auto hwcDisplayId = displayData.hwcDisplay->getId();
// TODO(b/74619554): Select internal/external display from remaining displays.
@@ -983,10 +987,6 @@
}
}
-uint32_t HWComposer::getMaxVirtualDisplayCount() const {
- return mComposer->getMaxVirtualDisplayCount();
-}
-
} // namespace impl
} // namespace android