diff --git a/impeller/display_list/dl_dispatcher.cc b/impeller/display_list/dl_dispatcher.cc index fa8782426c4ff..e3cc16c16d41d 100644 --- a/impeller/display_list/dl_dispatcher.cc +++ b/impeller/display_list/dl_dispatcher.cc @@ -18,10 +18,12 @@ #include "impeller/display_list/dl_vertices_geometry.h" #include "impeller/display_list/nine_patch_converter.h" #include "impeller/display_list/skia_conversions.h" +#include "impeller/entity/contents/content_context.h" #include "impeller/entity/contents/filters/filter_contents.h" #include "impeller/entity/contents/filters/inputs/filter_input.h" #include "impeller/entity/contents/runtime_effect_contents.h" #include "impeller/entity/entity.h" +#include "impeller/geometry/color.h" #include "impeller/geometry/path.h" #include "impeller/geometry/path_builder.h" #include "impeller/geometry/scalar.h" @@ -1168,11 +1170,24 @@ Canvas& DlDispatcher::GetCanvas() { return canvas_; } -ExperimentalDlDispatcher::ExperimentalDlDispatcher(ContentContext& renderer, - RenderTarget& render_target, - bool requires_readback, - IRect cull_rect) - : canvas_(renderer, render_target, requires_readback, cull_rect) {} +static bool RequiresReadbackForBlends( + const ContentContext& renderer, + flutter::DlBlendMode max_root_blend_mode) { + return !renderer.GetDeviceCapabilities().SupportsFramebufferFetch() && + ToBlendMode(max_root_blend_mode) > Entity::kLastPipelineBlendMode; +} + +ExperimentalDlDispatcher::ExperimentalDlDispatcher( + ContentContext& renderer, + RenderTarget& render_target, + bool has_root_backdrop_filter, + flutter::DlBlendMode max_root_blend_mode, + IRect cull_rect) + : canvas_(renderer, + render_target, + has_root_backdrop_filter || + RequiresReadbackForBlends(renderer, max_root_blend_mode), + cull_rect) {} Canvas& ExperimentalDlDispatcher::GetCanvas() { return canvas_; diff --git a/impeller/display_list/dl_dispatcher.h b/impeller/display_list/dl_dispatcher.h index ef694b2d2167e..3382af0971be7 100644 --- a/impeller/display_list/dl_dispatcher.h +++ b/impeller/display_list/dl_dispatcher.h @@ -12,6 +12,7 @@ #include "impeller/aiks/experimental_canvas.h" #include "impeller/aiks/paint.h" #include "impeller/entity/contents/content_context.h" +#include "impeller/geometry/color.h" namespace impeller { @@ -291,7 +292,8 @@ class ExperimentalDlDispatcher : public DlDispatcherBase { public: ExperimentalDlDispatcher(ContentContext& renderer, RenderTarget& render_target, - bool requires_readback, + bool has_root_backdrop_filter, + flutter::DlBlendMode max_root_blend_mode, IRect cull_rect); ~ExperimentalDlDispatcher() = default; diff --git a/impeller/display_list/dl_playground.cc b/impeller/display_list/dl_playground.cc index 3378df47a2ec9..d31526c51cec2 100644 --- a/impeller/display_list/dl_playground.cc +++ b/impeller/display_list/dl_playground.cc @@ -55,7 +55,9 @@ bool DlPlayground::OpenPlaygroundHere(DisplayListPlaygroundCallback callback) { list->Dispatch(collector); ExperimentalDlDispatcher impeller_dispatcher( - context.GetContentContext(), render_target, IRect::MakeMaximum()); + context.GetContentContext(), render_target, + display_list->root_has_backdrop_filter(), + display_list->max_root_blend_mode(), IRect::MakeMaximum()); list->Dispatch(impeller_dispatcher); impeller_dispatcher.FinishRecording(); context.GetContentContext().GetTransientsBuffer().Reset(); diff --git a/shell/gpu/gpu_surface_metal_impeller.mm b/shell/gpu/gpu_surface_metal_impeller.mm index 01093fe37612f..8664aed5e7c9a 100644 --- a/shell/gpu/gpu_surface_metal_impeller.mm +++ b/shell/gpu/gpu_surface_metal_impeller.mm @@ -164,8 +164,6 @@ impeller::IRect cull_rect = surface->coverage(); SkIRect sk_cull_rect = SkIRect::MakeWH(cull_rect.GetWidth(), cull_rect.GetHeight()); - [[maybe_unused]] auto supports_readback = - surface_frame.framebuffer_info().supports_readback; #if ENABLE_EXPERIMENTAL_CANVAS impeller::TextFrameDispatcher collector(aiks_context->GetContentContext(), @@ -176,7 +174,9 @@ fml::MakeCopyable([aiks_context, &display_list, &cull_rect, &sk_cull_rect](impeller::RenderTarget& render_target) -> bool { impeller::ExperimentalDlDispatcher impeller_dispatcher( - aiks_context->GetContentContext(), render_target, supports_readback, cull_rect); + aiks_context->GetContentContext(), render_target, + display_list->root_has_backdrop_filter(), display_list->max_root_blend_mode(), + cull_rect); display_list->Dispatch(impeller_dispatcher, sk_cull_rect); impeller_dispatcher.FinishRecording(); aiks_context->GetContentContext().GetTransientsBuffer().Reset(); diff --git a/shell/gpu/gpu_surface_vulkan_impeller.cc b/shell/gpu/gpu_surface_vulkan_impeller.cc index 430dfb6489903..3c0824f854832 100644 --- a/shell/gpu/gpu_surface_vulkan_impeller.cc +++ b/shell/gpu/gpu_surface_vulkan_impeller.cc @@ -84,8 +84,6 @@ std::unique_ptr GPUSurfaceVulkanImpeller::AcquireFrame( auto cull_rect = surface->GetTargetRenderPassDescriptor().GetRenderTargetSize(); - [[maybe_unused]] auto supports_readback = - surface_frame.framebuffer_info().supports_readback; return renderer->Render( std::move(surface), @@ -99,7 +97,8 @@ std::unique_ptr GPUSurfaceVulkanImpeller::AcquireFrame( SkIRect::MakeWH(cull_rect.width, cull_rect.height)); impeller::ExperimentalDlDispatcher impeller_dispatcher( aiks_context->GetContentContext(), render_target, - supports_readback, + display_list->root_has_backdrop_filter(), + display_list->max_root_blend_mode(), impeller::IRect::RoundOut( impeller::Rect::MakeSize(cull_rect))); display_list->Dispatch( diff --git a/shell/platform/embedder/embedder_external_view.cc b/shell/platform/embedder/embedder_external_view.cc index c549039183b75..c7806ff11b95e 100644 --- a/shell/platform/embedder/embedder_external_view.cc +++ b/shell/platform/embedder/embedder_external_view.cc @@ -117,7 +117,8 @@ bool EmbedderExternalView::Render(const EmbedderRenderTarget& render_target, impeller::ExperimentalDlDispatcher impeller_dispatcher( aiks_context->GetContentContext(), *impeller_target, - /*supports_readback=*/false, cull_rect); + display_list->root_has_backdrop_filter(), + display_list->max_root_blend_mode(), cull_rect); display_list->Dispatch(impeller_dispatcher, sk_cull_rect); impeller_dispatcher.FinishRecording(); aiks_context->GetContentContext().GetTransientsBuffer().Reset();