Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2501ad90 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Support rounded corners in RenderEngine::drawLayers"

parents e09f1e87 7c94edb4
Loading
Loading
Loading
Loading
+21 −1
Original line number Original line Diff line number Diff line
@@ -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();
@@ -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;
@@ -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);
+3 −0
Original line number Original line Diff line number Diff line
@@ -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;
+14 −0
Original line number Original line Diff line number Diff line
@@ -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.
+54 −0
Original line number Original line Diff line number Diff line
@@ -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();
@@ -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();
@@ -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>>();
}
}
@@ -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>>();
}
}
@@ -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();
}
}