SF: Remove obsolete HWComposer members
Remove mExternalHwcDisplayId, an obsolete special case for legacy multi-
display mode. Assert primary display existence instead of propagating to
callers, which is closer to how headless mode would work, i.e. injecting
a placeholder primary display. Remove isVirtual checks now that they are
enforced at compile time. Prevent primary display disconnection for now.
Bug: 182939859
Test: libsurfaceflinger_unittest
Change-Id: I507db6a3ac0bda93005a86b38cca6ebbcd5c0155
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 294a67e..e306152 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -633,17 +633,14 @@
}
std::vector<PhysicalDisplayId> SurfaceFlinger::getPhysicalDisplayIdsLocked() const {
- const auto internalDisplayId = getInternalDisplayIdLocked();
- if (!internalDisplayId) {
- return {};
- }
-
std::vector<PhysicalDisplayId> displayIds;
displayIds.reserve(mPhysicalDisplayTokens.size());
- displayIds.push_back(*internalDisplayId);
+
+ const auto internalDisplayId = getInternalDisplayIdLocked();
+ displayIds.push_back(internalDisplayId);
for (const auto& [id, token] : mPhysicalDisplayTokens) {
- if (id != *internalDisplayId) {
+ if (id != internalDisplayId) {
displayIds.push_back(id);
}
}
@@ -810,10 +807,10 @@
// Process any initial hotplug and resulting display changes.
processDisplayHotplugEventsLocked();
const auto display = getDefaultDisplayDeviceLocked();
- LOG_ALWAYS_FATAL_IF(!display, "Missing internal display after registering composer callback.");
+ LOG_ALWAYS_FATAL_IF(!display, "Missing primary display after registering composer callback.");
const auto displayId = display->getPhysicalId();
LOG_ALWAYS_FATAL_IF(!getHwComposer().isConnected(displayId),
- "Internal display is disconnected.");
+ "Primary display is disconnected.");
// initialize our drawing state
mDrawingState = mCurrentState;
@@ -982,6 +979,11 @@
return NAME_NOT_FOUND;
}
+ const auto displayId = PhysicalDisplayId::tryCast(display->getId());
+ if (!displayId) {
+ return INVALID_OPERATION;
+ }
+
info->activeDisplayModeId = static_cast<int32_t>(display->getActiveMode()->getId().value());
const auto& supportedModes = display->getSupportedModes();
@@ -1041,18 +1043,18 @@
}
info->activeColorMode = display->getCompositionDisplay()->getState().colorMode;
- const auto displayId = display->getPhysicalId();
- info->supportedColorModes = getDisplayColorModes(displayId);
-
+ info->supportedColorModes = getDisplayColorModes(*display);
info->hdrCapabilities = display->getHdrCapabilities();
+
info->autoLowLatencyModeSupported =
- getHwComposer().hasDisplayCapability(displayId,
+ getHwComposer().hasDisplayCapability(*displayId,
hal::DisplayCapability::AUTO_LOW_LATENCY_MODE);
std::vector<hal::ContentType> types;
- getHwComposer().getSupportedContentTypes(displayId, &types);
+ getHwComposer().getSupportedContentTypes(*displayId, &types);
info->gameContentTypeSupported = std::any_of(types.begin(), types.end(), [](auto type) {
return type == hal::ContentType::GAME;
});
+
return NO_ERROR;
}
@@ -1276,15 +1278,15 @@
}).wait();
}
-std::vector<ColorMode> SurfaceFlinger::getDisplayColorModes(PhysicalDisplayId displayId) {
- auto modes = getHwComposer().getColorModes(displayId);
- bool isInternalDisplay = displayId == getInternalDisplayIdLocked();
+std::vector<ColorMode> SurfaceFlinger::getDisplayColorModes(const DisplayDevice& display) {
+ auto modes = getHwComposer().getColorModes(display.getPhysicalId());
- // If it's built-in display and the configuration claims it's not wide color capable,
+ // If the display is internal and the configuration claims it's not wide color capable,
// filter out all wide color modes. The typical reason why this happens is that the
// hardware is not good enough to support GPU composition of wide color, and thus the
// OEMs choose to disable this capability.
- if (isInternalDisplay && !hasWideColorDisplay) {
+ if (display.getConnectionType() == ui::DisplayConnectionType::Internal &&
+ !hasWideColorDisplay) {
const auto newEnd = std::remove_if(modes.begin(), modes.end(), isWideColorMode);
modes.erase(newEnd, modes.end());
}
@@ -1308,35 +1310,40 @@
}
status_t SurfaceFlinger::setActiveColorMode(const sp<IBinder>& displayToken, ColorMode mode) {
- schedule([=]() MAIN_THREAD {
- const auto displayId = getPhysicalDisplayIdLocked(displayToken);
- if (!displayId) {
- ALOGE("Invalid display token %p", displayToken.get());
- return;
- }
- const auto modes = getDisplayColorModes(*displayId);
- bool exists = std::find(std::begin(modes), std::end(modes), mode) != std::end(modes);
- if (mode < ColorMode::NATIVE || !exists) {
- ALOGE("Attempt to set invalid active color mode %s (%d) for display token %p",
- decodeColorMode(mode).c_str(), mode, displayToken.get());
- return;
- }
+ if (!displayToken) {
+ return BAD_VALUE;
+ }
+
+ auto future = schedule([=]() MAIN_THREAD -> status_t {
const auto display = getDisplayDeviceLocked(displayToken);
if (!display) {
ALOGE("Attempt to set active color mode %s (%d) for invalid display token %p",
decodeColorMode(mode).c_str(), mode, displayToken.get());
- } else if (display->isVirtual()) {
+ return NAME_NOT_FOUND;
+ }
+
+ if (display->isVirtual()) {
ALOGW("Attempt to set active color mode %s (%d) for virtual display",
decodeColorMode(mode).c_str(), mode);
- } else {
- display->getCompositionDisplay()->setColorProfile(
- compositionengine::Output::ColorProfile{mode, Dataspace::UNKNOWN,
- RenderIntent::COLORIMETRIC,
- Dataspace::UNKNOWN});
+ return INVALID_OPERATION;
}
- }).wait();
- return NO_ERROR;
+ const auto modes = getDisplayColorModes(*display);
+ const bool exists = std::find(modes.begin(), modes.end(), mode) != modes.end();
+
+ if (mode < ColorMode::NATIVE || !exists) {
+ ALOGE("Attempt to set invalid active color mode %s (%d) for display token %p",
+ decodeColorMode(mode).c_str(), mode, displayToken.get());
+ return BAD_VALUE;
+ }
+
+ display->getCompositionDisplay()->setColorProfile(
+ {mode, Dataspace::UNKNOWN, RenderIntent::COLORIMETRIC, Dataspace::UNKNOWN});
+
+ return NO_ERROR;
+ });
+
+ return future.get();
}
void SurfaceFlinger::setAutoLowLatencyMode(const sp<IBinder>& displayToken, bool on) {
@@ -1749,8 +1756,8 @@
void SurfaceFlinger::onComposerHalHotplug(hal::HWDisplayId hwcDisplayId,
hal::Connection connection) {
- ALOGI("%s(%" PRIu64 ", %s)", __func__, hwcDisplayId,
- connection == hal::Connection::CONNECTED ? "connected" : "disconnected");
+ const bool connected = connection == hal::Connection::CONNECTED;
+ ALOGI("%s HAL display %" PRIu64, connected ? "Connecting" : "Disconnecting", hwcDisplayId);
// Only lock if we're not on the main thread. This function is normally
// called on a hwbinder thread, but for the primary display it's called on
@@ -1942,13 +1949,9 @@
}
if (mRefreshRateOverlaySpinner) {
- if (Mutex::Autolock lock(mStateLock);
- const auto display = getDefaultDisplayDeviceLocked()) {
- if (display) {
- display->onInvalidate();
- } else {
- ALOGW("%s: default display is null", __func__);
- }
+ Mutex::Autolock lock(mStateLock);
+ if (const auto display = getDefaultDisplayDeviceLocked()) {
+ display->onInvalidate();
}
}
@@ -2842,7 +2845,7 @@
setPowerModeInternal(display, hal::PowerMode::ON);
// TODO(b/175678251) Call a listener instead.
- if (currentState.physical->hwcDisplayId == getHwComposer().getInternalHwcDisplayId()) {
+ if (currentState.physical->hwcDisplayId == getHwComposer().getPrimaryHwcDisplayId()) {
updateInternalDisplayVsyncLocked(display);
}
}
@@ -5687,12 +5690,10 @@
// Inject a hotplug connected event for the primary display. This will deallocate and
// reallocate the display state including framebuffers.
case 1037: {
- std::optional<hal::HWDisplayId> hwcId;
- {
- Mutex::Autolock lock(mStateLock);
- hwcId = getHwComposer().getInternalHwcDisplayId();
- }
- onComposerHalHotplug(*hwcId, hal::Connection::CONNECTED);
+ const hal::HWDisplayId hwcId =
+ (Mutex::Autolock(mStateLock), getHwComposer().getPrimaryHwcDisplayId());
+
+ onComposerHalHotplug(hwcId, hal::Connection::CONNECTED);
return NO_ERROR;
}
// Modify the max number of display frames stored within FrameTimeline
@@ -6774,33 +6775,29 @@
}
status_t SurfaceFlinger::getMaxAcquiredBufferCount(int* buffers) const {
- const auto maxSupportedRefreshRate = [&] {
- const auto display = getDefaultDisplayDevice();
- if (display) {
- return display->refreshRateConfigs().getSupportedRefreshRateRange().max;
+ Fps maxRefreshRate(60.f);
+
+ if (!getHwComposer().isHeadless()) {
+ if (const auto display = getDefaultDisplayDevice()) {
+ maxRefreshRate = display->refreshRateConfigs().getSupportedRefreshRateRange().max;
}
- ALOGW("%s: default display is null", __func__);
- return Fps(60);
- }();
- *buffers = getMaxAcquiredBufferCountForRefreshRate(maxSupportedRefreshRate);
+ }
+
+ *buffers = getMaxAcquiredBufferCountForRefreshRate(maxRefreshRate);
return NO_ERROR;
}
int SurfaceFlinger::getMaxAcquiredBufferCountForCurrentRefreshRate(uid_t uid) const {
- const auto refreshRate = [&] {
- const auto frameRateOverride = mScheduler->getFrameRateOverride(uid);
- if (frameRateOverride.has_value()) {
- return frameRateOverride.value();
- }
+ Fps refreshRate(60.f);
- const auto display = ON_MAIN_THREAD(getDefaultDisplayDeviceLocked());
- if (display) {
- return display->refreshRateConfigs().getCurrentRefreshRate().getFps();
+ if (const auto frameRateOverride = mScheduler->getFrameRateOverride(uid)) {
+ refreshRate = *frameRateOverride;
+ } else if (!getHwComposer().isHeadless()) {
+ if (const auto display = ON_MAIN_THREAD(getDefaultDisplayDeviceLocked())) {
+ refreshRate = display->refreshRateConfigs().getCurrentRefreshRate().getFps();
}
+ }
- ALOGW("%s: default display is null", __func__);
- return Fps(60);
- }();
return getMaxAcquiredBufferCountForRefreshRate(refreshRate);
}