Add GPU draw stats to gfxinfo and GraphicsStatsService
Test: ran dumpsys with gfxinfo and graphicsstats
Change-Id: Id9950de87dc4343c6878baa6a6dd42fbc8aeddef
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index d19351b..88a0c6e 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -147,6 +147,7 @@
mNativeSurface = new ReliableSurface{std::move(surface)};
// TODO: Fix error handling & re-shorten timeout
mNativeSurface->setDequeueTimeout(4000_ms);
+ mNativeSurface->enableFrameTimestamps(true);
} else {
mNativeSurface = nullptr;
}
@@ -294,6 +295,7 @@
// just keep using the previous frame's structure instead
if (!wasSkipped(mCurrentFrameInfo)) {
mCurrentFrameInfo = mJankTracker.startFrame();
+ mLast4FrameInfos.next().first = mCurrentFrameInfo;
}
mCurrentFrameInfo->importUiThreadInfo(uiFrameInfo);
mCurrentFrameInfo->set(FrameInfoIndex::SyncQueued) = syncQueued;
@@ -445,7 +447,7 @@
mContentDrawBounds, mOpaque, mLightInfo, mRenderNodes,
&(profiler()));
- int64_t frameCompleteNr = mFrameCompleteCallbacks.size() ? getFrameNumber() : -1;
+ int64_t frameCompleteNr = getFrameNumber();
waitOnFences();
@@ -500,11 +502,13 @@
}
mCurrentFrameInfo->set(FrameInfoIndex::DequeueBufferDuration) = swap.dequeueDuration;
mCurrentFrameInfo->set(FrameInfoIndex::QueueBufferDuration) = swap.queueDuration;
+ mLast4FrameInfos[-1].second = frameCompleteNr;
mHaveNewSurface = false;
mFrameNumber = -1;
} else {
mCurrentFrameInfo->set(FrameInfoIndex::DequeueBufferDuration) = 0;
mCurrentFrameInfo->set(FrameInfoIndex::QueueBufferDuration) = 0;
+ mLast4FrameInfos[-1].second = -1;
}
// TODO: Use a fence for real completion?
@@ -537,6 +541,19 @@
mFrameMetricsReporter->reportFrameMetrics(mCurrentFrameInfo->data());
}
+ if (mLast4FrameInfos.size() == mLast4FrameInfos.capacity()) {
+ // By looking 4 frames back, we guarantee all SF stats are available. There are at
+ // most 3 buffers in BufferQueue. Surface object keeps stats for the last 8 frames.
+ FrameInfo* forthBehind = mLast4FrameInfos.front().first;
+ int64_t composedFrameId = mLast4FrameInfos.front().second;
+ nsecs_t acquireTime = -1;
+ mNativeSurface->getFrameTimestamps(composedFrameId, nullptr, &acquireTime, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr, nullptr);
+ // Ignore default -1, NATIVE_WINDOW_TIMESTAMP_INVALID and NATIVE_WINDOW_TIMESTAMP_PENDING
+ forthBehind->set(FrameInfoIndex::GpuCompleted) = acquireTime > 0 ? acquireTime : -1;
+ mJankTracker.finishGpuDraw(*forthBehind);
+ }
+
GpuMemoryTracker::onFrameCompleted();
}
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index f9b9310..8a76d6b 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -29,6 +29,7 @@
#include "RenderNode.h"
#include "renderthread/RenderTask.h"
#include "renderthread/RenderThread.h"
+#include "utils/RingBuffer.h"
#include <SkBitmap.h>
#include <SkRect.h>
@@ -41,6 +42,7 @@
#include <future>
#include <set>
#include <string>
+#include <utility>
#include <vector>
namespace android {
@@ -260,6 +262,7 @@
std::vector<sp<RenderNode>> mRenderNodes;
FrameInfo* mCurrentFrameInfo = nullptr;
+ RingBuffer<std::pair<FrameInfo*, int64_t>, 4> mLast4FrameInfos;
std::string mName;
JankTracker mJankTracker;
FrameInfoVisualizer mProfiler;
diff --git a/libs/hwui/renderthread/ReliableSurface.h b/libs/hwui/renderthread/ReliableSurface.h
index 41fc35e..7f1a078 100644
--- a/libs/hwui/renderthread/ReliableSurface.h
+++ b/libs/hwui/renderthread/ReliableSurface.h
@@ -49,6 +49,21 @@
return ret;
}
+ status_t getFrameTimestamps(uint64_t frameNumber,
+ nsecs_t* outRequestedPresentTime, nsecs_t* outAcquireTime,
+ nsecs_t* outLatchTime, nsecs_t* outFirstRefreshStartTime,
+ nsecs_t* outLastRefreshStartTime, nsecs_t* outGlCompositionDoneTime,
+ nsecs_t* outDisplayPresentTime, nsecs_t* outDequeueReadyTime,
+ nsecs_t* outReleaseTime) {
+ return mSurface->getFrameTimestamps(frameNumber, outRequestedPresentTime, outAcquireTime,
+ outLatchTime, outFirstRefreshStartTime, outLastRefreshStartTime,
+ outGlCompositionDoneTime, outDisplayPresentTime, outDequeueReadyTime, outReleaseTime);
+ }
+
+ void enableFrameTimestamps(bool enable) {
+ return mSurface->enableFrameTimestamps(enable);
+ }
+
private:
const sp<Surface> mSurface;