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

Commit c2f84139 authored by Robert Carr's avatar Robert Carr
Browse files

SurfaceFlinger: Disable early-release on multi displays

The current logic for handling multiple calls to onLayerDisplayed is
insufficient. For example if we did HWC comp followed by GL comp
on a single layer in a single compose cycle, FOLLOWING a previous
compose cycle in which we had done the same thing. The first time
we would enter the first conditional and clear the fence, but then the second
time we would enter the first conditional and keep it. We can't do this
though since the buffer was just used for HWC comp and we can't early
release it. To simplify things we only allow a single call to
onLayerDisplayed otherwise we disable the optimization. We can improve
this to re-enable the optimization with mirroring in the future
by tracking the state more carefully.

Bug: 221894151
Test: Run screenrecord and look for glitches
Change-Id: I73b5adac00d30750d4d79d0cbba9152df638d0e5
parent a692e0fd
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -362,6 +362,8 @@ void BufferLayer::onPostComposition(const DisplayDevice* display,
    // composition.
    if (!mBufferInfo.mFrameLatencyNeeded) return;

    mAlreadyDisplayedThisCompose = false;

    // Update mFrameEventHistory.
    {
        Mutex::Autolock lock(mFrameEventHistoryMutex);
+8 −10
Original line number Diff line number Diff line
@@ -75,17 +75,15 @@ BufferStateLayer::~BufferStateLayer() {
// -----------------------------------------------------------------------
void BufferStateLayer::onLayerDisplayed(
        std::shared_future<renderengine::RenderEngineResult> futureRenderEngineResult) {
    // If a layer has been displayed again we may need to clear
    // the mLastClientComposition fence that we use for early release in setBuffer
    // (as we now have a new fence which won't pass through the client composition path in some cases
    //  e.g. screenshot). We expect one call to onLayerDisplayed after receiving the GL comp fence
    // from a single composition cycle, and want to clear on the second call
    // (which we track with mLastClientCompositionDisplayed)
   if (mLastClientCompositionDisplayed) {
    // If we are displayed on multiple displays in a single composition cycle then we would
    // need to do careful tracking to enable the use of the mLastClientCompositionFence.
    //  For example we can only use it if all the displays are client comp, and we need
    //  to merge all the client comp fences. We could do this, but for now we just
    // disable the optimization when a layer is composed on multiple displays.
    if (mAlreadyDisplayedThisCompose) {
        mLastClientCompositionFence = nullptr;
        mLastClientCompositionDisplayed = false;
    } else if (mLastClientCompositionFence) {
        mLastClientCompositionDisplayed = true;
    } else {
        mAlreadyDisplayedThisCompose = true;
    }

    // The previous release fence notifies the client that SurfaceFlinger is done with the previous
+1 −1
Original line number Diff line number Diff line
@@ -1049,7 +1049,7 @@ protected:
    mutable bool mDrawingStateModified = false;

    sp<Fence> mLastClientCompositionFence;
    bool mLastClientCompositionDisplayed = false;
    bool mAlreadyDisplayedThisCompose = false;
private:
    virtual void setTransformHint(ui::Transform::RotationFlags) {}