diff options
| -rw-r--r-- | libs/renderengine/gl/GLESRenderEngine.cpp | 48 | ||||
| -rw-r--r-- | libs/renderengine/gl/GLESRenderEngine.h | 12 | ||||
| -rw-r--r-- | libs/renderengine/include/renderengine/RenderEngine.h | 3 | ||||
| -rw-r--r-- | libs/renderengine/include/renderengine/mock/RenderEngine.h | 2 |
4 files changed, 48 insertions, 17 deletions
diff --git a/libs/renderengine/gl/GLESRenderEngine.cpp b/libs/renderengine/gl/GLESRenderEngine.cpp index f65130906d..1980f50bac 100644 --- a/libs/renderengine/gl/GLESRenderEngine.cpp +++ b/libs/renderengine/gl/GLESRenderEngine.cpp @@ -595,11 +595,7 @@ void GLESRenderEngine::fillRegionWithColor(const Region& region, float red, floa } void GLESRenderEngine::setScissor(const Rect& region) { - // Invert y-coordinate to map to GL-space. - int32_t canvasHeight = mFboHeight; - int32_t glBottom = canvasHeight - region.bottom; - - glScissor(region.left, glBottom, region.getWidth(), region.getHeight()); + glScissor(region.left, region.top, region.getWidth(), region.getHeight()); glEnable(GL_SCISSOR_TEST); } @@ -719,6 +715,36 @@ FloatRect GLESRenderEngine::setupLayerCropping(const LayerSettings& layer, Mesh& return cropWin; } +void GLESRenderEngine::handleRoundedCorners(const DisplaySettings& display, + const LayerSettings& layer, const Mesh& mesh) { + // We separate the layer into 3 parts essentially, such that we only turn on blending for the + // top rectangle and the bottom rectangle, and turn off blending for the middle rectangle. + FloatRect bounds = layer.geometry.roundedCornersCrop; + const auto transformMatrix = display.globalTransform * layer.geometry.positionTransform; + const vec4 leftTopCoordinate(bounds.left, bounds.top, 1.0, 1.0); + const vec4 rightBottomCoordinate(bounds.right, bounds.bottom, 1.0, 1.0); + const vec4 leftTopCoordinateInBuffer = transformMatrix * leftTopCoordinate; + const vec4 rightBottomCoordinateInBuffer = transformMatrix * rightBottomCoordinate; + bounds = FloatRect(leftTopCoordinateInBuffer[0], leftTopCoordinateInBuffer[1], + rightBottomCoordinateInBuffer[0], rightBottomCoordinateInBuffer[1]); + const int32_t radius = ceil(layer.geometry.roundedCornersRadius); + + const Rect topRect(bounds.left, bounds.top, bounds.right, bounds.top + radius); + setScissor(topRect); + drawMesh(mesh); + const Rect bottomRect(bounds.left, bounds.bottom - radius, bounds.right, bounds.bottom); + setScissor(bottomRect); + drawMesh(mesh); + + // The middle part of the layer can turn off blending. + const Rect middleRect(bounds.left, bounds.top + radius, bounds.right, bounds.bottom - radius); + setScissor(middleRect); + mState.cornerRadius = 0.0; + disableBlending(); + drawMesh(mesh); + disableScissor(); +} + status_t GLESRenderEngine::bindFrameBuffer(Framebuffer* framebuffer) { ATRACE_CALL(); GLFramebuffer* glFramebuffer = static_cast<GLFramebuffer*>(framebuffer); @@ -738,8 +764,6 @@ status_t GLESRenderEngine::bindFrameBuffer(Framebuffer* framebuffer) { glBindFramebuffer(GL_FRAMEBUFFER, framebufferName); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureName, 0); - mFboHeight = glFramebuffer->getBufferHeight(); - uint32_t glStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER); ALOGE_IF(glStatus != GL_FRAMEBUFFER_COMPLETE_OES, "glCheckFramebufferStatusOES error %d", @@ -750,7 +774,6 @@ status_t GLESRenderEngine::bindFrameBuffer(Framebuffer* framebuffer) { void GLESRenderEngine::unbindFrameBuffer(Framebuffer* /* framebuffer */) { ATRACE_CALL(); - mFboHeight = 0; // back to main framebuffer glBindFramebuffer(GL_FRAMEBUFFER, 0); @@ -917,7 +940,14 @@ status_t GLESRenderEngine::drawLayers(const DisplaySettings& display, } setSourceDataSpace(layer.sourceDataspace); - drawMesh(mesh); + // We only want to do a special handling for rounded corners when having rounded corners + // is the only reason it needs to turn on blending, otherwise, we handle it like the + // usual way since it needs to turn on blending anyway. + if (layer.geometry.roundedCornersRadius > 0.0 && color.a >= 1.0f && isOpaque) { + handleRoundedCorners(display, layer, mesh); + } else { + drawMesh(mesh); + } // Cleanup if there's a buffer source if (layer.source.buffer.buffer != nullptr) { diff --git a/libs/renderengine/gl/GLESRenderEngine.h b/libs/renderengine/gl/GLESRenderEngine.h index efb6ef0043..8c8f308d3b 100644 --- a/libs/renderengine/gl/GLESRenderEngine.h +++ b/libs/renderengine/gl/GLESRenderEngine.h @@ -69,8 +69,6 @@ public: void clearWithColor(float red, float green, float blue, float alpha) override; void fillRegionWithColor(const Region& region, float red, float green, float blue, float alpha) override; - void setScissor(const Rect& region) override; - void disableScissor() override; void genTextures(size_t count, uint32_t* names) override; void deleteTextures(size_t count, uint32_t const* names) override; void bindExternalTextureImage(uint32_t texName, const Image& image) override; @@ -141,6 +139,8 @@ private: Protection protection); static EGLSurface createDummyEglPbufferSurface(EGLDisplay display, EGLConfig config, int hwcFormat, Protection protection); + void setScissor(const Rect& region); + void disableScissor(); bool waitSync(EGLSyncKHR sync, EGLint flags); // A data space is considered HDR data space if it has BT2020 color space @@ -156,6 +156,13 @@ private: // coordinates for the mesh. FloatRect setupLayerCropping(const LayerSettings& layer, Mesh& mesh); + // We do a special handling for rounded corners when it's possible to turn off blending + // for the majority of the layer. The rounded corners needs to turn on blending such that + // we can set the alpha value correctly, however, only the corners need this, and since + // blending is an expensive operation, we want to turn off blending when it's not necessary. + void handleRoundedCorners(const DisplaySettings& display, const LayerSettings& layer, + const Mesh& mesh); + EGLDisplay mEGLDisplay; EGLConfig mEGLConfig; EGLContext mEGLContext; @@ -185,7 +192,6 @@ private: bool mInProtectedContext = false; // If set to true, then enables tracing flush() and finish() to systrace. bool mTraceGpuCompletion = false; - int32_t mFboHeight = 0; // Maximum size of mFramebufferImageCache. If more images would be cached, then (approximately) // the last recently used buffer should be kicked out. uint32_t mFramebufferImageCacheSize = 0; diff --git a/libs/renderengine/include/renderengine/RenderEngine.h b/libs/renderengine/include/renderengine/RenderEngine.h index ab342744c2..b211551348 100644 --- a/libs/renderengine/include/renderengine/RenderEngine.h +++ b/libs/renderengine/include/renderengine/RenderEngine.h @@ -103,9 +103,6 @@ public: virtual void clearWithColor(float red, float green, float blue, float alpha) = 0; virtual void fillRegionWithColor(const Region& region, float red, float green, float blue, float alpha) = 0; - - virtual void setScissor(const Rect& region) = 0; - virtual void disableScissor() = 0; virtual void genTextures(size_t count, uint32_t* names) = 0; virtual void deleteTextures(size_t count, uint32_t const* names) = 0; virtual void bindExternalTextureImage(uint32_t texName, const Image& image) = 0; diff --git a/libs/renderengine/include/renderengine/mock/RenderEngine.h b/libs/renderengine/include/renderengine/mock/RenderEngine.h index ddf742098a..479c7ac035 100644 --- a/libs/renderengine/include/renderengine/mock/RenderEngine.h +++ b/libs/renderengine/include/renderengine/mock/RenderEngine.h @@ -48,8 +48,6 @@ public: bool waitFence(base::unique_fd fd) override { return waitFence(&fd); }; MOCK_METHOD4(clearWithColor, void(float, float, float, float)); MOCK_METHOD5(fillRegionWithColor, void(const Region&, float, float, float, float)); - MOCK_METHOD1(setScissor, void(const Rect&)); - MOCK_METHOD0(disableScissor, void()); MOCK_METHOD2(genTextures, void(size_t, uint32_t*)); MOCK_METHOD2(deleteTextures, void(size_t, uint32_t const*)); MOCK_METHOD2(bindExternalTextureImage, void(uint32_t, const renderengine::Image&)); |