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

Commit 3546a3f0 authored by Brian Anderson's avatar Brian Anderson
Browse files

Fix FenceTracker releaseFence

This patch:
* Fixes the release fence when GPU compositing.
* Stores the final release fence in ConsumerBase just
    before releasing the Buffer, which helps ensure
    sync points aren't added unknowningly.
* Makes HWC2 release pending buffers as the first step
    of postCompostion, rather than the last, which should
    allow dequeue to unblock a little earlier and helps
    make sure the previous buffer's release fence has
    been finalized before FenceTracker::addFrame is
    called.
* Fence tracker only sets the release fence once it
    has been finalized so it does not report a release
    fence for a buffer that is still latched.

Test: adb shell /data/nativetest/libgui_test/libgui_test
--gtest_filter=*GetFrameTimestamps*

Change-Id: I27d484bfd48f730bdcea2628f96795c6f4b4df7b
parent 069b3651
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -180,7 +180,7 @@ protected:
    // Derived classes should override this method to perform any cleanup that
    // must take place when a buffer is released back to the BufferQueue.  If
    // it is overridden the derived class's implementation must call
    // ConsumerBase::releaseBufferLocked.e
    // ConsumerBase::releaseBufferLocked.
    virtual status_t releaseBufferLocked(int slot,
            const sp<GraphicBuffer> graphicBuffer,
            EGLDisplay display, EGLSyncKHR eglFence);
@@ -244,6 +244,10 @@ protected:
    // if none is supplied
    sp<IGraphicBufferConsumer> mConsumer;

    // The final release fence of the most recent buffer released by
    // releaseBufferLocked.
    sp<Fence> mPrevFinalReleaseFence;

    // mMutex is the mutex used to prevent concurrent access to the member
    // variables of ConsumerBase objects. It must be locked whenever the
    // member variables are accessed or when any of the *Locked methods are
+1 −1
Original line number Diff line number Diff line
@@ -250,7 +250,7 @@ protected:
    // mEglSlots array in addition to the ConsumerBase.
    virtual status_t releaseBufferLocked(int slot,
            const sp<GraphicBuffer> graphicBuffer,
            EGLDisplay display, EGLSyncKHR eglFence);
            EGLDisplay display, EGLSyncKHR eglFence) override;

    status_t releaseBufferLocked(int slot,
            const sp<GraphicBuffer> graphicBuffer, EGLSyncKHR eglFence) {
+3 −1
Original line number Diff line number Diff line
@@ -56,7 +56,8 @@ static int32_t createProcessUniqueId() {

ConsumerBase::ConsumerBase(const sp<IGraphicBufferConsumer>& bufferQueue, bool controlledByApp) :
        mAbandoned(false),
        mConsumer(bufferQueue) {
        mConsumer(bufferQueue),
        mPrevFinalReleaseFence(Fence::NO_FENCE) {
    // Choose a name using the PID and a process-unique ID.
    mName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId());

@@ -366,6 +367,7 @@ status_t ConsumerBase::releaseBufferLocked(
        freeBufferLocked(slot);
    }

    mPrevFinalReleaseFence = mSlots[slot].mFence;
    mSlots[slot].mFence = Fence::NO_FENCE;

    return err;
+7 −28
Original line number Diff line number Diff line
@@ -158,38 +158,17 @@ void FenceTracker::addFrame(nsecs_t refreshStartTime, sp<Fence> presentFence,

        layers[i]->getFenceData(&name, &frameNumber, &glesComposition,
                &requestedPresentTime, &acquireFence, &prevReleaseFence);
#ifdef USE_HWC2
        if (glesComposition) {
            frame.layers.emplace(std::piecewise_construct,
                    std::forward_as_tuple(layerId),
                    std::forward_as_tuple(name, frameNumber, glesComposition,
                    requestedPresentTime, 0, 0, acquireFence,
                    prevReleaseFence));
            wasGlesCompositionDone = true;
        } else {

        frame.layers.emplace(std::piecewise_construct,
                std::forward_as_tuple(layerId),
                std::forward_as_tuple(name, frameNumber, glesComposition,
                requestedPresentTime, 0, 0, acquireFence, Fence::NO_FENCE));
        auto prevLayer = prevFrame.layers.find(layerId);
        if (prevLayer != prevFrame.layers.end()) {
            if (frameNumber != prevLayer->second.frameNumber) {
               prevLayer->second.releaseFence = prevReleaseFence;
            }
        }
#else
        frame.layers.emplace(std::piecewise_construct,
                std::forward_as_tuple(layerId),
                std::forward_as_tuple(name, frameNumber, glesComposition,
                requestedPresentTime, 0, 0, acquireFence,
                glesComposition ? Fence::NO_FENCE : prevReleaseFence));
        if (glesComposition) {
            wasGlesCompositionDone = true;
        }
#endif
        frame.layers.emplace(std::piecewise_construct,
                std::forward_as_tuple(layerId),
                std::forward_as_tuple(name, frameNumber, glesComposition,
                requestedPresentTime, 0, 0, acquireFence, prevReleaseFence));
    }

    frame.frameId = mFrameCounter;
+1 −1
Original line number Diff line number Diff line
@@ -2173,7 +2173,7 @@ void Layer::getFenceData(String8* outName, uint64_t* outFrameNumber,
#endif
    *outRequestedPresentTime = mSurfaceFlingerConsumer->getTimestamp();
    *outAcquireFence = mSurfaceFlingerConsumer->getCurrentFence();
    *outPrevReleaseFence = mSurfaceFlingerConsumer->getPrevReleaseFence();
    *outPrevReleaseFence = mSurfaceFlingerConsumer->getPrevFinalReleaseFence();
}

std::vector<OccupancyTracker::Segment> Layer::getOccupancyHistory(
Loading