Loading libs/renderengine/skia/Cache.cpp +7 −6 Original line number Diff line number Diff line Loading @@ -96,7 +96,6 @@ static void drawShadowLayers(SkiaRenderEngine* renderengine, const DisplaySettin .alpha = 1, }; auto layers = std::vector<LayerSettings>{layer, caster}; // Four combinations of settings are used (two transforms here, and drawShadowLayers is // called with two different destination data spaces) They're all rounded rect. // Three of these are cache misses that generate new shaders. Loading @@ -115,6 +114,8 @@ static void drawShadowLayers(SkiaRenderEngine* renderengine, const DisplaySettin for (auto transform : {mat4(), kFlip}) { layer.geometry.positionTransform = transform; caster.geometry.positionTransform = transform; auto layers = std::vector<LayerSettings>{layer, caster}; renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache, base::unique_fd()); } Loading @@ -141,7 +142,6 @@ static void drawImageLayers(SkiaRenderEngine* renderengine, const DisplaySetting }}, }; auto layers = std::vector<LayerSettings>{layer}; for (auto dataspace : {kDestDataSpace, kOtherDataSpace}) { layer.sourceDataspace = dataspace; // Cache shaders for both rects and round rects. Loading @@ -153,6 +153,7 @@ static void drawImageLayers(SkiaRenderEngine* renderengine, const DisplaySetting layer.source.buffer.isOpaque = isOpaque; for (auto alpha : {half(.2f), half(1.0f)}) { layer.alpha = alpha; auto layers = std::vector<LayerSettings>{layer}; renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache, base::unique_fd()); } Loading @@ -177,11 +178,11 @@ static void drawSolidLayers(SkiaRenderEngine* renderengine, const DisplaySetting .alpha = 0.5, }; auto layers = std::vector<LayerSettings>{layer}; for (auto transform : {mat4(), kScaleAndTranslate}) { layer.geometry.positionTransform = transform; for (float roundedCornersRadius : {0.0f, 50.f}) { layer.geometry.roundedCornersRadius = roundedCornersRadius; auto layers = std::vector<LayerSettings>{layer}; renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache, base::unique_fd()); } Loading @@ -202,10 +203,10 @@ static void drawBlurLayers(SkiaRenderEngine* renderengine, const DisplaySettings .skipContentDraw = true, }; auto layers = std::vector<LayerSettings>{layer}; // Different blur code is invoked for radii less and greater than 30 pixels for (int radius : {9, 60}) { layer.backgroundBlurRadius = radius; auto layers = std::vector<LayerSettings>{layer}; renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache, base::unique_fd()); } Loading Loading @@ -243,7 +244,6 @@ static void drawClippedLayers(SkiaRenderEngine* renderengine, const DisplaySetti }, }; auto layers = std::vector<LayerSettings>{layer}; for (auto pixelSource : {bufferSource, bufferOpaque, colorSource}) { layer.source = pixelSource; for (auto dataspace : {kDestDataSpace, kOtherDataSpace}) { Loading @@ -252,7 +252,8 @@ static void drawClippedLayers(SkiaRenderEngine* renderengine, const DisplaySetti for (auto transform : {kScaleAndTranslate, kScaleAsymmetric}) { layer.geometry.positionTransform = transform; for (float alpha : {0.5f, 1.f}) { layer.alpha = alpha, layer.alpha = alpha; auto layers = std::vector<LayerSettings>{layer}; renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache, base::unique_fd()); } Loading libs/renderengine/skia/SkiaGLRenderEngine.cpp +7 −3 Original line number Diff line number Diff line Loading @@ -1192,11 +1192,15 @@ void SkiaGLRenderEngine::drawLayersInternal( static constexpr float kInverseGamma22 = 1.f / 2.2f; const auto gammaCorrectedDimmingRatio = std::pow(layerDimmingRatio, kInverseGamma22); const auto dimmingMatrix = auto dimmingMatrix = mat4::scale(vec4(gammaCorrectedDimmingRatio, gammaCorrectedDimmingRatio, gammaCorrectedDimmingRatio, 1.f)); paint.setColorFilter(SkColorFilters::Matrix( toSkColorMatrix(display.colorTransform * dimmingMatrix))); const auto colorFilter = SkColorFilters::Matrix(toSkColorMatrix(std::move(dimmingMatrix))); paint.setColorFilter(displayColorTransform ? displayColorTransform->makeComposed(colorFilter) : colorFilter); } else { paint.setColorFilter(displayColorTransform); } Loading libs/renderengine/tests/RenderEngineTest.cpp +136 −4 Original line number Diff line number Diff line Loading @@ -91,6 +91,14 @@ vec3 OETF_sRGB(vec3 linear) { sign(linear.b) * OETF_sRGB(linear.b)); } // clang-format off // Converts red channels to green channels, and zeroes out an existing green channel. static const auto kRemoveGreenAndMoveRedToGreenMat4 = mat4(0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); // clang-format on } // namespace class RenderEngineFactory { Loading Loading @@ -2557,6 +2565,133 @@ TEST_P(RenderEngineTest, testDimming_inGammaSpace) { expectBufferColor(Rect(2, 0, 3, 1), 122, 0, 0, 255, 1); } TEST_P(RenderEngineTest, testDimming_inGammaSpace_withDisplayColorTransform) { if (GetParam()->type() == renderengine::RenderEngine::RenderEngineType::GLES) { GTEST_SKIP(); } initializeRenderEngine(); const ui::Dataspace dataspace = static_cast<ui::Dataspace>(ui::Dataspace::STANDARD_BT709 | ui::Dataspace::TRANSFER_GAMMA2_2 | ui::Dataspace::RANGE_FULL); const auto displayRect = Rect(3, 1); const renderengine::DisplaySettings display{ .physicalDisplay = displayRect, .clip = displayRect, .outputDataspace = dataspace, .colorTransform = kRemoveGreenAndMoveRedToGreenMat4, .targetLuminanceNits = 1000.f, .dimmingStage = aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF, }; const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255)); const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255)); const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255)); const renderengine::LayerSettings greenLayer{ .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f), .source = renderengine::PixelSource{ .buffer = renderengine::Buffer{ .buffer = greenBuffer, .usePremultipliedAlpha = true, }, }, .alpha = 1.0f, .sourceDataspace = dataspace, .whitePointNits = 200.f, }; const renderengine::LayerSettings redLayer{ .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f), .source = renderengine::PixelSource{ .buffer = renderengine::Buffer{ .buffer = redBuffer, .usePremultipliedAlpha = true, }, }, .alpha = 1.0f, .sourceDataspace = dataspace, // When the white point is not set for a layer, just ignore it and treat it as the same // as the max layer .whitePointNits = -1.f, }; std::vector<renderengine::LayerSettings> layers{greenLayer, redLayer}; invokeDraw(display, layers); expectBufferColor(Rect(1, 1), 0, 0, 0, 255, 1); expectBufferColor(Rect(1, 0, 2, 1), 0, 122, 0, 255, 1); } TEST_P(RenderEngineTest, testDimming_inGammaSpace_withDisplayColorTransform_deviceHandles) { if (GetParam()->type() == renderengine::RenderEngine::RenderEngineType::GLES) { GTEST_SKIP(); } initializeRenderEngine(); const ui::Dataspace dataspace = static_cast<ui::Dataspace>(ui::Dataspace::STANDARD_BT709 | ui::Dataspace::TRANSFER_GAMMA2_2 | ui::Dataspace::RANGE_FULL); const auto displayRect = Rect(3, 1); const renderengine::DisplaySettings display{ .physicalDisplay = displayRect, .clip = displayRect, .outputDataspace = dataspace, .colorTransform = kRemoveGreenAndMoveRedToGreenMat4, .deviceHandlesColorTransform = true, .targetLuminanceNits = 1000.f, .dimmingStage = aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF, }; const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255)); const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255)); const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255)); const renderengine::LayerSettings greenLayer{ .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f), .source = renderengine::PixelSource{ .buffer = renderengine::Buffer{ .buffer = greenBuffer, .usePremultipliedAlpha = true, }, }, .alpha = 1.0f, .sourceDataspace = dataspace, .whitePointNits = 200.f, }; const renderengine::LayerSettings redLayer{ .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f), .source = renderengine::PixelSource{ .buffer = renderengine::Buffer{ .buffer = redBuffer, .usePremultipliedAlpha = true, }, }, .alpha = 1.0f, .sourceDataspace = dataspace, // When the white point is not set for a layer, just ignore it and treat it as the same // as the max layer .whitePointNits = -1.f, }; std::vector<renderengine::LayerSettings> layers{greenLayer, redLayer}; invokeDraw(display, layers); expectBufferColor(Rect(1, 1), 0, 122, 0, 255, 1); expectBufferColor(Rect(1, 0, 2, 1), 122, 0, 0, 255, 1); } TEST_P(RenderEngineTest, testDimming_withoutTargetLuminance) { initializeRenderEngine(); if (GetParam()->type() == renderengine::RenderEngine::RenderEngineType::GLES) { Loading Loading @@ -2796,10 +2931,7 @@ TEST_P(RenderEngineTest, r8_respects_color_transform) { // pure red to pure green. That will occur when the R8 buffer is // 255. When the R8 buffer is 0, it will still change to black, as // with r8_behaves_as_mask. .colorTransform = mat4(0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1), .colorTransform = kRemoveGreenAndMoveRedToGreenMat4, .deviceHandlesColorTransform = false, }; Loading libs/ui/Gralloc4.cpp +3 −2 Original line number Diff line number Diff line Loading @@ -1245,8 +1245,9 @@ status_t Gralloc4Allocator::allocate(std::string requestorName, uint32_t width, } else { if (importBuffers) { for (uint32_t i = 0; i < bufferCount; i++) { error = mMapper.importBuffer(makeFromAidl(result.buffers[i]), &outBufferHandles[i]); auto handle = makeFromAidl(result.buffers[i]); error = mMapper.importBuffer(handle, &outBufferHandles[i]); native_handle_delete(handle); if (error != NO_ERROR) { for (uint32_t j = 0; j < i; j++) { mMapper.freeBuffer(outBufferHandles[j]); Loading Loading
libs/renderengine/skia/Cache.cpp +7 −6 Original line number Diff line number Diff line Loading @@ -96,7 +96,6 @@ static void drawShadowLayers(SkiaRenderEngine* renderengine, const DisplaySettin .alpha = 1, }; auto layers = std::vector<LayerSettings>{layer, caster}; // Four combinations of settings are used (two transforms here, and drawShadowLayers is // called with two different destination data spaces) They're all rounded rect. // Three of these are cache misses that generate new shaders. Loading @@ -115,6 +114,8 @@ static void drawShadowLayers(SkiaRenderEngine* renderengine, const DisplaySettin for (auto transform : {mat4(), kFlip}) { layer.geometry.positionTransform = transform; caster.geometry.positionTransform = transform; auto layers = std::vector<LayerSettings>{layer, caster}; renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache, base::unique_fd()); } Loading @@ -141,7 +142,6 @@ static void drawImageLayers(SkiaRenderEngine* renderengine, const DisplaySetting }}, }; auto layers = std::vector<LayerSettings>{layer}; for (auto dataspace : {kDestDataSpace, kOtherDataSpace}) { layer.sourceDataspace = dataspace; // Cache shaders for both rects and round rects. Loading @@ -153,6 +153,7 @@ static void drawImageLayers(SkiaRenderEngine* renderengine, const DisplaySetting layer.source.buffer.isOpaque = isOpaque; for (auto alpha : {half(.2f), half(1.0f)}) { layer.alpha = alpha; auto layers = std::vector<LayerSettings>{layer}; renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache, base::unique_fd()); } Loading @@ -177,11 +178,11 @@ static void drawSolidLayers(SkiaRenderEngine* renderengine, const DisplaySetting .alpha = 0.5, }; auto layers = std::vector<LayerSettings>{layer}; for (auto transform : {mat4(), kScaleAndTranslate}) { layer.geometry.positionTransform = transform; for (float roundedCornersRadius : {0.0f, 50.f}) { layer.geometry.roundedCornersRadius = roundedCornersRadius; auto layers = std::vector<LayerSettings>{layer}; renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache, base::unique_fd()); } Loading @@ -202,10 +203,10 @@ static void drawBlurLayers(SkiaRenderEngine* renderengine, const DisplaySettings .skipContentDraw = true, }; auto layers = std::vector<LayerSettings>{layer}; // Different blur code is invoked for radii less and greater than 30 pixels for (int radius : {9, 60}) { layer.backgroundBlurRadius = radius; auto layers = std::vector<LayerSettings>{layer}; renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache, base::unique_fd()); } Loading Loading @@ -243,7 +244,6 @@ static void drawClippedLayers(SkiaRenderEngine* renderengine, const DisplaySetti }, }; auto layers = std::vector<LayerSettings>{layer}; for (auto pixelSource : {bufferSource, bufferOpaque, colorSource}) { layer.source = pixelSource; for (auto dataspace : {kDestDataSpace, kOtherDataSpace}) { Loading @@ -252,7 +252,8 @@ static void drawClippedLayers(SkiaRenderEngine* renderengine, const DisplaySetti for (auto transform : {kScaleAndTranslate, kScaleAsymmetric}) { layer.geometry.positionTransform = transform; for (float alpha : {0.5f, 1.f}) { layer.alpha = alpha, layer.alpha = alpha; auto layers = std::vector<LayerSettings>{layer}; renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache, base::unique_fd()); } Loading
libs/renderengine/skia/SkiaGLRenderEngine.cpp +7 −3 Original line number Diff line number Diff line Loading @@ -1192,11 +1192,15 @@ void SkiaGLRenderEngine::drawLayersInternal( static constexpr float kInverseGamma22 = 1.f / 2.2f; const auto gammaCorrectedDimmingRatio = std::pow(layerDimmingRatio, kInverseGamma22); const auto dimmingMatrix = auto dimmingMatrix = mat4::scale(vec4(gammaCorrectedDimmingRatio, gammaCorrectedDimmingRatio, gammaCorrectedDimmingRatio, 1.f)); paint.setColorFilter(SkColorFilters::Matrix( toSkColorMatrix(display.colorTransform * dimmingMatrix))); const auto colorFilter = SkColorFilters::Matrix(toSkColorMatrix(std::move(dimmingMatrix))); paint.setColorFilter(displayColorTransform ? displayColorTransform->makeComposed(colorFilter) : colorFilter); } else { paint.setColorFilter(displayColorTransform); } Loading
libs/renderengine/tests/RenderEngineTest.cpp +136 −4 Original line number Diff line number Diff line Loading @@ -91,6 +91,14 @@ vec3 OETF_sRGB(vec3 linear) { sign(linear.b) * OETF_sRGB(linear.b)); } // clang-format off // Converts red channels to green channels, and zeroes out an existing green channel. static const auto kRemoveGreenAndMoveRedToGreenMat4 = mat4(0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); // clang-format on } // namespace class RenderEngineFactory { Loading Loading @@ -2557,6 +2565,133 @@ TEST_P(RenderEngineTest, testDimming_inGammaSpace) { expectBufferColor(Rect(2, 0, 3, 1), 122, 0, 0, 255, 1); } TEST_P(RenderEngineTest, testDimming_inGammaSpace_withDisplayColorTransform) { if (GetParam()->type() == renderengine::RenderEngine::RenderEngineType::GLES) { GTEST_SKIP(); } initializeRenderEngine(); const ui::Dataspace dataspace = static_cast<ui::Dataspace>(ui::Dataspace::STANDARD_BT709 | ui::Dataspace::TRANSFER_GAMMA2_2 | ui::Dataspace::RANGE_FULL); const auto displayRect = Rect(3, 1); const renderengine::DisplaySettings display{ .physicalDisplay = displayRect, .clip = displayRect, .outputDataspace = dataspace, .colorTransform = kRemoveGreenAndMoveRedToGreenMat4, .targetLuminanceNits = 1000.f, .dimmingStage = aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF, }; const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255)); const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255)); const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255)); const renderengine::LayerSettings greenLayer{ .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f), .source = renderengine::PixelSource{ .buffer = renderengine::Buffer{ .buffer = greenBuffer, .usePremultipliedAlpha = true, }, }, .alpha = 1.0f, .sourceDataspace = dataspace, .whitePointNits = 200.f, }; const renderengine::LayerSettings redLayer{ .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f), .source = renderengine::PixelSource{ .buffer = renderengine::Buffer{ .buffer = redBuffer, .usePremultipliedAlpha = true, }, }, .alpha = 1.0f, .sourceDataspace = dataspace, // When the white point is not set for a layer, just ignore it and treat it as the same // as the max layer .whitePointNits = -1.f, }; std::vector<renderengine::LayerSettings> layers{greenLayer, redLayer}; invokeDraw(display, layers); expectBufferColor(Rect(1, 1), 0, 0, 0, 255, 1); expectBufferColor(Rect(1, 0, 2, 1), 0, 122, 0, 255, 1); } TEST_P(RenderEngineTest, testDimming_inGammaSpace_withDisplayColorTransform_deviceHandles) { if (GetParam()->type() == renderengine::RenderEngine::RenderEngineType::GLES) { GTEST_SKIP(); } initializeRenderEngine(); const ui::Dataspace dataspace = static_cast<ui::Dataspace>(ui::Dataspace::STANDARD_BT709 | ui::Dataspace::TRANSFER_GAMMA2_2 | ui::Dataspace::RANGE_FULL); const auto displayRect = Rect(3, 1); const renderengine::DisplaySettings display{ .physicalDisplay = displayRect, .clip = displayRect, .outputDataspace = dataspace, .colorTransform = kRemoveGreenAndMoveRedToGreenMat4, .deviceHandlesColorTransform = true, .targetLuminanceNits = 1000.f, .dimmingStage = aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF, }; const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255)); const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255)); const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255)); const renderengine::LayerSettings greenLayer{ .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f), .source = renderengine::PixelSource{ .buffer = renderengine::Buffer{ .buffer = greenBuffer, .usePremultipliedAlpha = true, }, }, .alpha = 1.0f, .sourceDataspace = dataspace, .whitePointNits = 200.f, }; const renderengine::LayerSettings redLayer{ .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f), .source = renderengine::PixelSource{ .buffer = renderengine::Buffer{ .buffer = redBuffer, .usePremultipliedAlpha = true, }, }, .alpha = 1.0f, .sourceDataspace = dataspace, // When the white point is not set for a layer, just ignore it and treat it as the same // as the max layer .whitePointNits = -1.f, }; std::vector<renderengine::LayerSettings> layers{greenLayer, redLayer}; invokeDraw(display, layers); expectBufferColor(Rect(1, 1), 0, 122, 0, 255, 1); expectBufferColor(Rect(1, 0, 2, 1), 122, 0, 0, 255, 1); } TEST_P(RenderEngineTest, testDimming_withoutTargetLuminance) { initializeRenderEngine(); if (GetParam()->type() == renderengine::RenderEngine::RenderEngineType::GLES) { Loading Loading @@ -2796,10 +2931,7 @@ TEST_P(RenderEngineTest, r8_respects_color_transform) { // pure red to pure green. That will occur when the R8 buffer is // 255. When the R8 buffer is 0, it will still change to black, as // with r8_behaves_as_mask. .colorTransform = mat4(0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1), .colorTransform = kRemoveGreenAndMoveRedToGreenMat4, .deviceHandlesColorTransform = false, }; Loading
libs/ui/Gralloc4.cpp +3 −2 Original line number Diff line number Diff line Loading @@ -1245,8 +1245,9 @@ status_t Gralloc4Allocator::allocate(std::string requestorName, uint32_t width, } else { if (importBuffers) { for (uint32_t i = 0; i < bufferCount; i++) { error = mMapper.importBuffer(makeFromAidl(result.buffers[i]), &outBufferHandles[i]); auto handle = makeFromAidl(result.buffers[i]); error = mMapper.importBuffer(handle, &outBufferHandles[i]); native_handle_delete(handle); if (error != NO_ERROR) { for (uint32_t j = 0; j < i; j++) { mMapper.freeBuffer(outBufferHandles[j]); Loading