From 20adb6ce4d52b15472e7e5ee953e06cc349a827c Mon Sep 17 00:00:00 2001 From: "henry.uh_chen" Date: Wed, 2 Jul 2014 19:36:56 +0800 Subject: [PATCH] [HWUI]: fix residual line on FrameBuffer Symptom: If app applies animation to enlarge a bitmap, there will be an residual line on the screen Root Cause: On platform which has Tile Rendering implementation (ex. Qualcomm CPU), startTiling() call will restrict the framebuffer region which GPU can affect. So the expansion of clear region by 1 will not take effect if startTiling region is not expanded. Solution: Expand the startTiling region by 1, too. Reproduce steps: Apply animation to enlarge (and then shrink) a bitmap icon. Change-Id: I7b4a59e180daa29dbe909d9e11f4093ae1d7396f --- libs/hwui/OpenGLRenderer.cpp | 24 +++++++++++++++++++----- libs/hwui/OpenGLRenderer.h | 4 ++-- 2 files changed, 21 insertions(+), 7 deletions(-) mode change 100644 => 100755 libs/hwui/OpenGLRenderer.cpp mode change 100644 => 100755 libs/hwui/OpenGLRenderer.h diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp old mode 100644 new mode 100755 index 4d76bed204245..ee4a054ab86ff --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -283,21 +283,34 @@ void OpenGLRenderer::syncState() { } } -void OpenGLRenderer::startTiling(const sp& s, bool opaque) { +void OpenGLRenderer::startTiling(const sp& s, bool opaque, bool expand) { if (!mSuppressTiling) { Rect* clip = &mTilingClip; if (s->flags & Snapshot::kFlagFboTarget) { clip = &(s->layer->clipRect); } - startTiling(*clip, s->height, opaque); + startTiling(*clip, s->height, opaque, expand); } } -void OpenGLRenderer::startTiling(const Rect& clip, int windowHeight, bool opaque) { +void OpenGLRenderer::startTiling(const Rect& clip, int windowHeight, bool opaque, bool expand) { if (!mSuppressTiling) { - mCaches.startTiling(clip.left, windowHeight - clip.bottom, + if(expand) { + // Expand the startTiling region by 1 + int leftNotZero = (clip.left > 0) ? 1 : 0; + int topNotZero = (windowHeight - clip.bottom > 0) ? 1 : 0; + + mCaches.startTiling( + clip.left - leftNotZero, + windowHeight - clip.bottom - topNotZero, + clip.right - clip.left + leftNotZero + 1, + clip.bottom - clip.top + topNotZero + 1, + opaque); + } else { + mCaches.startTiling(clip.left, windowHeight - clip.bottom, clip.right - clip.left, clip.bottom - clip.top, opaque); + } } } @@ -1003,7 +1016,8 @@ bool OpenGLRenderer::createFboLayer(Layer* layer, Rect& bounds, Rect& clip, GLui glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, layer->getTexture(), 0); - startTiling(mSnapshot, true); + // Expand the startTiling region by 1 + startTiling(mSnapshot, true, true); // Clear the FBO, expand the clear region by 1 to get nice bilinear filtering mCaches.enableScissor(); diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h old mode 100644 new mode 100755 index 9afb7ad4f2d2f..2e03a1b8330e0 --- a/libs/hwui/OpenGLRenderer.h +++ b/libs/hwui/OpenGLRenderer.h @@ -587,14 +587,14 @@ private: * This method needs to be invoked every time getTargetFbo() is * bound again. */ - void startTiling(const sp& snapshot, bool opaque = false); + void startTiling(const sp& snapshot, bool opaque = false, bool expand = false); /** * Tells the GPU what part of the screen is about to be redrawn. * This method needs to be invoked every time getTargetFbo() is * bound again. */ - void startTiling(const Rect& clip, int windowHeight, bool opaque = false); + void startTiling(const Rect& clip, int windowHeight, bool opaque = false, bool expand = false); /** * Tells the GPU that we are done drawing the frame or that we