diff options
| author | 2021-03-19 13:06:32 -0400 | |
|---|---|---|
| committer | 2021-03-22 14:37:53 +0000 | |
| commit | cf3d95cdec56bea16b9b0f463d4b59377f8720cf (patch) | |
| tree | 780a6e8fe98c64fbdf6c14980304b76bef88b2d8 | |
| parent | d5ecb64ef43ea1e6fb85c1abe2bd9d679bc3df9b (diff) | |
SkiaRE: respect disableBlending
Fixes: 182617606
Test: atest librenderengine_test
RenderEngineTest#testClear
RenderEngineTest#testDisableBlendingBuffer
When drawing an image or a solid color, use SkBlendMode::kSrc to
avoid blending with other layers. Assert that disableBlending is not
combined with a shadow, since our existing API does not support that.
Continue to ignore disableBlending with blur, which we do not expect
to see as input.
Add RenderEngineTest#testClear and #testDisableBlendingBuffer to verify
the fix.
Change-Id: Ie12cbf497ecb6b71a9b4b625710161fce2b06ee4
| -rw-r--r-- | libs/renderengine/skia/SkiaGLRenderEngine.cpp | 8 | ||||
| -rw-r--r-- | libs/renderengine/tests/RenderEngineTest.cpp | 77 |
2 files changed, 84 insertions, 1 deletions
diff --git a/libs/renderengine/skia/SkiaGLRenderEngine.cpp b/libs/renderengine/skia/SkiaGLRenderEngine.cpp index f76bfa2495..908aae3c15 100644 --- a/libs/renderengine/skia/SkiaGLRenderEngine.cpp +++ b/libs/renderengine/skia/SkiaGLRenderEngine.cpp @@ -797,6 +797,8 @@ status_t SkiaGLRenderEngine::drawLayers(const DisplaySettings& display, const auto rect = layer->geometry.roundedCornersRadius > 0 ? getSkRect(layer->geometry.roundedCornersCrop) : bounds; + // This would require a new parameter/flag to SkShadowUtils::DrawShadow + LOG_ALWAYS_FATAL_IF(layer->disableBlending, "Cannot disableBlending with a shadow"); drawShadow(canvas, rect, layer->geometry.roundedCornersRadius, layer->shadow); continue; } @@ -806,7 +808,7 @@ status_t SkiaGLRenderEngine::drawLayers(const DisplaySettings& display, needsToneMapping(layer->sourceDataspace, display.outputDataspace)); // quick abort from drawing the remaining portion of the layer - if (layer->alpha == 0 && !requiresLinearEffect && + if (layer->alpha == 0 && !requiresLinearEffect && !layer->disableBlending && (!displayColorTransform || displayColorTransform->isAlphaUnchanged())) { continue; } @@ -912,6 +914,10 @@ status_t SkiaGLRenderEngine::drawLayers(const DisplaySettings& display, requiresLinearEffect)); } + if (layer->disableBlending) { + paint.setBlendMode(SkBlendMode::kSrc); + } + paint.setColorFilter(displayColorTransform); if (layer->geometry.roundedCornersRadius > 0) { diff --git a/libs/renderengine/tests/RenderEngineTest.cpp b/libs/renderengine/tests/RenderEngineTest.cpp index 500a90b6ef..7846156383 100644 --- a/libs/renderengine/tests/RenderEngineTest.cpp +++ b/libs/renderengine/tests/RenderEngineTest.cpp @@ -1920,6 +1920,83 @@ TEST_P(RenderEngineTest, testRoundedCornersCrop) { 0, 255, 0, 255); } +TEST_P(RenderEngineTest, testClear) { + initializeRenderEngine(); + + const auto rect = fullscreenRect(); + const renderengine::DisplaySettings display{ + .physicalDisplay = rect, + .clip = rect, + }; + + const renderengine::LayerSettings redLayer{ + .geometry.boundaries = rect.toFloatRect(), + .source.solidColor = half3(1.0f, 0.0f, 0.0f), + .alpha = 1.0f, + }; + + // This mimics prepareClearClientComposition. This layer should overwrite + // the redLayer, so that the buffer is transparent, rather than red. + const renderengine::LayerSettings clearLayer{ + .geometry.boundaries = rect.toFloatRect(), + .source.solidColor = half3(0.0f, 0.0f, 0.0f), + .alpha = 0.0f, + .disableBlending = true, + }; + + std::vector<const renderengine::LayerSettings*> layers{&redLayer, &clearLayer}; + invokeDraw(display, layers); + expectBufferColor(rect, 0, 0, 0, 0); +} + +TEST_P(RenderEngineTest, testDisableBlendingBuffer) { + initializeRenderEngine(); + + const auto rect = Rect(0, 0, 1, 1); + const renderengine::DisplaySettings display{ + .physicalDisplay = rect, + .clip = rect, + }; + + const renderengine::LayerSettings redLayer{ + .geometry.boundaries = rect.toFloatRect(), + .source.solidColor = half3(1.0f, 0.0f, 0.0f), + .alpha = 1.0f, + }; + + // The next layer will overwrite redLayer with a GraphicBuffer that is green + // applied with a translucent alpha. + auto buf = allocateSourceBuffer(1, 1); + { + uint8_t* pixels; + buf->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN, + reinterpret_cast<void**>(&pixels)); + pixels[0] = 0; + pixels[1] = 255; + pixels[2] = 0; + pixels[3] = 255; + buf->unlock(); + } + + const renderengine::LayerSettings greenLayer{ + .geometry.boundaries = rect.toFloatRect(), + .source = + renderengine::PixelSource{ + .buffer = + renderengine::Buffer{ + .buffer = buf, + .usePremultipliedAlpha = true, + }, + }, + .alpha = 0.5f, + .disableBlending = true, + }; + + std::vector<const renderengine::LayerSettings*> layers{&redLayer, &greenLayer}; + invokeDraw(display, layers); + expectBufferColor(rect, 0, 128, 0, 128); +} + } // namespace android // TODO(b/129481165): remove the #pragma below and fix conversion issues |