Loading libs/renderengine/gl/GLESRenderEngine.cpp +21 −1 Original line number Original line Diff line number Diff line Loading @@ -626,6 +626,25 @@ status_t GLESRenderEngine::bindExternalTextureBuffer(uint32_t texName, sp<Graphi return NO_ERROR; return NO_ERROR; } } FloatRect GLESRenderEngine::setupLayerCropping(const LayerSettings& layer, Mesh& mesh) { // Translate win by the rounded corners rect coordinates, to have all values in // layer coordinate space. FloatRect cropWin = layer.geometry.boundaries; const FloatRect& roundedCornersCrop = layer.geometry.roundedCornersCrop; cropWin.left -= roundedCornersCrop.left; cropWin.right -= roundedCornersCrop.left; cropWin.top -= roundedCornersCrop.top; cropWin.bottom -= roundedCornersCrop.top; Mesh::VertexArray<vec2> cropCoords(mesh.getCropCoordArray<vec2>()); cropCoords[0] = vec2(cropWin.left, cropWin.top); cropCoords[1] = vec2(cropWin.left, cropWin.top + cropWin.getHeight()); cropCoords[2] = vec2(cropWin.right, cropWin.top + cropWin.getHeight()); cropCoords[3] = vec2(cropWin.right, cropWin.top); setupCornerRadiusCropSize(roundedCornersCrop.getWidth(), roundedCornersCrop.getHeight()); return cropWin; } status_t GLESRenderEngine::bindFrameBuffer(Framebuffer* framebuffer) { status_t GLESRenderEngine::bindFrameBuffer(Framebuffer* framebuffer) { GLFramebuffer* glFramebuffer = static_cast<GLFramebuffer*>(framebuffer); GLFramebuffer* glFramebuffer = static_cast<GLFramebuffer*>(framebuffer); EGLImageKHR eglImage = glFramebuffer->getEGLImage(); EGLImageKHR eglImage = glFramebuffer->getEGLImage(); Loading Loading @@ -730,6 +749,7 @@ status_t GLESRenderEngine::drawLayers(const DisplaySettings& display, position[2] = vec2(bounds.right, bounds.bottom); position[2] = vec2(bounds.right, bounds.bottom); position[3] = vec2(bounds.right, bounds.top); position[3] = vec2(bounds.right, bounds.top); setupLayerCropping(layer, mesh); setColorTransform(display.colorTransform * layer.colorTransform); setColorTransform(display.colorTransform * layer.colorTransform); bool usePremultipliedAlpha = true; bool usePremultipliedAlpha = true; Loading Loading @@ -764,7 +784,7 @@ status_t GLESRenderEngine::drawLayers(const DisplaySettings& display, // Buffer sources will have a black solid color ignored in the shader, // Buffer sources will have a black solid color ignored in the shader, // so in that scenario the solid color passed here is arbitrary. // so in that scenario the solid color passed here is arbitrary. setupLayerBlending(usePremultipliedAlpha, layer.source.buffer.isOpaque, disableTexture, setupLayerBlending(usePremultipliedAlpha, layer.source.buffer.isOpaque, disableTexture, color, /*cornerRadius=*/0.0); color, layer.geometry.roundedCornersRadius); setSourceDataSpace(layer.sourceDataspace); setSourceDataSpace(layer.sourceDataspace); drawMesh(mesh); drawMesh(mesh); Loading libs/renderengine/gl/GLESRenderEngine.h +3 −0 Original line number Original line Diff line number Diff line Loading @@ -128,6 +128,9 @@ private: // defined by the clip. // defined by the clip. void setViewportAndProjection(Rect viewport, Rect clip); void setViewportAndProjection(Rect viewport, Rect clip); status_t bindExternalTextureBuffer(uint32_t texName, sp<GraphicBuffer> buffer, sp<Fence> fence); status_t bindExternalTextureBuffer(uint32_t texName, sp<GraphicBuffer> buffer, sp<Fence> fence); // Computes the cropping window for the layer and sets up cropping // coordinates for the mesh. FloatRect setupLayerCropping(const LayerSettings& layer, Mesh& mesh); EGLDisplay mEGLDisplay; EGLDisplay mEGLDisplay; EGLConfig mEGLConfig; EGLConfig mEGLConfig; Loading libs/renderengine/include/renderengine/LayerSettings.h +14 −0 Original line number Original line Diff line number Diff line Loading @@ -69,6 +69,20 @@ struct Geometry { // Transform matrix to apply to mesh coordinates. // Transform matrix to apply to mesh coordinates. mat4 positionTransform = mat4(); mat4 positionTransform = mat4(); // Radius of rounded corners, if greater than 0. Otherwise, this layer's // corners are not rounded. // Having corner radius will force GPU composition on the layer and its children, drawing it // with a special shader. The shader will receive the radius and the crop rectangle as input, // modifying the opacity of the destination texture, multiplying it by a number between 0 and 1. // We query Layer#getRoundedCornerState() to retrieve the radius as well as the rounded crop // rectangle to figure out how to apply the radius for this layer. The crop rectangle will be // in local layer coordinate space, so we have to take the layer transform into account when // walking up the tree. float roundedCornersRadius = 0.0; // Rectangle within which corners will be rounded. FloatRect roundedCornersCrop = FloatRect(); }; }; // Descriptor of the source pixels for this layer. // Descriptor of the source pixels for this layer. Loading libs/renderengine/tests/RenderEngineTest.cpp +54 −0 Original line number Original line Diff line number Diff line Loading @@ -172,6 +172,12 @@ struct RenderEngineTest : public ::testing::Test { template <typename SourceVariant> template <typename SourceVariant> void fillBufferColorTransform(); void fillBufferColorTransform(); template <typename SourceVariant> void fillRedBufferWithRoundedCorners(); template <typename SourceVariant> void fillBufferWithRoundedCorners(); void fillRedBufferTextureTransform(); void fillRedBufferTextureTransform(); void fillBufferTextureTransform(); void fillBufferTextureTransform(); Loading Loading @@ -501,6 +507,42 @@ void RenderEngineTest::fillBufferColorTransform() { expectBufferColor(fullscreenRect(), 191, 0, 0, 255); expectBufferColor(fullscreenRect(), 191, 0, 0, 255); } } template <typename SourceVariant> void RenderEngineTest::fillRedBufferWithRoundedCorners() { renderengine::DisplaySettings settings; settings.physicalDisplay = fullscreenRect(); settings.clip = fullscreenRect(); std::vector<renderengine::LayerSettings> layers; renderengine::LayerSettings layer; layer.geometry.boundaries = fullscreenRect().toFloatRect(); layer.geometry.roundedCornersRadius = 5.0f; layer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect(); SourceVariant::fillColor(layer, 1.0f, 0.0f, 0.0f, this); layer.alpha = 1.0f; layers.push_back(layer); invokeDraw(settings, layers, mBuffer); } template <typename SourceVariant> void RenderEngineTest::fillBufferWithRoundedCorners() { fillRedBufferWithRoundedCorners<SourceVariant>(); // Corners should be ignored... expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 0); expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, 0, DEFAULT_DISPLAY_WIDTH, 1), 0, 0, 0, 0); expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT - 1, 1, DEFAULT_DISPLAY_HEIGHT), 0, 0, 0, 0); expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1, DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT), 0, 0, 0, 0); // ...And the non-rounded portion should be red. // Other pixels may be anti-aliased, so let's not check those. expectBufferColor(Rect(5, 5, DEFAULT_DISPLAY_WIDTH - 5, DEFAULT_DISPLAY_HEIGHT - 5), 255, 0, 0, 255); } void RenderEngineTest::fillRedBufferTextureTransform() { void RenderEngineTest::fillRedBufferTextureTransform() { renderengine::DisplaySettings settings; renderengine::DisplaySettings settings; settings.physicalDisplay = fullscreenRect(); settings.physicalDisplay = fullscreenRect(); Loading Loading @@ -701,6 +743,10 @@ TEST_F(RenderEngineTest, drawLayers_fillBufferColorTransform_colorSource) { fillBufferLayerTransform<ColorSourceVariant>(); fillBufferLayerTransform<ColorSourceVariant>(); } } TEST_F(RenderEngineTest, drawLayers_fillBufferRoundedCorners_colorSource) { fillBufferWithRoundedCorners<ColorSourceVariant>(); } TEST_F(RenderEngineTest, drawLayers_fillRedBuffer_opaqueBufferSource) { TEST_F(RenderEngineTest, drawLayers_fillRedBuffer_opaqueBufferSource) { fillRedBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>(); fillRedBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>(); } } Loading Loading @@ -745,6 +791,10 @@ TEST_F(RenderEngineTest, drawLayers_fillBufferColorTransform_opaqueBufferSource) fillBufferLayerTransform<BufferSourceVariant<ForceOpaqueBufferVariant>>(); fillBufferLayerTransform<BufferSourceVariant<ForceOpaqueBufferVariant>>(); } } TEST_F(RenderEngineTest, drawLayers_fillBufferRoundedCorners_opaqueBufferSource) { fillBufferWithRoundedCorners<BufferSourceVariant<ForceOpaqueBufferVariant>>(); } TEST_F(RenderEngineTest, drawLayers_fillRedBuffer_bufferSource) { TEST_F(RenderEngineTest, drawLayers_fillRedBuffer_bufferSource) { fillRedBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>(); fillRedBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>(); } } Loading Loading @@ -789,6 +839,10 @@ TEST_F(RenderEngineTest, drawLayers_fillBufferColorTransform_bufferSource) { fillBufferLayerTransform<BufferSourceVariant<RelaxOpaqueBufferVariant>>(); fillBufferLayerTransform<BufferSourceVariant<RelaxOpaqueBufferVariant>>(); } } TEST_F(RenderEngineTest, drawLayers_fillBufferRoundedCorners_bufferSource) { fillBufferWithRoundedCorners<BufferSourceVariant<RelaxOpaqueBufferVariant>>(); } TEST_F(RenderEngineTest, drawLayers_fillBufferTextureTransform) { TEST_F(RenderEngineTest, drawLayers_fillBufferTextureTransform) { fillBufferTextureTransform(); fillBufferTextureTransform(); } } Loading Loading
libs/renderengine/gl/GLESRenderEngine.cpp +21 −1 Original line number Original line Diff line number Diff line Loading @@ -626,6 +626,25 @@ status_t GLESRenderEngine::bindExternalTextureBuffer(uint32_t texName, sp<Graphi return NO_ERROR; return NO_ERROR; } } FloatRect GLESRenderEngine::setupLayerCropping(const LayerSettings& layer, Mesh& mesh) { // Translate win by the rounded corners rect coordinates, to have all values in // layer coordinate space. FloatRect cropWin = layer.geometry.boundaries; const FloatRect& roundedCornersCrop = layer.geometry.roundedCornersCrop; cropWin.left -= roundedCornersCrop.left; cropWin.right -= roundedCornersCrop.left; cropWin.top -= roundedCornersCrop.top; cropWin.bottom -= roundedCornersCrop.top; Mesh::VertexArray<vec2> cropCoords(mesh.getCropCoordArray<vec2>()); cropCoords[0] = vec2(cropWin.left, cropWin.top); cropCoords[1] = vec2(cropWin.left, cropWin.top + cropWin.getHeight()); cropCoords[2] = vec2(cropWin.right, cropWin.top + cropWin.getHeight()); cropCoords[3] = vec2(cropWin.right, cropWin.top); setupCornerRadiusCropSize(roundedCornersCrop.getWidth(), roundedCornersCrop.getHeight()); return cropWin; } status_t GLESRenderEngine::bindFrameBuffer(Framebuffer* framebuffer) { status_t GLESRenderEngine::bindFrameBuffer(Framebuffer* framebuffer) { GLFramebuffer* glFramebuffer = static_cast<GLFramebuffer*>(framebuffer); GLFramebuffer* glFramebuffer = static_cast<GLFramebuffer*>(framebuffer); EGLImageKHR eglImage = glFramebuffer->getEGLImage(); EGLImageKHR eglImage = glFramebuffer->getEGLImage(); Loading Loading @@ -730,6 +749,7 @@ status_t GLESRenderEngine::drawLayers(const DisplaySettings& display, position[2] = vec2(bounds.right, bounds.bottom); position[2] = vec2(bounds.right, bounds.bottom); position[3] = vec2(bounds.right, bounds.top); position[3] = vec2(bounds.right, bounds.top); setupLayerCropping(layer, mesh); setColorTransform(display.colorTransform * layer.colorTransform); setColorTransform(display.colorTransform * layer.colorTransform); bool usePremultipliedAlpha = true; bool usePremultipliedAlpha = true; Loading Loading @@ -764,7 +784,7 @@ status_t GLESRenderEngine::drawLayers(const DisplaySettings& display, // Buffer sources will have a black solid color ignored in the shader, // Buffer sources will have a black solid color ignored in the shader, // so in that scenario the solid color passed here is arbitrary. // so in that scenario the solid color passed here is arbitrary. setupLayerBlending(usePremultipliedAlpha, layer.source.buffer.isOpaque, disableTexture, setupLayerBlending(usePremultipliedAlpha, layer.source.buffer.isOpaque, disableTexture, color, /*cornerRadius=*/0.0); color, layer.geometry.roundedCornersRadius); setSourceDataSpace(layer.sourceDataspace); setSourceDataSpace(layer.sourceDataspace); drawMesh(mesh); drawMesh(mesh); Loading
libs/renderengine/gl/GLESRenderEngine.h +3 −0 Original line number Original line Diff line number Diff line Loading @@ -128,6 +128,9 @@ private: // defined by the clip. // defined by the clip. void setViewportAndProjection(Rect viewport, Rect clip); void setViewportAndProjection(Rect viewport, Rect clip); status_t bindExternalTextureBuffer(uint32_t texName, sp<GraphicBuffer> buffer, sp<Fence> fence); status_t bindExternalTextureBuffer(uint32_t texName, sp<GraphicBuffer> buffer, sp<Fence> fence); // Computes the cropping window for the layer and sets up cropping // coordinates for the mesh. FloatRect setupLayerCropping(const LayerSettings& layer, Mesh& mesh); EGLDisplay mEGLDisplay; EGLDisplay mEGLDisplay; EGLConfig mEGLConfig; EGLConfig mEGLConfig; Loading
libs/renderengine/include/renderengine/LayerSettings.h +14 −0 Original line number Original line Diff line number Diff line Loading @@ -69,6 +69,20 @@ struct Geometry { // Transform matrix to apply to mesh coordinates. // Transform matrix to apply to mesh coordinates. mat4 positionTransform = mat4(); mat4 positionTransform = mat4(); // Radius of rounded corners, if greater than 0. Otherwise, this layer's // corners are not rounded. // Having corner radius will force GPU composition on the layer and its children, drawing it // with a special shader. The shader will receive the radius and the crop rectangle as input, // modifying the opacity of the destination texture, multiplying it by a number between 0 and 1. // We query Layer#getRoundedCornerState() to retrieve the radius as well as the rounded crop // rectangle to figure out how to apply the radius for this layer. The crop rectangle will be // in local layer coordinate space, so we have to take the layer transform into account when // walking up the tree. float roundedCornersRadius = 0.0; // Rectangle within which corners will be rounded. FloatRect roundedCornersCrop = FloatRect(); }; }; // Descriptor of the source pixels for this layer. // Descriptor of the source pixels for this layer. Loading
libs/renderengine/tests/RenderEngineTest.cpp +54 −0 Original line number Original line Diff line number Diff line Loading @@ -172,6 +172,12 @@ struct RenderEngineTest : public ::testing::Test { template <typename SourceVariant> template <typename SourceVariant> void fillBufferColorTransform(); void fillBufferColorTransform(); template <typename SourceVariant> void fillRedBufferWithRoundedCorners(); template <typename SourceVariant> void fillBufferWithRoundedCorners(); void fillRedBufferTextureTransform(); void fillRedBufferTextureTransform(); void fillBufferTextureTransform(); void fillBufferTextureTransform(); Loading Loading @@ -501,6 +507,42 @@ void RenderEngineTest::fillBufferColorTransform() { expectBufferColor(fullscreenRect(), 191, 0, 0, 255); expectBufferColor(fullscreenRect(), 191, 0, 0, 255); } } template <typename SourceVariant> void RenderEngineTest::fillRedBufferWithRoundedCorners() { renderengine::DisplaySettings settings; settings.physicalDisplay = fullscreenRect(); settings.clip = fullscreenRect(); std::vector<renderengine::LayerSettings> layers; renderengine::LayerSettings layer; layer.geometry.boundaries = fullscreenRect().toFloatRect(); layer.geometry.roundedCornersRadius = 5.0f; layer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect(); SourceVariant::fillColor(layer, 1.0f, 0.0f, 0.0f, this); layer.alpha = 1.0f; layers.push_back(layer); invokeDraw(settings, layers, mBuffer); } template <typename SourceVariant> void RenderEngineTest::fillBufferWithRoundedCorners() { fillRedBufferWithRoundedCorners<SourceVariant>(); // Corners should be ignored... expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 0); expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, 0, DEFAULT_DISPLAY_WIDTH, 1), 0, 0, 0, 0); expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT - 1, 1, DEFAULT_DISPLAY_HEIGHT), 0, 0, 0, 0); expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1, DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT), 0, 0, 0, 0); // ...And the non-rounded portion should be red. // Other pixels may be anti-aliased, so let's not check those. expectBufferColor(Rect(5, 5, DEFAULT_DISPLAY_WIDTH - 5, DEFAULT_DISPLAY_HEIGHT - 5), 255, 0, 0, 255); } void RenderEngineTest::fillRedBufferTextureTransform() { void RenderEngineTest::fillRedBufferTextureTransform() { renderengine::DisplaySettings settings; renderengine::DisplaySettings settings; settings.physicalDisplay = fullscreenRect(); settings.physicalDisplay = fullscreenRect(); Loading Loading @@ -701,6 +743,10 @@ TEST_F(RenderEngineTest, drawLayers_fillBufferColorTransform_colorSource) { fillBufferLayerTransform<ColorSourceVariant>(); fillBufferLayerTransform<ColorSourceVariant>(); } } TEST_F(RenderEngineTest, drawLayers_fillBufferRoundedCorners_colorSource) { fillBufferWithRoundedCorners<ColorSourceVariant>(); } TEST_F(RenderEngineTest, drawLayers_fillRedBuffer_opaqueBufferSource) { TEST_F(RenderEngineTest, drawLayers_fillRedBuffer_opaqueBufferSource) { fillRedBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>(); fillRedBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>(); } } Loading Loading @@ -745,6 +791,10 @@ TEST_F(RenderEngineTest, drawLayers_fillBufferColorTransform_opaqueBufferSource) fillBufferLayerTransform<BufferSourceVariant<ForceOpaqueBufferVariant>>(); fillBufferLayerTransform<BufferSourceVariant<ForceOpaqueBufferVariant>>(); } } TEST_F(RenderEngineTest, drawLayers_fillBufferRoundedCorners_opaqueBufferSource) { fillBufferWithRoundedCorners<BufferSourceVariant<ForceOpaqueBufferVariant>>(); } TEST_F(RenderEngineTest, drawLayers_fillRedBuffer_bufferSource) { TEST_F(RenderEngineTest, drawLayers_fillRedBuffer_bufferSource) { fillRedBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>(); fillRedBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>(); } } Loading Loading @@ -789,6 +839,10 @@ TEST_F(RenderEngineTest, drawLayers_fillBufferColorTransform_bufferSource) { fillBufferLayerTransform<BufferSourceVariant<RelaxOpaqueBufferVariant>>(); fillBufferLayerTransform<BufferSourceVariant<RelaxOpaqueBufferVariant>>(); } } TEST_F(RenderEngineTest, drawLayers_fillBufferRoundedCorners_bufferSource) { fillBufferWithRoundedCorners<BufferSourceVariant<RelaxOpaqueBufferVariant>>(); } TEST_F(RenderEngineTest, drawLayers_fillBufferTextureTransform) { TEST_F(RenderEngineTest, drawLayers_fillBufferTextureTransform) { fillBufferTextureTransform(); fillBufferTextureTransform(); } } Loading