summaryrefslogtreecommitdiff
path: root/services/surfaceflinger/SurfaceFlinger.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'services/surfaceflinger/SurfaceFlinger.cpp')
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp210
1 files changed, 108 insertions, 102 deletions
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index dd190a234e..2edc05bc08 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -561,13 +561,13 @@ void SurfaceFlinger::destroyDisplay(const sp<IBinder>& displayToken) {
const ssize_t index = mCurrentState.displays.indexOfKey(displayToken);
if (index < 0) {
- ALOGE("%s: Invalid display token %p", __FUNCTION__, displayToken.get());
+ ALOGE("%s: Invalid display token %p", __func__, displayToken.get());
return;
}
const DisplayDeviceState& state = mCurrentState.displays.valueAt(index);
if (state.physical) {
- ALOGE("%s: Invalid operation on physical display", __FUNCTION__);
+ ALOGE("%s: Invalid operation on physical display", __func__);
return;
}
mInterceptor->saveDisplayDeletion(state.sequenceId);
@@ -1020,20 +1020,18 @@ status_t SurfaceFlinger::getDynamicDisplayInfo(const sp<IBinder>& displayToken,
return INVALID_OPERATION;
}
- info->activeDisplayModeId = static_cast<int32_t>(display->getActiveMode()->getId().value());
+ info->activeDisplayModeId = display->getActiveMode()->getId().value();
const auto& supportedModes = display->getSupportedModes();
info->supportedDisplayModes.clear();
info->supportedDisplayModes.reserve(supportedModes.size());
- for (const auto& mode : supportedModes) {
- ui::DisplayMode outMode;
- outMode.id = static_cast<int32_t>(mode->getId().value());
- auto width = mode->getWidth();
- auto height = mode->getHeight();
+ for (const auto& [id, mode] : supportedModes) {
+ ui::DisplayMode outMode;
+ outMode.id = static_cast<int32_t>(id.value());
- auto xDpi = mode->getDpiX();
- auto yDpi = mode->getDpiY();
+ auto [width, height] = mode->getResolution();
+ auto [xDpi, yDpi] = mode->getDpi();
if (const auto physicalOrientation = display->getPhysicalOrientation();
physicalOrientation == ui::ROTATION_90 || physicalOrientation == ui::ROTATION_270) {
@@ -1084,13 +1082,17 @@ status_t SurfaceFlinger::getDynamicDisplayInfo(const sp<IBinder>& displayToken,
info->autoLowLatencyModeSupported =
getHwComposer().hasDisplayCapability(*displayId,
DisplayCapability::AUTO_LOW_LATENCY_MODE);
- std::vector<hal::ContentType> types;
- getHwComposer().getSupportedContentTypes(*displayId, &types);
- info->gameContentTypeSupported = std::any_of(types.begin(), types.end(), [](auto type) {
- return type == hal::ContentType::GAME;
- });
-
- info->preferredBootDisplayMode = display->getPreferredBootModeId();
+ info->gameContentTypeSupported =
+ getHwComposer().supportsContentType(*displayId, hal::ContentType::GAME);
+
+ info->preferredBootDisplayMode = static_cast<ui::DisplayModeId>(-1);
+ if (getHwComposer().getBootDisplayModeSupport()) {
+ if (const auto hwcId = getHwComposer().getPreferredBootDisplayMode(*displayId)) {
+ if (const auto modeId = display->translateModeId(*hwcId)) {
+ info->preferredBootDisplayMode = modeId->value();
+ }
+ }
+ }
return NO_ERROR;
}
@@ -1122,7 +1124,7 @@ void SurfaceFlinger::setDesiredActiveMode(const ActiveModeInfo& info) {
// Start receiving vsync samples now, so that we can detect a period
// switch.
- mScheduler->resyncToHardwareVsync(true, info.mode->getVsyncPeriod());
+ mScheduler->resyncToHardwareVsync(true, info.mode->getFps());
// As we called to set period, we will call to onRefreshRateChangeCompleted once
// VsyncController model is locked.
modulateVsync(&VsyncModulator::onRefreshRateChangeInitiated);
@@ -1188,7 +1190,7 @@ void SurfaceFlinger::updateInternalStateWithChangedMode() {
return;
}
- if (display->getActiveMode()->getSize() != upcomingModeInfo.mode->getSize()) {
+ if (display->getActiveMode()->getResolution() != upcomingModeInfo.mode->getResolution()) {
auto& state = mCurrentState.displays.editValueFor(display->getDisplayToken());
// We need to generate new sequenceId in order to recreate the display (and this
// way the framebuffer).
@@ -1224,7 +1226,7 @@ void SurfaceFlinger::clearDesiredActiveModeState(const sp<DisplayDevice>& displa
void SurfaceFlinger::desiredActiveModeChangeDone(const sp<DisplayDevice>& display) {
const auto refreshRate = display->getDesiredActiveMode()->mode->getFps();
clearDesiredActiveModeState(display);
- mScheduler->resyncToHardwareVsync(true, refreshRate.getPeriodNsecs());
+ mScheduler->resyncToHardwareVsync(true, refreshRate);
updatePhaseConfiguration(refreshRate);
}
@@ -1412,31 +1414,41 @@ status_t SurfaceFlinger::getBootDisplayModeSupport(bool* outSupport) const {
return future.get();
}
-status_t SurfaceFlinger::setBootDisplayMode(const sp<IBinder>& displayToken, ui::DisplayModeId id) {
+status_t SurfaceFlinger::setBootDisplayMode(const sp<IBinder>& displayToken,
+ ui::DisplayModeId modeId) {
+ const char* const whence = __func__;
auto future = mScheduler->schedule([=]() MAIN_THREAD -> status_t {
- if (const auto displayDevice = getDisplayDeviceLocked(displayToken)) {
- const auto mode = displayDevice->getMode(DisplayModeId{id});
- if (mode == nullptr) {
- ALOGE("%s: invalid display mode (%d)", __FUNCTION__, id);
- return BAD_VALUE;
- }
+ const auto display = getDisplayDeviceLocked(displayToken);
+ if (!display) {
+ ALOGE("%s: Invalid display token %p", whence, displayToken.get());
+ return NAME_NOT_FOUND;
+ }
- return getHwComposer().setBootDisplayMode(displayDevice->getPhysicalId(),
- mode->getHwcId());
- } else {
- ALOGE("%s: Invalid display token %p", __FUNCTION__, displayToken.get());
+ if (display->isVirtual()) {
+ ALOGE("%s: Invalid operation on virtual display", whence);
+ return INVALID_OPERATION;
+ }
+
+ const auto displayId = display->getPhysicalId();
+ const auto mode = display->getMode(DisplayModeId{modeId});
+ if (!mode) {
+ ALOGE("%s: Invalid mode %d for display %s", whence, modeId,
+ to_string(displayId).c_str());
return BAD_VALUE;
}
+
+ return getHwComposer().setBootDisplayMode(displayId, mode->getHwcId());
});
return future.get();
}
status_t SurfaceFlinger::clearBootDisplayMode(const sp<IBinder>& displayToken) {
+ const char* const whence = __func__;
auto future = mScheduler->schedule([=]() MAIN_THREAD -> status_t {
if (const auto displayId = getPhysicalDisplayIdLocked(displayToken)) {
return getHwComposer().clearBootDisplayMode(*displayId);
} else {
- ALOGE("%s: Invalid display token %p", __FUNCTION__, displayToken.get());
+ ALOGE("%s: Invalid display token %p", whence, displayToken.get());
return BAD_VALUE;
}
});
@@ -1484,7 +1496,7 @@ status_t SurfaceFlinger::overrideHdrTypes(const sp<IBinder>& displayToken,
auto display = getDisplayDeviceLocked(displayToken);
if (!display) {
- ALOGE("%s: Invalid display token %p", __FUNCTION__, displayToken.get());
+ ALOGE("%s: Invalid display token %p", __func__, displayToken.get());
return NAME_NOT_FOUND;
}
@@ -2682,11 +2694,11 @@ void SurfaceFlinger::commitTransactions() {
mDebugInTransaction = 0;
}
-void SurfaceFlinger::loadDisplayModes(PhysicalDisplayId displayId, DisplayModes& outModes,
- DisplayModePtr& outActiveMode) const {
+std::pair<DisplayModes, DisplayModePtr> SurfaceFlinger::loadDisplayModes(
+ PhysicalDisplayId displayId) const {
std::vector<HWComposer::HWCDisplayMode> hwcModes;
std::optional<hal::HWDisplayId> activeModeHwcId;
- bool activeModeIsSupported;
+
int attempt = 0;
constexpr int kMaxAttempts = 3;
do {
@@ -2694,63 +2706,60 @@ void SurfaceFlinger::loadDisplayModes(PhysicalDisplayId displayId, DisplayModes&
activeModeHwcId = getHwComposer().getActiveMode(displayId);
LOG_ALWAYS_FATAL_IF(!activeModeHwcId, "HWC returned no active mode");
- activeModeIsSupported =
- std::any_of(hwcModes.begin(), hwcModes.end(),
- [activeModeHwcId](const HWComposer::HWCDisplayMode& mode) {
- return mode.hwcId == *activeModeHwcId;
- });
- } while (!activeModeIsSupported && ++attempt < kMaxAttempts);
- LOG_ALWAYS_FATAL_IF(!activeModeIsSupported,
+ const auto isActiveMode = [activeModeHwcId](const HWComposer::HWCDisplayMode& mode) {
+ return mode.hwcId == *activeModeHwcId;
+ };
+
+ if (std::any_of(hwcModes.begin(), hwcModes.end(), isActiveMode)) {
+ break;
+ }
+ } while (++attempt < kMaxAttempts);
+
+ LOG_ALWAYS_FATAL_IF(attempt == kMaxAttempts,
"After %d attempts HWC still returns an active mode which is not"
- " supported. Active mode ID = %" PRIu64 " . Supported modes = %s",
+ " supported. Active mode ID = %" PRIu64 ". Supported modes = %s",
kMaxAttempts, *activeModeHwcId, base::Join(hwcModes, ", ").c_str());
DisplayModes oldModes;
-
if (const auto token = getPhysicalDisplayTokenLocked(displayId)) {
oldModes = getDisplayDeviceLocked(token)->getSupportedModes();
}
- int largestUsedModeId = -1; // Use int instead of DisplayModeId for signedness
- for (const auto& mode : oldModes) {
- const auto id = static_cast<int>(mode->getId().value());
- if (id > largestUsedModeId) {
- largestUsedModeId = id;
- }
- }
+ ui::DisplayModeId nextModeId = 1 +
+ std::accumulate(oldModes.begin(), oldModes.end(), static_cast<ui::DisplayModeId>(-1),
+ [](ui::DisplayModeId max, const auto& pair) {
+ return std::max(max, pair.first.value());
+ });
DisplayModes newModes;
- int32_t nextModeId = largestUsedModeId + 1;
for (const auto& hwcMode : hwcModes) {
- newModes.push_back(DisplayMode::Builder(hwcMode.hwcId)
- .setId(DisplayModeId{nextModeId++})
- .setPhysicalDisplayId(displayId)
- .setWidth(hwcMode.width)
- .setHeight(hwcMode.height)
- .setVsyncPeriod(hwcMode.vsyncPeriod)
- .setDpiX(hwcMode.dpiX)
- .setDpiY(hwcMode.dpiY)
- .setGroup(hwcMode.configGroup)
- .build());
- }
-
- const bool modesAreSame =
+ const DisplayModeId id{nextModeId++};
+ newModes.try_emplace(id,
+ DisplayMode::Builder(hwcMode.hwcId)
+ .setId(id)
+ .setPhysicalDisplayId(displayId)
+ .setResolution({hwcMode.width, hwcMode.height})
+ .setVsyncPeriod(hwcMode.vsyncPeriod)
+ .setDpiX(hwcMode.dpiX)
+ .setDpiY(hwcMode.dpiY)
+ .setGroup(hwcMode.configGroup)
+ .build());
+ }
+
+ const bool sameModes =
std::equal(newModes.begin(), newModes.end(), oldModes.begin(), oldModes.end(),
- [](DisplayModePtr left, DisplayModePtr right) {
- return left->equalsExceptDisplayModeId(right);
+ [](const auto& lhs, const auto& rhs) {
+ return equalsExceptDisplayModeId(*lhs.second, *rhs.second);
});
- if (modesAreSame) {
- // The supported modes have not changed, keep the old IDs.
- outModes = oldModes;
- } else {
- outModes = newModes;
- }
+ // Keep IDs if modes have not changed.
+ const auto& modes = sameModes ? oldModes : newModes;
+ const DisplayModePtr activeMode =
+ std::find_if(modes.begin(), modes.end(), [activeModeHwcId](const auto& pair) {
+ return pair.second->getHwcId() == activeModeHwcId;
+ })->second;
- outActiveMode = *std::find_if(outModes.begin(), outModes.end(),
- [activeModeHwcId](const DisplayModePtr& mode) {
- return mode->getHwcId() == *activeModeHwcId;
- });
+ return {modes, activeMode};
}
void SurfaceFlinger::processDisplayHotplugEventsLocked() {
@@ -2766,9 +2775,7 @@ void SurfaceFlinger::processDisplayHotplugEventsLocked() {
const auto it = mPhysicalDisplayTokens.find(displayId);
if (event.connection == hal::Connection::CONNECTED) {
- DisplayModes supportedModes;
- DisplayModePtr activeMode;
- loadDisplayModes(displayId, supportedModes, activeMode);
+ auto [supportedModes, activeMode] = loadDisplayModes(displayId);
if (it == mPhysicalDisplayTokens.end()) {
ALOGV("Creating display %s", to_string(displayId).c_str());
@@ -2779,7 +2786,7 @@ void SurfaceFlinger::processDisplayHotplugEventsLocked() {
.hwcDisplayId = event.hwcDisplayId,
.deviceProductInfo = std::move(info->deviceProductInfo),
.supportedModes = std::move(supportedModes),
- .activeMode = activeMode};
+ .activeMode = std::move(activeMode)};
state.isSecure = true; // All physical displays are currently considered secure.
state.displayName = std::move(info->name);
@@ -2794,7 +2801,7 @@ void SurfaceFlinger::processDisplayHotplugEventsLocked() {
auto& state = mCurrentState.displays.editValueFor(token);
state.sequenceId = DisplayDeviceState{}.sequenceId; // Generate new sequenceId
state.physical->supportedModes = std::move(supportedModes);
- state.physical->activeMode = activeMode;
+ state.physical->activeMode = std::move(activeMode);
if (getHwComposer().updatesDeviceProductInfoOnHotplugReconnect()) {
state.physical->deviceProductInfo = std::move(info->deviceProductInfo);
}
@@ -2928,7 +2935,7 @@ void SurfaceFlinger::processDisplayAdded(const wp<IBinder>& displayToken,
ui::Size resolution(0, 0);
ui::PixelFormat pixelFormat = static_cast<ui::PixelFormat>(PIXEL_FORMAT_UNKNOWN);
if (state.physical) {
- resolution = state.physical->activeMode->getSize();
+ resolution = state.physical->activeMode->getResolution();
pixelFormat = static_cast<ui::PixelFormat>(PIXEL_FORMAT_RGBA_8888);
} else if (state.surface != nullptr) {
int status = state.surface->query(NATIVE_WINDOW_WIDTH, &resolution.width);
@@ -2982,7 +2989,7 @@ void SurfaceFlinger::processDisplayAdded(const wp<IBinder>& displayToken,
LOG_FATAL_IF(!displayId);
displaySurface =
sp<FramebufferSurface>::make(getHwComposer(), *displayId, bqConsumer,
- state.physical->activeMode->getSize(),
+ state.physical->activeMode->getResolution(),
ui::Size(maxGraphicsWidth, maxGraphicsHeight));
producer = bqProducer;
}
@@ -3095,7 +3102,7 @@ void SurfaceFlinger::processDisplayChanged(const wp<IBinder>& displayToken,
}
void SurfaceFlinger::updateInternalDisplayVsyncLocked(const sp<DisplayDevice>& activeDisplay) {
mVsyncConfiguration->reset();
- const Fps refreshRate = activeDisplay->refreshRateConfigs().getCurrentRefreshRate().getFps();
+ const Fps refreshRate = activeDisplay->refreshRateConfigs().getActiveMode()->getFps();
updatePhaseConfiguration(refreshRate);
mRefreshRateStats->setRefreshRate(refreshRate);
}
@@ -3357,7 +3364,7 @@ void SurfaceFlinger::updateCursorAsync() {
mCompositionEngine->updateCursorAsync(refreshArgs);
}
-void SurfaceFlinger::changeRefreshRate(const RefreshRate& refreshRate, DisplayModeEvent event) {
+void SurfaceFlinger::requestDisplayMode(DisplayModePtr mode, DisplayModeEvent event) {
// If this is called from the main thread mStateLock must be locked before
// Currently the only way to call this function from the main thread is from
// Scheduler::chooseRefreshRateForContent
@@ -3370,14 +3377,12 @@ void SurfaceFlinger::changeRefreshRate(const RefreshRate& refreshRate, DisplayMo
}
ATRACE_CALL();
- // Don't do any updating if the current fps is the same as the new one.
- if (!display->refreshRateConfigs().isModeAllowed(refreshRate.getModeId())) {
- ALOGV("Skipping mode %d as it is not part of allowed modes",
- refreshRate.getModeId().value());
+ if (!display->refreshRateConfigs().isModeAllowed(mode->getId())) {
+ ALOGV("Skipping disallowed mode %d", mode->getId().value());
return;
}
- setDesiredActiveMode({refreshRate.getMode(), event});
+ setDesiredActiveMode({std::move(mode), event});
}
void SurfaceFlinger::triggerOnFrameRateOverridesChanged() {
@@ -4805,8 +4810,7 @@ void SurfaceFlinger::onInitializeDisplays() {
{}, mPid, getuid(), transactionId);
setPowerModeInternal(display, hal::PowerMode::ON);
- const nsecs_t vsyncPeriod =
- display->refreshRateConfigs().getCurrentRefreshRate().getVsyncPeriod();
+ const nsecs_t vsyncPeriod = display->refreshRateConfigs().getActiveMode()->getVsyncPeriod();
mAnimFrameTracker.setDisplayRefreshPeriod(vsyncPeriod);
mActiveDisplayTransformHint = display->getTransformHint();
// Use phase of 0 since phase is not known.
@@ -4822,7 +4826,7 @@ void SurfaceFlinger::initializeDisplays() {
void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& display, hal::PowerMode mode) {
if (display->isVirtual()) {
- ALOGE("%s: Invalid operation on virtual display", __FUNCTION__);
+ ALOGE("%s: Invalid operation on virtual display", __func__);
return;
}
@@ -4845,7 +4849,7 @@ void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& display, hal:
if (mInterceptor->isEnabled()) {
mInterceptor->savePowerModeUpdate(display->getSequenceId(), static_cast<int32_t>(mode));
}
- const auto vsyncPeriod = display->refreshRateConfigs().getCurrentRefreshRate().getVsyncPeriod();
+ const auto refreshRate = display->refreshRateConfigs().getActiveMode()->getFps();
if (currentMode == hal::PowerMode::OFF) {
// Turn on the display
if (display->isInternal() && (!activeDisplay || !activeDisplay->isPoweredOn())) {
@@ -4863,7 +4867,7 @@ void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& display, hal:
if (isDisplayActiveLocked(display) && mode != hal::PowerMode::DOZE_SUSPEND) {
setHWCVsyncEnabled(displayId, mHWCVsyncPendingState);
mScheduler->onScreenAcquired(mAppConnectionHandle);
- mScheduler->resyncToHardwareVsync(true, vsyncPeriod);
+ mScheduler->resyncToHardwareVsync(true, refreshRate);
}
mVisibleRegionsDirty = true;
@@ -4893,7 +4897,7 @@ void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& display, hal:
getHwComposer().setPowerMode(displayId, mode);
if (isDisplayActiveLocked(display) && currentMode == hal::PowerMode::DOZE_SUSPEND) {
mScheduler->onScreenAcquired(mAppConnectionHandle);
- mScheduler->resyncToHardwareVsync(true, vsyncPeriod);
+ mScheduler->resyncToHardwareVsync(true, refreshRate);
}
} else if (mode == hal::PowerMode::DOZE_SUSPEND) {
// Leave display going to doze
@@ -5379,8 +5383,10 @@ void SurfaceFlinger::dumpAllLocked(const DumpArgs& args, std::string& result) co
std::string fps, xDpi, yDpi;
if (const auto activeMode = display->getActiveMode()) {
fps = to_string(activeMode->getFps());
- xDpi = base::StringPrintf("%.2f", activeMode->getDpiX());
- yDpi = base::StringPrintf("%.2f", activeMode->getDpiY());
+
+ const auto dpi = activeMode->getDpi();
+ xDpi = base::StringPrintf("%.2f", dpi.x);
+ yDpi = base::StringPrintf("%.2f", dpi.y);
} else {
fps = "unknown";
xDpi = "unknown";
@@ -6142,7 +6148,7 @@ void SurfaceFlinger::kernelTimerChanged(bool expired) {
if (!updateOverlay) return;
// Update the overlay on the main thread to avoid race conditions with
- // mRefreshRateConfigs->getCurrentRefreshRate()
+ // mRefreshRateConfigs->getActiveMode()
static_cast<void>(mScheduler->schedule([=] {
const auto display = ON_MAIN_THREAD(getDefaultDisplayDeviceLocked());
if (!display) {
@@ -7188,7 +7194,7 @@ uint32_t SurfaceFlinger::getMaxAcquiredBufferCountForCurrentRefreshRate(uid_t ui
refreshRate = *frameRateOverride;
} else if (!getHwComposer().isHeadless()) {
if (const auto display = ON_MAIN_THREAD(getDefaultDisplayDeviceLocked())) {
- refreshRate = display->refreshRateConfigs().getCurrentRefreshRate().getFps();
+ refreshRate = display->refreshRateConfigs().getActiveMode()->getFps();
}
}