Loading libs/renderengine/include/renderengine/LayerSettings.h +16 −4 Original line number Diff line number Diff line Loading @@ -107,6 +107,9 @@ struct PixelSource { * material design guidelines. */ struct ShadowSettings { // Boundaries of the shadow. FloatRect boundaries = FloatRect(); // Color to the ambient shadow. The alpha is premultiplied. vec4 ambientColor = vec4(); Loading Loading @@ -150,6 +153,10 @@ struct LayerSettings { // True if blending will be forced to be disabled. bool disableBlending = false; // If true, then this layer casts a shadow and/or blurs behind it, but it does // not otherwise draw any of the layer's other contents. bool skipContentDraw = false; ShadowSettings shadow; int backgroundBlurRadius = 0; Loading Loading @@ -189,9 +196,10 @@ static inline bool operator==(const PixelSource& lhs, const PixelSource& rhs) { } static inline bool operator==(const ShadowSettings& lhs, const ShadowSettings& rhs) { return lhs.ambientColor == rhs.ambientColor && lhs.spotColor == rhs.spotColor && lhs.lightPos == rhs.lightPos && lhs.lightRadius == rhs.lightRadius && lhs.length == rhs.length && lhs.casterIsTranslucent == rhs.casterIsTranslucent; return lhs.boundaries == rhs.boundaries && lhs.ambientColor == rhs.ambientColor && lhs.spotColor == rhs.spotColor && lhs.lightPos == rhs.lightPos && lhs.lightRadius == rhs.lightRadius && lhs.length == rhs.length && lhs.casterIsTranslucent == rhs.casterIsTranslucent; } static inline bool operator==(const LayerSettings& lhs, const LayerSettings& rhs) { Loading @@ -208,7 +216,8 @@ static inline bool operator==(const LayerSettings& lhs, const LayerSettings& rhs return lhs.geometry == rhs.geometry && lhs.source == rhs.source && lhs.alpha == rhs.alpha && lhs.sourceDataspace == rhs.sourceDataspace && lhs.colorTransform == rhs.colorTransform && lhs.disableBlending == rhs.disableBlending && lhs.shadow == rhs.shadow && lhs.disableBlending == rhs.disableBlending && lhs.skipContentDraw == rhs.skipContentDraw && lhs.shadow == rhs.shadow && lhs.backgroundBlurRadius == rhs.backgroundBlurRadius && lhs.blurRegionTransform == rhs.blurRegionTransform && lhs.stretchEffect == rhs.stretchEffect; Loading Loading @@ -251,6 +260,8 @@ static inline void PrintTo(const PixelSource& settings, ::std::ostream* os) { static inline void PrintTo(const ShadowSettings& settings, ::std::ostream* os) { *os << "ShadowSettings {"; *os << "\n .boundaries = "; PrintTo(settings.boundaries, os); *os << "\n .ambientColor = " << settings.ambientColor; *os << "\n .spotColor = " << settings.spotColor; *os << "\n .lightPos = " << settings.lightPos; Loading Loading @@ -286,6 +297,7 @@ static inline void PrintTo(const LayerSettings& settings, ::std::ostream* os) { PrintTo(settings.sourceDataspace, os); *os << "\n .colorTransform = " << settings.colorTransform; *os << "\n .disableBlending = " << settings.disableBlending; *os << "\n .skipContentDraw = " << settings.skipContentDraw; *os << "\n .backgroundBlurRadius = " << settings.backgroundBlurRadius; for (auto blurRegion : settings.blurRegions) { *os << "\n"; Loading libs/renderengine/skia/SkiaGLRenderEngine.cpp +23 −14 Original line number Diff line number Diff line Loading @@ -846,7 +846,9 @@ status_t SkiaGLRenderEngine::drawLayers(const DisplaySettings& display, // Layers have a local transform that should be applied to them canvas->concat(getSkM44(layer->geometry.positionTransform).asM33()); const auto [bounds, roundRectClip] = getBoundsAndClip(layer); const auto [bounds, roundRectClip] = getBoundsAndClip(layer->geometry.boundaries, layer->geometry.roundedCornersCrop, layer->geometry.roundedCornersRadius); if (mBlurFilter && layerHasBlur(layer)) { std::unordered_map<uint32_t, sk_sp<SkImage>> cachedBlurs; Loading Loading @@ -895,14 +897,21 @@ status_t SkiaGLRenderEngine::drawLayers(const DisplaySettings& display, } } // Shadows are assumed to live only on their own layer - it's not valid // to draw the boundary rectangles when there is already a caster shadow // TODO(b/175915334): consider relaxing this restriction to enable more flexible // composition - using a well-defined invalid color is long-term less error-prone. 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"); SkRRect shadowBounds, shadowClip; if (layer->geometry.boundaries == layer->shadow.boundaries) { shadowBounds = bounds; shadowClip = roundRectClip; } else { std::tie(shadowBounds, shadowClip) = getBoundsAndClip(layer->shadow.boundaries, layer->geometry.roundedCornersCrop, layer->geometry.roundedCornersRadius); } // Technically, if bounds is a rect and roundRectClip is not empty, // it means that the bounds and roundedCornersCrop were different // enough that we should intersect them to find the proper shadow. Loading @@ -910,9 +919,8 @@ status_t SkiaGLRenderEngine::drawLayers(const DisplaySettings& display, // not match due to rounding errors. Draw the rounded version, which // looks more like the intent. const auto& rrect = bounds.isRect() && !roundRectClip.isEmpty() ? roundRectClip : bounds; shadowBounds.isRect() && !shadowClip.isEmpty() ? shadowClip : shadowBounds; drawShadow(canvas, rrect, layer->shadow); continue; } const bool requiresLinearEffect = layer->colorTransform != mat4() || Loading @@ -922,8 +930,9 @@ status_t SkiaGLRenderEngine::drawLayers(const DisplaySettings& display, display.sdrWhitePointNits != display.maxLuminance); // quick abort from drawing the remaining portion of the layer if (layer->alpha == 0 && !requiresLinearEffect && !layer->disableBlending && (!displayColorTransform || displayColorTransform->isAlphaUnchanged())) { if (layer->skipContentDraw || (layer->alpha == 0 && !requiresLinearEffect && !layer->disableBlending && (!displayColorTransform || displayColorTransform->isAlphaUnchanged()))) { continue; } Loading Loading @@ -1093,11 +1102,11 @@ inline SkRect SkiaGLRenderEngine::getSkRect(const Rect& rect) { return SkRect::MakeLTRB(rect.left, rect.top, rect.right, rect.bottom); } inline std::pair<SkRRect, SkRRect> SkiaGLRenderEngine::getBoundsAndClip( const LayerSettings* layer) { const auto bounds = getSkRect(layer->geometry.boundaries); const auto crop = getSkRect(layer->geometry.roundedCornersCrop); const auto cornerRadius = layer->geometry.roundedCornersRadius; inline std::pair<SkRRect, SkRRect> SkiaGLRenderEngine::getBoundsAndClip(const FloatRect& boundsRect, const FloatRect& cropRect, const float cornerRadius) { const SkRect bounds = getSkRect(boundsRect); const SkRect crop = getSkRect(cropRect); SkRRect clip; if (cornerRadius > 0) { Loading libs/renderengine/skia/SkiaGLRenderEngine.h +2 −1 Original line number Diff line number Diff line Loading @@ -88,7 +88,8 @@ private: int hwcFormat, Protection protection); inline SkRect getSkRect(const FloatRect& layer); inline SkRect getSkRect(const Rect& layer); inline std::pair<SkRRect, SkRRect> getBoundsAndClip(const LayerSettings* layer); inline std::pair<SkRRect, SkRRect> getBoundsAndClip(const FloatRect& bounds, const FloatRect& crop, float cornerRadius); inline bool layerHasBlur(const LayerSettings* layer); inline SkColor getSkColor(const vec4& color); inline SkM44 getSkM44(const mat4& matrix); Loading libs/renderengine/tests/RenderEngineTest.cpp +1 −0 Original line number Diff line number Diff line Loading @@ -1265,6 +1265,7 @@ void RenderEngineTest::drawShadowWithoutCaster(const FloatRect& castingBounds, renderengine::LayerSettings shadowLayer; shadowLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR; shadowLayer.geometry.boundaries = castingBounds; shadowLayer.skipContentDraw = true; shadowLayer.alpha = 1.0f; ColorSourceVariant::fillColor(shadowLayer, 0, 0, 0, this); shadowLayer.shadow = shadow; Loading services/surfaceflinger/EffectLayer.cpp +3 −7 Original line number Diff line number Diff line Loading @@ -57,19 +57,15 @@ std::vector<compositionengine::LayerFE::LayerSettings> EffectLayer::prepareClien return {}; } std::optional<compositionengine::LayerFE::LayerSettings> shadowSettings = prepareShadowClientComposition(*layerSettings, targetSettings.viewport, targetSettings.dataspace); if (shadowSettings) { results.push_back(*shadowSettings); } // set the shadow for the layer if needed prepareShadowClientComposition(*layerSettings, targetSettings.viewport); // If fill bounds are occluded or the fill color is invalid skip the fill settings. if (targetSettings.realContentIsVisible && fillsColor()) { // Set color for color fill settings. layerSettings->source.solidColor = getColor().rgb; results.push_back(*layerSettings); } else if (hasBlur()) { } else if (hasBlur() || drawShadows()) { results.push_back(*layerSettings); } Loading Loading
libs/renderengine/include/renderengine/LayerSettings.h +16 −4 Original line number Diff line number Diff line Loading @@ -107,6 +107,9 @@ struct PixelSource { * material design guidelines. */ struct ShadowSettings { // Boundaries of the shadow. FloatRect boundaries = FloatRect(); // Color to the ambient shadow. The alpha is premultiplied. vec4 ambientColor = vec4(); Loading Loading @@ -150,6 +153,10 @@ struct LayerSettings { // True if blending will be forced to be disabled. bool disableBlending = false; // If true, then this layer casts a shadow and/or blurs behind it, but it does // not otherwise draw any of the layer's other contents. bool skipContentDraw = false; ShadowSettings shadow; int backgroundBlurRadius = 0; Loading Loading @@ -189,9 +196,10 @@ static inline bool operator==(const PixelSource& lhs, const PixelSource& rhs) { } static inline bool operator==(const ShadowSettings& lhs, const ShadowSettings& rhs) { return lhs.ambientColor == rhs.ambientColor && lhs.spotColor == rhs.spotColor && lhs.lightPos == rhs.lightPos && lhs.lightRadius == rhs.lightRadius && lhs.length == rhs.length && lhs.casterIsTranslucent == rhs.casterIsTranslucent; return lhs.boundaries == rhs.boundaries && lhs.ambientColor == rhs.ambientColor && lhs.spotColor == rhs.spotColor && lhs.lightPos == rhs.lightPos && lhs.lightRadius == rhs.lightRadius && lhs.length == rhs.length && lhs.casterIsTranslucent == rhs.casterIsTranslucent; } static inline bool operator==(const LayerSettings& lhs, const LayerSettings& rhs) { Loading @@ -208,7 +216,8 @@ static inline bool operator==(const LayerSettings& lhs, const LayerSettings& rhs return lhs.geometry == rhs.geometry && lhs.source == rhs.source && lhs.alpha == rhs.alpha && lhs.sourceDataspace == rhs.sourceDataspace && lhs.colorTransform == rhs.colorTransform && lhs.disableBlending == rhs.disableBlending && lhs.shadow == rhs.shadow && lhs.disableBlending == rhs.disableBlending && lhs.skipContentDraw == rhs.skipContentDraw && lhs.shadow == rhs.shadow && lhs.backgroundBlurRadius == rhs.backgroundBlurRadius && lhs.blurRegionTransform == rhs.blurRegionTransform && lhs.stretchEffect == rhs.stretchEffect; Loading Loading @@ -251,6 +260,8 @@ static inline void PrintTo(const PixelSource& settings, ::std::ostream* os) { static inline void PrintTo(const ShadowSettings& settings, ::std::ostream* os) { *os << "ShadowSettings {"; *os << "\n .boundaries = "; PrintTo(settings.boundaries, os); *os << "\n .ambientColor = " << settings.ambientColor; *os << "\n .spotColor = " << settings.spotColor; *os << "\n .lightPos = " << settings.lightPos; Loading Loading @@ -286,6 +297,7 @@ static inline void PrintTo(const LayerSettings& settings, ::std::ostream* os) { PrintTo(settings.sourceDataspace, os); *os << "\n .colorTransform = " << settings.colorTransform; *os << "\n .disableBlending = " << settings.disableBlending; *os << "\n .skipContentDraw = " << settings.skipContentDraw; *os << "\n .backgroundBlurRadius = " << settings.backgroundBlurRadius; for (auto blurRegion : settings.blurRegions) { *os << "\n"; Loading
libs/renderengine/skia/SkiaGLRenderEngine.cpp +23 −14 Original line number Diff line number Diff line Loading @@ -846,7 +846,9 @@ status_t SkiaGLRenderEngine::drawLayers(const DisplaySettings& display, // Layers have a local transform that should be applied to them canvas->concat(getSkM44(layer->geometry.positionTransform).asM33()); const auto [bounds, roundRectClip] = getBoundsAndClip(layer); const auto [bounds, roundRectClip] = getBoundsAndClip(layer->geometry.boundaries, layer->geometry.roundedCornersCrop, layer->geometry.roundedCornersRadius); if (mBlurFilter && layerHasBlur(layer)) { std::unordered_map<uint32_t, sk_sp<SkImage>> cachedBlurs; Loading Loading @@ -895,14 +897,21 @@ status_t SkiaGLRenderEngine::drawLayers(const DisplaySettings& display, } } // Shadows are assumed to live only on their own layer - it's not valid // to draw the boundary rectangles when there is already a caster shadow // TODO(b/175915334): consider relaxing this restriction to enable more flexible // composition - using a well-defined invalid color is long-term less error-prone. 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"); SkRRect shadowBounds, shadowClip; if (layer->geometry.boundaries == layer->shadow.boundaries) { shadowBounds = bounds; shadowClip = roundRectClip; } else { std::tie(shadowBounds, shadowClip) = getBoundsAndClip(layer->shadow.boundaries, layer->geometry.roundedCornersCrop, layer->geometry.roundedCornersRadius); } // Technically, if bounds is a rect and roundRectClip is not empty, // it means that the bounds and roundedCornersCrop were different // enough that we should intersect them to find the proper shadow. Loading @@ -910,9 +919,8 @@ status_t SkiaGLRenderEngine::drawLayers(const DisplaySettings& display, // not match due to rounding errors. Draw the rounded version, which // looks more like the intent. const auto& rrect = bounds.isRect() && !roundRectClip.isEmpty() ? roundRectClip : bounds; shadowBounds.isRect() && !shadowClip.isEmpty() ? shadowClip : shadowBounds; drawShadow(canvas, rrect, layer->shadow); continue; } const bool requiresLinearEffect = layer->colorTransform != mat4() || Loading @@ -922,8 +930,9 @@ status_t SkiaGLRenderEngine::drawLayers(const DisplaySettings& display, display.sdrWhitePointNits != display.maxLuminance); // quick abort from drawing the remaining portion of the layer if (layer->alpha == 0 && !requiresLinearEffect && !layer->disableBlending && (!displayColorTransform || displayColorTransform->isAlphaUnchanged())) { if (layer->skipContentDraw || (layer->alpha == 0 && !requiresLinearEffect && !layer->disableBlending && (!displayColorTransform || displayColorTransform->isAlphaUnchanged()))) { continue; } Loading Loading @@ -1093,11 +1102,11 @@ inline SkRect SkiaGLRenderEngine::getSkRect(const Rect& rect) { return SkRect::MakeLTRB(rect.left, rect.top, rect.right, rect.bottom); } inline std::pair<SkRRect, SkRRect> SkiaGLRenderEngine::getBoundsAndClip( const LayerSettings* layer) { const auto bounds = getSkRect(layer->geometry.boundaries); const auto crop = getSkRect(layer->geometry.roundedCornersCrop); const auto cornerRadius = layer->geometry.roundedCornersRadius; inline std::pair<SkRRect, SkRRect> SkiaGLRenderEngine::getBoundsAndClip(const FloatRect& boundsRect, const FloatRect& cropRect, const float cornerRadius) { const SkRect bounds = getSkRect(boundsRect); const SkRect crop = getSkRect(cropRect); SkRRect clip; if (cornerRadius > 0) { Loading
libs/renderengine/skia/SkiaGLRenderEngine.h +2 −1 Original line number Diff line number Diff line Loading @@ -88,7 +88,8 @@ private: int hwcFormat, Protection protection); inline SkRect getSkRect(const FloatRect& layer); inline SkRect getSkRect(const Rect& layer); inline std::pair<SkRRect, SkRRect> getBoundsAndClip(const LayerSettings* layer); inline std::pair<SkRRect, SkRRect> getBoundsAndClip(const FloatRect& bounds, const FloatRect& crop, float cornerRadius); inline bool layerHasBlur(const LayerSettings* layer); inline SkColor getSkColor(const vec4& color); inline SkM44 getSkM44(const mat4& matrix); Loading
libs/renderengine/tests/RenderEngineTest.cpp +1 −0 Original line number Diff line number Diff line Loading @@ -1265,6 +1265,7 @@ void RenderEngineTest::drawShadowWithoutCaster(const FloatRect& castingBounds, renderengine::LayerSettings shadowLayer; shadowLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR; shadowLayer.geometry.boundaries = castingBounds; shadowLayer.skipContentDraw = true; shadowLayer.alpha = 1.0f; ColorSourceVariant::fillColor(shadowLayer, 0, 0, 0, this); shadowLayer.shadow = shadow; Loading
services/surfaceflinger/EffectLayer.cpp +3 −7 Original line number Diff line number Diff line Loading @@ -57,19 +57,15 @@ std::vector<compositionengine::LayerFE::LayerSettings> EffectLayer::prepareClien return {}; } std::optional<compositionengine::LayerFE::LayerSettings> shadowSettings = prepareShadowClientComposition(*layerSettings, targetSettings.viewport, targetSettings.dataspace); if (shadowSettings) { results.push_back(*shadowSettings); } // set the shadow for the layer if needed prepareShadowClientComposition(*layerSettings, targetSettings.viewport); // If fill bounds are occluded or the fill color is invalid skip the fill settings. if (targetSettings.realContentIsVisible && fillsColor()) { // Set color for color fill settings. layerSettings->source.solidColor = getColor().rgb; results.push_back(*layerSettings); } else if (hasBlur()) { } else if (hasBlur() || drawShadows()) { results.push_back(*layerSettings); } Loading