From ebdbead46c8dfd270481fcc714e798fc863cf9c5 Mon Sep 17 00:00:00 2001 From: Ben Widawsky Date: Thu, 24 Oct 2024 11:47:50 -0700 Subject: SF: Implement FrameStats directly in FrameTimeline Bug: 241394120 Test: builds, atest CtsUiAutomationTestCases:android.app.uiautomation.cts.UiAutomationTest#testWindowContentFrameStats$ Flag: com.android.graphics.surfaceflinger.flags.deprecate_frame_tracker Change-Id: I3f12d504e821a6ba15a26604eb56f317c9d59a18 --- .../surfaceflinger/FrameTimeline/FrameTimeline.cpp | 29 ++++++++++++++++++++++ .../surfaceflinger/FrameTimeline/FrameTimeline.h | 15 ++++++++--- 2 files changed, 41 insertions(+), 3 deletions(-) (limited to 'services/surfaceflinger/FrameTimeline') diff --git a/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp b/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp index 47b811b721..c13e444a99 100644 --- a/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp +++ b/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp @@ -378,6 +378,11 @@ void SurfaceFrame::setAcquireFenceTime(nsecs_t acquireFenceTime) { } } +void SurfaceFrame::setDesiredPresentTime(nsecs_t desiredPresentTime) { + std::scoped_lock lock(mMutex); + mActuals.desiredPresentTime = desiredPresentTime; +} + void SurfaceFrame::setDropTime(nsecs_t dropTime) { std::scoped_lock lock(mMutex); mDropTime = dropTime; @@ -1456,6 +1461,30 @@ float FrameTimeline::computeFps(const std::unordered_set& layerIds) { static_cast(totalPresentToPresentWalls); } +void FrameTimeline::generateFrameStats(int32_t layer, size_t count, FrameStats* outStats) const { + std::scoped_lock lock(mMutex); + + // TODO: Include FPS calculation here + for (auto displayFrame : mDisplayFrames) { + if (!count--) { + break; + } + + if (displayFrame->getActuals().presentTime <= 0) { + continue; + } + + for (const auto& surfaceFrame : displayFrame->getSurfaceFrames()) { + if (surfaceFrame->getLayerId() == layer) { + outStats->actualPresentTimesNano.push_back(surfaceFrame->getActuals().presentTime); + outStats->desiredPresentTimesNano.push_back( + surfaceFrame->getActuals().desiredPresentTime); + outStats->frameReadyTimesNano.push_back(surfaceFrame->getActuals().endTime); + } + } + } +} + std::optional FrameTimeline::getFirstSignalFenceIndex() const { for (size_t i = 0; i < mPendingPresentFences.size(); i++) { const auto& [fence, _] = mPendingPresentFences[i]; diff --git a/services/surfaceflinger/FrameTimeline/FrameTimeline.h b/services/surfaceflinger/FrameTimeline/FrameTimeline.h index cffb61ee10..6cda309440 100644 --- a/services/surfaceflinger/FrameTimeline/FrameTimeline.h +++ b/services/surfaceflinger/FrameTimeline/FrameTimeline.h @@ -85,16 +85,20 @@ enum class FrameStartMetadata : int8_t { */ struct TimelineItem { TimelineItem(const nsecs_t startTime = 0, const nsecs_t endTime = 0, - const nsecs_t presentTime = 0) - : startTime(startTime), endTime(endTime), presentTime(presentTime) {} + const nsecs_t presentTime = 0, const nsecs_t desiredPresentTime = 0) + : startTime(startTime), + endTime(endTime), + presentTime(presentTime), + desiredPresentTime(desiredPresentTime) {} nsecs_t startTime; nsecs_t endTime; nsecs_t presentTime; + nsecs_t desiredPresentTime; bool operator==(const TimelineItem& other) const { return startTime == other.startTime && endTime == other.endTime && - presentTime == other.presentTime; + presentTime == other.presentTime && desiredPresentTime != other.desiredPresentTime; } bool operator!=(const TimelineItem& other) const { return !(*this == other); } @@ -183,6 +187,7 @@ public: void setActualStartTime(nsecs_t actualStartTime); void setActualQueueTime(nsecs_t actualQueueTime); void setAcquireFenceTime(nsecs_t acquireFenceTime); + void setDesiredPresentTime(nsecs_t desiredPresentTime); void setDropTime(nsecs_t dropTime); void setPresentState(PresentState presentState, nsecs_t lastLatchTime = 0); void setRenderRate(Fps renderRate); @@ -341,6 +346,9 @@ public: // containing at least one layer ID. virtual float computeFps(const std::unordered_set& layerIds) = 0; + // Supports the legacy FrameStats interface + virtual void generateFrameStats(int32_t layer, size_t count, FrameStats* outStats) const = 0; + // Restores the max number of display frames to default. Called by SF backdoor. virtual void reset() = 0; }; @@ -501,6 +509,7 @@ public: void parseArgs(const Vector& args, std::string& result) override; void setMaxDisplayFrames(uint32_t size) override; float computeFps(const std::unordered_set& layerIds) override; + void generateFrameStats(int32_t layer, size_t count, FrameStats* outStats) const override; void reset() override; // Sets up the perfetto tracing backend and data source. -- cgit v1.2.3-59-g8ed1b