summaryrefslogtreecommitdiff
path: root/libs/hwui/renderthread/CanvasContext.cpp
diff options
context:
space:
mode:
authorJohn Reck <jreck@google.com>2016-07-07 16:40:20 +0000
committerandroid-build-merger <android-build-merger@google.com>2016-07-07 16:40:20 +0000
commite7f27fbf93ad0c26dfc6142ff1fde4a70b94aa23 (patch)
tree3d49666861cf49304da8a0cc7404d65dee9fc27f /libs/hwui/renderthread/CanvasContext.cpp
parentc48903b7e9ab79a18b71c1f937a4e31fe088307c (diff)
parent63543364933f51d69475b984adf4d6fa74fff041 (diff)
Merge \\"Consider queue & dequeue times for should draw\\" into nyc-mr1-dev am: 3a465e7a12
am: 6354336493 Change-Id: Idbe85f08c27cc6f9433badd886a1fe7d9ba73c4f
Diffstat (limited to 'libs/hwui/renderthread/CanvasContext.cpp')
-rw-r--r--libs/hwui/renderthread/CanvasContext.cpp59
1 files changed, 50 insertions, 9 deletions
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 0a48a0c0bc68..27a15e0305db 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -197,6 +197,45 @@ static bool wasSkipped(FrameInfo* info) {
return info && ((*info)[FrameInfoIndex::Flags] & FrameInfoFlags::SkippedFrame);
}
+bool CanvasContext::isSwapChainStuffed() {
+ if (mSwapHistory.size() != mSwapHistory.capacity()) {
+ // We want at least 3 frames of history before attempting to
+ // guess if the queue is stuffed
+ return false;
+ }
+ nsecs_t frameInterval = mRenderThread.timeLord().frameIntervalNanos();
+ auto& swapA = mSwapHistory[0];
+
+ // Was there a happy queue & dequeue time? If so, don't
+ // consider it stuffed
+ if (swapA.dequeueDuration < 3_ms
+ && swapA.queueDuration < 3_ms) {
+ return false;
+ }
+
+ for (size_t i = 1; i < mSwapHistory.size(); i++) {
+ auto& swapB = mSwapHistory[i];
+
+ // If there's a frameInterval gap we effectively already dropped a frame,
+ // so consider the queue healthy.
+ if (swapA.swapCompletedTime - swapB.swapCompletedTime > frameInterval) {
+ return false;
+ }
+
+ // Was there a happy queue & dequeue time? If so, don't
+ // consider it stuffed
+ if (swapB.dequeueDuration < 3_ms
+ && swapB.queueDuration < 3_ms) {
+ return false;
+ }
+
+ swapA = swapB;
+ }
+
+ // All signs point to a stuffed swap chain
+ return true;
+}
+
void CanvasContext::prepareTree(TreeInfo& info, int64_t* uiFrameInfo,
int64_t syncQueued, RenderNode* target) {
mRenderThread.removeFrameCallback(this);
@@ -242,7 +281,12 @@ void CanvasContext::prepareTree(TreeInfo& info, int64_t* uiFrameInfo,
if (CC_LIKELY(mSwapHistory.size() && !Properties::forceDrawFrame)) {
nsecs_t latestVsync = mRenderThread.timeLord().latestVsync();
- const SwapHistory& lastSwap = mSwapHistory.back();
+ SwapHistory& lastSwap = mSwapHistory.back();
+ int durationUs;
+ mNativeSurface->query(NATIVE_WINDOW_LAST_DEQUEUE_DURATION, &durationUs);
+ lastSwap.dequeueDuration = us2ns(durationUs);
+ mNativeSurface->query(NATIVE_WINDOW_LAST_QUEUE_DURATION, &durationUs);
+ lastSwap.queueDuration = us2ns(durationUs);
nsecs_t vsyncDelta = std::abs(lastSwap.vsyncTime - latestVsync);
// The slight fudge-factor is to deal with cases where
// the vsync was estimated due to being slow handling the signal.
@@ -252,15 +296,12 @@ void CanvasContext::prepareTree(TreeInfo& info, int64_t* uiFrameInfo,
// Already drew for this vsync pulse, UI draw request missed
// the deadline for RT animations
info.out.canDrawThisFrame = false;
- } else if (lastSwap.swapTime < latestVsync) {
+ } else if (vsyncDelta >= mRenderThread.timeLord().frameIntervalNanos()) {
+ // It's been at least an entire frame interval, assume
+ // the buffer queue is fine
info.out.canDrawThisFrame = true;
} else {
- // We're maybe behind? Find out for sure
- int runningBehind = 0;
- // TODO: Have this method be on Surface, too, not just ANativeWindow...
- ANativeWindow* window = mNativeSurface.get();
- window->query(window, NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND, &runningBehind);
- info.out.canDrawThisFrame = !runningBehind;
+ info.out.canDrawThisFrame = !isSwapChainStuffed();
}
} else {
info.out.canDrawThisFrame = true;
@@ -515,7 +556,7 @@ void CanvasContext::draw() {
}
SwapHistory& swap = mSwapHistory.next();
swap.damage = screenDirty;
- swap.swapTime = systemTime(CLOCK_MONOTONIC);
+ swap.swapCompletedTime = systemTime(CLOCK_MONOTONIC);
swap.vsyncTime = mRenderThread.timeLord().latestVsync();
mHaveNewSurface = false;
mFrameNumber = -1;