From 7b5b6abf852c039983eded25ebe43a70fef5a4ab Mon Sep 17 00:00:00 2001 From: Romain Guy Date: Mon, 14 Mar 2011 18:05:08 -0700 Subject: Fix rendering artifact in edge fades. Bug #4092053 The problem always existed but was made visible by partial invalidation. When saving a layer, the renderer would try to postpone glClear() operations until the next drawing command. This however does not work since the clip might have changed. The fix is rather simple and simply gets rid of this "optimization" (that turned out to be usless anyway given how View issues saveLayer() calls.) This change also fixes an issue with gradients (color stops where not properly computed when using a null stops array) and optimizes display lists rendering (quickly rejects larger portions of the tree to avoid executing unnecessary code.) Change-Id: I0f5b5f6e1220d41a09cc2fa84c212b0b4afd9c46 --- libs/hwui/OpenGLRenderer.cpp | 49 +++++++++++++++----------------------------- 1 file changed, 16 insertions(+), 33 deletions(-) (limited to 'libs/hwui/OpenGLRenderer.cpp') diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index 1f65201..5d9522e 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -403,10 +403,7 @@ bool OpenGLRenderer::createLayer(sp snapshot, float left, float top, // Window coordinates of the layer Rect bounds(left, top, right, bottom); - if (fboLayer) { - // Clear the previous layer regions before we change the viewport - clearLayerRegions(); - } else { + if (!fboLayer) { mSnapshot->transform->mapRect(bounds); // Layers only make sense if they are in the framebuffer's bounds @@ -464,8 +461,14 @@ bool OpenGLRenderer::createLayer(sp snapshot, float left, float top, glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, bounds.left, snapshot->height - bounds.bottom, bounds.getWidth(), bounds.getHeight()); } - // Enqueue the buffer coordinates to clear the corresponding region later - mLayers.push(new Rect(bounds)); + + // Clear the framebuffer where the layer will draw + glScissor(bounds.left, mSnapshot->height - bounds.bottom, + bounds.getWidth(), bounds.getHeight()); + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glClear(GL_COLOR_BUFFER_BIT); + + dirtyClip(); } } @@ -760,31 +763,6 @@ void OpenGLRenderer::dirtyLayerUnchecked(Rect& bounds, Region* region) { #endif } -void OpenGLRenderer::clearLayerRegions() { - if (mLayers.size() == 0 || mSnapshot->isIgnored()) return; - - Rect clipRect(*mSnapshot->clipRect); - clipRect.snapToPixelBoundaries(); - - for (uint32_t i = 0; i < mLayers.size(); i++) { - Rect* bounds = mLayers.itemAt(i); - if (clipRect.intersects(*bounds)) { - // Clear the framebuffer where the layer will draw - glScissor(bounds->left, mSnapshot->height - bounds->bottom, - bounds->getWidth(), bounds->getHeight()); - glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - glClear(GL_COLOR_BUFFER_BIT); - - // Restore the clip - dirtyClip(); - } - - delete bounds; - } - - mLayers.clear(); -} - /////////////////////////////////////////////////////////////////////////////// // Transforms /////////////////////////////////////////////////////////////////////////////// @@ -870,7 +848,6 @@ bool OpenGLRenderer::clipRect(float left, float top, float right, float bottom, /////////////////////////////////////////////////////////////////////////////// void OpenGLRenderer::setupDraw() { - clearLayerRegions(); if (mDirtyClip) { setScissorFromClip(); } @@ -1064,12 +1041,18 @@ void OpenGLRenderer::finishDrawTexture() { // Drawing /////////////////////////////////////////////////////////////////////////////// -bool OpenGLRenderer::drawDisplayList(DisplayList* displayList, Rect& dirty, uint32_t level) { +bool OpenGLRenderer::drawDisplayList(DisplayList* displayList, uint32_t width, uint32_t height, + Rect& dirty, uint32_t level) { + if (quickReject(0.0f, 0.0f, width, height)) { + return false; + } + // All the usual checks and setup operations (quickReject, setupDraw, etc.) // will be performed by the display list itself if (displayList) { return displayList->replay(*this, dirty, level); } + return false; } -- cgit v1.1