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

Commit a8955dd6 authored by Dominik Laskowski's avatar Dominik Laskowski
Browse files

SF: Factor out expected present time computation

Compute expected present time once and pass it to traversed layers
instead of calling back into SF for each layer. This will simplify
synchronization for per-display refresh.

Also, recompute on Binder transaction, since the cached value computed
on invalidate may be stale.

Bug: 130554049
Bug: 123715322
Test: go/wm-smoke
Change-Id: I7153a728360e789dc4f97d2c39c4bdaa14183624
parent 65495212
Loading
Loading
Loading
Loading
+11 −10
Original line number Diff line number Diff line
@@ -395,7 +395,8 @@ bool BufferLayer::onPostComposition(const std::optional<DisplayId>& displayId,
    return true;
}

bool BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime) {
bool BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime,
                              nsecs_t expectedPresentTime) {
    ATRACE_CALL();

    bool refreshRequired = latchSidebandStream(recomputeVisibleRegions);
@@ -430,12 +431,12 @@ bool BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime)
    const bool oldOpacity = isOpaque(s);
    sp<GraphicBuffer> oldBuffer = mActiveBuffer;

    if (!allTransactionsSignaled()) {
    if (!allTransactionsSignaled(expectedPresentTime)) {
        mFlinger->setTransactionFlags(eTraversalNeeded);
        return false;
    }

    status_t err = updateTexImage(recomputeVisibleRegions, latchTime);
    status_t err = updateTexImage(recomputeVisibleRegions, latchTime, expectedPresentTime);
    if (err != NO_ERROR) {
        return false;
    }
@@ -540,10 +541,10 @@ bool BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime)
}

