From cd18c2271d143fa842f0de40497a4685c52e2548 Mon Sep 17 00:00:00 2001 From: John Reck Date: Thu, 21 Nov 2019 14:40:53 -0800 Subject: [PATCH] Fix for Surface#lockHardwareCanvas lockups By avoiding setting a dequeue buffer timeout we avoid hitting a different path in BufferQueue that prevents async behavior from happening. This restores P's behavior in this path. Bug: 143860379 Test: repro app in bug Change-Id: Iffbd9f9e6689a40876ff3aa74c10020e3f09fc6a --- core/jni/android_view_ThreadedRenderer.cpp | 5 ++++- libs/hwui/renderthread/CanvasContext.cpp | 8 +++++--- libs/hwui/renderthread/CanvasContext.h | 2 +- libs/hwui/renderthread/RenderProxy.cpp | 7 ++++--- libs/hwui/renderthread/RenderProxy.h | 2 +- 5 files changed, 15 insertions(+), 9 deletions(-) diff --git a/core/jni/android_view_ThreadedRenderer.cpp b/core/jni/android_view_ThreadedRenderer.cpp index 7350396537ee2..170e467a72cdb 100644 --- a/core/jni/android_view_ThreadedRenderer.cpp +++ b/core/jni/android_view_ThreadedRenderer.cpp @@ -180,10 +180,13 @@ static void android_view_ThreadedRenderer_setSurface(JNIEnv* env, jobject clazz, if (jsurface) { surface = android_view_Surface_getSurface(env, jsurface); } + bool enableTimeout = true; if (discardBuffer) { + // Currently only Surface#lockHardwareCanvas takes this path + enableTimeout = false; proxy->setSwapBehavior(SwapBehavior::kSwap_discardBuffer); } - proxy->setSurface(surface); + proxy->setSurface(surface, enableTimeout); } static jboolean android_view_ThreadedRenderer_pause(JNIEnv* env, jobject clazz, diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp index f0867686c3218..84902210a7519 100644 --- a/libs/hwui/renderthread/CanvasContext.cpp +++ b/libs/hwui/renderthread/CanvasContext.cpp @@ -140,13 +140,15 @@ void CanvasContext::destroy() { mAnimationContext->destroy(); } -void CanvasContext::setSurface(sp&& surface) { +void CanvasContext::setSurface(sp&& surface, bool enableTimeout) { ATRACE_CALL(); if (surface) { mNativeSurface = new ReliableSurface{std::move(surface)}; - // TODO: Fix error handling & re-shorten timeout - ANativeWindow_setDequeueTimeout(mNativeSurface.get(), 4000_ms); + if (enableTimeout) { + // TODO: Fix error handling & re-shorten timeout + ANativeWindow_setDequeueTimeout(mNativeSurface.get(), 4000_ms); + } } else { mNativeSurface = nullptr; } diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h index b192d461da9b4..4490f80eb8af0 100644 --- a/libs/hwui/renderthread/CanvasContext.h +++ b/libs/hwui/renderthread/CanvasContext.h @@ -111,7 +111,7 @@ public: // Won't take effect until next EGLSurface creation void setSwapBehavior(SwapBehavior swapBehavior); - void setSurface(sp&& surface); + void setSurface(sp&& surface, bool enableTimeout = true); bool pauseSurface(); void setStopped(bool stopped); bool hasSurface() const { return mNativeSurface.get(); } diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp index 4f7ad7b69f57b..f9e401a2e93b2 100644 --- a/libs/hwui/renderthread/RenderProxy.cpp +++ b/libs/hwui/renderthread/RenderProxy.cpp @@ -78,9 +78,10 @@ void RenderProxy::setName(const char* name) { mRenderThread.queue().runSync([this, name]() { mContext->setName(std::string(name)); }); } -void RenderProxy::setSurface(const sp& surface) { - mRenderThread.queue().post( - [this, surf = surface]() mutable { mContext->setSurface(std::move(surf)); }); +void RenderProxy::setSurface(const sp& surface, bool enableTimeout) { + mRenderThread.queue().post([this, surf = surface, enableTimeout]() mutable { + mContext->setSurface(std::move(surf), enableTimeout); + }); } void RenderProxy::allocateBuffers() { diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h index e6fe1d4864dab..4683e1d69019c 100644 --- a/libs/hwui/renderthread/RenderProxy.h +++ b/libs/hwui/renderthread/RenderProxy.h @@ -69,7 +69,7 @@ public: ANDROID_API bool loadSystemProperties(); ANDROID_API void setName(const char* name); - ANDROID_API void setSurface(const sp& surface); + ANDROID_API void setSurface(const sp& surface, bool enableTimeout = true); ANDROID_API void allocateBuffers(); ANDROID_API bool pause(); ANDROID_API void setStopped(bool stopped);