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

Commit f0102c90 authored by Cairn Overturf's avatar Cairn Overturf
Browse files

Crop shadows by parent layer crop

Bug: 405906929, 403105984
Flag: EXEMPT bugfix
Test: Launch partial magnifier, there should be no large shadows drawn outside the magnifier bounds. Shadows seem normal on freeform windows and PIP.
Change-Id: Ieea54aef87d3a95ecab845a1259198cb837e01b3
parent af242ef0
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -93,6 +93,10 @@ struct Geometry {

    // Rectangle within which corners will be rounded.
    FloatRect roundedCornersCrop = FloatRect();

    // Crop geometry in local space, used for cropping outset rendering, e.g. shadows.
    vec2 otherRoundedCornersRadius = vec2(0.0f, 0.0f);
    FloatRect otherCrop = FloatRect();
};

// Descriptor of the source pixels for this layer.
@@ -228,6 +232,12 @@ static inline void PrintTo(const Geometry& settings, ::std::ostream* os) {
    *os << "\n    .roundedCornersRadiusY = " << settings.roundedCornersRadius.y;
    *os << "\n    .roundedCornersCrop = ";
    PrintTo(settings.roundedCornersCrop, os);

    *os << "\n    .otherRoundedCornersRadiusX = " << settings.otherRoundedCornersRadius.x;
    *os << "\n    .otherRoundedCornersRadiusY = " << settings.otherRoundedCornersRadius.y;
    *os << "\n    .otherCrop = ";
    PrintTo(settings.otherCrop, os);

    *os << "\n}";
}

+71 −54
Original line number Diff line number Diff line
@@ -887,6 +887,7 @@ void SkiaRenderEngine::drawLayersInternal(
        const auto [bounds, roundRectClip] =
                getBoundsAndClip(layer.geometry.boundaries, layer.geometry.roundedCornersCrop,
                                 layer.geometry.roundedCornersRadius);

        if (mBlurFilter && layerHasBlur(layer, ctModifiesAlpha)) {
            std::unordered_map<uint32_t, sk_sp<SkImage>> cachedBlurs;

@@ -963,6 +964,17 @@ void SkiaRenderEngine::drawLayersInternal(
            }
        }

        {
            SkRRect otherCrop;
            otherCrop.setRectXY(getSkRect(layer.geometry.otherCrop),
                                layer.geometry.otherRoundedCornersRadius.x,
                                layer.geometry.otherRoundedCornersRadius.y);
            // Outset rendering needs to be clipped by parent.
            SkAutoCanvasRestore acr(canvas, true);
            if (!otherCrop.isEmpty()) {
                canvas->clipRRect(otherCrop, true);
            }

            if (layer.shadow.length > 0) {
                // This would require a new parameter/flag to SkShadowUtils::DrawShadow
                LOG_ALWAYS_FATAL_IF(layer.disableBlending, "Cannot disableBlending with a shadow");
@@ -973,7 +985,8 @@ void SkiaRenderEngine::drawLayersInternal(
                    shadowClip = roundRectClip;
                } else {
                    std::tie(shadowBounds, shadowClip) =
                        getBoundsAndClip(layer.shadow.boundaries, layer.geometry.roundedCornersCrop,
                            getBoundsAndClip(layer.shadow.boundaries,
                                             layer.geometry.roundedCornersCrop,
                                             layer.geometry.roundedCornersRadius);
                }

@@ -993,16 +1006,19 @@ void SkiaRenderEngine::drawLayersInternal(
            // identical.
            SkRRect originalBounds, originalClip;
            std::tie(originalBounds, originalClip) =
                getBoundsAndClip(layer.geometry.originalBounds, layer.geometry.roundedCornersCrop,
                    getBoundsAndClip(layer.geometry.originalBounds,
                                     layer.geometry.roundedCornersCrop,
                                     layer.geometry.roundedCornersRadius);
            const SkRRect& preferredOriginalBounds =
                originalBounds.isRect() && !originalClip.isEmpty() ? originalClip : originalBounds;
                    originalBounds.isRect() && !originalClip.isEmpty() ? originalClip
                                                                       : originalBounds;

            // Similar to shadows, do the rendering before the clip is applied because even when the
            // layer is occluded it should have an outline.
            if (layer.borderSettings.strokeWidth > 0) {
                SkRRect outlineRect = preferredOriginalBounds;
            outlineRect.outset(layer.borderSettings.strokeWidth, layer.borderSettings.strokeWidth);
                outlineRect.outset(layer.borderSettings.strokeWidth,
                                   layer.borderSettings.strokeWidth);

                SkPaint paint;
                paint.setAntiAlias(true);
@@ -1025,6 +1041,7 @@ void SkiaRenderEngine::drawLayersInternal(
                    canvas->drawRRect(boxRect, blur);
                }
            }
        }

        const float layerDimmingRatio = layer.whitePointNits <= 0.f
                ? displayDimmingRatio
+5 −0
Original line number Diff line number Diff line
@@ -76,6 +76,11 @@ struct LayerSnapshot : public compositionengine::LayerFECompositionState {
    bool contentOpaque;
    bool layerOpaqueFlagSet;
    RoundedCornerState roundedCorner;
    // roundedCorner of the parent but in local space.
    RoundedCornerState parentRoundedCorner;
    // geomLayerCrop of the parent but in local space.
    FloatRect parentGeomLayerCrop;

    FloatRect transformedBounds;
    Rect transformedBoundsWithoutTransparentRegion;
    bool premultipliedAlpha;
+5 −0
Original line number Diff line number Diff line
@@ -1042,6 +1042,8 @@ void LayerSnapshotBuilder::updateRoundedCorner(LayerSnapshot& snapshot,
    } else {
        snapshot.roundedCorner.radius = snapshot.roundedCorner.requestedRadius;
    }

    snapshot.parentRoundedCorner = parentRoundedCorner;
}

/**
@@ -1128,6 +1130,9 @@ void LayerSnapshotBuilder::updateLayerBounds(LayerSnapshot& snapshot,
                                                        requested.getTransparentRegion());
        snapshot.cursorFrame = snapshot.geomLayerTransform.transform(bounds);
    }

    snapshot.parentGeomLayerCrop =
            snapshot.localTransform.inverse().transform(parentSnapshot.geomLayerCrop);
}

void LayerSnapshotBuilder::updateShadows(LayerSnapshot& snapshot, const RequestedLayerState&,
+8 −0
Original line number Diff line number Diff line
@@ -124,6 +124,14 @@ std::optional<compositionengine::LayerFE::LayerSettings> LayerFE::prepareClientC
    SFTRACE_CALL();
    compositionengine::LayerFE::LayerSettings layerSettings;
    layerSettings.geometry.originalBounds = mSnapshot->geomLayerBounds;

    if (mSnapshot->parentRoundedCorner.hasRequestedRadius()) {
        layerSettings.geometry.otherRoundedCornersRadius = mSnapshot->parentRoundedCorner.radius;
        layerSettings.geometry.otherCrop = mSnapshot->parentRoundedCorner.cropRect;
    } else {
        layerSettings.geometry.otherCrop = mSnapshot->parentGeomLayerCrop;
    }

    layerSettings.geometry.boundaries =
            reduce(mSnapshot->geomLayerBounds, mSnapshot->transparentRegionHint);
    layerSettings.geometry.positionTransform = mSnapshot->geomLayerTransform.asMatrix4();
Loading