// transaction
void BufferLayer::notifyAvailableFrames() {
    const auto headFrameNumber = getHeadFrameNumber();
void BufferLayer::notifyAvailableFrames(nsecs_t expectedPresentTime) {
    const auto headFrameNumber = getHeadFrameNumber(expectedPresentTime);
    const bool headFenceSignaled = fenceHasSignaled();
    const bool presentTimeIsCurrent = framePresentTimeIsCurrent();
    const bool presentTimeIsCurrent = framePresentTimeIsCurrent(expectedPresentTime);
    Mutex::Autolock lock(mLocalSyncPointMutex);
    for (auto& point : mLocalSyncPoints) {
        if (headFrameNumber >= point->getFrameNumber() && headFenceSignaled &&
@@ -591,8 +592,8 @@ bool BufferLayer::latchUnsignaledBuffers() {
}

// h/w composer set-up
bool BufferLayer::allTransactionsSignaled() {
    auto headFrameNumber = getHeadFrameNumber();
bool BufferLayer::allTransactionsSignaled(nsecs_t expectedPresentTime) {
    const auto headFrameNumber = getHeadFrameNumber(expectedPresentTime);
    bool matchingFramesFound = false;
    bool allTransactionsApplied = true;
    Mutex::Autolock lock(mLocalSyncPointMutex);
@@ -658,9 +659,9 @@ bool BufferLayer::needsFiltering(const sp<const DisplayDevice>& displayDevice) c
            sourceCrop.getWidth() != displayFrame.getWidth();
}

uint64_t BufferLayer::getHeadFrameNumber() const {
uint64_t BufferLayer::getHeadFrameNumber(nsecs_t expectedPresentTime) const {
    if (hasFrameUpdate()) {
        return getFrameNumber();
        return getFrameNumber(expectedPresentTime);
    } else {
        return mCurrentFrameNumber;
    }
+9 −7
Original line number Diff line number Diff line
@@ -96,11 +96,12 @@ public:
    // the visible regions need to be recomputed (this is a fairly heavy
    // operation, so this should be set only if needed). Typically this is used
    // to figure out if the content or size of a surface has changed.
    bool latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime) override;
    bool latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime,
                     nsecs_t expectedPresentTime) override;

    bool isBufferLatched() const override { return mRefreshPending; }

    void notifyAvailableFrames() override;
    void notifyAvailableFrames(nsecs_t expectedPresentTime) override;

    bool hasReadyFrame() const override;

@@ -114,7 +115,7 @@ public:
    // -----------------------------------------------------------------------
private:
    virtual bool fenceHasSignaled() const = 0;
    virtual bool framePresentTimeIsCurrent() const = 0;
    virtual bool framePresentTimeIsCurrent(nsecs_t expectedPresentTime) const = 0;

    virtual nsecs_t getDesiredPresentTime() = 0;
    virtual std::shared_ptr<FenceTime> getCurrentFenceTime() const = 0;
@@ -129,7 +130,7 @@ private:
    virtual int getDrawingApi() const = 0;
    virtual PixelFormat getPixelFormat() const = 0;

    virtual uint64_t getFrameNumber() const = 0;
    virtual uint64_t getFrameNumber(nsecs_t expectedPresentTime) const = 0;

    virtual bool getAutoRefresh() const = 0;
    virtual bool getSidebandStreamChanged() const = 0;
@@ -142,7 +143,8 @@ private:
    virtual void setFilteringEnabled(bool enabled) = 0;

    virtual status_t bindTextureImage() = 0;
    virtual status_t updateTexImage(bool& recomputeVisibleRegions, nsecs_t latchTime) = 0;
    virtual status_t updateTexImage(bool& recomputeVisibleRegions, nsecs_t latchTime,
                                    nsecs_t expectedPresentTime) = 0;

    virtual status_t updateActiveBuffer() = 0;
    virtual status_t updateFrameNumber(nsecs_t latchTime) = 0;
@@ -156,7 +158,7 @@ protected:
    // Check all of the local sync points to ensure that all transactions
    // which need to have been applied prior to the frame which is about to
    // be latched have signaled
    bool allTransactionsSignaled();
    bool allTransactionsSignaled(nsecs_t expectedPresentTime);

    static bool getOpacityForFormat(uint32_t format);

@@ -175,7 +177,7 @@ private:
    // Returns true if this layer requires filtering
    bool needsFiltering(const sp<const DisplayDevice>& displayDevice) const;

    uint64_t getHeadFrameNumber() const;
    uint64_t getHeadFrameNumber(nsecs_t expectedPresentTime) const;

    uint32_t mCurrentScalingMode{NATIVE_WINDOW_SCALING_MODE_FREEZE};

+6 −9
Original line number Diff line number Diff line
@@ -137,13 +137,13 @@ bool BufferQueueLayer::fenceHasSignaled() const {
    return mQueueItems[0].mFenceTime->getSignalTime() != Fence::SIGNAL_TIME_PENDING;
}

bool BufferQueueLayer::framePresentTimeIsCurrent() const {
bool BufferQueueLayer::framePresentTimeIsCurrent(nsecs_t expectedPresentTime) const {
    if (!hasFrameUpdate() || isRemovedFromCurrentState()) {
        return true;
    }

    Mutex::Autolock lock(mQueueItemLock);
    return mQueueItems[0].mTimestamp <= mFlinger->getExpectedPresentTime();
    return mQueueItems[0].mTimestamp <= expectedPresentTime;
}

nsecs_t BufferQueueLayer::getDesiredPresentTime() {
@@ -196,13 +196,11 @@ PixelFormat BufferQueueLayer::getPixelFormat() const {
    return mFormat;
}

uint64_t BufferQueueLayer::getFrameNumber() const {
uint64_t BufferQueueLayer::getFrameNumber(nsecs_t expectedPresentTime) const {
    Mutex::Autolock lock(mQueueItemLock);
    uint64_t frameNumber = mQueueItems[0].mFrameNumber;

    // The head of the queue will be dropped if there are signaled and timely frames behind it
    nsecs_t expectedPresentTime = mFlinger->getExpectedPresentTime();

    if (isRemovedFromCurrentState()) {
        expectedPresentTime = 0;
    }
@@ -268,7 +266,8 @@ status_t BufferQueueLayer::bindTextureImage() {
    return mConsumer->bindTextureImage();
}

status_t BufferQueueLayer::updateTexImage(bool& recomputeVisibleRegions, nsecs_t latchTime) {
status_t BufferQueueLayer::updateTexImage(bool& recomputeVisibleRegions, nsecs_t latchTime,
                                          nsecs_t expectedPresentTime) {
    // This boolean is used to make sure that SurfaceFlinger's shadow copy
    // of the buffer queue isn't modified when the buffer queue is returning
    // BufferItem's that weren't actually queued. This can happen in shared
@@ -279,8 +278,6 @@ status_t BufferQueueLayer::updateTexImage(bool& recomputeVisibleRegions, nsecs_t
                    getProducerStickyTransform() != 0, mName.string(), mOverrideScalingMode,
                    getTransformToDisplayInverse(), mFreezeGeometryUpdates);

    nsecs_t expectedPresentTime = mFlinger->getExpectedPresentTime();

    if (isRemovedFromCurrentState()) {
        expectedPresentTime = 0;
    }
@@ -432,7 +429,7 @@ void BufferQueueLayer::setHwcLayerBuffer(const sp<const DisplayDevice>& display)
void BufferQueueLayer::fakeVsync() {
    mRefreshPending = false;
    bool ignored = false;
    latchBuffer(ignored, systemTime());
    latchBuffer(ignored, systemTime(), 0 /* expectedPresentTime */);
    usleep(16000);
    releasePendingBuffer(systemTime());
}
+4 −3
Original line number Diff line number Diff line
@@ -61,7 +61,7 @@ public:
    // -----------------------------------------------------------------------
public:
    bool fenceHasSignaled() const override;
    bool framePresentTimeIsCurrent() const override;
    bool framePresentTimeIsCurrent(nsecs_t expectedPresentTime) const override;

private:
    nsecs_t getDesiredPresentTime() override;
@@ -77,7 +77,7 @@ private:
    int getDrawingApi() const override;
    PixelFormat getPixelFormat() const override;

    uint64_t getFrameNumber() const override;
    uint64_t getFrameNumber(nsecs_t expectedPresentTime) const override;

    bool getAutoRefresh() const override;
    bool getSidebandStreamChanged() const override;
@@ -89,7 +89,8 @@ private:
    void setFilteringEnabled(bool enabled) override;

    status_t bindTextureImage() override;
    status_t updateTexImage(bool& recomputeVisibleRegions, nsecs_t latchTime) override;
    status_t updateTexImage(bool& recomputeVisibleRegions, nsecs_t latchTime,
                            nsecs_t expectedPresentTime) override;

    status_t updateActiveBuffer() override;
    status_t updateFrameNumber(nsecs_t latchTime) override;
+9 −8
Original line number Diff line number Diff line
@@ -216,7 +216,7 @@ bool BufferStateLayer::setBuffer(const sp<GraphicBuffer>& buffer, nsecs_t postTi
    mCurrentState.modified = true;
    setTransactionFlags(eTransactionNeeded);

    mFlinger->mTimeStats->setPostTime(getSequence(), getFrameNumber(), getName().c_str(), postTime);
    mFlinger->mTimeStats->setPostTime(getSequence(), mFrameNumber, getName().c_str(), postTime);
    mDesiredPresentTime = desiredPresentTime;

    if (mFlinger->mUseSmart90ForVideo) {
@@ -369,12 +369,12 @@ bool BufferStateLayer::fenceHasSignaled() const {
    return getDrawingState().acquireFence->getStatus() == Fence::Status::Signaled;
}

bool BufferStateLayer::framePresentTimeIsCurrent() const {
bool BufferStateLayer::framePresentTimeIsCurrent(nsecs_t expectedPresentTime) const {
    if (!hasFrameUpdate() || isRemovedFromCurrentState()) {
        return true;
    }

    return mDesiredPresentTime <= mFlinger->getExpectedPresentTime();
    return mDesiredPresentTime <= expectedPresentTime;
}

nsecs_t BufferStateLayer::getDesiredPresentTime() {
@@ -446,7 +446,7 @@ PixelFormat BufferStateLayer::getPixelFormat() const {
    return mActiveBuffer->format;
}

uint64_t BufferStateLayer::getFrameNumber() const {
uint64_t BufferStateLayer::getFrameNumber(nsecs_t /*expectedPresentTime*/) const {
    return mFrameNumber;
}

@@ -494,7 +494,8 @@ status_t BufferStateLayer::bindTextureImage() {
    return engine.bindExternalTextureBuffer(mTextureName, s.buffer, s.acquireFence);
}

status_t BufferStateLayer::updateTexImage(bool& /*recomputeVisibleRegions*/, nsecs_t latchTime) {
status_t BufferStateLayer::updateTexImage(bool& /*recomputeVisibleRegions*/, nsecs_t latchTime,
                                          nsecs_t /*expectedPresentTime*/) {
    const State& s(getDrawingState());

    if (!s.buffer) {
@@ -528,7 +529,7 @@ status_t BufferStateLayer::updateTexImage(bool& /*recomputeVisibleRegions*/, nse
        ALOGE("[%s] rejecting buffer: "
              "bufferWidth=%d, bufferHeight=%d, front.active.{w=%d, h=%d}",
              mName.string(), bufferWidth, bufferHeight, s.active.w, s.active.h);
        mFlinger->mTimeStats->removeTimeRecord(layerID, getFrameNumber());
        mFlinger->mTimeStats->removeTimeRecord(layerID, mFrameNumber);
        return BAD_VALUE;
    }

@@ -550,8 +551,8 @@ status_t BufferStateLayer::updateTexImage(bool& /*recomputeVisibleRegions*/, nse
        }
    }

    mFlinger->mTimeStats->setAcquireFence(layerID, getFrameNumber(), getCurrentFenceTime());
    mFlinger->mTimeStats->setLatchTime(layerID, getFrameNumber(), latchTime);
    mFlinger->mTimeStats->setAcquireFence(layerID, mFrameNumber, getCurrentFenceTime());
    mFlinger->mTimeStats->setLatchTime(layerID, mFrameNumber, latchTime);

    mCurrentStateModified = false;

Loading