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

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

Merge "SF: Support xy scaling for rounded corners"

parents e2e8ef2b 50c0afe2
Loading
Loading
Loading
Loading
+8 −6
Original line number Diff line number Diff line
@@ -921,7 +921,8 @@ void GLESRenderEngine::handleRoundedCorners(const DisplaySettings& display,

    // Finally, we cut the layer into 3 parts, with top and bottom parts having rounded corners
    // and the middle part without rounded corners.
    const int32_t radius = ceil(layer.geometry.roundedCornersRadius);
    const int32_t radius = ceil(
            (layer.geometry.roundedCornersRadius.x + layer.geometry.roundedCornersRadius.y) / 2.0);
    const Rect topRect(bounds.left, bounds.top, bounds.right, bounds.top + radius);
    setScissor(topRect);
    drawMesh(mesh);
@@ -1266,23 +1267,24 @@ void GLESRenderEngine::drawLayersInternal(

        const half3 solidColor = layer.source.solidColor;
        const half4 color = half4(solidColor.r, solidColor.g, solidColor.b, layer.alpha);
        const float radius =
                (layer.geometry.roundedCornersRadius.x + layer.geometry.roundedCornersRadius.y) /
                2.0f;
        // Buffer sources will have a black solid color ignored in the shader,
        // so in that scenario the solid color passed here is arbitrary.
        setupLayerBlending(usePremultipliedAlpha, isOpaque, disableTexture, color,
                           layer.geometry.roundedCornersRadius);
        setupLayerBlending(usePremultipliedAlpha, isOpaque, disableTexture, color, radius);
        if (layer.disableBlending) {
            glDisable(GL_BLEND);
        }
        setSourceDataSpace(layer.sourceDataspace);

        if (layer.shadow.length > 0.0f) {
            handleShadow(layer.geometry.boundaries, layer.geometry.roundedCornersRadius,
                         layer.shadow);
            handleShadow(layer.geometry.boundaries, radius, layer.shadow);
        }
        // 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.
        else if (layer.geometry.roundedCornersRadius > 0.0 && color.a >= 1.0f && isOpaque) {
        else if (radius > 0.0 && color.a >= 1.0f && isOpaque) {
            handleRoundedCorners(display, layer, mesh);
        } else {
            drawMesh(mesh);
+3 −2
Original line number Diff line number Diff line
@@ -87,7 +87,7 @@ struct Geometry {
    // 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;
    vec2 roundedCornersRadius = vec2(0.0f, 0.0f);

    // Rectangle within which corners will be rounded.
    FloatRect roundedCornersCrop = FloatRect();
@@ -258,7 +258,8 @@ static inline void PrintTo(const Geometry& settings, ::std::ostream* os) {
    PrintTo(settings.boundaries, os);
    *os << "\n    .positionTransform = ";
    PrintMatrix(settings.positionTransform, os);
    *os << "\n    .roundedCornersRadius = " << settings.roundedCornersRadius;
    *os << "\n    .roundedCornersRadiusX = " << settings.roundedCornersRadius.x;
    *os << "\n    .roundedCornersRadiusY = " << settings.roundedCornersRadius.y;
    *os << "\n    .roundedCornersCrop = ";
    PrintTo(settings.roundedCornersCrop, os);
    *os << "\n}";
+11 −10
Original line number Diff line number Diff line
@@ -66,7 +66,7 @@ static void drawShadowLayers(SkiaRenderEngine* renderengine, const DisplaySettin
                    Geometry{
                            .boundaries = rect,
                            .roundedCornersCrop = rect,
                            .roundedCornersRadius = 50.f,
                            .roundedCornersRadius = {50.f, 50.f},
                    },
            // drawShadow ignores alpha
            .shadow =
@@ -87,7 +87,7 @@ static void drawShadowLayers(SkiaRenderEngine* renderengine, const DisplaySettin
                    Geometry{
                            .boundaries = smallerRect,
                            .roundedCornersCrop = rect,
                            .roundedCornersRadius = 50.f,
                            .roundedCornersRadius = {50.f, 50.f},
                    },
            .source =
                    PixelSource{
@@ -148,7 +148,7 @@ static void drawImageLayers(SkiaRenderEngine* renderengine, const DisplaySetting
        // In reduced shader mode, all non-zero round rect radii get the same code path.
        for (float roundedCornersRadius : {0.0f, 50.0f}) {
            // roundedCornersCrop is always set, but the radius triggers the behavior
            layer.geometry.roundedCornersRadius = roundedCornersRadius;
            layer.geometry.roundedCornersRadius = {roundedCornersRadius, roundedCornersRadius};
            for (bool isOpaque : {true, false}) {
                layer.source.buffer.isOpaque = isOpaque;
                for (auto alpha : {half(.2f), half(1.0f)}) {
@@ -181,7 +181,7 @@ static void drawSolidLayers(SkiaRenderEngine* renderengine, const DisplaySetting
    for (auto transform : {mat4(), kScaleAndTranslate}) {
        layer.geometry.positionTransform = transform;
        for (float roundedCornersRadius : {0.0f, 50.f}) {
            layer.geometry.roundedCornersRadius = roundedCornersRadius;
            layer.geometry.roundedCornersRadius = {roundedCornersRadius, roundedCornersRadius};
            auto layers = std::vector<LayerSettings>{layer};
            renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache,
                                     base::unique_fd());
@@ -238,7 +238,7 @@ static void drawClippedLayers(SkiaRenderEngine* renderengine, const DisplaySetti
            .geometry =
                    Geometry{
                            .boundaries = rect,
                            .roundedCornersRadius = 27, // larger than the 20 above.
                            .roundedCornersRadius = {27.f, 27.f},
                            .roundedCornersCrop =
                                    FloatRect(0, 0, displayRect.width(), displayRect.height()),
                    },
@@ -275,9 +275,9 @@ static void drawPIPImageLayer(SkiaRenderEngine* renderengine, const DisplaySetti
                            // larger than the layer bounds.
                            .positionTransform = kFlip,
                            .boundaries = rect,
                            .roundedCornersRadius = 94.2551,
                            .roundedCornersCrop = FloatRect(
                                -93.75, 0, displayRect.width() + 93.75, displayRect.height()),
                            .roundedCornersRadius = {94.2551f, 94.2551f},
                            .roundedCornersCrop = FloatRect(-93.75, 0, displayRect.width() + 93.75,
                                                            displayRect.height()),
                    },
            .source = PixelSource{.buffer =
                                          Buffer{
@@ -307,10 +307,11 @@ static void drawHolePunchLayer(SkiaRenderEngine* renderengine, const DisplaySett
                            // the boundaries have to be smaller than the rounded crop so that
                            // clipRRect is used instead of drawRRect
                            .boundaries = small,
                            .roundedCornersRadius = 50.f,
                            .roundedCornersRadius = {50.f, 50.f},
                            .roundedCornersCrop = rect,
                    },
            .source = PixelSource{
            .source =
                    PixelSource{
                            .solidColor = half3(0.f, 0.f, 0.f),
                    },
            .sourceDataspace = kDestDataSpace,
+12 −12
Original line number Diff line number Diff line
@@ -1307,7 +1307,7 @@ inline SkRect SkiaGLRenderEngine::getSkRect(const Rect& rect) {
 *  produce the insected roundRect. If false, the returned state of the radii param is undefined.
 */
static bool intersectionIsRoundRect(const SkRect& bounds, const SkRect& crop,
                                    const SkRect& insetCrop, float cornerRadius,
                                    const SkRect& insetCrop, const vec2& cornerRadius,
                                    SkVector radii[4]) {
    const bool leftEqual = bounds.fLeft == crop.fLeft;
    const bool topEqual = bounds.fTop == crop.fTop;
@@ -1319,8 +1319,8 @@ static bool intersectionIsRoundRect(const SkRect& bounds, const SkRect& crop,
    // In particular the round rect implementation will scale the value of all corner radii
    // if the sum of the radius along any edge is greater than the length of that edge.
    // See https://www.w3.org/TR/css-backgrounds-3/#corner-overlap
    const bool requiredWidth = bounds.width() > (cornerRadius * 2);
    const bool requiredHeight = bounds.height() > (cornerRadius * 2);
    const bool requiredWidth = bounds.width() > (cornerRadius.x * 2);
    const bool requiredHeight = bounds.height() > (cornerRadius.y * 2);
    if (!requiredWidth || !requiredHeight) {
        return false;
    }
@@ -1329,7 +1329,7 @@ static bool intersectionIsRoundRect(const SkRect& bounds, const SkRect& crop,
    // contained within the cropped shape and does not need rounded.
    // compute the UpperLeft corner radius
    if (leftEqual && topEqual) {
        radii[0].set(cornerRadius, cornerRadius);
        radii[0].set(cornerRadius.x, cornerRadius.y);
    } else if ((leftEqual && bounds.fTop >= insetCrop.fTop) ||
               (topEqual && bounds.fLeft >= insetCrop.fLeft)) {
        radii[0].set(0, 0);
@@ -1338,7 +1338,7 @@ static bool intersectionIsRoundRect(const SkRect& bounds, const SkRect& crop,
    }
    // compute the UpperRight corner radius
    if (rightEqual && topEqual) {
        radii[1].set(cornerRadius, cornerRadius);
        radii[1].set(cornerRadius.x, cornerRadius.y);
    } else if ((rightEqual && bounds.fTop >= insetCrop.fTop) ||
               (topEqual && bounds.fRight <= insetCrop.fRight)) {
        radii[1].set(0, 0);
@@ -1347,7 +1347,7 @@ static bool intersectionIsRoundRect(const SkRect& bounds, const SkRect& crop,
    }
    // compute the BottomRight corner radius
    if (rightEqual && bottomEqual) {
        radii[2].set(cornerRadius, cornerRadius);
        radii[2].set(cornerRadius.x, cornerRadius.y);
    } else if ((rightEqual && bounds.fBottom <= insetCrop.fBottom) ||
               (bottomEqual && bounds.fRight <= insetCrop.fRight)) {
        radii[2].set(0, 0);
@@ -1356,7 +1356,7 @@ static bool intersectionIsRoundRect(const SkRect& bounds, const SkRect& crop,
    }
    // compute the BottomLeft corner radius
    if (leftEqual && bottomEqual) {
        radii[3].set(cornerRadius, cornerRadius);
        radii[3].set(cornerRadius.x, cornerRadius.y);
    } else if ((leftEqual && bounds.fBottom <= insetCrop.fBottom) ||
               (bottomEqual && bounds.fLeft >= insetCrop.fLeft)) {
        radii[3].set(0, 0);
@@ -1369,22 +1369,22 @@ static bool intersectionIsRoundRect(const SkRect& bounds, const SkRect& crop,

inline std::pair<SkRRect, SkRRect> SkiaGLRenderEngine::getBoundsAndClip(const FloatRect& boundsRect,
                                                                        const FloatRect& cropRect,
                                                                        const float cornerRadius) {
                                                                        const vec2& cornerRadius) {
    const SkRect bounds = getSkRect(boundsRect);
    const SkRect crop = getSkRect(cropRect);

    SkRRect clip;
    if (cornerRadius > 0) {
    if (cornerRadius.x > 0 && cornerRadius.y > 0) {
        // it the crop and the bounds are equivalent or there is no crop then we don't need a clip
        if (bounds == crop || crop.isEmpty()) {
            return {SkRRect::MakeRectXY(bounds, cornerRadius, cornerRadius), clip};
            return {SkRRect::MakeRectXY(bounds, cornerRadius.x, cornerRadius.y), clip};
        }

        // This makes an effort to speed up common, simple bounds + clip combinations by
        // converting them to a single RRect draw. It is possible there are other cases
        // that can be converted.
        if (crop.contains(bounds)) {
            const auto insetCrop = crop.makeInset(cornerRadius, cornerRadius);
            const auto insetCrop = crop.makeInset(cornerRadius.x, cornerRadius.y);
            if (insetCrop.contains(bounds)) {
                return {SkRRect::MakeRect(bounds), clip}; // clip is empty - no rounding required
            }
@@ -1398,7 +1398,7 @@ inline std::pair<SkRRect, SkRRect> SkiaGLRenderEngine::getBoundsAndClip(const Fl
        }

        // we didn't hit any of our fast paths so set the clip to the cropRect
        clip.setRectXY(crop, cornerRadius, cornerRadius);
        clip.setRectXY(crop, cornerRadius.x, cornerRadius.y);
    }

    // if we hit this point then we either don't have rounded corners or we are going to rely
+2 −1
Original line number Diff line number Diff line
@@ -94,7 +94,8 @@ private:
    inline SkRect getSkRect(const FloatRect& layer);
    inline SkRect getSkRect(const Rect& layer);
    inline std::pair<SkRRect, SkRRect> getBoundsAndClip(const FloatRect& bounds,
                                                        const FloatRect& crop, float cornerRadius);
                                                        const FloatRect& crop,
                                                        const vec2& cornerRadius);
    inline bool layerHasBlur(const LayerSettings& layer, bool colorTransformModifiesAlpha);
    inline SkColor getSkColor(const vec4& color);
    inline SkM44 getSkM44(const mat4& matrix);
Loading