summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libs/renderengine/gl/GLESRenderEngine.cpp48
-rw-r--r--libs/renderengine/gl/GLESRenderEngine.h12
-rw-r--r--libs/renderengine/include/renderengine/RenderEngine.h3
-rw-r--r--libs/renderengine/include/renderengine/mock/RenderEngine.h2
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&));