Loading libs/renderengine/include/renderengine/LayerSettings.h +10 −0 Original line number Diff line number Diff line Loading @@ -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. Loading Loading @@ -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}"; } Loading libs/renderengine/skia/SkiaRenderEngine.cpp +71 −54 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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"); Loading @@ -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); } Loading @@ -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); Loading @@ -1025,6 +1041,7 @@ void SkiaRenderEngine::drawLayersInternal( canvas->drawRRect(boxRect, blur); } } } const float layerDimmingRatio = layer.whitePointNits <= 0.f ? displayDimmingRatio Loading services/surfaceflinger/FrontEnd/LayerSnapshot.h +5 −0 Original line number Diff line number Diff line Loading @@ -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; Loading services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp +5 −0 Original line number Diff line number Diff line Loading @@ -1048,6 +1048,8 @@ void LayerSnapshotBuilder::updateRoundedCorner(LayerSnapshot& snapshot, } else { snapshot.roundedCorner.radius = snapshot.roundedCorner.requestedRadius; } snapshot.parentRoundedCorner = parentRoundedCorner; } /** Loading Loading @@ -1134,6 +1136,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&, Loading services/surfaceflinger/LayerFE.cpp +8 −0 Original line number Diff line number Diff line Loading @@ -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 Loading
libs/renderengine/include/renderengine/LayerSettings.h +10 −0 Original line number Diff line number Diff line Loading @@ -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. Loading Loading @@ -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}"; } Loading
libs/renderengine/skia/SkiaRenderEngine.cpp +71 −54 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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"); Loading @@ -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); } Loading @@ -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); Loading @@ -1025,6 +1041,7 @@ void SkiaRenderEngine::drawLayersInternal( canvas->drawRRect(boxRect, blur); } } } const float layerDimmingRatio = layer.whitePointNits <= 0.f ? displayDimmingRatio Loading
services/surfaceflinger/FrontEnd/LayerSnapshot.h +5 −0 Original line number Diff line number Diff line Loading @@ -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; Loading
services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp +5 −0 Original line number Diff line number Diff line Loading @@ -1048,6 +1048,8 @@ void LayerSnapshotBuilder::updateRoundedCorner(LayerSnapshot& snapshot, } else { snapshot.roundedCorner.radius = snapshot.roundedCorner.requestedRadius; } snapshot.parentRoundedCorner = parentRoundedCorner; } /** Loading Loading @@ -1134,6 +1136,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&, Loading
services/surfaceflinger/LayerFE.cpp +8 −0 Original line number Diff line number Diff line Loading @@ -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