From 08837c246c9c27902c59b41c8661c2f27a4aa2bc Mon Sep 17 00:00:00 2001 From: Chet Haase Date: Mon, 28 Nov 2011 11:53:21 -0800 Subject: [PATCH] Fix flashing wifi dialog after rotating back from landscape. There was an error in some of the OpenGL layer logic such that we would occasionally set up a layer for rendering and then not clean up when it was done. This caused future OpenGL rendering to go into that layer instead of to the buffers being displayed on the screen, resulting in artifacts including flashes and displaying of stale content. This happened specifically when using the wifi settings dialog with the InputMethod keyboard displayed, but it was probably visible in other situations as well. Issue #5628248: Flickering/flashing after entering password for WiFi Change-Id: I38139f620b310f4309570fa7224552d2ee633999 --- core/java/android/view/HardwareRenderer.java | 12 +++++++++ core/java/android/view/ViewRootImpl.java | 27 ++++++++++---------- libs/hwui/OpenGLRenderer.cpp | 6 +++-- 3 files changed, 30 insertions(+), 15 deletions(-) diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java index f77cf7e8398b0..ccb64895703c2 100644 --- a/core/java/android/view/HardwareRenderer.java +++ b/core/java/android/view/HardwareRenderer.java @@ -218,6 +218,13 @@ public abstract class HardwareRenderer { */ abstract int getHeight(); + /** + * Gets the current canvas associated with this HardwareRenderer. + * + * @return the current HardwareCanvas + */ + abstract HardwareCanvas getCanvas(); + /** * Sets the directory to use as a persistent storage for hardware rendering * resources. @@ -783,6 +790,11 @@ public abstract class HardwareRenderer { return mHeight; } + @Override + HardwareCanvas getCanvas() { + return mCanvas; + } + boolean canDraw() { return mGl != null && mCanvas != null; } diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 5f70a39d0daa9..76f78fb8c5001 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -1216,7 +1216,8 @@ public final class ViewRootImpl extends Handler implements ViewParent, disposeResizeBuffer(); boolean completed = false; - HardwareCanvas canvas = null; + HardwareCanvas hwRendererCanvas = mAttachInfo.mHardwareRenderer.getCanvas(); + HardwareCanvas layerCanvas = null; try { if (mResizeBuffer == null) { mResizeBuffer = mAttachInfo.mHardwareRenderer.createHardwareLayer( @@ -1225,12 +1226,12 @@ public final class ViewRootImpl extends Handler implements ViewParent, mResizeBuffer.getHeight() != mHeight) { mResizeBuffer.resize(mWidth, mHeight); } - canvas = mResizeBuffer.start(mAttachInfo.mHardwareCanvas); - canvas.setViewport(mWidth, mHeight); - canvas.onPreDraw(null); - final int restoreCount = canvas.save(); + layerCanvas = mResizeBuffer.start(hwRendererCanvas); + layerCanvas.setViewport(mWidth, mHeight); + layerCanvas.onPreDraw(null); + final int restoreCount = layerCanvas.save(); - canvas.drawColor(0xff000000, PorterDuff.Mode.SRC); + layerCanvas.drawColor(0xff000000, PorterDuff.Mode.SRC); int yoff; final boolean scrolling = mScroller != null @@ -1242,27 +1243,27 @@ public final class ViewRootImpl extends Handler implements ViewParent, yoff = mScrollY; } - canvas.translate(0, -yoff); + layerCanvas.translate(0, -yoff); if (mTranslator != null) { - mTranslator.translateCanvas(canvas); + mTranslator.translateCanvas(layerCanvas); } - mView.draw(canvas); + mView.draw(layerCanvas); mResizeBufferStartTime = SystemClock.uptimeMillis(); mResizeBufferDuration = mView.getResources().getInteger( com.android.internal.R.integer.config_mediumAnimTime); completed = true; - canvas.restoreToCount(restoreCount); + layerCanvas.restoreToCount(restoreCount); } catch (OutOfMemoryError e) { Log.w(TAG, "Not enough memory for content change anim buffer", e); } finally { - if (canvas != null) { - canvas.onPostDraw(); + if (layerCanvas != null) { + layerCanvas.onPostDraw(); } if (mResizeBuffer != null) { - mResizeBuffer.end(mAttachInfo.mHardwareCanvas); + mResizeBuffer.end(hwRendererCanvas); if (!completed) { mResizeBuffer.destroy(); mResizeBuffer = null; diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index 7561a47fa533a..4d226461a02ad 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -201,14 +201,16 @@ void OpenGLRenderer::interrupt() { } void OpenGLRenderer::resume() { - glViewport(0, 0, mSnapshot->viewport.getWidth(), mSnapshot->viewport.getHeight()); + sp snapshot = (mSnapshot != NULL) ? mSnapshot : mFirstSnapshot; + + glViewport(0, 0, snapshot->viewport.getWidth(), snapshot->viewport.getHeight()); glEnable(GL_SCISSOR_TEST); dirtyClip(); glDisable(GL_DITHER); - glBindFramebuffer(GL_FRAMEBUFFER, mSnapshot->fbo); + glBindFramebuffer(GL_FRAMEBUFFER, snapshot->fbo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); mCaches.blend = true;