diff options
| -rw-r--r-- | core/java/android/view/ThreadedRenderer.java | 8 | ||||
| -rw-r--r-- | libs/hwui/renderthread/CanvasContext.cpp | 5 | ||||
| -rw-r--r-- | libs/hwui/renderthread/CanvasContext.h | 2 | ||||
| -rw-r--r-- | libs/hwui/renderthread/DrawFrameTask.cpp | 6 | ||||
| -rw-r--r-- | libs/hwui/renderthread/DrawFrameTask.h | 1 |
5 files changed, 22 insertions, 0 deletions
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java index 00a8884..5579c13 100644 --- a/core/java/android/view/ThreadedRenderer.java +++ b/core/java/android/view/ThreadedRenderer.java @@ -66,6 +66,8 @@ public class ThreadedRenderer extends HardwareRenderer { private static final int SYNC_OK = 0; // Needs a ViewRoot invalidate private static final int SYNC_INVALIDATE_REQUIRED = 1 << 0; + // Spoiler: the reward is GPU-accelerated drawing, better find that Surface! + private static final int SYNC_LOST_SURFACE_REWARD_IF_FOUND = 1 << 1; private static final String[] VISUALIZERS = { PROFILE_PROPERTY_VISUALIZE_BARS, @@ -336,6 +338,12 @@ public class ThreadedRenderer extends HardwareRenderer { int syncResult = nSyncAndDrawFrame(mNativeProxy, frameTimeNanos, recordDuration, view.getResources().getDisplayMetrics().density); + if ((syncResult & SYNC_LOST_SURFACE_REWARD_IF_FOUND) != 0) { + setEnabled(false); + // Invalidate since we failed to draw. This should fetch a Surface + // if it is still needed or do nothing if we are no longer drawing + attachInfo.mViewRootImpl.invalidate(); + } if ((syncResult & SYNC_INVALIDATE_REQUIRED) != 0) { attachInfo.mViewRootImpl.invalidate(); } diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp index 958202c..8299855 100644 --- a/libs/hwui/renderthread/CanvasContext.cpp +++ b/libs/hwui/renderthread/CanvasContext.cpp @@ -166,6 +166,11 @@ void CanvasContext::prepareTree(TreeInfo& info) { freePrefetechedLayers(); } + if (CC_UNLIKELY(!mNativeWindow.get())) { + info.out.canDrawThisFrame = false; + return; + } + int runningBehind = 0; // TODO: This query is moderately expensive, investigate adding some sort // of fast-path based off when we last called eglSwapBuffers() as well as diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h index e20564b..435244e 100644 --- a/libs/hwui/renderthread/CanvasContext.h +++ b/libs/hwui/renderthread/CanvasContext.h @@ -68,6 +68,8 @@ public: bool initialize(ANativeWindow* window); void updateSurface(ANativeWindow* window); void pauseSurface(ANativeWindow* window); + bool hasSurface() { return mNativeWindow.get(); } + void setup(int width, int height, const Vector3& lightCenter, float lightRadius, uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha); void setOpaque(bool opaque); diff --git a/libs/hwui/renderthread/DrawFrameTask.cpp b/libs/hwui/renderthread/DrawFrameTask.cpp index dd34e09..97b31a9 100644 --- a/libs/hwui/renderthread/DrawFrameTask.cpp +++ b/libs/hwui/renderthread/DrawFrameTask.cpp @@ -132,6 +132,12 @@ bool DrawFrameTask::syncFrameState(TreeInfo& info) { mLayers.clear(); mContext->prepareTree(info); + // This is after the prepareTree so that any pending operations + // (RenderNode tree state, prefetched layers, etc...) will be flushed. + if (CC_UNLIKELY(!mContext->hasSurface())) { + mSyncResult |= kSync_LostSurfaceRewardIfFound; + } + if (info.out.hasAnimations) { if (info.out.requiresUiRedraw) { mSyncResult |= kSync_UIRedrawRequired; diff --git a/libs/hwui/renderthread/DrawFrameTask.h b/libs/hwui/renderthread/DrawFrameTask.h index 243cc5d..28f6cb2 100644 --- a/libs/hwui/renderthread/DrawFrameTask.h +++ b/libs/hwui/renderthread/DrawFrameTask.h @@ -42,6 +42,7 @@ class RenderThread; enum SyncResult { kSync_OK = 0, kSync_UIRedrawRequired = 1 << 0, + kSync_LostSurfaceRewardIfFound = 1 << 1, }; /* |
