diff options
Diffstat (limited to 'services/surfaceflinger/SurfaceFlinger.cpp')
| -rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 210 |
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(); } } |