Loading libs/renderengine/skia/Cache.cpp +168 −0 Original line number Diff line number Diff line Loading @@ -49,6 +49,11 @@ const auto kFlip = mat4(1.1f, -0.1f, 0.f, 0.f, // a color correction effect is added to the shader. constexpr auto kDestDataSpace = ui::Dataspace::SRGB; constexpr auto kOtherDataSpace = ui::Dataspace::DISPLAY_P3; // Dimming is needed to trigger linear effects for some dataspace pairs const std::array<float, 3> kLayerWhitePoints = { 1000.0f, 500.0f, 100.0f, // trigger dithering by dimming below 20% }; } // namespace static void drawShadowLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display, Loading Loading @@ -317,6 +322,150 @@ static void drawHolePunchLayer(SkiaRenderEngine* renderengine, const DisplaySett renderengine->drawLayers(display, layers, dstTexture, base::unique_fd()); } static void drawImageDimmedLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display, const std::shared_ptr<ExternalTexture>& dstTexture, const std::shared_ptr<ExternalTexture>& srcTexture) { const Rect& displayRect = display.physicalDisplay; FloatRect rect(0, 0, displayRect.width(), displayRect.height()); LayerSettings layer{ .geometry = Geometry{ // The position transform doesn't matter when the reduced shader mode // in in effect. A matrix transform stage is always included. .positionTransform = mat4(), .boundaries = rect, .roundedCornersCrop = rect, .roundedCornersRadius = {0.f, 0.f}, }, .source = PixelSource{.buffer = Buffer{.buffer = srcTexture, .maxLuminanceNits = 1000.f, .usePremultipliedAlpha = true, .isOpaque = true}}, .alpha = 1.f, .sourceDataspace = kDestDataSpace, }; std::vector<LayerSettings> layers; for (auto layerWhitePoint : kLayerWhitePoints) { layer.whitePointNits = layerWhitePoint; layers.push_back(layer); } renderengine->drawLayers(display, layers, dstTexture, base::unique_fd()); } static void drawTransparentImageDimmedLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display, const std::shared_ptr<ExternalTexture>& dstTexture, const std::shared_ptr<ExternalTexture>& srcTexture) { const Rect& displayRect = display.physicalDisplay; FloatRect rect(0, 0, displayRect.width(), displayRect.height()); LayerSettings layer{ .geometry = Geometry{ .positionTransform = mat4(), .boundaries = rect, .roundedCornersCrop = rect, }, .source = PixelSource{.buffer = Buffer{ .buffer = srcTexture, .maxLuminanceNits = 1000.f, .usePremultipliedAlpha = true, .isOpaque = false, }}, .sourceDataspace = kDestDataSpace, }; for (auto roundedCornerRadius : {0.f, 50.f}) { layer.geometry.roundedCornersRadius = {roundedCornerRadius, roundedCornerRadius}; for (auto alpha : {0.5f, 1.0f}) { layer.alpha = alpha; std::vector<LayerSettings> layers; for (auto layerWhitePoint : kLayerWhitePoints) { layer.whitePointNits = layerWhitePoint; layers.push_back(layer); } renderengine->drawLayers(display, layers, dstTexture, base::unique_fd()); } } } static void drawClippedDimmedImageLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display, const std::shared_ptr<ExternalTexture>& dstTexture, const std::shared_ptr<ExternalTexture>& srcTexture) { const Rect& displayRect = display.physicalDisplay; // If rect and boundary is too small compared to roundedCornersRadius, Skia will switch to // blending instead of EllipticalRRect, so enlarge them a bit. FloatRect rect(0, 0, displayRect.width(), displayRect.height()); FloatRect boundary(0, 0, displayRect.width(), displayRect.height() - 20); // boundary is smaller LayerSettings layer{ .geometry = Geometry{ .positionTransform = mat4(), .boundaries = boundary, .roundedCornersCrop = rect, .roundedCornersRadius = {27.f, 27.f}, }, .source = PixelSource{.buffer = Buffer{ .buffer = srcTexture, .maxLuminanceNits = 1000.f, .usePremultipliedAlpha = true, .isOpaque = false, }}, .alpha = 1.f, .sourceDataspace = kDestDataSpace, }; std::array<mat4, 2> transforms = {kScaleAndTranslate, kScaleAsymmetric}; constexpr float radius = 27.f; for (size_t i = 0; i < transforms.size(); i++) { layer.geometry.positionTransform = transforms[i]; layer.geometry.roundedCornersRadius = {radius, radius}; std::vector<LayerSettings> layers; for (auto layerWhitePoint : kLayerWhitePoints) { layer.whitePointNits = layerWhitePoint; layers.push_back(layer); } renderengine->drawLayers(display, layers, dstTexture, base::unique_fd()); } } static void drawSolidDimmedLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display, const std::shared_ptr<ExternalTexture>& dstTexture) { const Rect& displayRect = display.physicalDisplay; FloatRect rect(0, 0, displayRect.width(), displayRect.height()); LayerSettings layer{ .geometry = Geometry{ .boundaries = rect, .roundedCornersCrop = rect, }, .source = PixelSource{ .solidColor = half3(0.1f, 0.2f, 0.3f), }, .alpha = 1.f, }; std::vector<LayerSettings> layers; for (auto layerWhitePoint : kLayerWhitePoints) { layer.whitePointNits = layerWhitePoint; layers.push_back(layer); } renderengine->drawLayers(display, layers, dstTexture, base::unique_fd()); } // // The collection of shaders cached here were found by using perfetto to record shader compiles // during actions that involve RenderEngine, logging the layer settings, and the shader code Loading Loading @@ -353,6 +502,15 @@ void Cache::primeShaderCache(SkiaRenderEngine* renderengine) { .maxLuminance = 500, .outputDataspace = kOtherDataSpace, }; DisplaySettings bt2020Display{.physicalDisplay = displayRect, .clip = displayRect, .maxLuminance = 500, .outputDataspace = ui::Dataspace::BT2020, .deviceHandlesColorTransform = true, .dimmingStage = aidl::android::hardware::graphics::composer3:: DimmingStage::GAMMA_OETF, .renderIntent = aidl::android::hardware::graphics::composer3:: RenderIntent::TONE_MAP_ENHANCE}; const int64_t usage = GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE; Loading @@ -377,6 +535,7 @@ void Cache::primeShaderCache(SkiaRenderEngine* renderengine) { impl::ExternalTexture::Usage::WRITEABLE); drawHolePunchLayer(renderengine, display, dstTexture); drawSolidLayers(renderengine, display, dstTexture); drawSolidDimmedLayers(renderengine, display, dstTexture); drawShadowLayers(renderengine, display, srcTexture); drawShadowLayers(renderengine, p3Display, srcTexture); Loading Loading @@ -417,12 +576,21 @@ void Cache::primeShaderCache(SkiaRenderEngine* renderengine) { for (auto texture : textures) { drawImageLayers(renderengine, display, dstTexture, texture); drawImageDimmedLayers(renderengine, display, dstTexture, texture); drawImageDimmedLayers(renderengine, p3Display, dstTexture, texture); drawImageDimmedLayers(renderengine, bt2020Display, dstTexture, texture); // Draw layers for b/185569240. drawClippedLayers(renderengine, display, dstTexture, texture); } drawPIPImageLayer(renderengine, display, dstTexture, externalTexture); drawTransparentImageDimmedLayers(renderengine, bt2020Display, dstTexture, externalTexture); drawTransparentImageDimmedLayers(renderengine, display, dstTexture, externalTexture); drawTransparentImageDimmedLayers(renderengine, p3Display, dstTexture, externalTexture); drawClippedDimmedImageLayers(renderengine, bt2020Display, dstTexture, externalTexture); // draw one final layer synchronously to force GL submit LayerSettings layer{ .source = PixelSource{.solidColor = half3(0.f, 0.f, 0.f)}, Loading Loading
libs/renderengine/skia/Cache.cpp +168 −0 Original line number Diff line number Diff line Loading @@ -49,6 +49,11 @@ const auto kFlip = mat4(1.1f, -0.1f, 0.f, 0.f, // a color correction effect is added to the shader. constexpr auto kDestDataSpace = ui::Dataspace::SRGB; constexpr auto kOtherDataSpace = ui::Dataspace::DISPLAY_P3; // Dimming is needed to trigger linear effects for some dataspace pairs const std::array<float, 3> kLayerWhitePoints = { 1000.0f, 500.0f, 100.0f, // trigger dithering by dimming below 20% }; } // namespace static void drawShadowLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display, Loading Loading @@ -317,6 +322,150 @@ static void drawHolePunchLayer(SkiaRenderEngine* renderengine, const DisplaySett renderengine->drawLayers(display, layers, dstTexture, base::unique_fd()); } static void drawImageDimmedLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display, const std::shared_ptr<ExternalTexture>& dstTexture, const std::shared_ptr<ExternalTexture>& srcTexture) { const Rect& displayRect = display.physicalDisplay; FloatRect rect(0, 0, displayRect.width(), displayRect.height()); LayerSettings layer{ .geometry = Geometry{ // The position transform doesn't matter when the reduced shader mode // in in effect. A matrix transform stage is always included. .positionTransform = mat4(), .boundaries = rect, .roundedCornersCrop = rect, .roundedCornersRadius = {0.f, 0.f}, }, .source = PixelSource{.buffer = Buffer{.buffer = srcTexture, .maxLuminanceNits = 1000.f, .usePremultipliedAlpha = true, .isOpaque = true}}, .alpha = 1.f, .sourceDataspace = kDestDataSpace, }; std::vector<LayerSettings> layers; for (auto layerWhitePoint : kLayerWhitePoints) { layer.whitePointNits = layerWhitePoint; layers.push_back(layer); } renderengine->drawLayers(display, layers, dstTexture, base::unique_fd()); } static void drawTransparentImageDimmedLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display, const std::shared_ptr<ExternalTexture>& dstTexture, const std::shared_ptr<ExternalTexture>& srcTexture) { const Rect& displayRect = display.physicalDisplay; FloatRect rect(0, 0, displayRect.width(), displayRect.height()); LayerSettings layer{ .geometry = Geometry{ .positionTransform = mat4(), .boundaries = rect, .roundedCornersCrop = rect, }, .source = PixelSource{.buffer = Buffer{ .buffer = srcTexture, .maxLuminanceNits = 1000.f, .usePremultipliedAlpha = true, .isOpaque = false, }}, .sourceDataspace = kDestDataSpace, }; for (auto roundedCornerRadius : {0.f, 50.f}) { layer.geometry.roundedCornersRadius = {roundedCornerRadius, roundedCornerRadius}; for (auto alpha : {0.5f, 1.0f}) { layer.alpha = alpha; std::vector<LayerSettings> layers; for (auto layerWhitePoint : kLayerWhitePoints) { layer.whitePointNits = layerWhitePoint; layers.push_back(layer); } renderengine->drawLayers(display, layers, dstTexture, base::unique_fd()); } } } static void drawClippedDimmedImageLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display, const std::shared_ptr<ExternalTexture>& dstTexture, const std::shared_ptr<ExternalTexture>& srcTexture) { const Rect& displayRect = display.physicalDisplay; // If rect and boundary is too small compared to roundedCornersRadius, Skia will switch to // blending instead of EllipticalRRect, so enlarge them a bit. FloatRect rect(0, 0, displayRect.width(), displayRect.height()); FloatRect boundary(0, 0, displayRect.width(), displayRect.height() - 20); // boundary is smaller LayerSettings layer{ .geometry = Geometry{ .positionTransform = mat4(), .boundaries = boundary, .roundedCornersCrop = rect, .roundedCornersRadius = {27.f, 27.f}, }, .source = PixelSource{.buffer = Buffer{ .buffer = srcTexture, .maxLuminanceNits = 1000.f, .usePremultipliedAlpha = true, .isOpaque = false, }}, .alpha = 1.f, .sourceDataspace = kDestDataSpace, }; std::array<mat4, 2> transforms = {kScaleAndTranslate, kScaleAsymmetric}; constexpr float radius = 27.f; for (size_t i = 0; i < transforms.size(); i++) { layer.geometry.positionTransform = transforms[i]; layer.geometry.roundedCornersRadius = {radius, radius}; std::vector<LayerSettings> layers; for (auto layerWhitePoint : kLayerWhitePoints) { layer.whitePointNits = layerWhitePoint; layers.push_back(layer); } renderengine->drawLayers(display, layers, dstTexture, base::unique_fd()); } } static void drawSolidDimmedLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display, const std::shared_ptr<ExternalTexture>& dstTexture) { const Rect& displayRect = display.physicalDisplay; FloatRect rect(0, 0, displayRect.width(), displayRect.height()); LayerSettings layer{ .geometry = Geometry{ .boundaries = rect, .roundedCornersCrop = rect, }, .source = PixelSource{ .solidColor = half3(0.1f, 0.2f, 0.3f), }, .alpha = 1.f, }; std::vector<LayerSettings> layers; for (auto layerWhitePoint : kLayerWhitePoints) { layer.whitePointNits = layerWhitePoint; layers.push_back(layer); } renderengine->drawLayers(display, layers, dstTexture, base::unique_fd()); } // // The collection of shaders cached here were found by using perfetto to record shader compiles // during actions that involve RenderEngine, logging the layer settings, and the shader code Loading Loading @@ -353,6 +502,15 @@ void Cache::primeShaderCache(SkiaRenderEngine* renderengine) { .maxLuminance = 500, .outputDataspace = kOtherDataSpace, }; DisplaySettings bt2020Display{.physicalDisplay = displayRect, .clip = displayRect, .maxLuminance = 500, .outputDataspace = ui::Dataspace::BT2020, .deviceHandlesColorTransform = true, .dimmingStage = aidl::android::hardware::graphics::composer3:: DimmingStage::GAMMA_OETF, .renderIntent = aidl::android::hardware::graphics::composer3:: RenderIntent::TONE_MAP_ENHANCE}; const int64_t usage = GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE; Loading @@ -377,6 +535,7 @@ void Cache::primeShaderCache(SkiaRenderEngine* renderengine) { impl::ExternalTexture::Usage::WRITEABLE); drawHolePunchLayer(renderengine, display, dstTexture); drawSolidLayers(renderengine, display, dstTexture); drawSolidDimmedLayers(renderengine, display, dstTexture); drawShadowLayers(renderengine, display, srcTexture); drawShadowLayers(renderengine, p3Display, srcTexture); Loading Loading @@ -417,12 +576,21 @@ void Cache::primeShaderCache(SkiaRenderEngine* renderengine) { for (auto texture : textures) { drawImageLayers(renderengine, display, dstTexture, texture); drawImageDimmedLayers(renderengine, display, dstTexture, texture); drawImageDimmedLayers(renderengine, p3Display, dstTexture, texture); drawImageDimmedLayers(renderengine, bt2020Display, dstTexture, texture); // Draw layers for b/185569240. drawClippedLayers(renderengine, display, dstTexture, texture); } drawPIPImageLayer(renderengine, display, dstTexture, externalTexture); drawTransparentImageDimmedLayers(renderengine, bt2020Display, dstTexture, externalTexture); drawTransparentImageDimmedLayers(renderengine, display, dstTexture, externalTexture); drawTransparentImageDimmedLayers(renderengine, p3Display, dstTexture, externalTexture); drawClippedDimmedImageLayers(renderengine, bt2020Display, dstTexture, externalTexture); // draw one final layer synchronously to force GL submit LayerSettings layer{ .source = PixelSource{.solidColor = half3(0.f, 0.f, 0.f)}, Loading