From 06e2e9cf4c3fe1eaac3271c9a346d5cc7fe5c3a8 Mon Sep 17 00:00:00 2001 From: Chris Craik Date: Wed, 31 Aug 2016 17:32:46 -0700 Subject: [PATCH] Wait on frame work fences when frames are dropped bug:30895941 Prevents a race where frame work could interleave between frames, causing SurfaceView position updates to be delivered out of order. Change-Id: I01e4cc557b69dcf33e877a0e16c0d115ec95e4cc --- libs/hwui/renderthread/CanvasContext.cpp | 3 +++ libs/hwui/renderthread/CanvasContext.h | 4 ++-- libs/hwui/renderthread/DrawFrameTask.cpp | 3 +++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp index dcaec428449c3..70b9a436dee26 100644 --- a/libs/hwui/renderthread/CanvasContext.cpp +++ b/libs/hwui/renderthread/CanvasContext.cpp @@ -633,6 +633,9 @@ void CanvasContext::prepareAndDraw(RenderNode* node) { prepareTree(info, frameInfo, systemTime(CLOCK_MONOTONIC), node); if (info.out.canDrawThisFrame) { draw(); + } else { + // wait on fences so tasks don't overlap next frame + waitOnFences(); } } diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h index 3eef29b24473b..e1821751b57fe 100644 --- a/libs/hwui/renderthread/CanvasContext.h +++ b/libs/hwui/renderthread/CanvasContext.h @@ -168,6 +168,8 @@ public: ANDROID_API int64_t getFrameNumber(); + void waitOnFences(); + private: friend class RegisterFrameCallbackTask; // TODO: Replace with something better for layer & other GL object @@ -178,8 +180,6 @@ private: void freePrefetchedLayers(TreeObserver* observer); - void waitOnFences(); - bool isSwapChainStuffed(); EGLint mLastFrameWidth = 0; diff --git a/libs/hwui/renderthread/DrawFrameTask.cpp b/libs/hwui/renderthread/DrawFrameTask.cpp index c9c07b3df292c..e3b6dc6fd9fee 100644 --- a/libs/hwui/renderthread/DrawFrameTask.cpp +++ b/libs/hwui/renderthread/DrawFrameTask.cpp @@ -104,6 +104,9 @@ void DrawFrameTask::run() { if (CC_LIKELY(canDrawThisFrame)) { context->draw(); + } else { + // wait on fences so tasks don't overlap next frame + context->waitOnFences(); } if (!canUnblockUiThread) {