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

Commit 6ba5125b authored by Tang Lee's avatar Tang Lee
Browse files

Enlarge mLast4FrameMetricsInfos from 4 to 6 entries

As a result of tuning SurfaceFlinger durations
(debug.sf.late.sf.duration etc.), the ring buffer of the frame metrics
infos is sometimes too small, and already popped the frame's info when
its GPU complete is triggered and doing onSurfaceStatsAvailable(), so
finishFrame() is not called for this frame, which causes incorrect
jank judgement on the next frame.

Increase the ring buffer size from 4 to 6 can avoid the issue.

Bug: 354618175
Test: no skipped frame in onSurfaceStatsAvailable
Flag: EXEMPT bugfix
Change-Id: I2865365213e16cfebe63b949aae332cea32d8927
parent bb0348ec
Loading
Loading
Loading
Loading
+12 −12
Original line number Diff line number Diff line
@@ -761,8 +761,8 @@ void CanvasContext::draw(bool solelyTextureViewUpdates) {
        if (mExpectSurfaceStats) {
            reportMetricsWithPresentTime();
            {  // acquire lock
                std::lock_guard lock(mLast4FrameMetricsInfosMutex);
                FrameMetricsInfo& next = mLast4FrameMetricsInfos.next();
                std::lock_guard lock(mLastFrameMetricsInfosMutex);
                FrameMetricsInfo& next = mLastFrameMetricsInfos.next();
                next.frameInfo = mCurrentFrameInfo;
                next.frameNumber = frameCompleteNr;
                next.surfaceId = mSurfaceControlGenerationId;
@@ -816,12 +816,12 @@ void CanvasContext::reportMetricsWithPresentTime() {
    int32_t surfaceControlId;

    {  // acquire lock
        std::scoped_lock lock(mLast4FrameMetricsInfosMutex);
        if (mLast4FrameMetricsInfos.size() != mLast4FrameMetricsInfos.capacity()) {
        std::scoped_lock lock(mLastFrameMetricsInfosMutex);
        if (mLastFrameMetricsInfos.size() != mLastFrameMetricsInfos.capacity()) {
            // Not enough frames yet
            return;
        }
        auto frameMetricsInfo = mLast4FrameMetricsInfos.front();
        auto frameMetricsInfo = mLastFrameMetricsInfos.front();
        forthBehind = frameMetricsInfo.frameInfo;
        frameNumber = frameMetricsInfo.frameNumber;
        surfaceControlId = frameMetricsInfo.surfaceId;
@@ -869,12 +869,12 @@ void CanvasContext::removeFrameMetricsObserver(FrameMetricsObserver* observer) {
    }
}

FrameInfo* CanvasContext::getFrameInfoFromLast4(uint64_t frameNumber, uint32_t surfaceControlId) {
    std::scoped_lock lock(mLast4FrameMetricsInfosMutex);
    for (size_t i = 0; i < mLast4FrameMetricsInfos.size(); i++) {
        if (mLast4FrameMetricsInfos[i].frameNumber == frameNumber &&
            mLast4FrameMetricsInfos[i].surfaceId == surfaceControlId) {
            return mLast4FrameMetricsInfos[i].frameInfo;
FrameInfo* CanvasContext::getFrameInfoFromLastFew(uint64_t frameNumber, uint32_t surfaceControlId) {
    std::scoped_lock lock(mLastFrameMetricsInfosMutex);
    for (size_t i = 0; i < mLastFrameMetricsInfos.size(); i++) {
        if (mLastFrameMetricsInfos[i].frameNumber == frameNumber &&
            mLastFrameMetricsInfos[i].surfaceId == surfaceControlId) {
            return mLastFrameMetricsInfos[i].frameInfo;
        }
    }

@@ -894,7 +894,7 @@ void CanvasContext::onSurfaceStatsAvailable(void* context, int32_t surfaceContro
    }
    uint64_t frameNumber = functions.getFrameNumberFunc(stats);

    FrameInfo* frameInfo = instance->getFrameInfoFromLast4(frameNumber, surfaceControlId);
    FrameInfo* frameInfo = instance->getFrameInfoFromLastFew(frameNumber, surfaceControlId);

    if (frameInfo != nullptr) {
        std::scoped_lock lock(instance->mFrameInfoMutex);
+5 −5
Original line number Diff line number Diff line
@@ -260,7 +260,7 @@ private:
    void finishFrame(FrameInfo* frameInfo);

    /**
     * Invoke 'reportFrameMetrics' on the last frame stored in 'mLast4FrameInfos'.
     * Invoke 'reportFrameMetrics' on the last frame stored in 'mLastFrameInfos'.
     * Populate the 'presentTime' field before calling.
     */
    void reportMetricsWithPresentTime();
@@ -271,7 +271,7 @@ private:
        int32_t surfaceId;
    };

    FrameInfo* getFrameInfoFromLast4(uint64_t frameNumber, uint32_t surfaceControlId);
    FrameInfo* getFrameInfoFromLastFew(uint64_t frameNumber, uint32_t surfaceControlId);

    Frame getFrame();

@@ -336,9 +336,9 @@ private:

    // List of data of frames that are awaiting GPU completion reporting. Used to compute frame
    // metrics and determine whether or not to report the metrics.
    RingBuffer<FrameMetricsInfo, 4> mLast4FrameMetricsInfos
            GUARDED_BY(mLast4FrameMetricsInfosMutex);
    std::mutex mLast4FrameMetricsInfosMutex;
    RingBuffer<FrameMetricsInfo, 6> mLastFrameMetricsInfos
            GUARDED_BY(mLastFrameMetricsInfosMutex);
    std::mutex mLastFrameMetricsInfosMutex;

    std::string mName;
    JankTracker mJankTracker;