From 2f8244a0c7f31b17e0ab902c754e50435dc446ac Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Mon, 8 Jul 2024 10:09:46 -0700 Subject: [PATCH 01/10] [Impeller] remove mip usage for blur downsample, cap at 1/4 --- impeller/entity/BUILD.gn | 1 + impeller/entity/contents/content_context.cc | 1 + impeller/entity/contents/content_context.h | 10 ++ .../filters/gaussian_blur_filter_contents.cc | 139 ++++++++++++------ .../entity/shaders/texture_downsample.frag | 40 +++++ 5 files changed, 146 insertions(+), 45 deletions(-) create mode 100644 impeller/entity/shaders/texture_downsample.frag diff --git a/impeller/entity/BUILD.gn b/impeller/entity/BUILD.gn index d4363be8d7804..d91d56cdfe5fe 100644 --- a/impeller/entity/BUILD.gn +++ b/impeller/entity/BUILD.gn @@ -50,6 +50,7 @@ impeller_shaders("entity_shaders") { "shaders/blending/vertices_uber.frag", "shaders/gradients/fast_gradient.vert", "shaders/gradients/fast_gradient.frag", + "shaders/texture_downsample.frag", ] } diff --git a/impeller/entity/contents/content_context.cc b/impeller/entity/contents/content_context.cc index 35d51c4795d54..d1975f9f3f90a 100644 --- a/impeller/entity/contents/content_context.cc +++ b/impeller/entity/contents/content_context.cc @@ -428,6 +428,7 @@ ContentContext::ContentContext( {static_cast(BlendSelectValues::kSoftLight), supports_decal}); } + texture_downsample_pipelines_.CreateDefault(*context_, options_trianglestrip); rrect_blur_pipelines_.CreateDefault(*context_, options_trianglestrip); texture_strict_src_pipelines_.CreateDefault(*context_, options); tiled_texture_pipelines_.CreateDefault(*context_, options, {supports_decal}); diff --git a/impeller/entity/contents/content_context.h b/impeller/entity/contents/content_context.h index 083412ecebeb8..8e947d2efa5a3 100644 --- a/impeller/entity/contents/content_context.h +++ b/impeller/entity/contents/content_context.h @@ -48,6 +48,7 @@ #include "impeller/entity/solid_fill.vert.h" #include "impeller/entity/srgb_to_linear_filter.frag.h" #include "impeller/entity/sweep_gradient_fill.frag.h" +#include "impeller/entity/texture_downsample.frag.h" #include "impeller/entity/texture_fill.frag.h" #include "impeller/entity/texture_fill.vert.h" #include "impeller/entity/texture_fill_strict_src.frag.h" @@ -110,6 +111,9 @@ using RRectBlurPipeline = RenderPipelineHandle; using TexturePipeline = RenderPipelineHandle; +using TextureDownsamplePipeline = + RenderPipelineHandle; using TextureStrictSrcPipeline = RenderPipelineHandle; @@ -590,6 +594,11 @@ class ContentContext { return GetPipeline(blend_softlight_pipelines_, opts); } + std::shared_ptr> GetDownsamplePipeline( + ContentContextOptions opts) const { + return GetPipeline(texture_downsample_pipelines_, opts); + } + // Framebuffer Advanced Blends std::shared_ptr> GetFramebufferBlendColorPipeline(ContentContextOptions opts) const { @@ -881,6 +890,7 @@ class ContentContext { sweep_gradient_ssbo_fill_pipelines_; mutable Variants rrect_blur_pipelines_; mutable Variants texture_pipelines_; + mutable Variants texture_downsample_pipelines_; mutable Variants texture_strict_src_pipelines_; #ifdef IMPELLER_ENABLE_OPENGLES mutable Variants diff --git a/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc b/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc index fe35f8f784cd3..2aaa924ee9dc8 100644 --- a/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc +++ b/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc @@ -9,6 +9,7 @@ #include "flutter/fml/make_copyable.h" #include "impeller/entity/contents/clip_contents.h" #include "impeller/entity/contents/content_context.h" +#include "impeller/entity/texture_downsample.frag.h" #include "impeller/entity/texture_fill.frag.h" #include "impeller/entity/texture_fill.vert.h" #include "impeller/renderer/render_pass.h" @@ -19,7 +20,7 @@ namespace impeller { using GaussianBlurVertexShader = GaussianBlurPipeline::VertexShader; using GaussianBlurFragmentShader = GaussianBlurPipeline::FragmentShader; -const int32_t GaussianBlurFilterContents::kBlurFilterRequiredMipCount = 4; +const int32_t GaussianBlurFilterContents::kBlurFilterRequiredMipCount = 1; namespace { @@ -242,6 +243,11 @@ DownsamplePassArgs CalculateDownsamplePassArgs( Scalar desired_scalar = std::min(GaussianBlurFilterContents::CalculateScale(scaled_sigma.x), GaussianBlurFilterContents::CalculateScale(scaled_sigma.y)); + + if (desired_scalar < 0.25) { + desired_scalar = 0.25; + } + // TODO(jonahwilliams): If desired_scalar is 1.0 and we fully acquired the // gutter from the expanded_coverage_hint, we can skip the downsample pass. // pass. @@ -327,50 +333,93 @@ fml::StatusOr MakeDownsampleSubpass( const SamplerDescriptor& sampler_descriptor, const DownsamplePassArgs& pass_args, Entity::TileMode tile_mode) { - ContentContext::SubpassCallback subpass_callback = - [&](const ContentContext& renderer, RenderPass& pass) { - HostBuffer& host_buffer = renderer.GetTransientsBuffer(); - - pass.SetCommandLabel("Gaussian blur downsample"); - auto pipeline_options = OptionsFromPass(pass); - pipeline_options.primitive_type = PrimitiveType::kTriangleStrip; - pass.SetPipeline(renderer.GetTexturePipeline(pipeline_options)); - - TextureFillVertexShader::FrameInfo frame_info; - frame_info.mvp = Matrix::MakeOrthographic(ISize(1, 1)); - frame_info.texture_sampler_y_coord_scale = 1.0; - - TextureFillFragmentShader::FragInfo frag_info; - frag_info.alpha = 1.0; - - const Quad& uvs = pass_args.uvs; - BindVertices(pass, host_buffer, - { - {Point(0, 0), uvs[0]}, - {Point(1, 0), uvs[1]}, - {Point(0, 1), uvs[2]}, - {Point(1, 1), uvs[3]}, - }); - - SamplerDescriptor linear_sampler_descriptor = sampler_descriptor; - SetTileMode(&linear_sampler_descriptor, renderer, tile_mode); - linear_sampler_descriptor.mag_filter = MinMagFilter::kLinear; - linear_sampler_descriptor.min_filter = MinMagFilter::kLinear; - TextureFillVertexShader::BindFrameInfo( - pass, host_buffer.EmplaceUniform(frame_info)); - TextureFillFragmentShader::BindFragInfo( - pass, host_buffer.EmplaceUniform(frag_info)); - TextureFillFragmentShader::BindTextureSampler( - pass, input_texture, - renderer.GetContext()->GetSamplerLibrary()->GetSampler( - linear_sampler_descriptor)); - - return pass.Draw().ok(); - }; - fml::StatusOr render_target = - renderer.MakeSubpass("Gaussian Blur Filter", pass_args.subpass_size, - command_buffer, subpass_callback); - return render_target; + if (pass_args.effective_scalar.x >= 0.5) { + ContentContext::SubpassCallback subpass_callback = + [&](const ContentContext& renderer, RenderPass& pass) { + HostBuffer& host_buffer = renderer.GetTransientsBuffer(); + + pass.SetCommandLabel("Gaussian blur downsample"); + auto pipeline_options = OptionsFromPass(pass); + pipeline_options.primitive_type = PrimitiveType::kTriangleStrip; + pass.SetPipeline(renderer.GetTexturePipeline(pipeline_options)); + + TextureFillVertexShader::FrameInfo frame_info; + frame_info.mvp = Matrix::MakeOrthographic(ISize(1, 1)); + frame_info.texture_sampler_y_coord_scale = 1.0; + + TextureFillFragmentShader::FragInfo frag_info; + frag_info.alpha = 1.0; + + const Quad& uvs = pass_args.uvs; + BindVertices(pass, host_buffer, + { + {Point(0, 0), uvs[0]}, + {Point(1, 0), uvs[1]}, + {Point(0, 1), uvs[2]}, + {Point(1, 1), uvs[3]}, + }); + + SamplerDescriptor linear_sampler_descriptor = sampler_descriptor; + SetTileMode(&linear_sampler_descriptor, renderer, tile_mode); + linear_sampler_descriptor.mag_filter = MinMagFilter::kLinear; + linear_sampler_descriptor.min_filter = MinMagFilter::kLinear; + TextureFillVertexShader::BindFrameInfo( + pass, host_buffer.EmplaceUniform(frame_info)); + TextureFillFragmentShader::BindFragInfo( + pass, host_buffer.EmplaceUniform(frag_info)); + TextureFillFragmentShader::BindTextureSampler( + pass, input_texture, + renderer.GetContext()->GetSamplerLibrary()->GetSampler( + linear_sampler_descriptor)); + + return pass.Draw().ok(); + }; + return renderer.MakeSubpass("Gaussian Blur Filter", pass_args.subpass_size, + command_buffer, subpass_callback); + } else { + ContentContext::SubpassCallback subpass_callback = + [&](const ContentContext& renderer, RenderPass& pass) { + HostBuffer& host_buffer = renderer.GetTransientsBuffer(); + + pass.SetCommandLabel("Gaussian blur downsample"); + auto pipeline_options = OptionsFromPass(pass); + pipeline_options.primitive_type = PrimitiveType::kTriangleStrip; + pass.SetPipeline(renderer.GetDownsamplePipeline(pipeline_options)); + + TextureFillVertexShader::FrameInfo frame_info; + frame_info.mvp = Matrix::MakeOrthographic(ISize(1, 1)); + frame_info.texture_sampler_y_coord_scale = 1.0; + + TextureDownsampleFragmentShader::FragInfo frag_info; + frag_info.pixel_size = Vector2(1.0 / input_texture->GetSize()); + + const Quad& uvs = pass_args.uvs; + BindVertices(pass, host_buffer, + { + {Point(0, 0), uvs[0]}, + {Point(1, 0), uvs[1]}, + {Point(0, 1), uvs[2]}, + {Point(1, 1), uvs[3]}, + }); + + SamplerDescriptor linear_sampler_descriptor = sampler_descriptor; + SetTileMode(&linear_sampler_descriptor, renderer, tile_mode); + linear_sampler_descriptor.mag_filter = MinMagFilter::kLinear; + linear_sampler_descriptor.min_filter = MinMagFilter::kLinear; + TextureFillVertexShader::BindFrameInfo( + pass, host_buffer.EmplaceUniform(frame_info)); + TextureDownsampleFragmentShader::BindFragInfo( + pass, host_buffer.EmplaceUniform(frag_info)); + TextureDownsampleFragmentShader::BindTextureSampler( + pass, input_texture, + renderer.GetContext()->GetSamplerLibrary()->GetSampler( + linear_sampler_descriptor)); + + return pass.Draw().ok(); + }; + return renderer.MakeSubpass("Gaussian Blur Filter", pass_args.subpass_size, + command_buffer, subpass_callback); + } } fml::StatusOr MakeBlurSubpass( diff --git a/impeller/entity/shaders/texture_downsample.frag b/impeller/entity/shaders/texture_downsample.frag new file mode 100644 index 0000000000000..de20d998cf84c --- /dev/null +++ b/impeller/entity/shaders/texture_downsample.frag @@ -0,0 +1,40 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +precision mediump float; + +#include +#include + +uniform f16sampler2D texture_sampler; + +uniform FragInfo { + vec2 pixel_size; +} +frag_info; + +in highp vec2 v_texture_coords; + +out f16vec4 frag_color; + +void main() { + f16vec4 lt = texture(texture_sampler, v_texture_coords - frag_info.pixel_size, + float16_t(kDefaultMipBias)) * + 0.25hf; + f16vec4 rt = texture(texture_sampler, + v_texture_coords + vec2(-frag_info.pixel_size.x, + frag_info.pixel_size.y), + float16_t(kDefaultMipBias)) * + 0.25hf; + f16vec4 lb = texture(texture_sampler, + v_texture_coords + vec2(frag_info.pixel_size.x, + -frag_info.pixel_size.y), + float16_t(kDefaultMipBias)) * + 0.25hf; + f16vec4 rb = texture(texture_sampler, v_texture_coords + frag_info.pixel_size, + float16_t(kDefaultMipBias)) * + 0.25hf; + + frag_color = lt + rb + lb + rb; +} From ca71526fb6bc680205f79c0173c0b8e6a8627979 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Mon, 8 Jul 2024 10:47:04 -0700 Subject: [PATCH 02/10] tests and blur. --- ci/licenses_golden/licenses_flutter | 2 ++ impeller/aiks/aiks_blur_unittests.cc | 12 ++++-------- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index 312b14e585b8a..fc92cd4c3d016 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -42118,6 +42118,7 @@ ORIGIN: ../../../flutter/impeller/entity/shaders/rrect_blur.vert + ../../../flut ORIGIN: ../../../flutter/impeller/entity/shaders/runtime_effect.vert + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/shaders/solid_fill.frag + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/shaders/solid_fill.vert + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/impeller/entity/shaders/texture_downsample.frag + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/shaders/texture_fill.frag + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/shaders/texture_fill.vert + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/shaders/texture_fill_strict_src.frag + ../../../flutter/LICENSE @@ -44984,6 +44985,7 @@ FILE: ../../../flutter/impeller/entity/shaders/rrect_blur.vert FILE: ../../../flutter/impeller/entity/shaders/runtime_effect.vert FILE: ../../../flutter/impeller/entity/shaders/solid_fill.frag FILE: ../../../flutter/impeller/entity/shaders/solid_fill.vert +FILE: ../../../flutter/impeller/entity/shaders/texture_downsample.frag FILE: ../../../flutter/impeller/entity/shaders/texture_fill.frag FILE: ../../../flutter/impeller/entity/shaders/texture_fill.vert FILE: ../../../flutter/impeller/entity/shaders/texture_fill_strict_src.frag diff --git a/impeller/aiks/aiks_blur_unittests.cc b/impeller/aiks/aiks_blur_unittests.cc index df9a937cc18a6..b6e9ecba81882 100644 --- a/impeller/aiks/aiks_blur_unittests.cc +++ b/impeller/aiks/aiks_blur_unittests.cc @@ -1055,8 +1055,7 @@ TEST_P(AiksTest, GaussianBlurSetsMipCountOnPass) { } TEST_P(AiksTest, GaussianBlurAllocatesCorrectMipCountRenderTarget) { - size_t blur_required_mip_count = - GetParam() == PlaygroundBackend::kOpenGLES ? 1 : 4; + size_t blur_required_mip_count = 1; Canvas canvas; canvas.DrawCircle({100, 100}, 50, {.color = Color::CornflowerBlue()}); @@ -1082,8 +1081,7 @@ TEST_P(AiksTest, GaussianBlurAllocatesCorrectMipCountRenderTarget) { TEST_P(AiksTest, GaussianBlurMipMapNestedLayer) { fml::testing::LogCapture log_capture; - size_t blur_required_mip_count = - GetParam() == PlaygroundBackend::kOpenGLES ? 1 : 4; + size_t blur_required_mip_count = 1; Canvas canvas; canvas.DrawPaint({.color = Color::Wheat()}); @@ -1120,8 +1118,7 @@ TEST_P(AiksTest, GaussianBlurMipMapNestedLayer) { } TEST_P(AiksTest, GaussianBlurMipMapImageFilter) { - size_t blur_required_mip_count = - GetParam() == PlaygroundBackend::kOpenGLES ? 1 : 4; + size_t blur_required_mip_count = 1; fml::testing::LogCapture log_capture; Canvas canvas; canvas.SaveLayer( @@ -1155,8 +1152,7 @@ TEST_P(AiksTest, GaussianBlurMipMapImageFilter) { } TEST_P(AiksTest, GaussianBlurMipMapSolidColor) { - size_t blur_required_mip_count = - GetParam() == PlaygroundBackend::kOpenGLES ? 1 : 4; + size_t blur_required_mip_count = 1; fml::testing::LogCapture log_capture; Canvas canvas; canvas.DrawPath(PathBuilder{} From ffaa21f1ef394bc2d8527d6f9bc38aecd74d08ea Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Mon, 8 Jul 2024 11:19:25 -0700 Subject: [PATCH 03/10] testing. --- impeller/aiks/aiks_blur_unittests.cc | 13 -- impeller/tools/malioc.json | 186 +++++++++++++++++++++++++++ 2 files changed, 186 insertions(+), 13 deletions(-) diff --git a/impeller/aiks/aiks_blur_unittests.cc b/impeller/aiks/aiks_blur_unittests.cc index b6e9ecba81882..fab985b5d6d59 100644 --- a/impeller/aiks/aiks_blur_unittests.cc +++ b/impeller/aiks/aiks_blur_unittests.cc @@ -1041,19 +1041,6 @@ TEST_P(AiksTest, GuassianBlurUpdatesMipmapContents) { ASSERT_TRUE(OpenPlaygroundHere(callback)); } -TEST_P(AiksTest, GaussianBlurSetsMipCountOnPass) { - Canvas canvas; - canvas.DrawCircle({100, 100}, 50, {.color = Color::CornflowerBlue()}); - canvas.SaveLayer({}, std::nullopt, - ImageFilter::MakeBlur(Sigma(3), Sigma(3), - FilterContents::BlurStyle::kNormal, - Entity::TileMode::kClamp)); - canvas.Restore(); - - Picture picture = canvas.EndRecordingAsPicture(); - EXPECT_EQ(4, picture.pass->GetRequiredMipCount()); -} - TEST_P(AiksTest, GaussianBlurAllocatesCorrectMipCountRenderTarget) { size_t blur_required_mip_count = 1; diff --git a/impeller/tools/malioc.json b/impeller/tools/malioc.json index b0ac489c58bb2..1935d42b98239 100644 --- a/impeller/tools/malioc.json +++ b/impeller/tools/malioc.json @@ -4729,6 +4729,122 @@ } } }, + "flutter/impeller/entity/gles/texture_downsample.frag.gles": { + "Mali-G78": { + "core": "Mali-G78", + "filename": "flutter/impeller/entity/gles/texture_downsample.frag.gles", + "has_side_effects": false, + "has_uniform_computation": false, + "modifies_coverage": false, + "reads_color_buffer": false, + "type": "Fragment", + "uses_late_zs_test": false, + "uses_late_zs_update": false, + "variants": { + "Main": { + "fp16_arithmetic": 66, + "has_stack_spilling": false, + "performance": { + "longest_path_bound_pipelines": [ + "texture" + ], + "longest_path_cycles": [ + 0.1875, + 0.1875, + 0.078125, + 0.0, + 0.0, + 0.25, + 0.75 + ], + "pipelines": [ + "arith_total", + "arith_fma", + "arith_cvt", + "arith_sfu", + "load_store", + "varying", + "texture" + ], + "shortest_path_bound_pipelines": [ + "texture" + ], + "shortest_path_cycles": [ + 0.1875, + 0.1875, + 0.046875, + 0.0, + 0.0, + 0.25, + 0.75 + ], + "total_bound_pipelines": [ + "texture" + ], + "total_cycles": [ + 0.1875, + 0.1875, + 0.078125, + 0.0, + 0.0, + 0.25, + 0.75 + ] + }, + "stack_spill_bytes": 0, + "thread_occupancy": 100, + "uniform_registers_used": 4, + "work_registers_used": 20 + } + } + }, + "Mali-T880": { + "core": "Mali-T880", + "filename": "flutter/impeller/entity/gles/texture_downsample.frag.gles", + "has_uniform_computation": false, + "type": "Fragment", + "variants": { + "Main": { + "has_stack_spilling": false, + "performance": { + "longest_path_bound_pipelines": [ + "texture" + ], + "longest_path_cycles": [ + 2.640000104904175, + 1.0, + 3.0 + ], + "pipelines": [ + "arithmetic", + "load_store", + "texture" + ], + "shortest_path_bound_pipelines": [ + "texture" + ], + "shortest_path_cycles": [ + 2.640000104904175, + 1.0, + 3.0 + ], + "total_bound_pipelines": [ + "arithmetic", + "texture" + ], + "total_cycles": [ + 3.0, + 1.0, + 3.0 + ] + }, + "thread_occupancy": 100, + "uniform_registers_used": 1, + "work_registers_used": 2 + } + } + } + }, "flutter/impeller/entity/gles/texture_fill.frag.gles": { "Mali-G78": { "core": "Mali-G78", @@ -7322,6 +7438,76 @@ } } }, + "flutter/impeller/entity/texture_downsample.frag.vkspv": { + "Mali-G78": { + "core": "Mali-G78", + "filename": "flutter/impeller/entity/texture_downsample.frag.vkspv", + "has_side_effects": false, + "has_uniform_computation": true, + "modifies_coverage": false, + "reads_color_buffer": false, + "type": "Fragment", + "uses_late_zs_test": false, + "uses_late_zs_update": false, + "variants": { + "Main": { + "fp16_arithmetic": 57, + "has_stack_spilling": false, + "performance": { + "longest_path_bound_pipelines": [ + "texture" + ], + "longest_path_cycles": [ + 0.21875, + 0.21875, + 0.015625, + 0.0, + 0.0, + 0.25, + 0.75 + ], + "pipelines": [ + "arith_total", + "arith_fma", + "arith_cvt", + "arith_sfu", + "load_store", + "varying", + "texture" + ], + "shortest_path_bound_pipelines": [ + "texture" + ], + "shortest_path_cycles": [ + 0.21875, + 0.21875, + 0.015625, + 0.0, + 0.0, + 0.25, + 0.75 + ], + "total_bound_pipelines": [ + "texture" + ], + "total_cycles": [ + 0.21875, + 0.21875, + 0.015625, + 0.0, + 0.0, + 0.25, + 0.75 + ] + }, + "stack_spill_bytes": 0, + "thread_occupancy": 100, + "uniform_registers_used": 6, + "work_registers_used": 13 + } + } + } + }, "flutter/impeller/entity/texture_fill.frag.vkspv": { "Mali-G78": { "core": "Mali-G78", From b723a654b83bc3b3af3b05edce1262b01a9c9d14 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Mon, 8 Jul 2024 12:03:35 -0700 Subject: [PATCH 04/10] remove mip only unittests. --- impeller/aiks/aiks_blur_unittests.cc | 137 ------------------ .../filters/gaussian_blur_filter_contents.cc | 3 - 2 files changed, 140 deletions(-) diff --git a/impeller/aiks/aiks_blur_unittests.cc b/impeller/aiks/aiks_blur_unittests.cc index fab985b5d6d59..92d8a95ee20f7 100644 --- a/impeller/aiks/aiks_blur_unittests.cc +++ b/impeller/aiks/aiks_blur_unittests.cc @@ -1041,143 +1041,6 @@ TEST_P(AiksTest, GuassianBlurUpdatesMipmapContents) { ASSERT_TRUE(OpenPlaygroundHere(callback)); } -TEST_P(AiksTest, GaussianBlurAllocatesCorrectMipCountRenderTarget) { - size_t blur_required_mip_count = 1; - - Canvas canvas; - canvas.DrawCircle({100, 100}, 50, {.color = Color::CornflowerBlue()}); - canvas.SaveLayer({}, std::nullopt, - ImageFilter::MakeBlur(Sigma(3), Sigma(3), - FilterContents::BlurStyle::kNormal, - Entity::TileMode::kClamp)); - canvas.Restore(); - - Picture picture = canvas.EndRecordingAsPicture(); - std::shared_ptr cache = - std::make_shared(GetContext()->GetResourceAllocator()); - AiksContext aiks_context(GetContext(), nullptr, cache); - picture.ToImage(aiks_context, {100, 100}); - - size_t max_mip_count = 0; - for (auto it = cache->GetRenderTargetDataBegin(); - it != cache->GetRenderTargetDataEnd(); ++it) { - max_mip_count = std::max(it->config.mip_count, max_mip_count); - } - EXPECT_EQ(max_mip_count, blur_required_mip_count); -} - -TEST_P(AiksTest, GaussianBlurMipMapNestedLayer) { - fml::testing::LogCapture log_capture; - size_t blur_required_mip_count = 1; - - Canvas canvas; - canvas.DrawPaint({.color = Color::Wheat()}); - canvas.SaveLayer({.blend_mode = BlendMode::kMultiply}); - canvas.DrawCircle({100, 100}, 50, {.color = Color::CornflowerBlue()}); - canvas.SaveLayer({}, std::nullopt, - ImageFilter::MakeBlur(Sigma(30), Sigma(30), - FilterContents::BlurStyle::kNormal, - Entity::TileMode::kClamp)); - canvas.DrawCircle({200, 200}, 50, {.color = Color::Chartreuse()}); - - Picture picture = canvas.EndRecordingAsPicture(); - std::shared_ptr cache = - std::make_shared(GetContext()->GetResourceAllocator()); - AiksContext aiks_context(GetContext(), nullptr, cache); - picture.ToImage(aiks_context, {100, 100}); - - size_t max_mip_count = 0; - for (auto it = cache->GetRenderTargetDataBegin(); - it != cache->GetRenderTargetDataEnd(); ++it) { - max_mip_count = std::max(it->config.mip_count, max_mip_count); - } - EXPECT_EQ(max_mip_count, blur_required_mip_count); - // The log is FML_DLOG, so only check in debug builds. -#ifndef NDEBUG - if (GetParam() != PlaygroundBackend::kOpenGLES) { - EXPECT_EQ(log_capture.str().find(GaussianBlurFilterContents::kNoMipsError), - std::string::npos); - } else { - EXPECT_NE(log_capture.str().find(GaussianBlurFilterContents::kNoMipsError), - std::string::npos); - } -#endif -} - -TEST_P(AiksTest, GaussianBlurMipMapImageFilter) { - size_t blur_required_mip_count = 1; - fml::testing::LogCapture log_capture; - Canvas canvas; - canvas.SaveLayer( - {.image_filter = ImageFilter::MakeBlur(Sigma(30), Sigma(30), - FilterContents::BlurStyle::kNormal, - Entity::TileMode::kClamp)}); - canvas.DrawCircle({200, 200}, 50, {.color = Color::Chartreuse()}); - - Picture picture = canvas.EndRecordingAsPicture(); - std::shared_ptr cache = - std::make_shared(GetContext()->GetResourceAllocator()); - AiksContext aiks_context(GetContext(), nullptr, cache); - picture.ToImage(aiks_context, {1024, 768}); - - size_t max_mip_count = 0; - for (auto it = cache->GetRenderTargetDataBegin(); - it != cache->GetRenderTargetDataEnd(); ++it) { - max_mip_count = std::max(it->config.mip_count, max_mip_count); - } - EXPECT_EQ(max_mip_count, blur_required_mip_count); - // The log is FML_DLOG, so only check in debug builds. -#ifndef NDEBUG - if (GetParam() != PlaygroundBackend::kOpenGLES) { - EXPECT_EQ(log_capture.str().find(GaussianBlurFilterContents::kNoMipsError), - std::string::npos); - } else { - EXPECT_NE(log_capture.str().find(GaussianBlurFilterContents::kNoMipsError), - std::string::npos); - } -#endif -} - -TEST_P(AiksTest, GaussianBlurMipMapSolidColor) { - size_t blur_required_mip_count = 1; - fml::testing::LogCapture log_capture; - Canvas canvas; - canvas.DrawPath(PathBuilder{} - .MoveTo({100, 100}) - .LineTo({200, 100}) - .LineTo({150, 200}) - .LineTo({50, 200}) - .Close() - .TakePath(), - {.color = Color::Chartreuse(), - .image_filter = ImageFilter::MakeBlur( - Sigma(30), Sigma(30), FilterContents::BlurStyle::kNormal, - Entity::TileMode::kClamp)}); - - Picture picture = canvas.EndRecordingAsPicture(); - std::shared_ptr cache = - std::make_shared(GetContext()->GetResourceAllocator()); - AiksContext aiks_context(GetContext(), nullptr, cache); - picture.ToImage(aiks_context, {1024, 768}); - - size_t max_mip_count = 0; - for (auto it = cache->GetRenderTargetDataBegin(); - it != cache->GetRenderTargetDataEnd(); ++it) { - max_mip_count = std::max(it->config.mip_count, max_mip_count); - } - EXPECT_EQ(max_mip_count, blur_required_mip_count); - // The log is FML_DLOG, so only check in debug builds. -#ifndef NDEBUG - if (GetParam() != PlaygroundBackend::kOpenGLES) { - EXPECT_EQ(log_capture.str().find(GaussianBlurFilterContents::kNoMipsError), - std::string::npos); - } else { - EXPECT_NE(log_capture.str().find(GaussianBlurFilterContents::kNoMipsError), - std::string::npos); - } -#endif -} - TEST_P(AiksTest, MaskBlurDoesntStretchContents) { Scalar sigma = 70; auto callback = [&](AiksContext& renderer) -> std::optional { diff --git a/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc b/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc index 2aaa924ee9dc8..2c014e1dc314d 100644 --- a/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc +++ b/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc @@ -586,9 +586,6 @@ Entity ApplyBlurStyle(FilterContents::BlurStyle blur_style, } } // namespace -std::string_view GaussianBlurFilterContents::kNoMipsError = - "Applying gaussian blur without mipmap."; - GaussianBlurFilterContents::GaussianBlurFilterContents( Scalar sigma_x, Scalar sigma_y, From 4c94fe23b8e729f698d755d83873f27322003d99 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Mon, 8 Jul 2024 12:45:18 -0700 Subject: [PATCH 05/10] remove mip computation. --- impeller/aiks/canvas.cc | 41 ----------------- .../filters/gaussian_blur_filter_contents.cc | 44 ++----------------- .../filters/gaussian_blur_filter_contents.h | 3 -- 3 files changed, 4 insertions(+), 84 deletions(-) diff --git a/impeller/aiks/canvas.cc b/impeller/aiks/canvas.cc index 9f7544a952826..5859978394348 100644 --- a/impeller/aiks/canvas.cc +++ b/impeller/aiks/canvas.cc @@ -185,37 +185,6 @@ void Canvas::Save(uint32_t total_content_depth) { Save(false, total_content_depth); } -namespace { -class MipCountVisitor : public ImageFilterVisitor { - public: - virtual void Visit(const BlurImageFilter& filter) { - required_mip_count_ = FilterContents::kBlurFilterRequiredMipCount; - } - virtual void Visit(const LocalMatrixImageFilter& filter) { - required_mip_count_ = 1; - } - virtual void Visit(const DilateImageFilter& filter) { - required_mip_count_ = 1; - } - virtual void Visit(const ErodeImageFilter& filter) { - required_mip_count_ = 1; - } - virtual void Visit(const MatrixImageFilter& filter) { - required_mip_count_ = 1; - } - virtual void Visit(const ComposeImageFilter& filter) { - required_mip_count_ = 1; - } - virtual void Visit(const ColorImageFilter& filter) { - required_mip_count_ = 1; - } - int32_t GetRequiredMipCount() const { return required_mip_count_; } - - private: - int32_t required_mip_count_ = -1; -}; -} // namespace - void Canvas::Save(bool create_subpass, uint32_t total_content_depth, BlendMode blend_mode, @@ -240,11 +209,6 @@ void Canvas::Save(bool create_subpass, return filter; }; subpass->SetBackdropFilter(backdrop_filter_proc); - MipCountVisitor mip_count_visitor; - backdrop_filter->Visit(mip_count_visitor); - current_pass_->SetRequiredMipCount( - std::max(current_pass_->GetRequiredMipCount(), - mip_count_visitor.GetRequiredMipCount())); } subpass->SetBlendMode(blend_mode); current_pass_ = GetCurrentPass().AddSubpass(std::move(subpass)); @@ -868,11 +832,6 @@ void Canvas::SaveLayer(const Paint& paint, new_layer_pass.SetBoundsLimit(bounds, bounds_promise); } - if (paint.image_filter) { - MipCountVisitor mip_count_visitor; - paint.image_filter->Visit(mip_count_visitor); - new_layer_pass.SetRequiredMipCount(mip_count_visitor.GetRequiredMipCount()); - } // When applying a save layer, absorb any pending distributed opacity. Paint paint_copy = paint; paint_copy.color.alpha *= transform_stack_.back().distributed_opacity; diff --git a/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc b/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc index 2c014e1dc314d..6a436ada4c8ea 100644 --- a/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc +++ b/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc @@ -20,8 +20,6 @@ namespace impeller { using GaussianBlurVertexShader = GaussianBlurPipeline::VertexShader; using GaussianBlurFragmentShader = GaussianBlurPipeline::FragmentShader; -const int32_t GaussianBlurFilterContents::kBlurFilterRequiredMipCount = 1; - namespace { constexpr Scalar kMaxSigma = 500.0f; @@ -132,28 +130,13 @@ std::optional GetSnapshot(const std::shared_ptr& input, const ContentContext& renderer, const Entity& entity, const std::optional& coverage_hint) { - int32_t mip_count = GaussianBlurFilterContents::kBlurFilterRequiredMipCount; - if (renderer.GetContext()->GetBackendType() == - Context::BackendType::kOpenGLES) { - // TODO(https://github.com/flutter/flutter/issues/141732): Implement mip map - // generation on opengles. - mip_count = 1; - } - std::optional input_snapshot = input->GetSnapshot("GaussianBlur", renderer, entity, - /*coverage_limit=*/coverage_hint, - /*mip_count=*/mip_count); + /*coverage_limit=*/coverage_hint); if (!input_snapshot.has_value()) { return std::nullopt; } - // In order to avoid shimmering in downsampling step, we should have mips. - if (input_snapshot->texture->GetMipCount() <= 1) { - FML_DLOG(ERROR) << GaussianBlurFilterContents::kNoMipsError; - } - FML_DCHECK(!input_snapshot->texture->NeedsMipmapGeneration()); - return input_snapshot; } @@ -244,10 +227,6 @@ DownsamplePassArgs CalculateDownsamplePassArgs( std::min(GaussianBlurFilterContents::CalculateScale(scaled_sigma.x), GaussianBlurFilterContents::CalculateScale(scaled_sigma.y)); - if (desired_scalar < 0.25) { - desired_scalar = 0.25; - } - // TODO(jonahwilliams): If desired_scalar is 1.0 and we fully acquired the // gutter from the expanded_coverage_hint, we can skip the downsample pass. // pass. @@ -333,7 +312,7 @@ fml::StatusOr MakeDownsampleSubpass( const SamplerDescriptor& sampler_descriptor, const DownsamplePassArgs& pass_args, Entity::TileMode tile_mode) { - if (pass_args.effective_scalar.x >= 0.5) { + if (pass_args.effective_scalar.x >= 0.5f) { ContentContext::SubpassCallback subpass_callback = [&](const ContentContext& renderer, RenderPass& pass) { HostBuffer& host_buffer = renderer.GetTransientsBuffer(); @@ -391,7 +370,7 @@ fml::StatusOr MakeDownsampleSubpass( frame_info.texture_sampler_y_coord_scale = 1.0; TextureDownsampleFragmentShader::FragInfo frag_info; - frag_info.pixel_size = Vector2(1.0 / input_texture->GetSize()); + frag_info.pixel_size = Vector2(1.0f / input_texture->GetSize()); const Quad& uvs = pass_args.uvs; BindVertices(pass, host_buffer, @@ -612,22 +591,7 @@ Scalar GaussianBlurFilterContents::CalculateScale(Scalar sigma) { Scalar exponent = round(log2f(raw_result)); // Don't scale down below 1/16th to preserve signal. exponent = std::max(-4.0f, exponent); - Scalar rounded = powf(2.0f, exponent); - Scalar result = rounded; - // Extend the range of the 1/8th downsample based on the effective kernel size - // for the blur. - if (rounded < 0.125f) { - Scalar rounded_plus = powf(2.0f, exponent + 1); - Scalar blur_radius = CalculateBlurRadius(sigma); - int kernel_size_plus = (ScaleBlurRadius(blur_radius, rounded_plus) * 2) + 1; - // This constant was picked by looking at the results to make sure no - // shimmering was introduced at the highest sigma values that downscale to - // 1/16th. - static constexpr int32_t kEighthDownsampleKernalWidthMax = 41; - result = kernel_size_plus <= kEighthDownsampleKernalWidthMax ? rounded_plus - : rounded; - } - return result; + return std::max(powf(2.0f, exponent), 0.25f); }; std::optional GaussianBlurFilterContents::GetFilterSourceCoverage( diff --git a/impeller/entity/contents/filters/gaussian_blur_filter_contents.h b/impeller/entity/contents/filters/gaussian_blur_filter_contents.h index 3c91d23e65bb0..4408858e08b2c 100644 --- a/impeller/entity/contents/filters/gaussian_blur_filter_contents.h +++ b/impeller/entity/contents/filters/gaussian_blur_filter_contents.h @@ -46,9 +46,6 @@ GaussianBlurPipeline::FragmentShader::KernelSamples LerpHackKernelSamples( /// Note: This will replace `DirectionalGaussianBlurFilterContents`. class GaussianBlurFilterContents final : public FilterContents { public: - static std::string_view kNoMipsError; - static const int32_t kBlurFilterRequiredMipCount; - explicit GaussianBlurFilterContents( Scalar sigma_x, Scalar sigma_y, From a7df1bbe3500766b75af4a8b232ec0d0ca6343a2 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Mon, 8 Jul 2024 13:58:41 -0700 Subject: [PATCH 06/10] uncap downsample. --- .../filters/gaussian_blur_filter_contents.cc | 28 ++++++++++++++++-- .../entity/shaders/texture_downsample.frag | 29 +++++++------------ 2 files changed, 37 insertions(+), 20 deletions(-) diff --git a/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc b/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc index 6a436ada4c8ea..63c95f932fb54 100644 --- a/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc +++ b/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc @@ -356,6 +356,13 @@ fml::StatusOr MakeDownsampleSubpass( return renderer.MakeSubpass("Gaussian Blur Filter", pass_args.subpass_size, command_buffer, subpass_callback); } else { + // This assumes we don't scale below 1/8 + Scalar edge = 1.0; + Scalar ratio = 0.25; + if (pass_args.effective_scalar.x <= 0.125f) { + edge = 3.0; + ratio = 0.125; + } ContentContext::SubpassCallback subpass_callback = [&](const ContentContext& renderer, RenderPass& pass) { HostBuffer& host_buffer = renderer.GetTransientsBuffer(); @@ -370,7 +377,9 @@ fml::StatusOr MakeDownsampleSubpass( frame_info.texture_sampler_y_coord_scale = 1.0; TextureDownsampleFragmentShader::FragInfo frag_info; - frag_info.pixel_size = Vector2(1.0f / input_texture->GetSize()); + frag_info.edge = edge; + frag_info.ratio = ratio; + frag_info.pixel_size = Vector2(1.0f / Size(input_texture->GetSize())); const Quad& uvs = pass_args.uvs; BindVertices(pass, host_buffer, @@ -591,7 +600,22 @@ Scalar GaussianBlurFilterContents::CalculateScale(Scalar sigma) { Scalar exponent = round(log2f(raw_result)); // Don't scale down below 1/16th to preserve signal. exponent = std::max(-4.0f, exponent); - return std::max(powf(2.0f, exponent), 0.25f); + Scalar rounded = powf(2.0f, exponent); + Scalar result = rounded; + // Extend the range of the 1/8th downsample based on the effective kernel size + // for the blur. + if (rounded < 0.125f) { + Scalar rounded_plus = powf(2.0f, exponent + 1); + Scalar blur_radius = CalculateBlurRadius(sigma); + int kernel_size_plus = (ScaleBlurRadius(blur_radius, rounded_plus) * 2) + 1; + // This constant was picked by looking at the results to make sure no + // shimmering was introduced at the highest sigma values that downscale to + // 1/16th. + static constexpr int32_t kEighthDownsampleKernalWidthMax = 41; + result = kernel_size_plus <= kEighthDownsampleKernalWidthMax ? rounded_plus + : rounded; + } + return result; }; std::optional GaussianBlurFilterContents::GetFilterSourceCoverage( diff --git a/impeller/entity/shaders/texture_downsample.frag b/impeller/entity/shaders/texture_downsample.frag index de20d998cf84c..f595509ea2764 100644 --- a/impeller/entity/shaders/texture_downsample.frag +++ b/impeller/entity/shaders/texture_downsample.frag @@ -10,6 +10,8 @@ precision mediump float; uniform f16sampler2D texture_sampler; uniform FragInfo { + float edge; + float ratio; vec2 pixel_size; } frag_info; @@ -19,22 +21,13 @@ in highp vec2 v_texture_coords; out f16vec4 frag_color; void main() { - f16vec4 lt = texture(texture_sampler, v_texture_coords - frag_info.pixel_size, - float16_t(kDefaultMipBias)) * - 0.25hf; - f16vec4 rt = texture(texture_sampler, - v_texture_coords + vec2(-frag_info.pixel_size.x, - frag_info.pixel_size.y), - float16_t(kDefaultMipBias)) * - 0.25hf; - f16vec4 lb = texture(texture_sampler, - v_texture_coords + vec2(frag_info.pixel_size.x, - -frag_info.pixel_size.y), - float16_t(kDefaultMipBias)) * - 0.25hf; - f16vec4 rb = texture(texture_sampler, v_texture_coords + frag_info.pixel_size, - float16_t(kDefaultMipBias)) * - 0.25hf; - - frag_color = lt + rb + lb + rb; + f16vec4 total = f16vec4(0.0hf); + float16_t ratio = float16_t(frag_info.ratio); + for (float i = -frag_info.edge; i <= frag_info.edge; i += 2) { + for (float j = -frag_info.edge; j <= frag_info.edge; j += 2) { + total += (texture(texture_sampler, v_texture_coords + frag_info.pixel_size * vec2(i, j), + float16_t(kDefaultMipBias)) * ratio); + } + } + frag_color = total; } From 490fa464da7c4c5c393d10197edffd0683772112 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Mon, 8 Jul 2024 13:59:15 -0700 Subject: [PATCH 07/10] ++ --- impeller/entity/shaders/texture_downsample.frag | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/impeller/entity/shaders/texture_downsample.frag b/impeller/entity/shaders/texture_downsample.frag index f595509ea2764..9c48934f0ba7f 100644 --- a/impeller/entity/shaders/texture_downsample.frag +++ b/impeller/entity/shaders/texture_downsample.frag @@ -25,8 +25,10 @@ void main() { float16_t ratio = float16_t(frag_info.ratio); for (float i = -frag_info.edge; i <= frag_info.edge; i += 2) { for (float j = -frag_info.edge; j <= frag_info.edge; j += 2) { - total += (texture(texture_sampler, v_texture_coords + frag_info.pixel_size * vec2(i, j), - float16_t(kDefaultMipBias)) * ratio); + total += (texture(texture_sampler, + v_texture_coords + frag_info.pixel_size * vec2(i, j), + float16_t(kDefaultMipBias)) * + ratio); } } frag_color = total; From 1bba3a9b5f4d1deeb48e894ecd8858a70d7c44ba Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Mon, 8 Jul 2024 14:43:42 -0700 Subject: [PATCH 08/10] fix ratio. --- .../contents/filters/gaussian_blur_filter_contents.cc | 2 +- impeller/entity/shaders/texture_downsample.frag | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc b/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc index 63c95f932fb54..3757e5f67d87f 100644 --- a/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc +++ b/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc @@ -361,7 +361,7 @@ fml::StatusOr MakeDownsampleSubpass( Scalar ratio = 0.25; if (pass_args.effective_scalar.x <= 0.125f) { edge = 3.0; - ratio = 0.125; + ratio = 0.0625; } ContentContext::SubpassCallback subpass_callback = [&](const ContentContext& renderer, RenderPass& pass) { diff --git a/impeller/entity/shaders/texture_downsample.frag b/impeller/entity/shaders/texture_downsample.frag index 9c48934f0ba7f..8b512fe29abf5 100644 --- a/impeller/entity/shaders/texture_downsample.frag +++ b/impeller/entity/shaders/texture_downsample.frag @@ -18,17 +18,16 @@ frag_info; in highp vec2 v_texture_coords; -out f16vec4 frag_color; +out vec4 frag_color; void main() { - f16vec4 total = f16vec4(0.0hf); - float16_t ratio = float16_t(frag_info.ratio); + vec4 total = vec4(0.0); for (float i = -frag_info.edge; i <= frag_info.edge; i += 2) { for (float j = -frag_info.edge; j <= frag_info.edge; j += 2) { total += (texture(texture_sampler, v_texture_coords + frag_info.pixel_size * vec2(i, j), float16_t(kDefaultMipBias)) * - ratio); + frag_info.ratio); } } frag_color = total; From 2e8f4492b92f30a8b5136c7c5a1f48500038d7e4 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Mon, 8 Jul 2024 15:19:39 -0700 Subject: [PATCH 09/10] update malioc. --- impeller/tools/malioc.json | 118 +++++++++++++++++++------------------ 1 file changed, 62 insertions(+), 56 deletions(-) diff --git a/impeller/tools/malioc.json b/impeller/tools/malioc.json index 1935d42b98239..65d69603b1dac 100644 --- a/impeller/tools/malioc.json +++ b/impeller/tools/malioc.json @@ -4734,7 +4734,7 @@ "core": "Mali-G78", "filename": "flutter/impeller/entity/gles/texture_downsample.frag.gles", "has_side_effects": false, - "has_uniform_computation": false, + "has_uniform_computation": true, "modifies_coverage": false, "reads_color_buffer": false, "type": "Fragment", @@ -4742,20 +4742,20 @@ "uses_late_zs_update": false, "variants": { "Main": { - "fp16_arithmetic": 66, + "fp16_arithmetic": 80, "has_stack_spilling": false, "performance": { "longest_path_bound_pipelines": [ - "texture" + null ], "longest_path_cycles": [ - 0.1875, - 0.1875, - 0.078125, - 0.0, - 0.0, - 0.25, - 0.75 + null, + null, + null, + null, + null, + null, + null ], "pipelines": [ "arith_total", @@ -4767,34 +4767,38 @@ "texture" ], "shortest_path_bound_pipelines": [ - "texture" + "arith_total", + "arith_cvt" ], "shortest_path_cycles": [ - 0.1875, - 0.1875, - 0.046875, + 0.0625, 0.0, + 0.0625, 0.0, - 0.25, - 0.75 + 0.0, + 0.0, + 0.0 ], "total_bound_pipelines": [ + "arith_total", + "arith_cvt", + "varying", "texture" ], "total_cycles": [ - 0.1875, - 0.1875, - 0.078125, + 0.25, + 0.125, + 0.25, 0.0, 0.0, 0.25, - 0.75 + 0.25 ] }, "stack_spill_bytes": 0, "thread_occupancy": 100, - "uniform_registers_used": 4, - "work_registers_used": 20 + "uniform_registers_used": 6, + "work_registers_used": 19 } } }, @@ -4808,12 +4812,12 @@ "has_stack_spilling": false, "performance": { "longest_path_bound_pipelines": [ - "texture" + null ], "longest_path_cycles": [ - 2.640000104904175, - 1.0, - 3.0 + null, + null, + null ], "pipelines": [ "arithmetic", @@ -4821,26 +4825,26 @@ "texture" ], "shortest_path_bound_pipelines": [ - "texture" + "arithmetic", + "load_store" ], "shortest_path_cycles": [ - 2.640000104904175, 1.0, - 3.0 + 1.0, + 0.0 ], "total_bound_pipelines": [ - "arithmetic", - "texture" + "arithmetic" ], "total_cycles": [ - 3.0, + 3.3333332538604736, 1.0, - 3.0 + 1.0 ] }, "thread_occupancy": 100, "uniform_registers_used": 1, - "work_registers_used": 2 + "work_registers_used": 4 } } } @@ -7451,20 +7455,20 @@ "uses_late_zs_update": false, "variants": { "Main": { - "fp16_arithmetic": 57, + "fp16_arithmetic": 40, "has_stack_spilling": false, "performance": { "longest_path_bound_pipelines": [ - "texture" + null ], "longest_path_cycles": [ - 0.21875, - 0.21875, - 0.015625, - 0.0, - 0.0, - 0.25, - 0.75 + null, + null, + null, + null, + null, + null, + null ], "pipelines": [ "arith_total", @@ -7476,34 +7480,36 @@ "texture" ], "shortest_path_bound_pipelines": [ - "texture" + "arith_total", + "arith_cvt" ], "shortest_path_cycles": [ - 0.21875, - 0.21875, - 0.015625, + 0.109375, 0.0, + 0.109375, 0.0, - 0.25, - 0.75 + 0.0, + 0.0, + 0.0 ], "total_bound_pipelines": [ - "texture" + "arith_total", + "arith_cvt" ], "total_cycles": [ - 0.21875, - 0.21875, - 0.015625, + 0.328125, + 0.09375, + 0.328125, 0.0, 0.0, 0.25, - 0.75 + 0.25 ] }, "stack_spill_bytes": 0, "thread_occupancy": 100, - "uniform_registers_used": 6, - "work_registers_used": 13 + "uniform_registers_used": 8, + "work_registers_used": 14 } } } From eff3cb0f32399d59dd171d24e2232addf962dd8a Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Tue, 9 Jul 2024 11:30:47 -0700 Subject: [PATCH 10/10] ++ --- .../contents/filters/gaussian_blur_filter_contents.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc b/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc index 3757e5f67d87f..ad184172317df 100644 --- a/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc +++ b/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc @@ -312,7 +312,11 @@ fml::StatusOr MakeDownsampleSubpass( const SamplerDescriptor& sampler_descriptor, const DownsamplePassArgs& pass_args, Entity::TileMode tile_mode) { - if (pass_args.effective_scalar.x >= 0.5f) { + // If the texture already had mip levels generated, then we can use the + // original downsample shader. + if (pass_args.effective_scalar.x >= 0.5f || + (!input_texture->NeedsMipmapGeneration() && + input_texture->GetTextureDescriptor().mip_count > 1)) { ContentContext::SubpassCallback subpass_callback = [&](const ContentContext& renderer, RenderPass& pass) { HostBuffer& host_buffer = renderer.GetTransientsBuffer();