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

Commit 1ce6581a authored by Dan Stoza's avatar Dan Stoza
Browse files

SF: Only latch buffers after fence signals

Changes SurfaceFlinger to only latch a buffer after its corresponding
acquire fence has signaled. This will enable us to move
SurfaceFlinger closer to vsync since there is no risk of fence waits
blocking composition.

Bug: 29413700
Change-Id: I26f4fd600c1611b8d736ec654d1f0f02cf69ae5f
parent 0ade247d
Loading
Loading
Loading
Loading
+28 −1
Original line number Diff line number Diff line
@@ -1100,6 +1100,25 @@ uint64_t Layer::getHeadFrameNumber() const {
    }
}

bool Layer::headFenceHasSignaled() const {
#ifdef USE_HWC2
    Mutex::Autolock lock(mQueueItemLock);
    if (mQueueItems.empty()) {
        return true;
    }
    if (mQueueItems[0].mIsDroppable) {
        // Even though this buffer's fence may not have signaled yet, it could
        // be replaced by another buffer before it has a chance to, which means
        // that it's possible to get into a situation where a buffer is never
        // able to be latched. To avoid this, grab this buffer anyway.
        return true;
    }
    return mQueueItems[0].mFence->getSignalTime() != INT64_MAX;
#else
    return true;
#endif
}

bool Layer::addSyncPoint(const std::shared_ptr<SyncPoint>& point) {
    if (point->getFrameNumber() <= mCurrentFrameNumber) {
        // Don't bother with a SyncPoint, since we've already latched the
@@ -1357,9 +1376,10 @@ bool Layer::applyPendingStates(State* stateToCommit) {

void Layer::notifyAvailableFrames() {
    auto headFrameNumber = getHeadFrameNumber();
    bool headFenceSignaled = headFenceHasSignaled();
    Mutex::Autolock lock(mLocalSyncPointMutex);
    for (auto& point : mLocalSyncPoints) {
        if (headFrameNumber >= point->getFrameNumber()) {
        if (headFrameNumber >= point->getFrameNumber() && headFenceSignaled) {
            point->setFrameAvailable();
        }
    }
@@ -1756,6 +1776,13 @@ Region Layer::latchBuffer(bool& recomputeVisibleRegions)
            return outDirtyRegion;
        }

        // If the head buffer's acquire fence hasn't signaled yet, return and
        // try again later
        if (!headFenceHasSignaled()) {
            mFlinger->signalLayerUpdate();
            return outDirtyRegion;
        }

        // Capture the old state of the layer for comparisons later
        const State& s(getDrawingState());
        const bool oldOpacity = isOpaque(s);
+1 −0
Original line number Diff line number Diff line
@@ -510,6 +510,7 @@ private:
    std::list<std::shared_ptr<SyncPoint>> mRemoteSyncPoints;

    uint64_t getHeadFrameNumber() const;
    bool headFenceHasSignaled() const;

    // Returns false if the relevant frame has already been latched
    bool addSyncPoint(const std::shared_ptr<SyncPoint>& point);