Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b58f74f5 authored by Su Hong Koo's avatar Su Hong Koo
Browse files

SF: Break down onActiveDisplaySizeChanged()

Remove SF::onActiveDisplaySizeChanged(), and replace it with
independent calls to Scheduler::onPacesetterDisplayAreaChanged() and
RenderEngine::onActiveDisplayAreaChanged().

The main difference in this CL is that the Scheduler is fed the display
area of the pacesetter instead of the "active" display, and that the
render engine is given the area of the largest configured display for
the cache instead of the active display.

Flag: com.android.graphics.surfaceflinger.flags.pacesetter_selection
Bug: 255635821
Test: dumpsys SurfaceFlinger | grep displayArea w/ foldable
Change-Id: I724066f39289e21e395d637720bc8994f070e1bf
parent 99e76ce9
Loading
Loading
Loading
Loading
+9 −3
Original line number Diff line number Diff line
@@ -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())) {
@@ -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 {
@@ -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;
+5 −3
Original line number Diff line number Diff line
@@ -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; }
@@ -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.
@@ -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
+6 −4
Original line number Diff line number Diff line
@@ -128,6 +128,7 @@ void Scheduler::setPacesetterDisplay(PhysicalDisplayId pacesetterId) {
        std::scoped_lock lock{mVsyncConfigLock};
        mVsyncConfiguration->reset();
    }

    updatePhaseConfiguration(pacesetterId, pacesetterSelectorPtr()->getActiveMode().fps);
}

@@ -1069,11 +1070,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;
@@ -1354,8 +1356,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) {
+1 −1
Original line number Diff line number Diff line
@@ -300,7 +300,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.
+37 −9
Original line number Diff line number Diff line
@@ -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());
@@ -4182,6 +4183,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());
@@ -4201,7 +4204,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);
@@ -4218,8 +4221,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());
                    }
                }
            }
        };
@@ -4728,6 +4740,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) {
@@ -8476,11 +8507,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;

@@ -8498,7 +8524,6 @@ void SurfaceFlinger::onNewFrontInternalDisplay(const DisplayDevice* oldFrontInte
    SFTRACE_CALL();

    mFrontInternalDisplayId = newFrontInternalDisplay.getPhysicalId();
    onFrontInternalDisplaySizeChanged(newFrontInternalDisplay);

    mFrontInternalDisplayTransformHint = newFrontInternalDisplay.getTransformHint();
    sFrontInternalDisplayRotationFlags =
@@ -8511,6 +8536,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