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
This commit is contained in:
John Reck
2019-11-21 14:40:53 -08:00
parent a2186c9f79
commit cd18c2271d
5 changed files with 15 additions and 9 deletions

View File

@@ -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,

View File

@@ -140,13 +140,15 @@ void CanvasContext::destroy() {
mAnimationContext->destroy();
}
void CanvasContext::setSurface(sp<Surface>&& surface) {
void CanvasContext::setSurface(sp<Surface>&& 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;
}

View File

@@ -111,7 +111,7 @@ public:
// Won't take effect until next EGLSurface creation
void setSwapBehavior(SwapBehavior swapBehavior);
void setSurface(sp<Surface>&& surface);
void setSurface(sp<Surface>&& surface, bool enableTimeout = true);
bool pauseSurface();
void setStopped(bool stopped);
bool hasSurface() const { return mNativeSurface.get(); }

View File

@@ -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>& surface) {
mRenderThread.queue().post(
[this, surf = surface]() mutable { mContext->setSurface(std::move(surf)); });
void RenderProxy::setSurface(const sp<Surface>& surface, bool enableTimeout) {
mRenderThread.queue().post([this, surf = surface, enableTimeout]() mutable {
mContext->setSurface(std::move(surf), enableTimeout);
});
}
void RenderProxy::allocateBuffers() {

View File

@@ -69,7 +69,7 @@ public:
ANDROID_API bool loadSystemProperties();
ANDROID_API void setName(const char* name);
ANDROID_API void setSurface(const sp<Surface>& surface);
ANDROID_API void setSurface(const sp<Surface>& surface, bool enableTimeout = true);
ANDROID_API void allocateBuffers();
ANDROID_API bool pause();
ANDROID_API void setStopped(bool stopped);