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

Commit 49a108cd authored by chaviw's avatar chaviw
Browse files

Latch and relase buffers for offscreen layers on main thread.

The current code was calling fakeVsync, which was latching and releasing
buffers on a binder thread when a new frame arrived. This was causing a
race with the latchBuffer on the main thread. This change calls
latchAndReleaseBuffer on the main thread for offscreen layers to ensure
we don't block dequeueBuffer but also don't race the other latchBuffer
call.

Fixes: 139118508
Test: Race was only reproducible in monkey tests
Change-Id: Ie7d87aa775c215de3fb2322b73849402596cc3fc
parent c603c81d
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -668,6 +668,15 @@ FloatRect BufferLayer::computeSourceBounds(const FloatRect& parentBounds) const
    return FloatRect(0, 0, bufWidth, bufHeight);
}

void BufferLayer::latchAndReleaseBuffer() {
    mRefreshPending = false;
    if (hasReadyFrame()) {
        bool ignored = false;
        latchBuffer(ignored, systemTime(), 0 /* expectedPresentTime */);
    }
    releasePendingBuffer(systemTime());
}

} // namespace android

#if defined(__gl_h_)
+7 −0
Original line number Diff line number Diff line
@@ -103,6 +103,13 @@ public:
    // Returns the current scaling mode, unless mOverrideScalingMode
    // is set, in which case, it returns mOverrideScalingMode
    uint32_t getEffectiveScalingMode() const override;

    // Calls latchBuffer if the buffer has a frame queued and then releases the buffer.
    // This is used if the buffer is just latched and releases to free up the buffer
    // and will not be shown on screen.
    // Should only be called on the main thread.
    void latchAndReleaseBuffer() override;

    // -----------------------------------------------------------------------

    // -----------------------------------------------------------------------
+1 −15
Original line number Diff line number Diff line
@@ -412,14 +412,6 @@ void BufferQueueLayer::latchPerFrameState(
// Interface implementation for BufferLayerConsumer::ContentsChangedListener
// -----------------------------------------------------------------------

void BufferQueueLayer::fakeVsync() {
    mRefreshPending = false;
    bool ignored = false;
    latchBuffer(ignored, systemTime(), 0 /* expectedPresentTime */);
    usleep(16000);
    releasePendingBuffer(systemTime());
}

void BufferQueueLayer::onFrameAvailable(const BufferItem& item) {
    ATRACE_CALL();
    // Add this buffer from our internal queue tracker
@@ -456,13 +448,7 @@ void BufferQueueLayer::onFrameAvailable(const BufferItem& item) {
    mFlinger->mInterceptor->saveBufferUpdate(this, item.mGraphicBuffer->getWidth(),
                                             item.mGraphicBuffer->getHeight(), item.mFrameNumber);

    // If this layer is orphaned, then we run a fake vsync pulse so that
    // dequeueBuffer doesn't block indefinitely.
    if (isRemovedFromCurrentState()) {
        fakeVsync();
    } else {
    mFlinger->signalLayerUpdate();
    }
    mConsumer->onBufferAvailable(item);
}

+0 −2
Original line number Diff line number Diff line
@@ -138,8 +138,6 @@ private:
    // thread-safe
    std::atomic<int32_t> mQueuedFrames{0};
    std::atomic<bool> mSidebandStreamChanged{false};

    void fakeVsync();
};

} // namespace android
+2 −0
Original line number Diff line number Diff line
@@ -544,6 +544,8 @@ public:

    virtual bool isBufferLatched() const { return false; }

    virtual void latchAndReleaseBuffer() {}

    /*
     * Remove relative z for the layer if its relative parent is not part of the
     * provided layer tree.
Loading