Loading services/surfaceflinger/Scheduler/LayerHistory.cpp +9 −3 Original line number Diff line number Diff line Loading @@ -122,6 +122,10 @@ void LayerHistory::registerLayer(Layer* layer, bool contentDetectionEnabled, mInactiveLayerInfos.insert({layer->getSequence(), std::make_pair(layer, std::move(info))}); } void LayerHistory::setDisplaySize(ui::Size displaySize) { mDisplayArea = static_cast<uint32_t>(displaySize.width * displaySize.height); } void LayerHistory::deregisterLayer(Layer* layer) { std::lock_guard lock(mLock); if (!mActiveLayerInfos.erase(layer->getSequence())) { Loading Loading @@ -405,9 +409,11 @@ void LayerHistory::clear() { std::string LayerHistory::dump() const { std::lock_guard lock(mLock); return base::StringPrintf("{size=%zu, active=%zu}\n\tGameFrameRateOverrides=\n\t\t%s", return base::StringPrintf("{size=%zu, active=%zu}\n\tdisplayArea=%" PRIu32 "\n\tGameFrameRateOverrides=\n\t\t%s", mActiveLayerInfos.size() + mInactiveLayerInfos.size(), mActiveLayerInfos.size(), dumpGameFrameRateOverridesLocked().c_str()); mActiveLayerInfos.size(), mDisplayArea, dumpGameFrameRateOverridesLocked().c_str()); } std::string LayerHistory::dumpGameFrameRateOverridesLocked() const { Loading Loading @@ -442,7 +448,7 @@ auto LayerHistory::findLayer(int32_t id) -> std::pair<LayerStatus, LayerPair*> { } bool LayerHistory::isSmallDirtyArea(uint32_t dirtyArea, float threshold) const { const float ratio = (float)dirtyArea / mDisplayArea; const float ratio = static_cast<float>(dirtyArea) / mDisplayArea; const bool isSmallDirty = ratio <= threshold; SFTRACE_FORMAT_INSTANT("small dirty=%s, ratio=%.3f", isSmallDirty ? "true" : "false", ratio); return isSmallDirty; Loading services/surfaceflinger/Scheduler/LayerHistory.h +5 −3 Original line number Diff line number Diff line Loading @@ -54,8 +54,8 @@ public: void registerLayer(Layer*, bool contentDetectionEnabled, FrameRateCompatibility frameRateCompatibility); // Sets the display size. Client is responsible for synchronization. void setDisplayArea(uint32_t displayArea) { mDisplayArea = displayArea; } // Client is responsible for synchronization. void setDisplaySize(ui::Size displaySize); // Sets whether a mode change is pending to be applied void setModeChangePending(bool pending) { mModeChangePending = pending; } Loading Loading @@ -143,6 +143,7 @@ private: LayerInfos mActiveLayerInfos GUARDED_BY(mLock); LayerInfos mInactiveLayerInfos GUARDED_BY(mLock); // TODO: Track display areas on a per-display basis rather than as a single global state. uint32_t mDisplayArea = 0; // Whether to emit systrace output and debug logs. Loading @@ -151,7 +152,8 @@ private: // Whether to use priority sent from WindowManager to determine the relevancy of the layer. const bool mUseFrameRatePriority; // Whether a mode change is in progress or not // Whether a mode change is in progress or not. /// TODO: Track mode change pending on a per-display basis rather than as a single global state. std::atomic<bool> mModeChangePending = false; // A list to look up the game frame rate overrides Loading services/surfaceflinger/Scheduler/Scheduler.cpp +6 −4 Original line number Diff line number Diff line Loading @@ -123,6 +123,7 @@ void Scheduler::setPacesetterDisplay(PhysicalDisplayId pacesetterId) { std::scoped_lock lock{mVsyncConfigLock}; mVsyncConfiguration->reset(); } updatePhaseConfiguration(pacesetterId, pacesetterSelectorPtr()->getActiveMode().fps); } Loading Loading @@ -1065,11 +1066,12 @@ std::shared_ptr<VsyncSchedule> Scheduler::promotePacesetterDisplayLocked( newVsyncSchedulePtr = pacesetter.schedulePtr; constexpr bool kForce = true; newVsyncSchedulePtr->onDisplayModeChanged(pacesetter.selectorPtr->getActiveMode().modePtr, kForce); const auto pacesetterActiveModePtr = pacesetter.selectorPtr->getActiveMode().modePtr; newVsyncSchedulePtr->onDisplayModeChanged(pacesetterActiveModePtr, kForce); if (FlagManager::getInstance().pacesetter_selection()) { mSchedulerCallback.enableLayerCachingTexturePool(pacesetterId, true); onPacesetterDisplaySizeChanged(pacesetterActiveModePtr->getResolution()); } } return newVsyncSchedulePtr; Loading Loading @@ -1350,8 +1352,8 @@ bool Scheduler::onCompositionPresented(nsecs_t presentTime) { return false; } void Scheduler::onActiveDisplayAreaChanged(uint32_t displayArea) { mLayerHistory.setDisplayArea(displayArea); void Scheduler::onPacesetterDisplaySizeChanged(ui::Size displaySize) { mLayerHistory.setDisplaySize(displaySize); } void Scheduler::setGameModeFrameRateForUid(FrameRateOverride frameRateOverride) { Loading services/surfaceflinger/Scheduler/Scheduler.h +1 −1 Original line number Diff line number Diff line Loading @@ -296,7 +296,7 @@ public: bool onCompositionPresented(nsecs_t presentTime); // Notifies the scheduler when the display size has changed. Called from SF's main thread void onActiveDisplayAreaChanged(uint32_t displayArea); void onPacesetterDisplaySizeChanged(ui::Size displaySize); // Stores the preferred refresh rate that an app should run at. // FrameRateOverride.refreshRateHz == 0 means no preference. Loading services/surfaceflinger/SurfaceFlinger.cpp +37 −9 Original line number Diff line number Diff line Loading @@ -1012,6 +1012,7 @@ void SurfaceFlinger::init() FTL_FAKE_GUARD(kMainThreadContext) { // No need to trigger update for pacesetter via Scheduler::setPacesetterDisplay() as it is // done as part of adding the `display` in initScheduler(). getRenderEngine().onActiveDisplaySizeChanged(findLargestFramebufferSizeLocked()); const auto pacesetter = getPacesetterDisplayLocked(); applyRefreshRateSelectorPolicy(pacesetter->getPhysicalId(), pacesetter->refreshRateSelector()); Loading Loading @@ -4168,6 +4169,8 @@ void SurfaceFlinger::processDisplayChanged(const wp<IBinder>& displayToken, if (FlagManager::getInstance().pacesetter_selection()) { mScheduler->setPacesetterDisplay(mFrontInternalDisplayId); getRenderEngine().onActiveDisplaySizeChanged( findLargestFramebufferSizeLocked()); const auto pacesetter = getPacesetterDisplayLocked(); applyRefreshRateSelectorPolicy(pacesetter->getPhysicalId(), pacesetter->refreshRateSelector()); Loading @@ -4187,7 +4190,7 @@ void SurfaceFlinger::processDisplayChanged(const wp<IBinder>& displayToken, display->setFlags(currentState.flags); } const auto updateDisplaySize = [&]() { const auto updateDisplaySize = [&]() REQUIRES(mStateLock) { if (currentState.width != drawingState.width || currentState.height != drawingState.height) { const ui::Size resolution = ui::Size(currentState.width, currentState.height); Loading @@ -4204,8 +4207,17 @@ void SurfaceFlinger::processDisplayChanged(const wp<IBinder>& displayToken, display->setDisplaySize(resolution); } if (FlagManager::getInstance().pacesetter_selection()) { if (display->getId() == mScheduler->getPacesetterDisplayId()) { mScheduler->onPacesetterDisplaySizeChanged(display->getSize()); getRenderEngine().onActiveDisplaySizeChanged( findLargestFramebufferSizeLocked()); } } else { if (display->getId() == mFrontInternalDisplayId) { onFrontInternalDisplaySizeChanged(*display); mScheduler->onPacesetterDisplaySizeChanged(display->getSize()); getRenderEngine().onActiveDisplaySizeChanged(display->getSize()); } } } }; Loading Loading @@ -4710,6 +4722,25 @@ void SurfaceFlinger::invalidateLayerStack(const ui::LayerFilter& layerFilter, co } } ui::Size SurfaceFlinger::findLargestFramebufferSizeLocked() const { ui::Size maxSize(0, 0); int64_t maxArea = 0; for (const auto& [_, display] : mDisplays) { if (!display->isPoweredOn()) { continue; } const ui::Size size = display->getSize(); const int64_t area = size.getWidth() * size.getHeight(); if (area > maxArea) { maxSize = size; maxArea = area; } } return maxSize; } status_t SurfaceFlinger::addClientLayer(LayerCreationArgs& args, const sp<IBinder>& handle, const sp<Layer>& layer, const wp<Layer>& parent, uint32_t* outTransformHint) { Loading Loading @@ -8437,11 +8468,6 @@ void SurfaceFlinger::sample() { mRegionSamplingThread->onCompositionComplete(scheduleFrameTimeOpt); } void SurfaceFlinger::onFrontInternalDisplaySizeChanged(const DisplayDevice& activeDisplay) { mScheduler->onActiveDisplayAreaChanged(activeDisplay.getWidth() * activeDisplay.getHeight()); getRenderEngine().onActiveDisplaySizeChanged(activeDisplay.getSize()); } sp<DisplayDevice> SurfaceFlinger::findFrontInternalDisplay() const { if (mPhysicalDisplays.size() == 1) return nullptr; Loading @@ -8459,7 +8485,6 @@ void SurfaceFlinger::onNewFrontInternalDisplay(const DisplayDevice* oldFrontInte SFTRACE_CALL(); mFrontInternalDisplayId = newFrontInternalDisplay.getPhysicalId(); onFrontInternalDisplaySizeChanged(newFrontInternalDisplay); mFrontInternalDisplayTransformHint = newFrontInternalDisplay.getTransformHint(); sFrontInternalDisplayRotationFlags = Loading @@ -8472,6 +8497,9 @@ void SurfaceFlinger::onNewFrontInternalDisplay(const DisplayDevice* oldFrontInte mScheduler->setModeChangePending(oldFrontInternalDisplayPtr->getPhysicalId(), false); } mScheduler->onPacesetterDisplaySizeChanged(newFrontInternalDisplay.getSize()); getRenderEngine().onActiveDisplaySizeChanged(newFrontInternalDisplay.getSize()); newFrontInternalDisplay.getCompositionDisplay()->setLayerCachingTexturePoolEnabled(true); mScheduler->setPacesetterDisplay(mFrontInternalDisplayId); Loading Loading
services/surfaceflinger/Scheduler/LayerHistory.cpp +9 −3 Original line number Diff line number Diff line Loading @@ -122,6 +122,10 @@ void LayerHistory::registerLayer(Layer* layer, bool contentDetectionEnabled, mInactiveLayerInfos.insert({layer->getSequence(), std::make_pair(layer, std::move(info))}); } void LayerHistory::setDisplaySize(ui::Size displaySize) { mDisplayArea = static_cast<uint32_t>(displaySize.width * displaySize.height); } void LayerHistory::deregisterLayer(Layer* layer) { std::lock_guard lock(mLock); if (!mActiveLayerInfos.erase(layer->getSequence())) { Loading Loading @@ -405,9 +409,11 @@ void LayerHistory::clear() { std::string LayerHistory::dump() const { std::lock_guard lock(mLock); return base::StringPrintf("{size=%zu, active=%zu}\n\tGameFrameRateOverrides=\n\t\t%s", return base::StringPrintf("{size=%zu, active=%zu}\n\tdisplayArea=%" PRIu32 "\n\tGameFrameRateOverrides=\n\t\t%s", mActiveLayerInfos.size() + mInactiveLayerInfos.size(), mActiveLayerInfos.size(), dumpGameFrameRateOverridesLocked().c_str()); mActiveLayerInfos.size(), mDisplayArea, dumpGameFrameRateOverridesLocked().c_str()); } std::string LayerHistory::dumpGameFrameRateOverridesLocked() const { Loading Loading @@ -442,7 +448,7 @@ auto LayerHistory::findLayer(int32_t id) -> std::pair<LayerStatus, LayerPair*> { } bool LayerHistory::isSmallDirtyArea(uint32_t dirtyArea, float threshold) const { const float ratio = (float)dirtyArea / mDisplayArea; const float ratio = static_cast<float>(dirtyArea) / mDisplayArea; const bool isSmallDirty = ratio <= threshold; SFTRACE_FORMAT_INSTANT("small dirty=%s, ratio=%.3f", isSmallDirty ? "true" : "false", ratio); return isSmallDirty; Loading
services/surfaceflinger/Scheduler/LayerHistory.h +5 −3 Original line number Diff line number Diff line Loading @@ -54,8 +54,8 @@ public: void registerLayer(Layer*, bool contentDetectionEnabled, FrameRateCompatibility frameRateCompatibility); // Sets the display size. Client is responsible for synchronization. void setDisplayArea(uint32_t displayArea) { mDisplayArea = displayArea; } // Client is responsible for synchronization. void setDisplaySize(ui::Size displaySize); // Sets whether a mode change is pending to be applied void setModeChangePending(bool pending) { mModeChangePending = pending; } Loading Loading @@ -143,6 +143,7 @@ private: LayerInfos mActiveLayerInfos GUARDED_BY(mLock); LayerInfos mInactiveLayerInfos GUARDED_BY(mLock); // TODO: Track display areas on a per-display basis rather than as a single global state. uint32_t mDisplayArea = 0; // Whether to emit systrace output and debug logs. Loading @@ -151,7 +152,8 @@ private: // Whether to use priority sent from WindowManager to determine the relevancy of the layer. const bool mUseFrameRatePriority; // Whether a mode change is in progress or not // Whether a mode change is in progress or not. /// TODO: Track mode change pending on a per-display basis rather than as a single global state. std::atomic<bool> mModeChangePending = false; // A list to look up the game frame rate overrides Loading
services/surfaceflinger/Scheduler/Scheduler.cpp +6 −4 Original line number Diff line number Diff line Loading @@ -123,6 +123,7 @@ void Scheduler::setPacesetterDisplay(PhysicalDisplayId pacesetterId) { std::scoped_lock lock{mVsyncConfigLock}; mVsyncConfiguration->reset(); } updatePhaseConfiguration(pacesetterId, pacesetterSelectorPtr()->getActiveMode().fps); } Loading Loading @@ -1065,11 +1066,12 @@ std::shared_ptr<VsyncSchedule> Scheduler::promotePacesetterDisplayLocked( newVsyncSchedulePtr = pacesetter.schedulePtr; constexpr bool kForce = true; newVsyncSchedulePtr->onDisplayModeChanged(pacesetter.selectorPtr->getActiveMode().modePtr, kForce); const auto pacesetterActiveModePtr = pacesetter.selectorPtr->getActiveMode().modePtr; newVsyncSchedulePtr->onDisplayModeChanged(pacesetterActiveModePtr, kForce); if (FlagManager::getInstance().pacesetter_selection()) { mSchedulerCallback.enableLayerCachingTexturePool(pacesetterId, true); onPacesetterDisplaySizeChanged(pacesetterActiveModePtr->getResolution()); } } return newVsyncSchedulePtr; Loading Loading @@ -1350,8 +1352,8 @@ bool Scheduler::onCompositionPresented(nsecs_t presentTime) { return false; } void Scheduler::onActiveDisplayAreaChanged(uint32_t displayArea) { mLayerHistory.setDisplayArea(displayArea); void Scheduler::onPacesetterDisplaySizeChanged(ui::Size displaySize) { mLayerHistory.setDisplaySize(displaySize); } void Scheduler::setGameModeFrameRateForUid(FrameRateOverride frameRateOverride) { Loading
services/surfaceflinger/Scheduler/Scheduler.h +1 −1 Original line number Diff line number Diff line Loading @@ -296,7 +296,7 @@ public: bool onCompositionPresented(nsecs_t presentTime); // Notifies the scheduler when the display size has changed. Called from SF's main thread void onActiveDisplayAreaChanged(uint32_t displayArea); void onPacesetterDisplaySizeChanged(ui::Size displaySize); // Stores the preferred refresh rate that an app should run at. // FrameRateOverride.refreshRateHz == 0 means no preference. Loading
services/surfaceflinger/SurfaceFlinger.cpp +37 −9 Original line number Diff line number Diff line Loading @@ -1012,6 +1012,7 @@ void SurfaceFlinger::init() FTL_FAKE_GUARD(kMainThreadContext) { // No need to trigger update for pacesetter via Scheduler::setPacesetterDisplay() as it is // done as part of adding the `display` in initScheduler(). getRenderEngine().onActiveDisplaySizeChanged(findLargestFramebufferSizeLocked()); const auto pacesetter = getPacesetterDisplayLocked(); applyRefreshRateSelectorPolicy(pacesetter->getPhysicalId(), pacesetter->refreshRateSelector()); Loading Loading @@ -4168,6 +4169,8 @@ void SurfaceFlinger::processDisplayChanged(const wp<IBinder>& displayToken, if (FlagManager::getInstance().pacesetter_selection()) { mScheduler->setPacesetterDisplay(mFrontInternalDisplayId); getRenderEngine().onActiveDisplaySizeChanged( findLargestFramebufferSizeLocked()); const auto pacesetter = getPacesetterDisplayLocked(); applyRefreshRateSelectorPolicy(pacesetter->getPhysicalId(), pacesetter->refreshRateSelector()); Loading @@ -4187,7 +4190,7 @@ void SurfaceFlinger::processDisplayChanged(const wp<IBinder>& displayToken, display->setFlags(currentState.flags); } const auto updateDisplaySize = [&]() { const auto updateDisplaySize = [&]() REQUIRES(mStateLock) { if (currentState.width != drawingState.width || currentState.height != drawingState.height) { const ui::Size resolution = ui::Size(currentState.width, currentState.height); Loading @@ -4204,8 +4207,17 @@ void SurfaceFlinger::processDisplayChanged(const wp<IBinder>& displayToken, display->setDisplaySize(resolution); } if (FlagManager::getInstance().pacesetter_selection()) { if (display->getId() == mScheduler->getPacesetterDisplayId()) { mScheduler->onPacesetterDisplaySizeChanged(display->getSize()); getRenderEngine().onActiveDisplaySizeChanged( findLargestFramebufferSizeLocked()); } } else { if (display->getId() == mFrontInternalDisplayId) { onFrontInternalDisplaySizeChanged(*display); mScheduler->onPacesetterDisplaySizeChanged(display->getSize()); getRenderEngine().onActiveDisplaySizeChanged(display->getSize()); } } } }; Loading Loading @@ -4710,6 +4722,25 @@ void SurfaceFlinger::invalidateLayerStack(const ui::LayerFilter& layerFilter, co } } ui::Size SurfaceFlinger::findLargestFramebufferSizeLocked() const { ui::Size maxSize(0, 0); int64_t maxArea = 0; for (const auto& [_, display] : mDisplays) { if (!display->isPoweredOn()) { continue; } const ui::Size size = display->getSize(); const int64_t area = size.getWidth() * size.getHeight(); if (area > maxArea) { maxSize = size; maxArea = area; } } return maxSize; } status_t SurfaceFlinger::addClientLayer(LayerCreationArgs& args, const sp<IBinder>& handle, const sp<Layer>& layer, const wp<Layer>& parent, uint32_t* outTransformHint) { Loading Loading @@ -8437,11 +8468,6 @@ void SurfaceFlinger::sample() { mRegionSamplingThread->onCompositionComplete(scheduleFrameTimeOpt); } void SurfaceFlinger::onFrontInternalDisplaySizeChanged(const DisplayDevice& activeDisplay) { mScheduler->onActiveDisplayAreaChanged(activeDisplay.getWidth() * activeDisplay.getHeight()); getRenderEngine().onActiveDisplaySizeChanged(activeDisplay.getSize()); } sp<DisplayDevice> SurfaceFlinger::findFrontInternalDisplay() const { if (mPhysicalDisplays.size() == 1) return nullptr; Loading @@ -8459,7 +8485,6 @@ void SurfaceFlinger::onNewFrontInternalDisplay(const DisplayDevice* oldFrontInte SFTRACE_CALL(); mFrontInternalDisplayId = newFrontInternalDisplay.getPhysicalId(); onFrontInternalDisplaySizeChanged(newFrontInternalDisplay); mFrontInternalDisplayTransformHint = newFrontInternalDisplay.getTransformHint(); sFrontInternalDisplayRotationFlags = Loading @@ -8472,6 +8497,9 @@ void SurfaceFlinger::onNewFrontInternalDisplay(const DisplayDevice* oldFrontInte mScheduler->setModeChangePending(oldFrontInternalDisplayPtr->getPhysicalId(), false); } mScheduler->onPacesetterDisplaySizeChanged(newFrontInternalDisplay.getSize()); getRenderEngine().onActiveDisplaySizeChanged(newFrontInternalDisplay.getSize()); newFrontInternalDisplay.getCompositionDisplay()->setLayerCachingTexturePoolEnabled(true); mScheduler->setPacesetterDisplay(mFrontInternalDisplayId); Loading