Loading libs/renderengine/skia/SkiaGLRenderEngine.cpp +10 −6 Original line number Original line Diff line number Diff line Loading @@ -672,13 +672,17 @@ status_t SkiaGLRenderEngine::drawLayers(const DisplaySettings& display, ? getSkRect(layer->geometry.roundedCornersCrop) ? getSkRect(layer->geometry.roundedCornersCrop) : dest; : dest; drawShadow(canvas, rect, layer->geometry.roundedCornersRadius, layer->shadow); drawShadow(canvas, rect, layer->geometry.roundedCornersRadius, layer->shadow); } } else { // Shadows are assumed to live only on their own layer - it's not valid // to draw the boundary retangles 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. // Push the clipRRect onto the clip stack. Draw the image. Pop the clip. // Push the clipRRect onto the clip stack. Draw the image. Pop the clip. if (layer->geometry.roundedCornersRadius > 0) { if (layer->geometry.roundedCornersRadius > 0) { canvas->clipRRect(getRoundedRect(layer), true); canvas->clipRRect(getRoundedRect(layer), true); } } canvas->drawRect(dest, paint); canvas->drawRect(dest, paint); } canvas->restore(); canvas->restore(); } } canvas->restore(); canvas->restore(); Loading libs/renderengine/tests/RenderEngineTest.cpp +71 −0 Original line number Original line Diff line number Diff line Loading @@ -306,6 +306,26 @@ public: backgroundColor.a); backgroundColor.a); } } void expectShadowColorWithoutCaster(const FloatRect& casterBounds, const renderengine::ShadowSettings& shadow, const ubyte4& backgroundColor) { const float shadowInset = shadow.length * -1.0f; const Rect casterRect(casterBounds); const Rect shadowRect = Rect(casterRect).inset(shadowInset, shadowInset, shadowInset, shadowInset); const Region backgroundRegion = Region(fullscreenRect()).subtractSelf(casterRect).subtractSelf(shadowRect); expectAlpha(shadowRect, 255); // (0, 0, 0) fill on the bounds of the layer should be ignored. expectBufferColor(casterRect, 255, 255, 255, 255, 254); // verify background expectBufferColor(backgroundRegion, backgroundColor.r, backgroundColor.g, backgroundColor.b, backgroundColor.a); } static renderengine::ShadowSettings getShadowSettings(const vec2& casterPos, float shadowLength, static renderengine::ShadowSettings getShadowSettings(const vec2& casterPos, float shadowLength, bool casterIsTranslucent) { bool casterIsTranslucent) { renderengine::ShadowSettings shadow; renderengine::ShadowSettings shadow; Loading Loading @@ -447,6 +467,10 @@ public: const renderengine::ShadowSettings& shadow, const ubyte4& casterColor, const renderengine::ShadowSettings& shadow, const ubyte4& casterColor, const ubyte4& backgroundColor); const ubyte4& backgroundColor); void drawShadowWithoutCaster(const FloatRect& castingBounds, const renderengine::ShadowSettings& shadow, const ubyte4& backgroundColor); std::unique_ptr<renderengine::gl::GLESRenderEngine> mRE; std::unique_ptr<renderengine::gl::GLESRenderEngine> mRE; // Dumb hack to avoid NPE in the EGL driver: the GraphicBuffer needs to // Dumb hack to avoid NPE in the EGL driver: the GraphicBuffer needs to Loading Loading @@ -1119,6 +1143,37 @@ void RenderEngineTest::drawShadow(const renderengine::LayerSettings& castingLaye invokeDraw(settings, layers, mBuffer); invokeDraw(settings, layers, mBuffer); } } void RenderEngineTest::drawShadowWithoutCaster(const FloatRect& castingBounds, const renderengine::ShadowSettings& shadow, const ubyte4& backgroundColor) { renderengine::DisplaySettings settings; settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR; settings.physicalDisplay = fullscreenRect(); settings.clip = fullscreenRect(); std::vector<const renderengine::LayerSettings*> layers; // add background layer renderengine::LayerSettings bgLayer; bgLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR; bgLayer.geometry.boundaries = fullscreenRect().toFloatRect(); ColorSourceVariant::fillColor(bgLayer, backgroundColor.r / 255.0f, backgroundColor.g / 255.0f, backgroundColor.b / 255.0f, this); bgLayer.alpha = backgroundColor.a / 255.0f; layers.push_back(&bgLayer); // add shadow layer renderengine::LayerSettings shadowLayer; shadowLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR; shadowLayer.geometry.boundaries = castingBounds; shadowLayer.alpha = 1.0f; ColorSourceVariant::fillColor(shadowLayer, 0, 0, 0, this); shadowLayer.shadow = shadow; layers.push_back(&shadowLayer); invokeDraw(settings, layers, mBuffer); } INSTANTIATE_TEST_SUITE_P(PerRenderEngineType, RenderEngineTest, INSTANTIATE_TEST_SUITE_P(PerRenderEngineType, RenderEngineTest, testing::Values(std::make_shared<GLESRenderEngineFactory>(), testing::Values(std::make_shared<GLESRenderEngineFactory>(), std::make_shared<GLESCMRenderEngineFactory>(), std::make_shared<GLESCMRenderEngineFactory>(), Loading Loading @@ -1609,6 +1664,22 @@ TEST_P(RenderEngineTest, cacheExternalBuffer_cachesImages) { EXPECT_FALSE(mRE->isImageCachedForTesting(bufferId)); EXPECT_FALSE(mRE->isImageCachedForTesting(bufferId)); } } TEST_P(RenderEngineTest, drawLayers_fillShadow_castsWithoutCasterLayer) { const auto& renderEngineFactory = GetParam(); mRE = renderEngineFactory->createRenderEngine(); const ubyte4 backgroundColor(255, 255, 255, 255); const float shadowLength = 5.0f; Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f); casterBounds.offsetBy(shadowLength + 1, shadowLength + 1); renderengine::ShadowSettings settings = getShadowSettings(vec2(casterBounds.left, casterBounds.top), shadowLength, false /* casterIsTranslucent */); drawShadowWithoutCaster(casterBounds.toFloatRect(), settings, backgroundColor); expectShadowColorWithoutCaster(casterBounds.toFloatRect(), settings, backgroundColor); } TEST_P(RenderEngineTest, drawLayers_fillShadow_casterLayerMinSize) { TEST_P(RenderEngineTest, drawLayers_fillShadow_casterLayerMinSize) { const auto& renderEngineFactory = GetParam(); const auto& renderEngineFactory = GetParam(); mRE = renderEngineFactory->createRenderEngine(); mRE = renderEngineFactory->createRenderEngine(); Loading services/surfaceflinger/Layer.cpp +2 −0 Original line number Original line Diff line number Diff line Loading @@ -688,6 +688,7 @@ std::optional<compositionengine::LayerFE::LayerSettings> Layer::prepareShadowCli shadowLayer.source.buffer.fence = nullptr; shadowLayer.source.buffer.fence = nullptr; shadowLayer.frameNumber = 0; shadowLayer.frameNumber = 0; shadowLayer.bufferId = 0; shadowLayer.bufferId = 0; shadowLayer.name = getName(); if (shadowLayer.shadow.ambientColor.a <= 0.f && shadowLayer.shadow.spotColor.a <= 0.f) { if (shadowLayer.shadow.ambientColor.a <= 0.f && shadowLayer.shadow.spotColor.a <= 0.f) { return {}; return {}; Loading Loading @@ -723,6 +724,7 @@ void Layer::prepareClearClientComposition(LayerFE::LayerSettings& layerSettings, // If layer is blacked out, force alpha to 1 so that we draw a black color layer. // If layer is blacked out, force alpha to 1 so that we draw a black color layer. layerSettings.alpha = blackout ? 1.0f : 0.0f; layerSettings.alpha = blackout ? 1.0f : 0.0f; layerSettings.name = getName(); } } std::vector<compositionengine::LayerFE::LayerSettings> Layer::prepareClientCompositionList( std::vector<compositionengine::LayerFE::LayerSettings> Layer::prepareClientCompositionList( Loading Loading
libs/renderengine/skia/SkiaGLRenderEngine.cpp +10 −6 Original line number Original line Diff line number Diff line Loading @@ -672,13 +672,17 @@ status_t SkiaGLRenderEngine::drawLayers(const DisplaySettings& display, ? getSkRect(layer->geometry.roundedCornersCrop) ? getSkRect(layer->geometry.roundedCornersCrop) : dest; : dest; drawShadow(canvas, rect, layer->geometry.roundedCornersRadius, layer->shadow); drawShadow(canvas, rect, layer->geometry.roundedCornersRadius, layer->shadow); } } else { // Shadows are assumed to live only on their own layer - it's not valid // to draw the boundary retangles 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. // Push the clipRRect onto the clip stack. Draw the image. Pop the clip. // Push the clipRRect onto the clip stack. Draw the image. Pop the clip. if (layer->geometry.roundedCornersRadius > 0) { if (layer->geometry.roundedCornersRadius > 0) { canvas->clipRRect(getRoundedRect(layer), true); canvas->clipRRect(getRoundedRect(layer), true); } } canvas->drawRect(dest, paint); canvas->drawRect(dest, paint); } canvas->restore(); canvas->restore(); } } canvas->restore(); canvas->restore(); Loading
libs/renderengine/tests/RenderEngineTest.cpp +71 −0 Original line number Original line Diff line number Diff line Loading @@ -306,6 +306,26 @@ public: backgroundColor.a); backgroundColor.a); } } void expectShadowColorWithoutCaster(const FloatRect& casterBounds, const renderengine::ShadowSettings& shadow, const ubyte4& backgroundColor) { const float shadowInset = shadow.length * -1.0f; const Rect casterRect(casterBounds); const Rect shadowRect = Rect(casterRect).inset(shadowInset, shadowInset, shadowInset, shadowInset); const Region backgroundRegion = Region(fullscreenRect()).subtractSelf(casterRect).subtractSelf(shadowRect); expectAlpha(shadowRect, 255); // (0, 0, 0) fill on the bounds of the layer should be ignored. expectBufferColor(casterRect, 255, 255, 255, 255, 254); // verify background expectBufferColor(backgroundRegion, backgroundColor.r, backgroundColor.g, backgroundColor.b, backgroundColor.a); } static renderengine::ShadowSettings getShadowSettings(const vec2& casterPos, float shadowLength, static renderengine::ShadowSettings getShadowSettings(const vec2& casterPos, float shadowLength, bool casterIsTranslucent) { bool casterIsTranslucent) { renderengine::ShadowSettings shadow; renderengine::ShadowSettings shadow; Loading Loading @@ -447,6 +467,10 @@ public: const renderengine::ShadowSettings& shadow, const ubyte4& casterColor, const renderengine::ShadowSettings& shadow, const ubyte4& casterColor, const ubyte4& backgroundColor); const ubyte4& backgroundColor); void drawShadowWithoutCaster(const FloatRect& castingBounds, const renderengine::ShadowSettings& shadow, const ubyte4& backgroundColor); std::unique_ptr<renderengine::gl::GLESRenderEngine> mRE; std::unique_ptr<renderengine::gl::GLESRenderEngine> mRE; // Dumb hack to avoid NPE in the EGL driver: the GraphicBuffer needs to // Dumb hack to avoid NPE in the EGL driver: the GraphicBuffer needs to Loading Loading @@ -1119,6 +1143,37 @@ void RenderEngineTest::drawShadow(const renderengine::LayerSettings& castingLaye invokeDraw(settings, layers, mBuffer); invokeDraw(settings, layers, mBuffer); } } void RenderEngineTest::drawShadowWithoutCaster(const FloatRect& castingBounds, const renderengine::ShadowSettings& shadow, const ubyte4& backgroundColor) { renderengine::DisplaySettings settings; settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR; settings.physicalDisplay = fullscreenRect(); settings.clip = fullscreenRect(); std::vector<const renderengine::LayerSettings*> layers; // add background layer renderengine::LayerSettings bgLayer; bgLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR; bgLayer.geometry.boundaries = fullscreenRect().toFloatRect(); ColorSourceVariant::fillColor(bgLayer, backgroundColor.r / 255.0f, backgroundColor.g / 255.0f, backgroundColor.b / 255.0f, this); bgLayer.alpha = backgroundColor.a / 255.0f; layers.push_back(&bgLayer); // add shadow layer renderengine::LayerSettings shadowLayer; shadowLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR; shadowLayer.geometry.boundaries = castingBounds; shadowLayer.alpha = 1.0f; ColorSourceVariant::fillColor(shadowLayer, 0, 0, 0, this); shadowLayer.shadow = shadow; layers.push_back(&shadowLayer); invokeDraw(settings, layers, mBuffer); } INSTANTIATE_TEST_SUITE_P(PerRenderEngineType, RenderEngineTest, INSTANTIATE_TEST_SUITE_P(PerRenderEngineType, RenderEngineTest, testing::Values(std::make_shared<GLESRenderEngineFactory>(), testing::Values(std::make_shared<GLESRenderEngineFactory>(), std::make_shared<GLESCMRenderEngineFactory>(), std::make_shared<GLESCMRenderEngineFactory>(), Loading Loading @@ -1609,6 +1664,22 @@ TEST_P(RenderEngineTest, cacheExternalBuffer_cachesImages) { EXPECT_FALSE(mRE->isImageCachedForTesting(bufferId)); EXPECT_FALSE(mRE->isImageCachedForTesting(bufferId)); } } TEST_P(RenderEngineTest, drawLayers_fillShadow_castsWithoutCasterLayer) { const auto& renderEngineFactory = GetParam(); mRE = renderEngineFactory->createRenderEngine(); const ubyte4 backgroundColor(255, 255, 255, 255); const float shadowLength = 5.0f; Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f); casterBounds.offsetBy(shadowLength + 1, shadowLength + 1); renderengine::ShadowSettings settings = getShadowSettings(vec2(casterBounds.left, casterBounds.top), shadowLength, false /* casterIsTranslucent */); drawShadowWithoutCaster(casterBounds.toFloatRect(), settings, backgroundColor); expectShadowColorWithoutCaster(casterBounds.toFloatRect(), settings, backgroundColor); } TEST_P(RenderEngineTest, drawLayers_fillShadow_casterLayerMinSize) { TEST_P(RenderEngineTest, drawLayers_fillShadow_casterLayerMinSize) { const auto& renderEngineFactory = GetParam(); const auto& renderEngineFactory = GetParam(); mRE = renderEngineFactory->createRenderEngine(); mRE = renderEngineFactory->createRenderEngine(); Loading
services/surfaceflinger/Layer.cpp +2 −0 Original line number Original line Diff line number Diff line Loading @@ -688,6 +688,7 @@ std::optional<compositionengine::LayerFE::LayerSettings> Layer::prepareShadowCli shadowLayer.source.buffer.fence = nullptr; shadowLayer.source.buffer.fence = nullptr; shadowLayer.frameNumber = 0; shadowLayer.frameNumber = 0; shadowLayer.bufferId = 0; shadowLayer.bufferId = 0; shadowLayer.name = getName(); if (shadowLayer.shadow.ambientColor.a <= 0.f && shadowLayer.shadow.spotColor.a <= 0.f) { if (shadowLayer.shadow.ambientColor.a <= 0.f && shadowLayer.shadow.spotColor.a <= 0.f) { return {}; return {}; Loading Loading @@ -723,6 +724,7 @@ void Layer::prepareClearClientComposition(LayerFE::LayerSettings& layerSettings, // If layer is blacked out, force alpha to 1 so that we draw a black color layer. // If layer is blacked out, force alpha to 1 so that we draw a black color layer. layerSettings.alpha = blackout ? 1.0f : 0.0f; layerSettings.alpha = blackout ? 1.0f : 0.0f; layerSettings.name = getName(); } } std::vector<compositionengine::LayerFE::LayerSettings> Layer::prepareClientCompositionList( std::vector<compositionengine::LayerFE::LayerSettings> Layer::prepareClientCompositionList( Loading