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

Commit faf3ded9 authored by Yiwei Zhang's avatar Yiwei Zhang
Browse files

SurfaceFlinger TimeStats Metrics

Add timestats metrics for SurfaceFlinger. Keep track of global metrics
like total frames, missed frames, frames fellback to client
compositions, etc, as well as layer timing metrics like the delta
combination of postTime, desiredPresentTime, acqureTime, latchTime,
presentTime, etc. This metric is aimed at GMScore.

Test: dumpsys SurfaceFlinger --timestats [go/sf-timestats for more args]
Bug: b/70388650
Change-Id: I6e4545aef62f7893020533a4e7521541ea453ecd
parent 196b3d21
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ cc_defaults {
        "libpdx_default_transport",
        "libprotobuf-cpp-lite",
        "libsync",
        "libtimestats_proto",
        "libui",
        "libutils",
        "libvulkan",
@@ -128,6 +129,7 @@ filegroup {
        "SurfaceFlinger.cpp",
        "SurfaceInterceptor.cpp",
        "SurfaceTracing.cpp",
        "TimeStats/TimeStats.cpp",
        "Transform.cpp",
    ],
}
@@ -176,6 +178,7 @@ cc_binary {
        "liblayers_proto",
        "liblog",
        "libsurfaceflinger",
        "libtimestats_proto",
        "libutils",
    ],
    static_libs: [
@@ -217,5 +220,6 @@ cc_library_shared {

subdirs = [
    "layerproto",
    "TimeStats/timestatsproto",
    "tests",
]
+15 −2
Original line number Diff line number Diff line
@@ -311,6 +311,9 @@ bool BufferLayer::onPostComposition(const std::shared_ptr<FenceTime>& glDoneFenc
    nsecs_t desiredPresentTime = mConsumer->getTimestamp();
    mFrameTracker.setDesiredPresentTime(desiredPresentTime);

    const std::string layerName(getName().c_str());
    mTimeStats.setDesiredTime(layerName, mCurrentFrameNumber, desiredPresentTime);

    std::shared_ptr<FenceTime> frameReadyFence = mConsumer->getCurrentFenceTime();
    if (frameReadyFence->isValid()) {
        mFrameTracker.setFrameReadyFence(std::move(frameReadyFence));
@@ -321,12 +324,15 @@ bool BufferLayer::onPostComposition(const std::shared_ptr<FenceTime>& glDoneFenc
    }

    if (presentFence->isValid()) {
        mTimeStats.setPresentFence(layerName, mCurrentFrameNumber, presentFence);
        mFrameTracker.setActualPresentFence(std::shared_ptr<FenceTime>(presentFence));
    } else {
        // The HWC doesn't support present fences, so use the refresh
        // timestamp instead.
        mFrameTracker.setActualPresentTime(
                mFlinger->getHwComposer().getRefreshTimestamp(HWC_DISPLAY_PRIMARY));
        const nsecs_t actualPresentTime =
                mFlinger->getHwComposer().getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
        mTimeStats.setPresentTime(layerName, mCurrentFrameNumber, actualPresentTime);
        mFrameTracker.setActualPresentTime(actualPresentTime);
    }

    mFrameTracker.advanceFrame();
@@ -433,6 +439,7 @@ Region BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime
        // and return early
        if (queuedBuffer) {
            Mutex::Autolock lock(mQueueItemLock);
            mTimeStats.removeTimeRecord(getName().c_str(), mQueueItems[0].mFrameNumber);
            mQueueItems.removeAt(0);
            android_atomic_dec(&mQueuedFrames);
        }
@@ -446,6 +453,7 @@ Region BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime
            Mutex::Autolock lock(mQueueItemLock);
            mQueueItems.clear();
            android_atomic_and(0, &mQueuedFrames);
            mTimeStats.clearLayerRecord(getName().c_str());
        }

        // Once we have hit this state, the shadow queue may no longer
@@ -466,10 +474,15 @@ Region BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime
        // Remove any stale buffers that have been dropped during
        // updateTexImage
        while (mQueueItems[0].mFrameNumber != currentFrameNumber) {
            mTimeStats.removeTimeRecord(getName().c_str(), mQueueItems[0].mFrameNumber);
            mQueueItems.removeAt(0);
            android_atomic_dec(&mQueuedFrames);
        }

        const std::string layerName(getName().c_str());
        mTimeStats.setAcquireFence(layerName, currentFrameNumber, mQueueItems[0].mFenceTime);
        mTimeStats.setLatchTime(layerName, currentFrameNumber, latchTime);

        mQueueItems.removeAt(0);
    }

+6 −0
Original line number Diff line number Diff line
@@ -1528,10 +1528,16 @@ void Layer::dumpFrameEvents(String8& result) {
void Layer::onDisconnect() {
    Mutex::Autolock lock(mFrameEventHistoryMutex);
    mFrameEventHistory.onDisconnect();
    mTimeStats.onDisconnect(getName().c_str());
}

void Layer::addAndGetFrameTimestamps(const NewFrameEventsEntry* newTimestamps,
                                     FrameEventHistoryDelta* outDelta) {
    if (newTimestamps) {
        mTimeStats.setPostTime(getName().c_str(), newTimestamps->frameNumber,
                               newTimestamps->postedTime);
    }

    Mutex::Autolock lock(mFrameEventHistoryMutex);
    if (newTimestamps) {
        // If there are any unsignaled fences in the aquire timeline at this
+4 −1
Original line number Diff line number Diff line
@@ -38,11 +38,12 @@

#include "Client.h"
#include "FrameTracker.h"
#include "LayerBE.h"
#include "LayerVector.h"
#include "MonitoredProducer.h"
#include "SurfaceFlinger.h"
#include "TimeStats/TimeStats.h"
#include "Transform.h"
#include "LayerBE.h"

#include <layerproto/LayerProtoHeader.h>
#include "DisplayHardware/HWComposer.h"
@@ -682,6 +683,8 @@ protected:
    FenceTimeline mAcquireTimeline;
    FenceTimeline mReleaseTimeline;

    TimeStats& mTimeStats = TimeStats::getInstance();

    // main thread
    int mActiveBufferSlot;
    sp<GraphicBuffer> mActiveBuffer;
+21 −7
Original line number Diff line number Diff line
@@ -1470,9 +1470,13 @@ void SurfaceFlinger::onMessageReceived(int32_t what) {
                            Fence::SIGNAL_TIME_PENDING);
            ATRACE_INT("FrameMissed", static_cast<int>(frameMissed));
            if (mPropagateBackpressure && frameMissed) {
                mTimeStats.incrementMissedFrames(true);
                signalLayerUpdate();
                break;
            }
            if (frameMissed) {
                mTimeStats.incrementMissedFrames(false);
            }

            // Now that we're going to make it to the handleMessageTransaction()
            // call below it's safe to call updateVrFlinger(), which will
@@ -1771,6 +1775,11 @@ void SurfaceFlinger::postComposition(nsecs_t refreshStartTime)
        mAnimFrameTracker.advanceFrame();
    }

    mTimeStats.incrementTotalFrames();
    if (mHadClientComposition) {
        mTimeStats.incrementClientCompositionFrames();
    }

    if (getBE().mHwc->isConnected(HWC_DISPLAY_PRIMARY) &&
            hw->getPowerMode() == HWC_POWER_MODE_OFF) {
        return;
@@ -3825,12 +3834,6 @@ status_t SurfaceFlinger::doDump(int fd, const Vector<String16>& args, bool asPro
        size_t index = 0;
        size_t numArgs = args.size();

        if (asProto) {
            LayersProto layersProto = dumpProtoInfo(LayerVector::StateSet::Current);
            result.append(layersProto.SerializeAsString().c_str(), layersProto.ByteSize());
            dumpAll = false;
        }

        if (numArgs) {
            if ((index < numArgs) &&
                    (args[index] == String16("--list"))) {
@@ -3914,11 +3917,22 @@ status_t SurfaceFlinger::doDump(int fd, const Vector<String16>& args, bool asPro
                dumpDisplayIdentificationData(result);
                dumpAll = false;
            }

            if ((index < numArgs) && (args[index] == String16("--timestats"))) {
                index++;
                mTimeStats.parseArgs(asProto, args, index, result);
                dumpAll = false;
            }
        }

        if (dumpAll) {
            if (asProto) {
                LayersProto layersProto = dumpProtoInfo(LayerVector::StateSet::Current);
                result.append(layersProto.SerializeAsString().c_str(), layersProto.ByteSize());
            } else {
                dumpAllLocked(args, index, result);
            }
        }

        if (locked) {
            mStateLock.unlock();
Loading