From 03f53163436194c1fa9722deef0d2d848a476cae Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Tue, 7 Mar 2023 12:53:09 -0800 Subject: [PATCH 1/5] [Impeller] reduce quantity of FML_OS_PHYSICAL_IOS checks --- impeller/entity/BUILD.gn | 11 +- impeller/entity/contents/atlas_contents.cc | 64 ++- impeller/entity/contents/content_context.cc | 43 +- impeller/entity/contents/content_context.h | 181 +-------- .../contents/framebuffer_blend_contents.cc | 40 +- .../contents/framebuffer_blend_context.cc | 73 ++++ .../contents/framebuffer_blend_context.h | 380 ++++++++++++++++++ impeller/entity/entity_pass.cc | 29 +- impeller/entity/entity_pass.h | 10 +- .../renderer/backend/gles/context_gles.cc | 1 + .../renderer/backend/metal/context_mtl.mm | 9 + .../renderer/backend/vulkan/context_vk.cc | 1 + impeller/renderer/device_capabilities.cc | 13 + impeller/renderer/device_capabilities.h | 7 + 14 files changed, 579 insertions(+), 283 deletions(-) create mode 100644 impeller/entity/contents/framebuffer_blend_context.cc create mode 100644 impeller/entity/contents/framebuffer_blend_context.h diff --git a/impeller/entity/BUILD.gn b/impeller/entity/BUILD.gn index 7507599a57e25..4098ca24c326e 100644 --- a/impeller/entity/BUILD.gn +++ b/impeller/entity/BUILD.gn @@ -143,6 +143,10 @@ impeller_component("entity") { "contents/filters/srgb_to_linear_filter_contents.h", "contents/filters/yuv_to_rgb_filter_contents.cc", "contents/filters/yuv_to_rgb_filter_contents.h", + "contents/framebuffer_blend_contents.cc", + "contents/framebuffer_blend_contents.h", + "contents/framebuffer_blend_context.cc", + "contents/framebuffer_blend_context.h", "contents/gradient_generator.cc", "contents/gradient_generator.h", "contents/linear_gradient_contents.cc", @@ -179,13 +183,6 @@ impeller_component("entity") { "inline_pass_context.h", ] - if (is_ios && !use_ios_simulator) { - sources += [ - "contents/framebuffer_blend_contents.cc", - "contents/framebuffer_blend_contents.h", - ] - } - public_deps = [ ":entity_shaders", ":modern_entity_shaders", diff --git a/impeller/entity/contents/atlas_contents.cc b/impeller/entity/contents/atlas_contents.cc index cb636e89fb4d2..88dc130ecc87e 100644 --- a/impeller/entity/contents/atlas_contents.cc +++ b/impeller/entity/contents/atlas_contents.cc @@ -12,6 +12,7 @@ #include "impeller/entity/contents/content_context.h" #include "impeller/entity/contents/filters/color_filter_contents.h" #include "impeller/entity/contents/filters/filter_contents.h" +#include "impeller/entity/contents/framebuffer_blend_contents.h" #include "impeller/entity/contents/texture_contents.h" #include "impeller/entity/entity.h" #include "impeller/entity/geometry.h" @@ -22,10 +23,6 @@ #include "impeller/renderer/sampler_library.h" #include "impeller/renderer/vertex_buffer_builder.h" -#ifdef FML_OS_PHYSICAL_IOS -#include "impeller/entity/contents/framebuffer_blend_contents.h" -#endif - namespace impeller { AtlasContents::AtlasContents() = default; @@ -224,38 +221,39 @@ bool AtlasContents::Render(const ContentContext& renderer, dst_contents->SetSubAtlas(sub_atlas); dst_contents->SetCoverage(sub_coverage); -#ifdef FML_OS_PHYSICAL_IOS - auto new_texture = renderer.MakeSubpass( - "Atlas Blend", sub_atlas->size, - [&](const ContentContext& context, RenderPass& pass) { - Entity entity; - entity.SetContents(dst_contents); - entity.SetBlendMode(BlendMode::kSource); - if (!entity.Render(context, pass)) { - return false; - } - if (blend_mode_ >= Entity::kLastPipelineBlendMode) { - auto contents = std::make_shared(); - contents->SetBlendMode(blend_mode_); - contents->SetChildContents(src_contents); - entity.SetContents(std::move(contents)); + std::shared_ptr new_texture; + if (renderer.GetDeviceCapabilities().SupportsFramebufferBlending()) { + new_texture = renderer.MakeSubpass( + "Atlas Blend", sub_atlas->size, + [&](const ContentContext& context, RenderPass& pass) { + Entity entity; + entity.SetContents(dst_contents); entity.SetBlendMode(BlendMode::kSource); + if (!entity.Render(context, pass)) { + return false; + } + if (blend_mode_ >= Entity::kLastPipelineBlendMode) { + auto contents = std::make_shared(); + contents->SetBlendMode(blend_mode_); + contents->SetChildContents(src_contents); + entity.SetContents(std::move(contents)); + entity.SetBlendMode(BlendMode::kSource); + return entity.Render(context, pass); + } + entity.SetContents(src_contents); + entity.SetBlendMode(blend_mode_); return entity.Render(context, pass); - } - entity.SetContents(src_contents); - entity.SetBlendMode(blend_mode_); - return entity.Render(context, pass); - }); -#else - auto contents = ColorFilterContents::MakeBlend( - blend_mode_, - {FilterInput::Make(dst_contents), FilterInput::Make(src_contents)}); - auto snapshot = contents->RenderToSnapshot(renderer, entity); - if (!snapshot.has_value()) { - return false; + }); + } else { + auto contents = ColorFilterContents::MakeBlend( + blend_mode_, + {FilterInput::Make(dst_contents), FilterInput::Make(src_contents)}); + auto snapshot = contents->RenderToSnapshot(renderer, entity); + if (!snapshot.has_value()) { + return false; + } + new_texture = snapshot.value().texture; } - auto new_texture = snapshot.value().texture; -#endif auto child_contents = AtlasTextureContents(*this); child_contents.SetAlpha(alpha_); diff --git a/impeller/entity/contents/content_context.cc b/impeller/entity/contents/content_context.cc index e15058d5fb330..7c3774b0bc3b5 100644 --- a/impeller/entity/contents/content_context.cc +++ b/impeller/entity/contents/content_context.cc @@ -8,6 +8,7 @@ #include #include "impeller/base/strings.h" +#include "impeller/entity/contents/framebuffer_blend_context.h" #include "impeller/entity/entity.h" #include "impeller/renderer/command_buffer.h" #include "impeller/renderer/formats.h" @@ -164,7 +165,9 @@ ContentContext::ContentContext(std::shared_ptr context) : context_(std::move(context)), tessellator_(std::make_shared()), glyph_atlas_context_(std::make_shared()), - scene_context_(std::make_shared(context_)) { + scene_context_(std::make_shared(context_)), + framebuffer_blend_context_( + std::make_shared(context_)) { if (!context_ || !context_->IsValid()) { return; } @@ -213,39 +216,6 @@ ContentContext::ContentContext(std::shared_ptr context) CreateDefaultPipeline(*context_); blend_softlight_pipelines_[{}] = CreateDefaultPipeline(*context_); -#if FML_OS_PHYSICAL_IOS - framebuffer_blend_color_pipelines_[{}] = - CreateDefaultPipeline(*context_); - framebuffer_blend_colorburn_pipelines_[{}] = - CreateDefaultPipeline(*context_); - framebuffer_blend_colordodge_pipelines_[{}] = - CreateDefaultPipeline(*context_); - framebuffer_blend_darken_pipelines_[{}] = - CreateDefaultPipeline(*context_); - framebuffer_blend_difference_pipelines_[{}] = - CreateDefaultPipeline(*context_); - framebuffer_blend_exclusion_pipelines_[{}] = - CreateDefaultPipeline(*context_); - framebuffer_blend_hardlight_pipelines_[{}] = - CreateDefaultPipeline(*context_); - framebuffer_blend_hue_pipelines_[{}] = - CreateDefaultPipeline(*context_); - framebuffer_blend_lighten_pipelines_[{}] = - CreateDefaultPipeline(*context_); - framebuffer_blend_luminosity_pipelines_[{}] = - CreateDefaultPipeline(*context_); - framebuffer_blend_multiply_pipelines_[{}] = - CreateDefaultPipeline(*context_); - framebuffer_blend_overlay_pipelines_[{}] = - CreateDefaultPipeline(*context_); - framebuffer_blend_saturation_pipelines_[{}] = - CreateDefaultPipeline(*context_); - framebuffer_blend_screen_pipelines_[{}] = - CreateDefaultPipeline(*context_); - framebuffer_blend_softlight_pipelines_[{}] = - CreateDefaultPipeline(*context_); -#endif // FML_OS_PHYSICAL_IOS - sweep_gradient_fill_pipelines_[{}] = CreateDefaultPipeline(*context_); rrect_blur_pipelines_[{}] = @@ -385,4 +355,9 @@ void ContentContext::SetWireframe(bool wireframe) { wireframe_ = wireframe; } +std::shared_ptr +ContentContext::GetFramebufferBlendContext() const { + return framebuffer_blend_context_; +} + } // namespace impeller diff --git a/impeller/entity/contents/content_context.h b/impeller/entity/contents/content_context.h index fdad286a4016c..0faa23ad3cfbc 100644 --- a/impeller/entity/contents/content_context.h +++ b/impeller/entity/contents/content_context.h @@ -78,27 +78,11 @@ #include "impeller/entity/advanced_blend_saturation.frag.h" #include "impeller/entity/advanced_blend_screen.frag.h" #include "impeller/entity/advanced_blend_softlight.frag.h" -#if FML_OS_PHYSICAL_IOS -#include "impeller/entity/framebuffer_blend.vert.h" -#include "impeller/entity/framebuffer_blend_color.frag.h" -#include "impeller/entity/framebuffer_blend_colorburn.frag.h" -#include "impeller/entity/framebuffer_blend_colordodge.frag.h" -#include "impeller/entity/framebuffer_blend_darken.frag.h" -#include "impeller/entity/framebuffer_blend_difference.frag.h" -#include "impeller/entity/framebuffer_blend_exclusion.frag.h" -#include "impeller/entity/framebuffer_blend_hardlight.frag.h" -#include "impeller/entity/framebuffer_blend_hue.frag.h" -#include "impeller/entity/framebuffer_blend_lighten.frag.h" -#include "impeller/entity/framebuffer_blend_luminosity.frag.h" -#include "impeller/entity/framebuffer_blend_multiply.frag.h" -#include "impeller/entity/framebuffer_blend_overlay.frag.h" -#include "impeller/entity/framebuffer_blend_saturation.frag.h" -#include "impeller/entity/framebuffer_blend_screen.frag.h" -#include "impeller/entity/framebuffer_blend_softlight.frag.h" -#endif // FML_OS_PHYSICAL_IOS namespace impeller { +class FramebufferBlendContext; + using LinearGradientFillPipeline = RenderPipelineT; using SolidFillPipeline = @@ -202,55 +186,6 @@ using BlendScreenPipeline = RenderPipelineT; -#if FML_OS_PHYSICAL_IOS -// iOS only advanced blends. -using FramebufferBlendColorPipeline = - RenderPipelineT; -using FramebufferBlendColorBurnPipeline = - RenderPipelineT; -using FramebufferBlendColorDodgePipeline = - RenderPipelineT; -using FramebufferBlendDarkenPipeline = - RenderPipelineT; -using FramebufferBlendDifferencePipeline = - RenderPipelineT; -using FramebufferBlendExclusionPipeline = - RenderPipelineT; -using FramebufferBlendHardLightPipeline = - RenderPipelineT; -using FramebufferBlendHuePipeline = - RenderPipelineT; -using FramebufferBlendLightenPipeline = - RenderPipelineT; -using FramebufferBlendLuminosityPipeline = - RenderPipelineT; -using FramebufferBlendMultiplyPipeline = - RenderPipelineT; -using FramebufferBlendOverlayPipeline = - RenderPipelineT; -using FramebufferBlendSaturationPipeline = - RenderPipelineT; -using FramebufferBlendScreenPipeline = - RenderPipelineT; -using FramebufferBlendSoftLightPipeline = - RenderPipelineT; -#endif // FML_OS_PHYSICAL_IOS - /// Pipeline state configuration. /// /// Each unique combination of these options requires a different pipeline state @@ -516,88 +451,13 @@ class ContentContext { ContentContextOptions opts) const { return GetPipeline(blend_softlight_pipelines_, opts); } -#if FML_OS_PHYSICAL_IOS - // iOS advanced blends. - std::shared_ptr> - GetFramebufferBlendColorPipeline(ContentContextOptions opts) const { - return GetPipeline(framebuffer_blend_color_pipelines_, opts); - } - - std::shared_ptr> - GetFramebufferBlendColorBurnPipeline(ContentContextOptions opts) const { - return GetPipeline(framebuffer_blend_colorburn_pipelines_, opts); - } - - std::shared_ptr> - GetFramebufferBlendColorDodgePipeline(ContentContextOptions opts) const { - return GetPipeline(framebuffer_blend_colordodge_pipelines_, opts); - } - - std::shared_ptr> - GetFramebufferBlendDarkenPipeline(ContentContextOptions opts) const { - return GetPipeline(framebuffer_blend_darken_pipelines_, opts); - } - - std::shared_ptr> - GetFramebufferBlendDifferencePipeline(ContentContextOptions opts) const { - return GetPipeline(framebuffer_blend_difference_pipelines_, opts); - } - - std::shared_ptr> - GetFramebufferBlendExclusionPipeline(ContentContextOptions opts) const { - return GetPipeline(framebuffer_blend_exclusion_pipelines_, opts); - } - - std::shared_ptr> - GetFramebufferBlendHardLightPipeline(ContentContextOptions opts) const { - return GetPipeline(framebuffer_blend_hardlight_pipelines_, opts); - } - - std::shared_ptr> GetFramebufferBlendHuePipeline( - ContentContextOptions opts) const { - return GetPipeline(framebuffer_blend_hue_pipelines_, opts); - } - - std::shared_ptr> - GetFramebufferBlendLightenPipeline(ContentContextOptions opts) const { - return GetPipeline(framebuffer_blend_lighten_pipelines_, opts); - } - - std::shared_ptr> - GetFramebufferBlendLuminosityPipeline(ContentContextOptions opts) const { - return GetPipeline(framebuffer_blend_luminosity_pipelines_, opts); - } - - std::shared_ptr> - GetFramebufferBlendMultiplyPipeline(ContentContextOptions opts) const { - return GetPipeline(framebuffer_blend_multiply_pipelines_, opts); - } - - std::shared_ptr> - GetFramebufferBlendOverlayPipeline(ContentContextOptions opts) const { - return GetPipeline(framebuffer_blend_overlay_pipelines_, opts); - } - - std::shared_ptr> - GetFramebufferBlendSaturationPipeline(ContentContextOptions opts) const { - return GetPipeline(framebuffer_blend_saturation_pipelines_, opts); - } - - std::shared_ptr> - GetFramebufferBlendScreenPipeline(ContentContextOptions opts) const { - return GetPipeline(framebuffer_blend_screen_pipelines_, opts); - } - - std::shared_ptr> - GetFramebufferBlendSoftLightPipeline(ContentContextOptions opts) const { - return GetPipeline(framebuffer_blend_softlight_pipelines_, opts); - } -#endif // FML_OS_PHYSICAL_IOS std::shared_ptr GetContext() const; std::shared_ptr GetGlyphAtlasContext() const; + std::shared_ptr GetFramebufferBlendContext() const; + const IDeviceCapabilities& GetDeviceCapabilities() const; void SetWireframe(bool wireframe); @@ -669,38 +529,6 @@ class ContentContext { mutable Variants blend_saturation_pipelines_; mutable Variants blend_screen_pipelines_; mutable Variants blend_softlight_pipelines_; -#if FML_OS_PHYSICAL_IOS - mutable Variants - framebuffer_blend_color_pipelines_; - mutable Variants - framebuffer_blend_colorburn_pipelines_; - mutable Variants - framebuffer_blend_colordodge_pipelines_; - mutable Variants - framebuffer_blend_darken_pipelines_; - mutable Variants - framebuffer_blend_difference_pipelines_; - mutable Variants - framebuffer_blend_exclusion_pipelines_; - mutable Variants - framebuffer_blend_hardlight_pipelines_; - mutable Variants - framebuffer_blend_hue_pipelines_; - mutable Variants - framebuffer_blend_lighten_pipelines_; - mutable Variants - framebuffer_blend_luminosity_pipelines_; - mutable Variants - framebuffer_blend_multiply_pipelines_; - mutable Variants - framebuffer_blend_overlay_pipelines_; - mutable Variants - framebuffer_blend_saturation_pipelines_; - mutable Variants - framebuffer_blend_screen_pipelines_; - mutable Variants - framebuffer_blend_softlight_pipelines_; -#endif // FML_OS_PHYSICAL_IOS template std::shared_ptr> GetPipeline( @@ -739,6 +567,7 @@ class ContentContext { std::shared_ptr tessellator_; std::shared_ptr glyph_atlas_context_; std::shared_ptr scene_context_; + std::shared_ptr framebuffer_blend_context_; bool wireframe_ = false; FML_DISALLOW_COPY_AND_ASSIGN(ContentContext); diff --git a/impeller/entity/contents/framebuffer_blend_contents.cc b/impeller/entity/contents/framebuffer_blend_contents.cc index 3943adba77abe..632496dbe75f5 100644 --- a/impeller/entity/contents/framebuffer_blend_contents.cc +++ b/impeller/entity/contents/framebuffer_blend_contents.cc @@ -5,6 +5,7 @@ #include "framebuffer_blend_contents.h" #include "impeller/entity/contents/content_context.h" +#include "impeller/entity/contents/framebuffer_blend_context.h" #include "impeller/renderer/render_pass.h" #include "impeller/renderer/sampler_library.h" @@ -32,6 +33,11 @@ std::optional FramebufferBlendContents::GetCoverage( bool FramebufferBlendContents::Render(const ContentContext& renderer, const Entity& entity, RenderPass& pass) const { + if (!renderer.GetDeviceCapabilities().SupportsFramebufferBlending()) { + return false; + } + // TODO(jonahwilliams): get these shaders compiling more generally. +#if FML_OS_PHYSICAL_IOS using VS = FramebufferBlendScreenPipeline::VertexShader; using FS = FramebufferBlendScreenPipeline::FragmentShader; @@ -72,51 +78,52 @@ bool FramebufferBlendContents::Render(const ContentContext& renderer, cmd.BindVertices(vtx_buffer); cmd.stencil_reference = entity.GetStencilDepth(); + const auto ctx = renderer.GetFramebufferBlendContext(); switch (blend_mode_) { case BlendMode::kScreen: - cmd.pipeline = renderer.GetFramebufferBlendScreenPipeline(options); + cmd.pipeline = ctx->GetFramebufferBlendScreenPipeline(options); break; case BlendMode::kOverlay: - cmd.pipeline = renderer.GetFramebufferBlendOverlayPipeline(options); + cmd.pipeline = ctx->GetFramebufferBlendOverlayPipeline(options); break; case BlendMode::kDarken: - cmd.pipeline = renderer.GetFramebufferBlendDarkenPipeline(options); + cmd.pipeline = ctx->GetFramebufferBlendDarkenPipeline(options); break; case BlendMode::kLighten: - cmd.pipeline = renderer.GetFramebufferBlendLightenPipeline(options); + cmd.pipeline = ctx->GetFramebufferBlendLightenPipeline(options); break; case BlendMode::kColorDodge: - cmd.pipeline = renderer.GetFramebufferBlendColorDodgePipeline(options); + cmd.pipeline = ctx->GetFramebufferBlendColorDodgePipeline(options); break; case BlendMode::kColorBurn: - cmd.pipeline = renderer.GetFramebufferBlendColorBurnPipeline(options); + cmd.pipeline = ctx->GetFramebufferBlendColorBurnPipeline(options); break; case BlendMode::kHardLight: - cmd.pipeline = renderer.GetFramebufferBlendHardLightPipeline(options); + cmd.pipeline = ctx->GetFramebufferBlendHardLightPipeline(options); break; case BlendMode::kSoftLight: - cmd.pipeline = renderer.GetFramebufferBlendSoftLightPipeline(options); + cmd.pipeline = ctx->GetFramebufferBlendSoftLightPipeline(options); break; case BlendMode::kDifference: - cmd.pipeline = renderer.GetFramebufferBlendDifferencePipeline(options); + cmd.pipeline = ctx->GetFramebufferBlendDifferencePipeline(options); break; case BlendMode::kExclusion: - cmd.pipeline = renderer.GetFramebufferBlendExclusionPipeline(options); + cmd.pipeline = ctx->GetFramebufferBlendExclusionPipeline(options); break; case BlendMode::kMultiply: - cmd.pipeline = renderer.GetFramebufferBlendMultiplyPipeline(options); + cmd.pipeline = ctx->GetFramebufferBlendMultiplyPipeline(options); break; case BlendMode::kHue: - cmd.pipeline = renderer.GetFramebufferBlendHuePipeline(options); + cmd.pipeline = ctx->GetFramebufferBlendHuePipeline(options); break; case BlendMode::kSaturation: - cmd.pipeline = renderer.GetFramebufferBlendSaturationPipeline(options); + cmd.pipeline = ctx->GetFramebufferBlendSaturationPipeline(options); break; case BlendMode::kColor: - cmd.pipeline = renderer.GetFramebufferBlendColorPipeline(options); + cmd.pipeline = ctx->GetFramebufferBlendColorPipeline(options); break; case BlendMode::kLuminosity: - cmd.pipeline = renderer.GetFramebufferBlendLuminosityPipeline(options); + cmd.pipeline = ctx->GetFramebufferBlendLuminosityPipeline(options); break; default: return false; @@ -136,6 +143,9 @@ bool FramebufferBlendContents::Render(const ContentContext& renderer, VS::BindFrameInfo(cmd, uniform_view); return pass.AddCommand(cmd); +#else + return false; +#endif // FML_OS_PHYSICAL_IOS } } // namespace impeller diff --git a/impeller/entity/contents/framebuffer_blend_context.cc b/impeller/entity/contents/framebuffer_blend_context.cc new file mode 100644 index 0000000000000..d11709e9df3e4 --- /dev/null +++ b/impeller/entity/contents/framebuffer_blend_context.cc @@ -0,0 +1,73 @@ +// 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. + +#include "impeller/entity/contents/framebuffer_blend_context.h" + +#include "impeller/entity/entity.h" + +namespace impeller { + +template +static std::unique_ptr CreateDefaultPipeline( + const Context& context) { + auto desc = PipelineT::Builder::MakeDefaultPipelineDescriptor(context); + if (!desc.has_value()) { + return nullptr; + } + // Apply default ContentContextOptions to the descriptor. + const auto default_color_fmt = context.GetColorAttachmentPixelFormat(); + ContentContextOptions{.color_attachment_pixel_format = default_color_fmt} + .ApplyToPipelineDescriptor(*desc); + return std::make_unique(context, desc); +} + +FramebufferBlendContext::FramebufferBlendContext( + std::shared_ptr context) + : context_(std::move(context)) { + if (!context_ || !context_->IsValid()) { + return; + } + +#if FML_OS_PHYSICAL_IOS + framebuffer_blend_color_pipelines_[{}] = + CreateDefaultPipeline(*context_); + framebuffer_blend_colorburn_pipelines_[{}] = + CreateDefaultPipeline(*context_); + framebuffer_blend_colordodge_pipelines_[{}] = + CreateDefaultPipeline(*context_); + framebuffer_blend_darken_pipelines_[{}] = + CreateDefaultPipeline(*context_); + framebuffer_blend_difference_pipelines_[{}] = + CreateDefaultPipeline(*context_); + framebuffer_blend_exclusion_pipelines_[{}] = + CreateDefaultPipeline(*context_); + framebuffer_blend_hardlight_pipelines_[{}] = + CreateDefaultPipeline(*context_); + framebuffer_blend_hue_pipelines_[{}] = + CreateDefaultPipeline(*context_); + framebuffer_blend_lighten_pipelines_[{}] = + CreateDefaultPipeline(*context_); + framebuffer_blend_luminosity_pipelines_[{}] = + CreateDefaultPipeline(*context_); + framebuffer_blend_multiply_pipelines_[{}] = + CreateDefaultPipeline(*context_); + framebuffer_blend_overlay_pipelines_[{}] = + CreateDefaultPipeline(*context_); + framebuffer_blend_saturation_pipelines_[{}] = + CreateDefaultPipeline(*context_); + framebuffer_blend_screen_pipelines_[{}] = + CreateDefaultPipeline(*context_); + framebuffer_blend_softlight_pipelines_[{}] = + CreateDefaultPipeline(*context_); +#endif // FML_OS_PHYSICAL_IOS + is_valid_ = true; +} + +FramebufferBlendContext::~FramebufferBlendContext() = default; + +bool FramebufferBlendContext::IsValid() const { + return is_valid_; +} + +} // namespace impeller \ No newline at end of file diff --git a/impeller/entity/contents/framebuffer_blend_context.h b/impeller/entity/contents/framebuffer_blend_context.h new file mode 100644 index 0000000000000..2e84fed7e7ce0 --- /dev/null +++ b/impeller/entity/contents/framebuffer_blend_context.h @@ -0,0 +1,380 @@ +// 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. + +#pragma once + +#include +#include +#include + +#include "flutter/fml/hash_combine.h" +#include "flutter/fml/logging.h" +#include "flutter/fml/macros.h" +#include "impeller/base/validation.h" +#include "impeller/entity/contents/content_context.h" +#include "impeller/entity/entity.h" +#include "impeller/renderer/pipeline.h" + +#if FML_OS_PHYSICAL_IOS +#include "impeller/entity/framebuffer_blend.vert.h" +#include "impeller/entity/framebuffer_blend_color.frag.h" +#include "impeller/entity/framebuffer_blend_colorburn.frag.h" +#include "impeller/entity/framebuffer_blend_colordodge.frag.h" +#include "impeller/entity/framebuffer_blend_darken.frag.h" +#include "impeller/entity/framebuffer_blend_difference.frag.h" +#include "impeller/entity/framebuffer_blend_exclusion.frag.h" +#include "impeller/entity/framebuffer_blend_hardlight.frag.h" +#include "impeller/entity/framebuffer_blend_hue.frag.h" +#include "impeller/entity/framebuffer_blend_lighten.frag.h" +#include "impeller/entity/framebuffer_blend_luminosity.frag.h" +#include "impeller/entity/framebuffer_blend_multiply.frag.h" +#include "impeller/entity/framebuffer_blend_overlay.frag.h" +#include "impeller/entity/framebuffer_blend_saturation.frag.h" +#include "impeller/entity/framebuffer_blend_screen.frag.h" +#include "impeller/entity/framebuffer_blend_softlight.frag.h" +#endif // FML_OS_PHYSICAL_IOS + +namespace impeller { + +#if FML_OS_PHYSICAL_IOS +// iOS only advanced blends. +using FramebufferBlendColorPipeline = + RenderPipelineT; +using FramebufferBlendColorBurnPipeline = + RenderPipelineT; +using FramebufferBlendColorDodgePipeline = + RenderPipelineT; +using FramebufferBlendDarkenPipeline = + RenderPipelineT; +using FramebufferBlendDifferencePipeline = + RenderPipelineT; +using FramebufferBlendExclusionPipeline = + RenderPipelineT; +using FramebufferBlendHardLightPipeline = + RenderPipelineT; +using FramebufferBlendHuePipeline = + RenderPipelineT; +using FramebufferBlendLightenPipeline = + RenderPipelineT; +using FramebufferBlendLuminosityPipeline = + RenderPipelineT; +using FramebufferBlendMultiplyPipeline = + RenderPipelineT; +using FramebufferBlendOverlayPipeline = + RenderPipelineT; +using FramebufferBlendSaturationPipeline = + RenderPipelineT; +using FramebufferBlendScreenPipeline = + RenderPipelineT; +using FramebufferBlendSoftLightPipeline = + RenderPipelineT; +#endif // FML_OS_PHYSICAL_IOS + +class FramebufferBlendContext { + public: + explicit FramebufferBlendContext(std::shared_ptr context); + + ~FramebufferBlendContext(); + + bool IsValid() const; + +#if FML_OS_PHYSICAL_IOS + // iOS only advanced blends. + using FramebufferBlendColorPipeline = + RenderPipelineT; + using FramebufferBlendColorBurnPipeline = + RenderPipelineT; + using FramebufferBlendColorDodgePipeline = + RenderPipelineT; + using FramebufferBlendDarkenPipeline = + RenderPipelineT; + using FramebufferBlendDifferencePipeline = + RenderPipelineT; + using FramebufferBlendExclusionPipeline = + RenderPipelineT; + using FramebufferBlendHardLightPipeline = + RenderPipelineT; + using FramebufferBlendHuePipeline = + RenderPipelineT; + using FramebufferBlendLightenPipeline = + RenderPipelineT; + using FramebufferBlendLuminosityPipeline = + RenderPipelineT; + using FramebufferBlendMultiplyPipeline = + RenderPipelineT; + using FramebufferBlendOverlayPipeline = + RenderPipelineT; + using FramebufferBlendSaturationPipeline = + RenderPipelineT; + using FramebufferBlendScreenPipeline = + RenderPipelineT; + using FramebufferBlendSoftLightPipeline = + RenderPipelineT; + + std::shared_ptr> + GetFramebufferBlendColorPipeline(ContentContextOptions opts) const { + return GetPipeline(framebuffer_blend_color_pipelines_, opts); + } + + std::shared_ptr> + GetFramebufferBlendColorBurnPipeline(ContentContextOptions opts) const { + return GetPipeline(framebuffer_blend_colorburn_pipelines_, opts); + } + + std::shared_ptr> + GetFramebufferBlendColorDodgePipeline(ContentContextOptions opts) const { + return GetPipeline(framebuffer_blend_colordodge_pipelines_, opts); + } + + std::shared_ptr> + GetFramebufferBlendDarkenPipeline(ContentContextOptions opts) const { + return GetPipeline(framebuffer_blend_darken_pipelines_, opts); + } + + std::shared_ptr> + GetFramebufferBlendDifferencePipeline(ContentContextOptions opts) const { + return GetPipeline(framebuffer_blend_difference_pipelines_, opts); + } + + std::shared_ptr> + GetFramebufferBlendExclusionPipeline(ContentContextOptions opts) const { + return GetPipeline(framebuffer_blend_exclusion_pipelines_, opts); + } + + std::shared_ptr> + GetFramebufferBlendHardLightPipeline(ContentContextOptions opts) const { + return GetPipeline(framebuffer_blend_hardlight_pipelines_, opts); + } + + std::shared_ptr> GetFramebufferBlendHuePipeline( + ContentContextOptions opts) const { + return GetPipeline(framebuffer_blend_hue_pipelines_, opts); + } + + std::shared_ptr> + GetFramebufferBlendLightenPipeline(ContentContextOptions opts) const { + return GetPipeline(framebuffer_blend_lighten_pipelines_, opts); + } + + std::shared_ptr> + GetFramebufferBlendLuminosityPipeline(ContentContextOptions opts) const { + return GetPipeline(framebuffer_blend_luminosity_pipelines_, opts); + } + + std::shared_ptr> + GetFramebufferBlendMultiplyPipeline(ContentContextOptions opts) const { + return GetPipeline(framebuffer_blend_multiply_pipelines_, opts); + } + + std::shared_ptr> + GetFramebufferBlendOverlayPipeline(ContentContextOptions opts) const { + return GetPipeline(framebuffer_blend_overlay_pipelines_, opts); + } + + std::shared_ptr> + GetFramebufferBlendSaturationPipeline(ContentContextOptions opts) const { + return GetPipeline(framebuffer_blend_saturation_pipelines_, opts); + } + + std::shared_ptr> + GetFramebufferBlendScreenPipeline(ContentContextOptions opts) const { + return GetPipeline(framebuffer_blend_screen_pipelines_, opts); + } + + std::shared_ptr> + GetFramebufferBlendSoftLightPipeline(ContentContextOptions opts) const { + return GetPipeline(framebuffer_blend_softlight_pipelines_, opts); + } +#else + std::shared_ptr> + GetFramebufferBlendColorPipeline(ContentContextOptions opts) const { + FML_UNREACHABLE(); + } + + std::shared_ptr> + GetFramebufferBlendColorBurnPipeline(ContentContextOptions opts) const { + FML_UNREACHABLE(); + } + + std::shared_ptr> + GetFramebufferBlendColorDodgePipeline(ContentContextOptions opts) const { + FML_UNREACHABLE(); + } + + std::shared_ptr> + GetFramebufferBlendDarkenPipeline(ContentContextOptions opts) const { + FML_UNREACHABLE(); + } + + std::shared_ptr> + GetFramebufferBlendDifferencePipeline(ContentContextOptions opts) const { + FML_UNREACHABLE(); + } + + std::shared_ptr> + GetFramebufferBlendExclusionPipeline(ContentContextOptions opts) const { + FML_UNREACHABLE(); + } + + std::shared_ptr> + GetFramebufferBlendHardLightPipeline(ContentContextOptions opts) const { + FML_UNREACHABLE(); + } + + std::shared_ptr> GetFramebufferBlendHuePipeline( + ContentContextOptions opts) const { + FML_UNREACHABLE(); + } + + std::shared_ptr> + GetFramebufferBlendLightenPipeline(ContentContextOptions opts) const { + FML_UNREACHABLE(); + } + + std::shared_ptr> + GetFramebufferBlendLuminosityPipeline(ContentContextOptions opts) const { + FML_UNREACHABLE(); + } + + std::shared_ptr> + GetFramebufferBlendMultiplyPipeline(ContentContextOptions opts) const { + FML_UNREACHABLE(); + } + + std::shared_ptr> + GetFramebufferBlendOverlayPipeline(ContentContextOptions opts) const { + FML_UNREACHABLE(); + } + + std::shared_ptr> + GetFramebufferBlendSaturationPipeline(ContentContextOptions opts) const { + FML_UNREACHABLE(); + } + + std::shared_ptr> + GetFramebufferBlendScreenPipeline(ContentContextOptions opts) const { + FML_UNREACHABLE(); + } + + std::shared_ptr> + GetFramebufferBlendSoftLightPipeline(ContentContextOptions opts) const { + FML_UNREACHABLE(); + } +#endif // FML_OS_PHYSICAL_IOS + + private: + std::shared_ptr context_; + + template + using Variants = std::unordered_map, + ContentContextOptions::Hash, + ContentContextOptions::Equal>; + + // These are mutable because while the prototypes are created eagerly, any + // variants requested from that are lazily created and cached in the variants + // map. +#if FML_OS_PHYSICAL_IOS + mutable Variants + framebuffer_blend_color_pipelines_; + mutable Variants + framebuffer_blend_colorburn_pipelines_; + mutable Variants + framebuffer_blend_colordodge_pipelines_; + mutable Variants + framebuffer_blend_darken_pipelines_; + mutable Variants + framebuffer_blend_difference_pipelines_; + mutable Variants + framebuffer_blend_exclusion_pipelines_; + mutable Variants + framebuffer_blend_hardlight_pipelines_; + mutable Variants + framebuffer_blend_hue_pipelines_; + mutable Variants + framebuffer_blend_lighten_pipelines_; + mutable Variants + framebuffer_blend_luminosity_pipelines_; + mutable Variants + framebuffer_blend_multiply_pipelines_; + mutable Variants + framebuffer_blend_overlay_pipelines_; + mutable Variants + framebuffer_blend_saturation_pipelines_; + mutable Variants + framebuffer_blend_screen_pipelines_; + mutable Variants + framebuffer_blend_softlight_pipelines_; +#endif // FML_OS_PHYSICAL_IOS + + template + std::shared_ptr> GetPipeline( + Variants& container, + ContentContextOptions opts) const { + if (!IsValid()) { + return nullptr; + } + + if (wireframe_) { + opts.wireframe = true; + } + + if (auto found = container.find(opts); found != container.end()) { + return found->second->WaitAndGet(); + } + + auto prototype = container.find({}); + + // The prototype must always be initialized in the constructor. + FML_CHECK(prototype != container.end()); + + auto variant_future = prototype->second->WaitAndGet()->CreateVariant( + [&opts, variants_count = container.size()](PipelineDescriptor& desc) { + opts.ApplyToPipelineDescriptor(desc); + desc.SetLabel( + SPrintF("%s V#%zu", desc.GetLabel().c_str(), variants_count)); + }); + auto variant = std::make_unique(std::move(variant_future)); + auto variant_pipeline = variant->WaitAndGet(); + container[opts] = std::move(variant); + return variant_pipeline; + } + + bool is_valid_ = false; + bool wireframe_ = false; + + FML_DISALLOW_COPY_AND_ASSIGN(FramebufferBlendContext); +}; + +} // namespace impeller diff --git a/impeller/entity/entity_pass.cc b/impeller/entity/entity_pass.cc index 23e7f861085c1..301eb352620c6 100644 --- a/impeller/entity/entity_pass.cc +++ b/impeller/entity/entity_pass.cc @@ -16,9 +16,7 @@ #include "impeller/entity/contents/content_context.h" #include "impeller/entity/contents/filters/color_filter_contents.h" #include "impeller/entity/contents/filters/inputs/filter_input.h" -#if FML_OS_PHYSICAL_IOS #include "impeller/entity/contents/framebuffer_blend_contents.h" -#endif #include "impeller/entity/contents/texture_contents.h" #include "impeller/entity/entity.h" #include "impeller/entity/inline_pass_context.h" @@ -44,12 +42,9 @@ void EntityPass::SetDelegate(std::unique_ptr delegate) { } void EntityPass::AddEntity(Entity entity) { -#ifndef FML_OS_PHYSICAL_IOS if (entity.GetBlendMode() > Entity::kLastPipelineBlendMode) { - reads_from_pass_texture_ += 1; + blend_reads_from_pass_texture_ += 1; } -#endif - elements_.emplace_back(std::move(entity)); } @@ -135,16 +130,12 @@ EntityPass* EntityPass::AddSubpass(std::unique_ptr pass) { FML_DCHECK(pass->superpass_ == nullptr); pass->superpass_ = this; -#if FML_OS_PHYSICAL_IOS if (pass->backdrop_filter_proc_.has_value()) { - reads_from_pass_texture_ += 1; + filter_reads_from_pass_texture_ += 1; } -#else - if (pass->blend_mode_ > Entity::kLastPipelineBlendMode || - pass->backdrop_filter_proc_.has_value()) { - reads_from_pass_texture_ += 1; + if (pass->blend_mode_ > Entity::kLastPipelineBlendMode) { + blend_reads_from_pass_texture_ += 1; } -#endif auto subpass_pointer = pass.get(); elements_.emplace_back(std::move(pass)); @@ -199,9 +190,15 @@ static RenderTarget CreateRenderTarget(ContentContext& renderer, ); } +uint32_t EntityPass::ComputeTotalReads(ContentContext& renderer) const { + return renderer.GetDeviceCapabilities().SupportsFramebufferBlending() + ? filter_reads_from_pass_texture_ + : filter_reads_from_pass_texture_ + blend_reads_from_pass_texture_; +} + bool EntityPass::Render(ContentContext& renderer, const RenderTarget& render_target) const { - if (reads_from_pass_texture_ > 0) { + if (ComputeTotalReads(renderer) > 0) { auto offscreen_target = CreateRenderTarget(renderer, render_target.GetRenderTargetSize(), true); if (!OnRender(renderer, offscreen_target.GetRenderTargetSize(), @@ -357,7 +354,7 @@ EntityPass::EntityResult EntityPass::GetEntityForElement( auto subpass_target = CreateRenderTarget(renderer, // ISize(subpass_coverage->size), // - subpass->reads_from_pass_texture_ > 0); + subpass->ComputeTotalReads(renderer) > 0); auto subpass_texture = subpass_target.GetRenderTargetTexture(); @@ -420,7 +417,7 @@ bool EntityPass::OnRender(ContentContext& renderer, auto context = renderer.GetContext(); InlinePassContext pass_context(context, render_target, - reads_from_pass_texture_, + ComputeTotalReads(renderer), std::move(collapsed_parent_pass)); if (!pass_context.IsValid()) { return false; diff --git a/impeller/entity/entity_pass.h b/impeller/entity/entity_pass.h index d15beab319429..c958420157d13 100644 --- a/impeller/entity/entity_pass.h +++ b/impeller/entity/entity_pass.h @@ -118,12 +118,18 @@ class EntityPass { BlendMode blend_mode_ = BlendMode::kSourceOver; bool cover_whole_screen_ = false; - /// This value is incremented whenever something is added to the pass that + /// These value are incremented whenever something is added to the pass that /// requires reading from the backdrop texture. Currently, this can happen in /// the following scenarios: /// 1. An entity with an "advanced blend" is added to the pass. /// 2. A subpass with a backdrop filter is added to the pass. - uint32_t reads_from_pass_texture_ = 0; + /// These are tracked as separate values because we may ignore + /// blend_reads_from_pass_texture_ if the device supports framebuffer based + /// advanced blends. + uint32_t filter_reads_from_pass_texture_ = 0; + uint32_t blend_reads_from_pass_texture_ = 0; + + uint32_t ComputeTotalReads(ContentContext& renderer) const; std::optional backdrop_filter_proc_ = std::nullopt; diff --git a/impeller/renderer/backend/gles/context_gles.cc b/impeller/renderer/backend/gles/context_gles.cc index 99922ba7efaeb..62024f13fbd34 100644 --- a/impeller/renderer/backend/gles/context_gles.cc +++ b/impeller/renderer/backend/gles/context_gles.cc @@ -78,6 +78,7 @@ ContextGLES::ContextGLES(std::unique_ptr gl, .SetSupportsSSBO(false) .SetSupportsTextureToTextureBlits( reactor_->GetProcTable().BlitFramebuffer.IsAvailable()) + .SetSupportsFramebufferBlending(false) .SetDefaultColorFormat(PixelFormat::kB8G8R8A8UNormInt) .SetDefaultStencilFormat(PixelFormat::kS8UInt) .Build(); diff --git a/impeller/renderer/backend/metal/context_mtl.mm b/impeller/renderer/backend/metal/context_mtl.mm index a601f099fd001..11d0031bf3b36 100644 --- a/impeller/renderer/backend/metal/context_mtl.mm +++ b/impeller/renderer/backend/metal/context_mtl.mm @@ -90,12 +90,21 @@ #endif { + // TODO(jonahwilliams): find a way to query support for this for + // macOS/Simulator. +#if FML_OS_PHYSICAL_IOS + bool supports_framebuffer_blend = true; +#else + bool supports_framebuffer_blend = false; +#endif // FML_OS_PHYSICAL_IOS + device_capabilities_ = DeviceCapabilitiesBuilder() .SetHasThreadingRestrictions(false) .SetSupportsOffscreenMSAA(true) .SetSupportsSSBO(true) .SetSupportsTextureToTextureBlits(true) + .SetSupportsFramebufferBlending(supports_framebuffer_blend) .SetDefaultColorFormat(PixelFormat::kB8G8R8A8UNormInt) .SetDefaultStencilFormat(PixelFormat::kS8UInt) .Build(); diff --git a/impeller/renderer/backend/vulkan/context_vk.cc b/impeller/renderer/backend/vulkan/context_vk.cc index 41594818f7b8f..97c2bdce7e365 100644 --- a/impeller/renderer/backend/vulkan/context_vk.cc +++ b/impeller/renderer/backend/vulkan/context_vk.cc @@ -554,6 +554,7 @@ ContextVK::ContextVK( .SetSupportsOffscreenMSAA(true) .SetSupportsSSBO(false) .SetSupportsTextureToTextureBlits(true) + .SetSupportsFramebufferBlending(false) .SetDefaultColorFormat(PixelFormat::kB8G8R8A8UNormInt) .SetDefaultStencilFormat(PixelFormat::kS8UInt) .Build(); diff --git a/impeller/renderer/device_capabilities.cc b/impeller/renderer/device_capabilities.cc index 87653bb63beef..b98d8432e55f3 100644 --- a/impeller/renderer/device_capabilities.cc +++ b/impeller/renderer/device_capabilities.cc @@ -10,12 +10,14 @@ IDeviceCapabilities::IDeviceCapabilities(bool has_threading_restrictions, bool supports_offscreen_msaa, bool supports_ssbo, bool supports_texture_to_texture_blits, + bool supports_framebuffer_blending, PixelFormat default_color_format, PixelFormat default_stencil_format) : has_threading_restrictions_(has_threading_restrictions), supports_offscreen_msaa_(supports_offscreen_msaa), supports_ssbo_(supports_ssbo), supports_texture_to_texture_blits_(supports_texture_to_texture_blits), + supports_framebuffer_blending_(supports_framebuffer_blending), default_color_format_(default_color_format), default_stencil_format_(default_stencil_format) {} @@ -37,6 +39,10 @@ bool IDeviceCapabilities::SupportsTextureToTextureBlits() const { return supports_texture_to_texture_blits_; } +bool IDeviceCapabilities::SupportsFramebufferBlending() const { + return supports_framebuffer_blending_; +} + PixelFormat IDeviceCapabilities::GetDefaultColorFormat() const { return default_color_format_; } @@ -73,6 +79,12 @@ DeviceCapabilitiesBuilder::SetSupportsTextureToTextureBlits(bool value) { return *this; } +DeviceCapabilitiesBuilder& +DeviceCapabilitiesBuilder::SetSupportsFramebufferBlending(bool value) { + supports_framebuffer_blending_ = value; + return *this; +} + DeviceCapabilitiesBuilder& DeviceCapabilitiesBuilder::SetDefaultColorFormat( PixelFormat value) { default_color_format_ = value; @@ -96,6 +108,7 @@ std::unique_ptr DeviceCapabilitiesBuilder::Build() { supports_offscreen_msaa_, // supports_ssbo_, // supports_texture_to_texture_blits_, // + supports_framebuffer_blending_, // *default_color_format_, // *default_stencil_format_ // ); diff --git a/impeller/renderer/device_capabilities.h b/impeller/renderer/device_capabilities.h index 010281da37a4d..83439d5b0cd9e 100644 --- a/impeller/renderer/device_capabilities.h +++ b/impeller/renderer/device_capabilities.h @@ -23,6 +23,8 @@ class IDeviceCapabilities { bool SupportsTextureToTextureBlits() const; + bool SupportsFramebufferBlending() const; + PixelFormat GetDefaultColorFormat() const; PixelFormat GetDefaultStencilFormat() const; @@ -32,6 +34,7 @@ class IDeviceCapabilities { bool supports_offscreen_msaa, bool supports_ssbo, bool supports_texture_to_texture_blits, + bool supports_framebuffer_blending, PixelFormat default_color_format, PixelFormat default_stencil_format); @@ -41,6 +44,7 @@ class IDeviceCapabilities { bool supports_offscreen_msaa_ = false; bool supports_ssbo_ = false; bool supports_texture_to_texture_blits_ = false; + bool supports_framebuffer_blending_ = false; PixelFormat default_color_format_; PixelFormat default_stencil_format_; @@ -61,6 +65,8 @@ class DeviceCapabilitiesBuilder { DeviceCapabilitiesBuilder& SetSupportsTextureToTextureBlits(bool value); + DeviceCapabilitiesBuilder& SetSupportsFramebufferBlending(bool value); + DeviceCapabilitiesBuilder& SetDefaultColorFormat(PixelFormat value); DeviceCapabilitiesBuilder& SetDefaultStencilFormat(PixelFormat value); @@ -72,6 +78,7 @@ class DeviceCapabilitiesBuilder { bool supports_offscreen_msaa_ = false; bool supports_ssbo_ = false; bool supports_texture_to_texture_blits_ = false; + bool supports_framebuffer_blending_ = false; std::optional default_color_format_ = std::nullopt; std::optional default_stencil_format_ = std::nullopt; From 49956440cd8a9a868810321d6b807b488a708728 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Tue, 7 Mar 2023 14:33:20 -0800 Subject: [PATCH 2/5] Use runtime check to support framebuffer blend on M1/M2 devices --- fml/build_config.h | 6 -- impeller/compiler/compiler.cc | 2 +- impeller/entity/BUILD.gn | 52 +++++++----- .../contents/framebuffer_blend_contents.cc | 6 +- .../contents/framebuffer_blend_context.cc | 66 +++++++------- .../contents/framebuffer_blend_context.h | 85 ------------------- impeller/entity/entity_pass.cc | 75 ++++++++-------- .../blending/ios/framebuffer_blend.glsl | 13 +-- impeller/playground/BUILD.gn | 1 + .../backend/metal/playground_impl_mtl.mm | 4 + .../renderer/backend/metal/context_mtl.mm | 19 +++-- .../FlutterDarwinContextMetalImpeller.mm | 3 + 12 files changed, 127 insertions(+), 205 deletions(-) diff --git a/fml/build_config.h b/fml/build_config.h index e1abd5c8dec42..d42a88e5bbce0 100644 --- a/fml/build_config.h +++ b/fml/build_config.h @@ -100,10 +100,4 @@ #error Please add support for your architecture in flutter/fml/build_config.h #endif -#if defined(FML_OS_IOS) -#if !defined(FML_OS_IOS_SIMULATOR) -#define FML_OS_PHYSICAL_IOS 1 -#endif -#endif - #endif // FLUTTER_FML_BUILD_CONFIG_H_ diff --git a/impeller/compiler/compiler.cc b/impeller/compiler/compiler.cc index 05be9d20133b3..38ea2a2b495ec 100644 --- a/impeller/compiler/compiler.cc +++ b/impeller/compiler/compiler.cc @@ -42,7 +42,7 @@ static uint32_t ParseMSLVersion(const std::string& msl_version) { } } } - if (major < 1 || minor < 2) { + if (major < 1 || (major == 1 && minor < 2)) { std::cerr << "--metal-version version must be at least 1.2. Have " << msl_version << std::endl; } diff --git a/impeller/entity/BUILD.gn b/impeller/entity/BUILD.gn index 4098ca24c326e..821bd59246af2 100644 --- a/impeller/entity/BUILD.gn +++ b/impeller/entity/BUILD.gn @@ -77,26 +77,39 @@ impeller_shaders("modern_entity_shaders") { "shaders/radial_gradient_ssbo_fill.frag", "shaders/sweep_gradient_ssbo_fill.frag", ] - if (is_ios && !use_ios_simulator) { - shaders += [ - "shaders/blending/ios/framebuffer_blend.vert", - "shaders/blending/ios/framebuffer_blend_color.frag", - "shaders/blending/ios/framebuffer_blend_colorburn.frag", - "shaders/blending/ios/framebuffer_blend_colordodge.frag", - "shaders/blending/ios/framebuffer_blend_darken.frag", - "shaders/blending/ios/framebuffer_blend_difference.frag", - "shaders/blending/ios/framebuffer_blend_exclusion.frag", - "shaders/blending/ios/framebuffer_blend_hardlight.frag", - "shaders/blending/ios/framebuffer_blend_hue.frag", - "shaders/blending/ios/framebuffer_blend_lighten.frag", - "shaders/blending/ios/framebuffer_blend_luminosity.frag", - "shaders/blending/ios/framebuffer_blend_multiply.frag", - "shaders/blending/ios/framebuffer_blend_overlay.frag", - "shaders/blending/ios/framebuffer_blend_saturation.frag", - "shaders/blending/ios/framebuffer_blend_screen.frag", - "shaders/blending/ios/framebuffer_blend_softlight.frag", - ] +} + +impeller_shaders("framebuffer_blend_entity_shaders") { + name = "framebuffer_blend" + + if (is_mac && !is_ios) { + # Note: this needs to correspond to the Apple7 Support family + # for M1 and M2. + metal_version = "2.3" + } + + if (impeller_enable_opengles) { + gles_language_version = "460" } + + shaders = [ + "shaders/blending/ios/framebuffer_blend.vert", + "shaders/blending/ios/framebuffer_blend_color.frag", + "shaders/blending/ios/framebuffer_blend_colorburn.frag", + "shaders/blending/ios/framebuffer_blend_colordodge.frag", + "shaders/blending/ios/framebuffer_blend_darken.frag", + "shaders/blending/ios/framebuffer_blend_difference.frag", + "shaders/blending/ios/framebuffer_blend_exclusion.frag", + "shaders/blending/ios/framebuffer_blend_hardlight.frag", + "shaders/blending/ios/framebuffer_blend_hue.frag", + "shaders/blending/ios/framebuffer_blend_lighten.frag", + "shaders/blending/ios/framebuffer_blend_luminosity.frag", + "shaders/blending/ios/framebuffer_blend_multiply.frag", + "shaders/blending/ios/framebuffer_blend_overlay.frag", + "shaders/blending/ios/framebuffer_blend_saturation.frag", + "shaders/blending/ios/framebuffer_blend_screen.frag", + "shaders/blending/ios/framebuffer_blend_softlight.frag", + ] } impeller_component("entity") { @@ -185,6 +198,7 @@ impeller_component("entity") { public_deps = [ ":entity_shaders", + ":framebuffer_blend_entity_shaders", ":modern_entity_shaders", "../archivist", "../image", diff --git a/impeller/entity/contents/framebuffer_blend_contents.cc b/impeller/entity/contents/framebuffer_blend_contents.cc index 632496dbe75f5..f5adfde2c8015 100644 --- a/impeller/entity/contents/framebuffer_blend_contents.cc +++ b/impeller/entity/contents/framebuffer_blend_contents.cc @@ -36,8 +36,7 @@ bool FramebufferBlendContents::Render(const ContentContext& renderer, if (!renderer.GetDeviceCapabilities().SupportsFramebufferBlending()) { return false; } - // TODO(jonahwilliams): get these shaders compiling more generally. -#if FML_OS_PHYSICAL_IOS + using VS = FramebufferBlendScreenPipeline::VertexShader; using FS = FramebufferBlendScreenPipeline::FragmentShader; @@ -143,9 +142,6 @@ bool FramebufferBlendContents::Render(const ContentContext& renderer, VS::BindFrameInfo(cmd, uniform_view); return pass.AddCommand(cmd); -#else - return false; -#endif // FML_OS_PHYSICAL_IOS } } // namespace impeller diff --git a/impeller/entity/contents/framebuffer_blend_context.cc b/impeller/entity/contents/framebuffer_blend_context.cc index d11709e9df3e4..7b59aa6a51770 100644 --- a/impeller/entity/contents/framebuffer_blend_context.cc +++ b/impeller/entity/contents/framebuffer_blend_context.cc @@ -4,8 +4,8 @@ #include "impeller/entity/contents/framebuffer_blend_context.h" +#include #include "impeller/entity/entity.h" - namespace impeller { template @@ -29,38 +29,38 @@ FramebufferBlendContext::FramebufferBlendContext( return; } -#if FML_OS_PHYSICAL_IOS - framebuffer_blend_color_pipelines_[{}] = - CreateDefaultPipeline(*context_); - framebuffer_blend_colorburn_pipelines_[{}] = - CreateDefaultPipeline(*context_); - framebuffer_blend_colordodge_pipelines_[{}] = - CreateDefaultPipeline(*context_); - framebuffer_blend_darken_pipelines_[{}] = - CreateDefaultPipeline(*context_); - framebuffer_blend_difference_pipelines_[{}] = - CreateDefaultPipeline(*context_); - framebuffer_blend_exclusion_pipelines_[{}] = - CreateDefaultPipeline(*context_); - framebuffer_blend_hardlight_pipelines_[{}] = - CreateDefaultPipeline(*context_); - framebuffer_blend_hue_pipelines_[{}] = - CreateDefaultPipeline(*context_); - framebuffer_blend_lighten_pipelines_[{}] = - CreateDefaultPipeline(*context_); - framebuffer_blend_luminosity_pipelines_[{}] = - CreateDefaultPipeline(*context_); - framebuffer_blend_multiply_pipelines_[{}] = - CreateDefaultPipeline(*context_); - framebuffer_blend_overlay_pipelines_[{}] = - CreateDefaultPipeline(*context_); - framebuffer_blend_saturation_pipelines_[{}] = - CreateDefaultPipeline(*context_); - framebuffer_blend_screen_pipelines_[{}] = - CreateDefaultPipeline(*context_); - framebuffer_blend_softlight_pipelines_[{}] = - CreateDefaultPipeline(*context_); -#endif // FML_OS_PHYSICAL_IOS + if (context_->GetDeviceCapabilities().SupportsFramebufferBlending()) { + framebuffer_blend_color_pipelines_[{}] = + CreateDefaultPipeline(*context_); + framebuffer_blend_colorburn_pipelines_[{}] = + CreateDefaultPipeline(*context_); + framebuffer_blend_colordodge_pipelines_[{}] = + CreateDefaultPipeline(*context_); + framebuffer_blend_darken_pipelines_[{}] = + CreateDefaultPipeline(*context_); + framebuffer_blend_difference_pipelines_[{}] = + CreateDefaultPipeline(*context_); + framebuffer_blend_exclusion_pipelines_[{}] = + CreateDefaultPipeline(*context_); + framebuffer_blend_hardlight_pipelines_[{}] = + CreateDefaultPipeline(*context_); + framebuffer_blend_hue_pipelines_[{}] = + CreateDefaultPipeline(*context_); + framebuffer_blend_lighten_pipelines_[{}] = + CreateDefaultPipeline(*context_); + framebuffer_blend_luminosity_pipelines_[{}] = + CreateDefaultPipeline(*context_); + framebuffer_blend_multiply_pipelines_[{}] = + CreateDefaultPipeline(*context_); + framebuffer_blend_overlay_pipelines_[{}] = + CreateDefaultPipeline(*context_); + framebuffer_blend_saturation_pipelines_[{}] = + CreateDefaultPipeline(*context_); + framebuffer_blend_screen_pipelines_[{}] = + CreateDefaultPipeline(*context_); + framebuffer_blend_softlight_pipelines_[{}] = + CreateDefaultPipeline(*context_); + } is_valid_ = true; } diff --git a/impeller/entity/contents/framebuffer_blend_context.h b/impeller/entity/contents/framebuffer_blend_context.h index 2e84fed7e7ce0..5a7e82977e333 100644 --- a/impeller/entity/contents/framebuffer_blend_context.h +++ b/impeller/entity/contents/framebuffer_blend_context.h @@ -16,7 +16,6 @@ #include "impeller/entity/entity.h" #include "impeller/renderer/pipeline.h" -#if FML_OS_PHYSICAL_IOS #include "impeller/entity/framebuffer_blend.vert.h" #include "impeller/entity/framebuffer_blend_color.frag.h" #include "impeller/entity/framebuffer_blend_colorburn.frag.h" @@ -33,12 +32,9 @@ #include "impeller/entity/framebuffer_blend_saturation.frag.h" #include "impeller/entity/framebuffer_blend_screen.frag.h" #include "impeller/entity/framebuffer_blend_softlight.frag.h" -#endif // FML_OS_PHYSICAL_IOS namespace impeller { -#if FML_OS_PHYSICAL_IOS -// iOS only advanced blends. using FramebufferBlendColorPipeline = RenderPipelineT; @@ -84,7 +80,6 @@ using FramebufferBlendScreenPipeline = using FramebufferBlendSoftLightPipeline = RenderPipelineT; -#endif // FML_OS_PHYSICAL_IOS class FramebufferBlendContext { public: @@ -94,8 +89,6 @@ class FramebufferBlendContext { bool IsValid() const; -#if FML_OS_PHYSICAL_IOS - // iOS only advanced blends. using FramebufferBlendColorPipeline = RenderPipelineT; @@ -216,82 +209,6 @@ class FramebufferBlendContext { GetFramebufferBlendSoftLightPipeline(ContentContextOptions opts) const { return GetPipeline(framebuffer_blend_softlight_pipelines_, opts); } -#else - std::shared_ptr> - GetFramebufferBlendColorPipeline(ContentContextOptions opts) const { - FML_UNREACHABLE(); - } - - std::shared_ptr> - GetFramebufferBlendColorBurnPipeline(ContentContextOptions opts) const { - FML_UNREACHABLE(); - } - - std::shared_ptr> - GetFramebufferBlendColorDodgePipeline(ContentContextOptions opts) const { - FML_UNREACHABLE(); - } - - std::shared_ptr> - GetFramebufferBlendDarkenPipeline(ContentContextOptions opts) const { - FML_UNREACHABLE(); - } - - std::shared_ptr> - GetFramebufferBlendDifferencePipeline(ContentContextOptions opts) const { - FML_UNREACHABLE(); - } - - std::shared_ptr> - GetFramebufferBlendExclusionPipeline(ContentContextOptions opts) const { - FML_UNREACHABLE(); - } - - std::shared_ptr> - GetFramebufferBlendHardLightPipeline(ContentContextOptions opts) const { - FML_UNREACHABLE(); - } - - std::shared_ptr> GetFramebufferBlendHuePipeline( - ContentContextOptions opts) const { - FML_UNREACHABLE(); - } - - std::shared_ptr> - GetFramebufferBlendLightenPipeline(ContentContextOptions opts) const { - FML_UNREACHABLE(); - } - - std::shared_ptr> - GetFramebufferBlendLuminosityPipeline(ContentContextOptions opts) const { - FML_UNREACHABLE(); - } - - std::shared_ptr> - GetFramebufferBlendMultiplyPipeline(ContentContextOptions opts) const { - FML_UNREACHABLE(); - } - - std::shared_ptr> - GetFramebufferBlendOverlayPipeline(ContentContextOptions opts) const { - FML_UNREACHABLE(); - } - - std::shared_ptr> - GetFramebufferBlendSaturationPipeline(ContentContextOptions opts) const { - FML_UNREACHABLE(); - } - - std::shared_ptr> - GetFramebufferBlendScreenPipeline(ContentContextOptions opts) const { - FML_UNREACHABLE(); - } - - std::shared_ptr> - GetFramebufferBlendSoftLightPipeline(ContentContextOptions opts) const { - FML_UNREACHABLE(); - } -#endif // FML_OS_PHYSICAL_IOS private: std::shared_ptr context_; @@ -305,7 +222,6 @@ class FramebufferBlendContext { // These are mutable because while the prototypes are created eagerly, any // variants requested from that are lazily created and cached in the variants // map. -#if FML_OS_PHYSICAL_IOS mutable Variants framebuffer_blend_color_pipelines_; mutable Variants @@ -336,7 +252,6 @@ class FramebufferBlendContext { framebuffer_blend_screen_pipelines_; mutable Variants framebuffer_blend_softlight_pipelines_; -#endif // FML_OS_PHYSICAL_IOS template std::shared_ptr> GetPipeline( diff --git a/impeller/entity/entity_pass.cc b/impeller/entity/entity_pass.cc index 301eb352620c6..26874d79f3e60 100644 --- a/impeller/entity/entity_pass.cc +++ b/impeller/entity/entity_pass.cc @@ -549,46 +549,45 @@ bool EntityPass::OnRender(ContentContext& renderer, /// if (result.entity.GetBlendMode() > Entity::kLastPipelineBlendMode) { -#if FML_OS_PHYSICAL_IOS - auto src_contents = result.entity.GetContents(); - auto contents = std::make_shared(); - contents->SetChildContents(src_contents); - contents->SetBlendMode(result.entity.GetBlendMode()); - result.entity.SetContents(std::move(contents)); - result.entity.SetBlendMode(BlendMode::kSource); - -#else - // End the active pass and flush the buffer before rendering "advanced" - // blends. Advanced blends work by binding the current render target - // texture as an input ("destination"), blending with a second texture - // input ("source"), writing the result to an intermediate texture, and - // finally copying the data from the intermediate texture back to the - // render target texture. And so all of the commands that have written - // to the render target texture so far need to execute before it's bound - // for blending (otherwise the blend pass will end up executing before - // all the previous commands in the active pass). - - if (!pass_context.EndPass()) { - return false; - } + if (renderer.GetDeviceCapabilities().SupportsFramebufferBlending()) { + auto src_contents = result.entity.GetContents(); + auto contents = std::make_shared(); + contents->SetChildContents(src_contents); + contents->SetBlendMode(result.entity.GetBlendMode()); + result.entity.SetContents(std::move(contents)); + result.entity.SetBlendMode(BlendMode::kSource); + } else { + // End the active pass and flush the buffer before rendering "advanced" + // blends. Advanced blends work by binding the current render target + // texture as an input ("destination"), blending with a second texture + // input ("source"), writing the result to an intermediate texture, and + // finally copying the data from the intermediate texture back to the + // render target texture. And so all of the commands that have written + // to the render target texture so far need to execute before it's bound + // for blending (otherwise the blend pass will end up executing before + // all the previous commands in the active pass). + + if (!pass_context.EndPass()) { + return false; + } - // Amend an advanced blend filter to the contents, attaching the pass - // texture. - auto texture = pass_context.GetTexture(); - if (!texture) { - return false; - } + // Amend an advanced blend filter to the contents, attaching the pass + // texture. + auto texture = pass_context.GetTexture(); + if (!texture) { + return false; + } - FilterInput::Vector inputs = { - FilterInput::Make(texture, - result.entity.GetTransformation().Invert()), - FilterInput::Make(result.entity.GetContents())}; - auto contents = - ColorFilterContents::MakeBlend(result.entity.GetBlendMode(), inputs); - contents->SetCoverageCrop(result.entity.GetCoverage()); - result.entity.SetContents(std::move(contents)); - result.entity.SetBlendMode(BlendMode::kSource); -#endif // FML_OS_PHYSICAL_IOS + FilterInput::Vector inputs = { + FilterInput::Make(texture, + result.entity.GetTransformation().Invert()), + FilterInput::Make(result.entity.GetContents())}; + auto contents = ColorFilterContents::MakeBlend( + result.entity.GetBlendMode(), inputs); + contents->SetCoverageCrop(result.entity.GetCoverage()); + result.entity.SetContents(std::move(contents)); + result.entity.SetBlendMode(BlendMode::kSource); + } } //-------------------------------------------------------------------------- diff --git a/impeller/entity/shaders/blending/ios/framebuffer_blend.glsl b/impeller/entity/shaders/blending/ios/framebuffer_blend.glsl index 391b2841905b5..7a81745abff91 100644 --- a/impeller/entity/shaders/blending/ios/framebuffer_blend.glsl +++ b/impeller/entity/shaders/blending/ios/framebuffer_blend.glsl @@ -9,21 +9,10 @@ #include #include -#ifdef IMPELLER_TARGET_METAL_IOS layout(set = 0, binding = 0, input_attachment_index = 0) uniform subpassInput uSub; -vec4 ReadDestination() { - return subpassLoad(uSub); -} -#else - -vec4 ReadDestination() { - return vec4(0); -} -#endif - uniform sampler2D texture_sampler_src; in vec2 v_src_texture_coords; @@ -31,7 +20,7 @@ in vec2 v_src_texture_coords; out vec4 frag_color; void main() { - vec4 dst_sample = ReadDestination(); + vec4 dst_sample = subpassLoad(uSub); vec4 dst = IPUnpremultiply(dst_sample); vec4 src = IPUnpremultiply(IPSampleDecal(texture_sampler_src, // sampler diff --git a/impeller/playground/BUILD.gn b/impeller/playground/BUILD.gn index b6c26fcad9e2b..623b0d2557b9e 100644 --- a/impeller/playground/BUILD.gn +++ b/impeller/playground/BUILD.gn @@ -40,6 +40,7 @@ impeller_component("playground") { public_deps = [ "../entity:entity_shaders", + "../entity:framebuffer_blend_entity_shaders", "../entity:modern_entity_shaders", "../fixtures:shader_fixtures", "../renderer", diff --git a/impeller/playground/backend/metal/playground_impl_mtl.mm b/impeller/playground/backend/metal/playground_impl_mtl.mm index 1e900d7da7bdd..2418d1dae7c9a 100644 --- a/impeller/playground/backend/metal/playground_impl_mtl.mm +++ b/impeller/playground/backend/metal/playground_impl_mtl.mm @@ -15,6 +15,7 @@ #include "flutter/fml/mapping.h" #include "impeller/entity/mtl/entity_shaders.h" +#include "impeller/entity/mtl/framebuffer_blend_shaders.h" #include "impeller/entity/mtl/modern_shaders.h" #include "impeller/fixtures/mtl/fixtures_shaders.h" #include "impeller/fixtures/mtl/subgroup_fixtures_shaders.h" @@ -38,6 +39,9 @@ impeller_entity_shaders_length), std::make_shared(impeller_modern_shaders_data, impeller_modern_shaders_length), + std::make_shared( + impeller_framebuffer_blend_shaders_data, + impeller_framebuffer_blend_shaders_length), std::make_shared(impeller_fixtures_shaders_data, impeller_fixtures_shaders_length), std::make_shared( diff --git a/impeller/renderer/backend/metal/context_mtl.mm b/impeller/renderer/backend/metal/context_mtl.mm index 11d0031bf3b36..afe60f3108e23 100644 --- a/impeller/renderer/backend/metal/context_mtl.mm +++ b/impeller/renderer/backend/metal/context_mtl.mm @@ -90,13 +90,20 @@ #endif { - // TODO(jonahwilliams): find a way to query support for this for - // macOS/Simulator. -#if FML_OS_PHYSICAL_IOS - bool supports_framebuffer_blend = true; -#else bool supports_framebuffer_blend = false; -#endif // FML_OS_PHYSICAL_IOS + if (@available(macOS 10.15, iOS 13, tvOS 13, *)) { + supports_framebuffer_blend = [device supportsFamily:MTLGPUFamilyApple2]; + } else { + // According to + // https://developer.apple.com/metal/Metal-Feature-Set-Tables.pdf , Apple2 + // corresponds to iOS GPU family 2, which supports A8 devices. +#if FML_OS_IOS + supports_framebuffer_blend = + [device supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily2_v1]; +#else + supports_framebuffer_blend = false; +#endif // FML_OS_IOS + } device_capabilities_ = DeviceCapabilitiesBuilder() diff --git a/shell/platform/darwin/graphics/FlutterDarwinContextMetalImpeller.mm b/shell/platform/darwin/graphics/FlutterDarwinContextMetalImpeller.mm index 4810aaae7a7a0..e84a2e29cb30f 100644 --- a/shell/platform/darwin/graphics/FlutterDarwinContextMetalImpeller.mm +++ b/shell/platform/darwin/graphics/FlutterDarwinContextMetalImpeller.mm @@ -10,6 +10,7 @@ #include "flutter/shell/common/context_options.h" #import "flutter/shell/platform/darwin/common/framework/Headers/FlutterMacros.h" #include "impeller/entity/mtl/entity_shaders.h" +#include "impeller/entity/mtl/framebuffer_blend_shaders.h" #include "impeller/entity/mtl/modern_shaders.h" #include "impeller/scene/shaders/mtl/scene_shaders.h" @@ -23,6 +24,8 @@ impeller_scene_shaders_length), std::make_shared(impeller_modern_shaders_data, impeller_modern_shaders_length), + std::make_shared(impeller_framebuffer_blend_shaders_data, + impeller_framebuffer_blend_shaders_length), }; auto context = impeller::ContextMTL::Create(shader_mappings, "Impeller Library"); if (!context) { From 9e52d5e663e677dfd71e0206077e8a4cd2663019 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Tue, 7 Mar 2023 14:42:04 -0800 Subject: [PATCH 3/5] ifdef out subpass for gles/spriv --- impeller/entity/BUILD.gn | 4 ---- .../shaders/blending/ios/framebuffer_blend.glsl | 13 ++++++++++++- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/impeller/entity/BUILD.gn b/impeller/entity/BUILD.gn index 821bd59246af2..913336ac91b50 100644 --- a/impeller/entity/BUILD.gn +++ b/impeller/entity/BUILD.gn @@ -88,10 +88,6 @@ impeller_shaders("framebuffer_blend_entity_shaders") { metal_version = "2.3" } - if (impeller_enable_opengles) { - gles_language_version = "460" - } - shaders = [ "shaders/blending/ios/framebuffer_blend.vert", "shaders/blending/ios/framebuffer_blend_color.frag", diff --git a/impeller/entity/shaders/blending/ios/framebuffer_blend.glsl b/impeller/entity/shaders/blending/ios/framebuffer_blend.glsl index 7a81745abff91..06324909a6af5 100644 --- a/impeller/entity/shaders/blending/ios/framebuffer_blend.glsl +++ b/impeller/entity/shaders/blending/ios/framebuffer_blend.glsl @@ -9,10 +9,21 @@ #include #include +#ifdef IMPELLER_TARGET_METAL layout(set = 0, binding = 0, input_attachment_index = 0) uniform subpassInput uSub; +vec4 ReadDestination() { + return subpassLoad(uSub); +} +#else + +vec4 ReadDestination() { + return vec4(0); +} +#endif + uniform sampler2D texture_sampler_src; in vec2 v_src_texture_coords; @@ -20,7 +31,7 @@ in vec2 v_src_texture_coords; out vec4 frag_color; void main() { - vec4 dst_sample = subpassLoad(uSub); + vec4 dst_sample = ReadDestination(); vec4 dst = IPUnpremultiply(dst_sample); vec4 src = IPUnpremultiply(IPSampleDecal(texture_sampler_src, // sampler From 47f49a3321ab98bb8b175282ec7538d042236f1b Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Tue, 7 Mar 2023 16:08:07 -0800 Subject: [PATCH 4/5] remove subcontext --- impeller/entity/BUILD.gn | 7 +- impeller/entity/contents/content_context.cc | 42 ++- impeller/entity/contents/content_context.h | 191 +++++++++++- .../contents/framebuffer_blend_contents.cc | 32 +- .../contents/framebuffer_blend_context.cc | 73 ----- .../contents/framebuffer_blend_context.h | 295 ------------------ 6 files changed, 239 insertions(+), 401 deletions(-) delete mode 100644 impeller/entity/contents/framebuffer_blend_context.cc delete mode 100644 impeller/entity/contents/framebuffer_blend_context.h diff --git a/impeller/entity/BUILD.gn b/impeller/entity/BUILD.gn index 913336ac91b50..dd328219e6b17 100644 --- a/impeller/entity/BUILD.gn +++ b/impeller/entity/BUILD.gn @@ -88,6 +88,11 @@ impeller_shaders("framebuffer_blend_entity_shaders") { metal_version = "2.3" } + # This version is to disable malioc checks. + if (impeller_enable_opengles) { + gles_language_version = "460" + } + shaders = [ "shaders/blending/ios/framebuffer_blend.vert", "shaders/blending/ios/framebuffer_blend_color.frag", @@ -154,8 +159,6 @@ impeller_component("entity") { "contents/filters/yuv_to_rgb_filter_contents.h", "contents/framebuffer_blend_contents.cc", "contents/framebuffer_blend_contents.h", - "contents/framebuffer_blend_context.cc", - "contents/framebuffer_blend_context.h", "contents/gradient_generator.cc", "contents/gradient_generator.h", "contents/linear_gradient_contents.cc", diff --git a/impeller/entity/contents/content_context.cc b/impeller/entity/contents/content_context.cc index 7c3774b0bc3b5..7c05701ab27b6 100644 --- a/impeller/entity/contents/content_context.cc +++ b/impeller/entity/contents/content_context.cc @@ -8,7 +8,6 @@ #include #include "impeller/base/strings.h" -#include "impeller/entity/contents/framebuffer_blend_context.h" #include "impeller/entity/entity.h" #include "impeller/renderer/command_buffer.h" #include "impeller/renderer/formats.h" @@ -165,9 +164,7 @@ ContentContext::ContentContext(std::shared_ptr context) : context_(std::move(context)), tessellator_(std::make_shared()), glyph_atlas_context_(std::make_shared()), - scene_context_(std::make_shared(context_)), - framebuffer_blend_context_( - std::make_shared(context_)) { + scene_context_(std::make_shared(context_)) { if (!context_ || !context_->IsValid()) { return; } @@ -186,6 +183,38 @@ ContentContext::ContentContext(std::shared_ptr context) sweep_gradient_ssbo_fill_pipelines_[{}] = CreateDefaultPipeline(*context_); } + if (context_->GetDeviceCapabilities().SupportsFramebufferBlending()) { + framebuffer_blend_color_pipelines_[{}] = + CreateDefaultPipeline(*context_); + framebuffer_blend_colorburn_pipelines_[{}] = + CreateDefaultPipeline(*context_); + framebuffer_blend_colordodge_pipelines_[{}] = + CreateDefaultPipeline(*context_); + framebuffer_blend_darken_pipelines_[{}] = + CreateDefaultPipeline(*context_); + framebuffer_blend_difference_pipelines_[{}] = + CreateDefaultPipeline(*context_); + framebuffer_blend_exclusion_pipelines_[{}] = + CreateDefaultPipeline(*context_); + framebuffer_blend_hardlight_pipelines_[{}] = + CreateDefaultPipeline(*context_); + framebuffer_blend_hue_pipelines_[{}] = + CreateDefaultPipeline(*context_); + framebuffer_blend_lighten_pipelines_[{}] = + CreateDefaultPipeline(*context_); + framebuffer_blend_luminosity_pipelines_[{}] = + CreateDefaultPipeline(*context_); + framebuffer_blend_multiply_pipelines_[{}] = + CreateDefaultPipeline(*context_); + framebuffer_blend_overlay_pipelines_[{}] = + CreateDefaultPipeline(*context_); + framebuffer_blend_saturation_pipelines_[{}] = + CreateDefaultPipeline(*context_); + framebuffer_blend_screen_pipelines_[{}] = + CreateDefaultPipeline(*context_); + framebuffer_blend_softlight_pipelines_[{}] = + CreateDefaultPipeline(*context_); + } blend_color_pipelines_[{}] = CreateDefaultPipeline(*context_); @@ -355,9 +384,4 @@ void ContentContext::SetWireframe(bool wireframe) { wireframe_ = wireframe; } -std::shared_ptr -ContentContext::GetFramebufferBlendContext() const { - return framebuffer_blend_context_; -} - } // namespace impeller diff --git a/impeller/entity/contents/content_context.h b/impeller/entity/contents/content_context.h index 0faa23ad3cfbc..45c16bcc5f0f5 100644 --- a/impeller/entity/contents/content_context.h +++ b/impeller/entity/contents/content_context.h @@ -79,9 +79,24 @@ #include "impeller/entity/advanced_blend_screen.frag.h" #include "impeller/entity/advanced_blend_softlight.frag.h" -namespace impeller { +#include "impeller/entity/framebuffer_blend.vert.h" +#include "impeller/entity/framebuffer_blend_color.frag.h" +#include "impeller/entity/framebuffer_blend_colorburn.frag.h" +#include "impeller/entity/framebuffer_blend_colordodge.frag.h" +#include "impeller/entity/framebuffer_blend_darken.frag.h" +#include "impeller/entity/framebuffer_blend_difference.frag.h" +#include "impeller/entity/framebuffer_blend_exclusion.frag.h" +#include "impeller/entity/framebuffer_blend_hardlight.frag.h" +#include "impeller/entity/framebuffer_blend_hue.frag.h" +#include "impeller/entity/framebuffer_blend_lighten.frag.h" +#include "impeller/entity/framebuffer_blend_luminosity.frag.h" +#include "impeller/entity/framebuffer_blend_multiply.frag.h" +#include "impeller/entity/framebuffer_blend_overlay.frag.h" +#include "impeller/entity/framebuffer_blend_saturation.frag.h" +#include "impeller/entity/framebuffer_blend_screen.frag.h" +#include "impeller/entity/framebuffer_blend_softlight.frag.h" -class FramebufferBlendContext; +namespace impeller { using LinearGradientFillPipeline = RenderPipelineT; @@ -186,6 +201,53 @@ using BlendScreenPipeline = RenderPipelineT; +// Framebuffer Advanced Blends +using FramebufferBlendColorPipeline = + RenderPipelineT; +using FramebufferBlendColorBurnPipeline = + RenderPipelineT; +using FramebufferBlendColorDodgePipeline = + RenderPipelineT; +using FramebufferBlendDarkenPipeline = + RenderPipelineT; +using FramebufferBlendDifferencePipeline = + RenderPipelineT; +using FramebufferBlendExclusionPipeline = + RenderPipelineT; +using FramebufferBlendHardLightPipeline = + RenderPipelineT; +using FramebufferBlendHuePipeline = + RenderPipelineT; +using FramebufferBlendLightenPipeline = + RenderPipelineT; +using FramebufferBlendLuminosityPipeline = + RenderPipelineT; +using FramebufferBlendMultiplyPipeline = + RenderPipelineT; +using FramebufferBlendOverlayPipeline = + RenderPipelineT; +using FramebufferBlendSaturationPipeline = + RenderPipelineT; +using FramebufferBlendScreenPipeline = + RenderPipelineT; +using FramebufferBlendSoftLightPipeline = + RenderPipelineT; + /// Pipeline state configuration. /// /// Each unique combination of these options requires a different pipeline state @@ -452,12 +514,101 @@ class ContentContext { return GetPipeline(blend_softlight_pipelines_, opts); } + // Framebuffer Advanced Blends + std::shared_ptr> + GetFramebufferBlendColorPipeline(ContentContextOptions opts) const { + FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferBlending()); + return GetPipeline(framebuffer_blend_color_pipelines_, opts); + } + + std::shared_ptr> + GetFramebufferBlendColorBurnPipeline(ContentContextOptions opts) const { + FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferBlending()); + return GetPipeline(framebuffer_blend_colorburn_pipelines_, opts); + } + + std::shared_ptr> + GetFramebufferBlendColorDodgePipeline(ContentContextOptions opts) const { + FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferBlending()); + return GetPipeline(framebuffer_blend_colordodge_pipelines_, opts); + } + + std::shared_ptr> + GetFramebufferBlendDarkenPipeline(ContentContextOptions opts) const { + FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferBlending()); + return GetPipeline(framebuffer_blend_darken_pipelines_, opts); + } + + std::shared_ptr> + GetFramebufferBlendDifferencePipeline(ContentContextOptions opts) const { + FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferBlending()); + return GetPipeline(framebuffer_blend_difference_pipelines_, opts); + } + + std::shared_ptr> + GetFramebufferBlendExclusionPipeline(ContentContextOptions opts) const { + FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferBlending()); + return GetPipeline(framebuffer_blend_exclusion_pipelines_, opts); + } + + std::shared_ptr> + GetFramebufferBlendHardLightPipeline(ContentContextOptions opts) const { + FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferBlending()); + return GetPipeline(framebuffer_blend_hardlight_pipelines_, opts); + } + + std::shared_ptr> GetFramebufferBlendHuePipeline( + ContentContextOptions opts) const { + FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferBlending()); + return GetPipeline(framebuffer_blend_hue_pipelines_, opts); + } + + std::shared_ptr> + GetFramebufferBlendLightenPipeline(ContentContextOptions opts) const { + FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferBlending()); + return GetPipeline(framebuffer_blend_lighten_pipelines_, opts); + } + + std::shared_ptr> + GetFramebufferBlendLuminosityPipeline(ContentContextOptions opts) const { + FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferBlending()); + return GetPipeline(framebuffer_blend_luminosity_pipelines_, opts); + } + + std::shared_ptr> + GetFramebufferBlendMultiplyPipeline(ContentContextOptions opts) const { + FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferBlending()); + return GetPipeline(framebuffer_blend_multiply_pipelines_, opts); + } + + std::shared_ptr> + GetFramebufferBlendOverlayPipeline(ContentContextOptions opts) const { + FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferBlending()); + return GetPipeline(framebuffer_blend_overlay_pipelines_, opts); + } + + std::shared_ptr> + GetFramebufferBlendSaturationPipeline(ContentContextOptions opts) const { + FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferBlending()); + return GetPipeline(framebuffer_blend_saturation_pipelines_, opts); + } + + std::shared_ptr> + GetFramebufferBlendScreenPipeline(ContentContextOptions opts) const { + FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferBlending()); + return GetPipeline(framebuffer_blend_screen_pipelines_, opts); + } + + std::shared_ptr> + GetFramebufferBlendSoftLightPipeline(ContentContextOptions opts) const { + FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferBlending()); + return GetPipeline(framebuffer_blend_softlight_pipelines_, opts); + } + std::shared_ptr GetContext() const; std::shared_ptr GetGlyphAtlasContext() const; - std::shared_ptr GetFramebufferBlendContext() const; - const IDeviceCapabilities& GetDeviceCapabilities() const; void SetWireframe(bool wireframe); @@ -529,6 +680,37 @@ class ContentContext { mutable Variants blend_saturation_pipelines_; mutable Variants blend_screen_pipelines_; mutable Variants blend_softlight_pipelines_; + // Framebuffer Advanced blends. + mutable Variants + framebuffer_blend_color_pipelines_; + mutable Variants + framebuffer_blend_colorburn_pipelines_; + mutable Variants + framebuffer_blend_colordodge_pipelines_; + mutable Variants + framebuffer_blend_darken_pipelines_; + mutable Variants + framebuffer_blend_difference_pipelines_; + mutable Variants + framebuffer_blend_exclusion_pipelines_; + mutable Variants + framebuffer_blend_hardlight_pipelines_; + mutable Variants + framebuffer_blend_hue_pipelines_; + mutable Variants + framebuffer_blend_lighten_pipelines_; + mutable Variants + framebuffer_blend_luminosity_pipelines_; + mutable Variants + framebuffer_blend_multiply_pipelines_; + mutable Variants + framebuffer_blend_overlay_pipelines_; + mutable Variants + framebuffer_blend_saturation_pipelines_; + mutable Variants + framebuffer_blend_screen_pipelines_; + mutable Variants + framebuffer_blend_softlight_pipelines_; template std::shared_ptr> GetPipeline( @@ -567,7 +749,6 @@ class ContentContext { std::shared_ptr tessellator_; std::shared_ptr glyph_atlas_context_; std::shared_ptr scene_context_; - std::shared_ptr framebuffer_blend_context_; bool wireframe_ = false; FML_DISALLOW_COPY_AND_ASSIGN(ContentContext); diff --git a/impeller/entity/contents/framebuffer_blend_contents.cc b/impeller/entity/contents/framebuffer_blend_contents.cc index f5adfde2c8015..d24d87a317d56 100644 --- a/impeller/entity/contents/framebuffer_blend_contents.cc +++ b/impeller/entity/contents/framebuffer_blend_contents.cc @@ -5,7 +5,6 @@ #include "framebuffer_blend_contents.h" #include "impeller/entity/contents/content_context.h" -#include "impeller/entity/contents/framebuffer_blend_context.h" #include "impeller/renderer/render_pass.h" #include "impeller/renderer/sampler_library.h" @@ -77,52 +76,51 @@ bool FramebufferBlendContents::Render(const ContentContext& renderer, cmd.BindVertices(vtx_buffer); cmd.stencil_reference = entity.GetStencilDepth(); - const auto ctx = renderer.GetFramebufferBlendContext(); switch (blend_mode_) { case BlendMode::kScreen: - cmd.pipeline = ctx->GetFramebufferBlendScreenPipeline(options); + cmd.pipeline = renderer.GetFramebufferBlendScreenPipeline(options); break; case BlendMode::kOverlay: - cmd.pipeline = ctx->GetFramebufferBlendOverlayPipeline(options); + cmd.pipeline = renderer.GetFramebufferBlendOverlayPipeline(options); break; case BlendMode::kDarken: - cmd.pipeline = ctx->GetFramebufferBlendDarkenPipeline(options); + cmd.pipeline = renderer.GetFramebufferBlendDarkenPipeline(options); break; case BlendMode::kLighten: - cmd.pipeline = ctx->GetFramebufferBlendLightenPipeline(options); + cmd.pipeline = renderer.GetFramebufferBlendLightenPipeline(options); break; case BlendMode::kColorDodge: - cmd.pipeline = ctx->GetFramebufferBlendColorDodgePipeline(options); + cmd.pipeline = renderer.GetFramebufferBlendColorDodgePipeline(options); break; case BlendMode::kColorBurn: - cmd.pipeline = ctx->GetFramebufferBlendColorBurnPipeline(options); + cmd.pipeline = renderer.GetFramebufferBlendColorBurnPipeline(options); break; case BlendMode::kHardLight: - cmd.pipeline = ctx->GetFramebufferBlendHardLightPipeline(options); + cmd.pipeline = renderer.GetFramebufferBlendHardLightPipeline(options); break; case BlendMode::kSoftLight: - cmd.pipeline = ctx->GetFramebufferBlendSoftLightPipeline(options); + cmd.pipeline = renderer.GetFramebufferBlendSoftLightPipeline(options); break; case BlendMode::kDifference: - cmd.pipeline = ctx->GetFramebufferBlendDifferencePipeline(options); + cmd.pipeline = renderer.GetFramebufferBlendDifferencePipeline(options); break; case BlendMode::kExclusion: - cmd.pipeline = ctx->GetFramebufferBlendExclusionPipeline(options); + cmd.pipeline = renderer.GetFramebufferBlendExclusionPipeline(options); break; case BlendMode::kMultiply: - cmd.pipeline = ctx->GetFramebufferBlendMultiplyPipeline(options); + cmd.pipeline = renderer.GetFramebufferBlendMultiplyPipeline(options); break; case BlendMode::kHue: - cmd.pipeline = ctx->GetFramebufferBlendHuePipeline(options); + cmd.pipeline = renderer.GetFramebufferBlendHuePipeline(options); break; case BlendMode::kSaturation: - cmd.pipeline = ctx->GetFramebufferBlendSaturationPipeline(options); + cmd.pipeline = renderer.GetFramebufferBlendSaturationPipeline(options); break; case BlendMode::kColor: - cmd.pipeline = ctx->GetFramebufferBlendColorPipeline(options); + cmd.pipeline = renderer.GetFramebufferBlendColorPipeline(options); break; case BlendMode::kLuminosity: - cmd.pipeline = ctx->GetFramebufferBlendLuminosityPipeline(options); + cmd.pipeline = renderer.GetFramebufferBlendLuminosityPipeline(options); break; default: return false; diff --git a/impeller/entity/contents/framebuffer_blend_context.cc b/impeller/entity/contents/framebuffer_blend_context.cc deleted file mode 100644 index 7b59aa6a51770..0000000000000 --- a/impeller/entity/contents/framebuffer_blend_context.cc +++ /dev/null @@ -1,73 +0,0 @@ -// 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. - -#include "impeller/entity/contents/framebuffer_blend_context.h" - -#include -#include "impeller/entity/entity.h" -namespace impeller { - -template -static std::unique_ptr CreateDefaultPipeline( - const Context& context) { - auto desc = PipelineT::Builder::MakeDefaultPipelineDescriptor(context); - if (!desc.has_value()) { - return nullptr; - } - // Apply default ContentContextOptions to the descriptor. - const auto default_color_fmt = context.GetColorAttachmentPixelFormat(); - ContentContextOptions{.color_attachment_pixel_format = default_color_fmt} - .ApplyToPipelineDescriptor(*desc); - return std::make_unique(context, desc); -} - -FramebufferBlendContext::FramebufferBlendContext( - std::shared_ptr context) - : context_(std::move(context)) { - if (!context_ || !context_->IsValid()) { - return; - } - - if (context_->GetDeviceCapabilities().SupportsFramebufferBlending()) { - framebuffer_blend_color_pipelines_[{}] = - CreateDefaultPipeline(*context_); - framebuffer_blend_colorburn_pipelines_[{}] = - CreateDefaultPipeline(*context_); - framebuffer_blend_colordodge_pipelines_[{}] = - CreateDefaultPipeline(*context_); - framebuffer_blend_darken_pipelines_[{}] = - CreateDefaultPipeline(*context_); - framebuffer_blend_difference_pipelines_[{}] = - CreateDefaultPipeline(*context_); - framebuffer_blend_exclusion_pipelines_[{}] = - CreateDefaultPipeline(*context_); - framebuffer_blend_hardlight_pipelines_[{}] = - CreateDefaultPipeline(*context_); - framebuffer_blend_hue_pipelines_[{}] = - CreateDefaultPipeline(*context_); - framebuffer_blend_lighten_pipelines_[{}] = - CreateDefaultPipeline(*context_); - framebuffer_blend_luminosity_pipelines_[{}] = - CreateDefaultPipeline(*context_); - framebuffer_blend_multiply_pipelines_[{}] = - CreateDefaultPipeline(*context_); - framebuffer_blend_overlay_pipelines_[{}] = - CreateDefaultPipeline(*context_); - framebuffer_blend_saturation_pipelines_[{}] = - CreateDefaultPipeline(*context_); - framebuffer_blend_screen_pipelines_[{}] = - CreateDefaultPipeline(*context_); - framebuffer_blend_softlight_pipelines_[{}] = - CreateDefaultPipeline(*context_); - } - is_valid_ = true; -} - -FramebufferBlendContext::~FramebufferBlendContext() = default; - -bool FramebufferBlendContext::IsValid() const { - return is_valid_; -} - -} // namespace impeller \ No newline at end of file diff --git a/impeller/entity/contents/framebuffer_blend_context.h b/impeller/entity/contents/framebuffer_blend_context.h deleted file mode 100644 index 5a7e82977e333..0000000000000 --- a/impeller/entity/contents/framebuffer_blend_context.h +++ /dev/null @@ -1,295 +0,0 @@ -// 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. - -#pragma once - -#include -#include -#include - -#include "flutter/fml/hash_combine.h" -#include "flutter/fml/logging.h" -#include "flutter/fml/macros.h" -#include "impeller/base/validation.h" -#include "impeller/entity/contents/content_context.h" -#include "impeller/entity/entity.h" -#include "impeller/renderer/pipeline.h" - -#include "impeller/entity/framebuffer_blend.vert.h" -#include "impeller/entity/framebuffer_blend_color.frag.h" -#include "impeller/entity/framebuffer_blend_colorburn.frag.h" -#include "impeller/entity/framebuffer_blend_colordodge.frag.h" -#include "impeller/entity/framebuffer_blend_darken.frag.h" -#include "impeller/entity/framebuffer_blend_difference.frag.h" -#include "impeller/entity/framebuffer_blend_exclusion.frag.h" -#include "impeller/entity/framebuffer_blend_hardlight.frag.h" -#include "impeller/entity/framebuffer_blend_hue.frag.h" -#include "impeller/entity/framebuffer_blend_lighten.frag.h" -#include "impeller/entity/framebuffer_blend_luminosity.frag.h" -#include "impeller/entity/framebuffer_blend_multiply.frag.h" -#include "impeller/entity/framebuffer_blend_overlay.frag.h" -#include "impeller/entity/framebuffer_blend_saturation.frag.h" -#include "impeller/entity/framebuffer_blend_screen.frag.h" -#include "impeller/entity/framebuffer_blend_softlight.frag.h" - -namespace impeller { - -using FramebufferBlendColorPipeline = - RenderPipelineT; -using FramebufferBlendColorBurnPipeline = - RenderPipelineT; -using FramebufferBlendColorDodgePipeline = - RenderPipelineT; -using FramebufferBlendDarkenPipeline = - RenderPipelineT; -using FramebufferBlendDifferencePipeline = - RenderPipelineT; -using FramebufferBlendExclusionPipeline = - RenderPipelineT; -using FramebufferBlendHardLightPipeline = - RenderPipelineT; -using FramebufferBlendHuePipeline = - RenderPipelineT; -using FramebufferBlendLightenPipeline = - RenderPipelineT; -using FramebufferBlendLuminosityPipeline = - RenderPipelineT; -using FramebufferBlendMultiplyPipeline = - RenderPipelineT; -using FramebufferBlendOverlayPipeline = - RenderPipelineT; -using FramebufferBlendSaturationPipeline = - RenderPipelineT; -using FramebufferBlendScreenPipeline = - RenderPipelineT; -using FramebufferBlendSoftLightPipeline = - RenderPipelineT; - -class FramebufferBlendContext { - public: - explicit FramebufferBlendContext(std::shared_ptr context); - - ~FramebufferBlendContext(); - - bool IsValid() const; - - using FramebufferBlendColorPipeline = - RenderPipelineT; - using FramebufferBlendColorBurnPipeline = - RenderPipelineT; - using FramebufferBlendColorDodgePipeline = - RenderPipelineT; - using FramebufferBlendDarkenPipeline = - RenderPipelineT; - using FramebufferBlendDifferencePipeline = - RenderPipelineT; - using FramebufferBlendExclusionPipeline = - RenderPipelineT; - using FramebufferBlendHardLightPipeline = - RenderPipelineT; - using FramebufferBlendHuePipeline = - RenderPipelineT; - using FramebufferBlendLightenPipeline = - RenderPipelineT; - using FramebufferBlendLuminosityPipeline = - RenderPipelineT; - using FramebufferBlendMultiplyPipeline = - RenderPipelineT; - using FramebufferBlendOverlayPipeline = - RenderPipelineT; - using FramebufferBlendSaturationPipeline = - RenderPipelineT; - using FramebufferBlendScreenPipeline = - RenderPipelineT; - using FramebufferBlendSoftLightPipeline = - RenderPipelineT; - - std::shared_ptr> - GetFramebufferBlendColorPipeline(ContentContextOptions opts) const { - return GetPipeline(framebuffer_blend_color_pipelines_, opts); - } - - std::shared_ptr> - GetFramebufferBlendColorBurnPipeline(ContentContextOptions opts) const { - return GetPipeline(framebuffer_blend_colorburn_pipelines_, opts); - } - - std::shared_ptr> - GetFramebufferBlendColorDodgePipeline(ContentContextOptions opts) const { - return GetPipeline(framebuffer_blend_colordodge_pipelines_, opts); - } - - std::shared_ptr> - GetFramebufferBlendDarkenPipeline(ContentContextOptions opts) const { - return GetPipeline(framebuffer_blend_darken_pipelines_, opts); - } - - std::shared_ptr> - GetFramebufferBlendDifferencePipeline(ContentContextOptions opts) const { - return GetPipeline(framebuffer_blend_difference_pipelines_, opts); - } - - std::shared_ptr> - GetFramebufferBlendExclusionPipeline(ContentContextOptions opts) const { - return GetPipeline(framebuffer_blend_exclusion_pipelines_, opts); - } - - std::shared_ptr> - GetFramebufferBlendHardLightPipeline(ContentContextOptions opts) const { - return GetPipeline(framebuffer_blend_hardlight_pipelines_, opts); - } - - std::shared_ptr> GetFramebufferBlendHuePipeline( - ContentContextOptions opts) const { - return GetPipeline(framebuffer_blend_hue_pipelines_, opts); - } - - std::shared_ptr> - GetFramebufferBlendLightenPipeline(ContentContextOptions opts) const { - return GetPipeline(framebuffer_blend_lighten_pipelines_, opts); - } - - std::shared_ptr> - GetFramebufferBlendLuminosityPipeline(ContentContextOptions opts) const { - return GetPipeline(framebuffer_blend_luminosity_pipelines_, opts); - } - - std::shared_ptr> - GetFramebufferBlendMultiplyPipeline(ContentContextOptions opts) const { - return GetPipeline(framebuffer_blend_multiply_pipelines_, opts); - } - - std::shared_ptr> - GetFramebufferBlendOverlayPipeline(ContentContextOptions opts) const { - return GetPipeline(framebuffer_blend_overlay_pipelines_, opts); - } - - std::shared_ptr> - GetFramebufferBlendSaturationPipeline(ContentContextOptions opts) const { - return GetPipeline(framebuffer_blend_saturation_pipelines_, opts); - } - - std::shared_ptr> - GetFramebufferBlendScreenPipeline(ContentContextOptions opts) const { - return GetPipeline(framebuffer_blend_screen_pipelines_, opts); - } - - std::shared_ptr> - GetFramebufferBlendSoftLightPipeline(ContentContextOptions opts) const { - return GetPipeline(framebuffer_blend_softlight_pipelines_, opts); - } - - private: - std::shared_ptr context_; - - template - using Variants = std::unordered_map, - ContentContextOptions::Hash, - ContentContextOptions::Equal>; - - // These are mutable because while the prototypes are created eagerly, any - // variants requested from that are lazily created and cached in the variants - // map. - mutable Variants - framebuffer_blend_color_pipelines_; - mutable Variants - framebuffer_blend_colorburn_pipelines_; - mutable Variants - framebuffer_blend_colordodge_pipelines_; - mutable Variants - framebuffer_blend_darken_pipelines_; - mutable Variants - framebuffer_blend_difference_pipelines_; - mutable Variants - framebuffer_blend_exclusion_pipelines_; - mutable Variants - framebuffer_blend_hardlight_pipelines_; - mutable Variants - framebuffer_blend_hue_pipelines_; - mutable Variants - framebuffer_blend_lighten_pipelines_; - mutable Variants - framebuffer_blend_luminosity_pipelines_; - mutable Variants - framebuffer_blend_multiply_pipelines_; - mutable Variants - framebuffer_blend_overlay_pipelines_; - mutable Variants - framebuffer_blend_saturation_pipelines_; - mutable Variants - framebuffer_blend_screen_pipelines_; - mutable Variants - framebuffer_blend_softlight_pipelines_; - - template - std::shared_ptr> GetPipeline( - Variants& container, - ContentContextOptions opts) const { - if (!IsValid()) { - return nullptr; - } - - if (wireframe_) { - opts.wireframe = true; - } - - if (auto found = container.find(opts); found != container.end()) { - return found->second->WaitAndGet(); - } - - auto prototype = container.find({}); - - // The prototype must always be initialized in the constructor. - FML_CHECK(prototype != container.end()); - - auto variant_future = prototype->second->WaitAndGet()->CreateVariant( - [&opts, variants_count = container.size()](PipelineDescriptor& desc) { - opts.ApplyToPipelineDescriptor(desc); - desc.SetLabel( - SPrintF("%s V#%zu", desc.GetLabel().c_str(), variants_count)); - }); - auto variant = std::make_unique(std::move(variant_future)); - auto variant_pipeline = variant->WaitAndGet(); - container[opts] = std::move(variant); - return variant_pipeline; - } - - bool is_valid_ = false; - bool wireframe_ = false; - - FML_DISALLOW_COPY_AND_ASSIGN(FramebufferBlendContext); -}; - -} // namespace impeller From 96d7fbb76da759292f758fa3ea5f72a973b704d3 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Tue, 7 Mar 2023 18:19:39 -0800 Subject: [PATCH 5/5] rename to framebuffer fetch, disable on simulator --- impeller/entity/contents/atlas_contents.cc | 2 +- impeller/entity/contents/content_context.cc | 2 +- impeller/entity/contents/content_context.h | 30 ++++++++-------- .../contents/framebuffer_blend_contents.cc | 2 +- impeller/entity/entity_pass.cc | 4 +-- .../renderer/backend/gles/context_gles.cc | 2 +- impeller/renderer/backend/metal/context_mtl.h | 2 ++ .../renderer/backend/metal/context_mtl.mm | 36 ++++++++++--------- .../renderer/backend/vulkan/context_vk.cc | 2 +- impeller/renderer/device_capabilities.cc | 14 ++++---- impeller/renderer/device_capabilities.h | 10 +++--- 11 files changed, 56 insertions(+), 50 deletions(-) diff --git a/impeller/entity/contents/atlas_contents.cc b/impeller/entity/contents/atlas_contents.cc index 88dc130ecc87e..f1a82ef6616df 100644 --- a/impeller/entity/contents/atlas_contents.cc +++ b/impeller/entity/contents/atlas_contents.cc @@ -222,7 +222,7 @@ bool AtlasContents::Render(const ContentContext& renderer, dst_contents->SetCoverage(sub_coverage); std::shared_ptr new_texture; - if (renderer.GetDeviceCapabilities().SupportsFramebufferBlending()) { + if (renderer.GetDeviceCapabilities().SupportsFramebufferFetch()) { new_texture = renderer.MakeSubpass( "Atlas Blend", sub_atlas->size, [&](const ContentContext& context, RenderPass& pass) { diff --git a/impeller/entity/contents/content_context.cc b/impeller/entity/contents/content_context.cc index 7c05701ab27b6..fcbead26b251c 100644 --- a/impeller/entity/contents/content_context.cc +++ b/impeller/entity/contents/content_context.cc @@ -183,7 +183,7 @@ ContentContext::ContentContext(std::shared_ptr context) sweep_gradient_ssbo_fill_pipelines_[{}] = CreateDefaultPipeline(*context_); } - if (context_->GetDeviceCapabilities().SupportsFramebufferBlending()) { + if (context_->GetDeviceCapabilities().SupportsFramebufferFetch()) { framebuffer_blend_color_pipelines_[{}] = CreateDefaultPipeline(*context_); framebuffer_blend_colorburn_pipelines_[{}] = diff --git a/impeller/entity/contents/content_context.h b/impeller/entity/contents/content_context.h index 45c16bcc5f0f5..72c11360cf8f3 100644 --- a/impeller/entity/contents/content_context.h +++ b/impeller/entity/contents/content_context.h @@ -517,91 +517,91 @@ class ContentContext { // Framebuffer Advanced Blends std::shared_ptr> GetFramebufferBlendColorPipeline(ContentContextOptions opts) const { - FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferBlending()); + FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch()); return GetPipeline(framebuffer_blend_color_pipelines_, opts); } std::shared_ptr> GetFramebufferBlendColorBurnPipeline(ContentContextOptions opts) const { - FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferBlending()); + FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch()); return GetPipeline(framebuffer_blend_colorburn_pipelines_, opts); } std::shared_ptr> GetFramebufferBlendColorDodgePipeline(ContentContextOptions opts) const { - FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferBlending()); + FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch()); return GetPipeline(framebuffer_blend_colordodge_pipelines_, opts); } std::shared_ptr> GetFramebufferBlendDarkenPipeline(ContentContextOptions opts) const { - FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferBlending()); + FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch()); return GetPipeline(framebuffer_blend_darken_pipelines_, opts); } std::shared_ptr> GetFramebufferBlendDifferencePipeline(ContentContextOptions opts) const { - FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferBlending()); + FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch()); return GetPipeline(framebuffer_blend_difference_pipelines_, opts); } std::shared_ptr> GetFramebufferBlendExclusionPipeline(ContentContextOptions opts) const { - FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferBlending()); + FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch()); return GetPipeline(framebuffer_blend_exclusion_pipelines_, opts); } std::shared_ptr> GetFramebufferBlendHardLightPipeline(ContentContextOptions opts) const { - FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferBlending()); + FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch()); return GetPipeline(framebuffer_blend_hardlight_pipelines_, opts); } std::shared_ptr> GetFramebufferBlendHuePipeline( ContentContextOptions opts) const { - FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferBlending()); + FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch()); return GetPipeline(framebuffer_blend_hue_pipelines_, opts); } std::shared_ptr> GetFramebufferBlendLightenPipeline(ContentContextOptions opts) const { - FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferBlending()); + FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch()); return GetPipeline(framebuffer_blend_lighten_pipelines_, opts); } std::shared_ptr> GetFramebufferBlendLuminosityPipeline(ContentContextOptions opts) const { - FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferBlending()); + FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch()); return GetPipeline(framebuffer_blend_luminosity_pipelines_, opts); } std::shared_ptr> GetFramebufferBlendMultiplyPipeline(ContentContextOptions opts) const { - FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferBlending()); + FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch()); return GetPipeline(framebuffer_blend_multiply_pipelines_, opts); } std::shared_ptr> GetFramebufferBlendOverlayPipeline(ContentContextOptions opts) const { - FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferBlending()); + FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch()); return GetPipeline(framebuffer_blend_overlay_pipelines_, opts); } std::shared_ptr> GetFramebufferBlendSaturationPipeline(ContentContextOptions opts) const { - FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferBlending()); + FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch()); return GetPipeline(framebuffer_blend_saturation_pipelines_, opts); } std::shared_ptr> GetFramebufferBlendScreenPipeline(ContentContextOptions opts) const { - FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferBlending()); + FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch()); return GetPipeline(framebuffer_blend_screen_pipelines_, opts); } std::shared_ptr> GetFramebufferBlendSoftLightPipeline(ContentContextOptions opts) const { - FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferBlending()); + FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch()); return GetPipeline(framebuffer_blend_softlight_pipelines_, opts); } diff --git a/impeller/entity/contents/framebuffer_blend_contents.cc b/impeller/entity/contents/framebuffer_blend_contents.cc index d24d87a317d56..7b2699ce4f453 100644 --- a/impeller/entity/contents/framebuffer_blend_contents.cc +++ b/impeller/entity/contents/framebuffer_blend_contents.cc @@ -32,7 +32,7 @@ std::optional FramebufferBlendContents::GetCoverage( bool FramebufferBlendContents::Render(const ContentContext& renderer, const Entity& entity, RenderPass& pass) const { - if (!renderer.GetDeviceCapabilities().SupportsFramebufferBlending()) { + if (!renderer.GetDeviceCapabilities().SupportsFramebufferFetch()) { return false; } diff --git a/impeller/entity/entity_pass.cc b/impeller/entity/entity_pass.cc index 26874d79f3e60..487c56d063976 100644 --- a/impeller/entity/entity_pass.cc +++ b/impeller/entity/entity_pass.cc @@ -191,7 +191,7 @@ static RenderTarget CreateRenderTarget(ContentContext& renderer, } uint32_t EntityPass::ComputeTotalReads(ContentContext& renderer) const { - return renderer.GetDeviceCapabilities().SupportsFramebufferBlending() + return renderer.GetDeviceCapabilities().SupportsFramebufferFetch() ? filter_reads_from_pass_texture_ : filter_reads_from_pass_texture_ + blend_reads_from_pass_texture_; } @@ -549,7 +549,7 @@ bool EntityPass::OnRender(ContentContext& renderer, /// if (result.entity.GetBlendMode() > Entity::kLastPipelineBlendMode) { - if (renderer.GetDeviceCapabilities().SupportsFramebufferBlending()) { + if (renderer.GetDeviceCapabilities().SupportsFramebufferFetch()) { auto src_contents = result.entity.GetContents(); auto contents = std::make_shared(); contents->SetChildContents(src_contents); diff --git a/impeller/renderer/backend/gles/context_gles.cc b/impeller/renderer/backend/gles/context_gles.cc index 62024f13fbd34..a9de32f2c3df3 100644 --- a/impeller/renderer/backend/gles/context_gles.cc +++ b/impeller/renderer/backend/gles/context_gles.cc @@ -78,7 +78,7 @@ ContextGLES::ContextGLES(std::unique_ptr gl, .SetSupportsSSBO(false) .SetSupportsTextureToTextureBlits( reactor_->GetProcTable().BlitFramebuffer.IsAvailable()) - .SetSupportsFramebufferBlending(false) + .SetSupportsFramebufferFetch(false) .SetDefaultColorFormat(PixelFormat::kB8G8R8A8UNormInt) .SetDefaultStencilFormat(PixelFormat::kS8UInt) .Build(); diff --git a/impeller/renderer/backend/metal/context_mtl.h b/impeller/renderer/backend/metal/context_mtl.h index ceea472db4364..bd75e585d86c0 100644 --- a/impeller/renderer/backend/metal/context_mtl.h +++ b/impeller/renderer/backend/metal/context_mtl.h @@ -51,6 +51,8 @@ class ContextMTL final : public Context, ContextMTL(id device, NSArray>* shader_libraries); + bool SupportsFramebufferFetch() const; + // |Context| bool IsValid() const override; diff --git a/impeller/renderer/backend/metal/context_mtl.mm b/impeller/renderer/backend/metal/context_mtl.mm index afe60f3108e23..c9f0dd9c24216 100644 --- a/impeller/renderer/backend/metal/context_mtl.mm +++ b/impeller/renderer/backend/metal/context_mtl.mm @@ -90,28 +90,13 @@ #endif { - bool supports_framebuffer_blend = false; - if (@available(macOS 10.15, iOS 13, tvOS 13, *)) { - supports_framebuffer_blend = [device supportsFamily:MTLGPUFamilyApple2]; - } else { - // According to - // https://developer.apple.com/metal/Metal-Feature-Set-Tables.pdf , Apple2 - // corresponds to iOS GPU family 2, which supports A8 devices. -#if FML_OS_IOS - supports_framebuffer_blend = - [device supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily2_v1]; -#else - supports_framebuffer_blend = false; -#endif // FML_OS_IOS - } - device_capabilities_ = DeviceCapabilitiesBuilder() .SetHasThreadingRestrictions(false) .SetSupportsOffscreenMSAA(true) .SetSupportsSSBO(true) .SetSupportsTextureToTextureBlits(true) - .SetSupportsFramebufferBlending(supports_framebuffer_blend) + .SetSupportsFramebufferFetch(SupportsFramebufferFetch()) .SetDefaultColorFormat(PixelFormat::kB8G8R8A8UNormInt) .SetDefaultStencilFormat(PixelFormat::kS8UInt) .Build(); @@ -120,6 +105,25 @@ is_valid_ = true; } +bool ContextMTL::SupportsFramebufferFetch() const { + // The iOS simulator lies about supporting framebuffer fetch. +#if FML_OS_IOS_SIMULATOR + return false; +#endif // FML_OS_IOS_SIMULATOR + + if (@available(macOS 10.15, iOS 13, tvOS 13, *)) { + return [device_ supportsFamily:MTLGPUFamilyApple2]; + } + // According to + // https://developer.apple.com/metal/Metal-Feature-Set-Tables.pdf , Apple2 + // corresponds to iOS GPU family 2, which supports A8 devices. +#if FML_OS_IOS + return [device_ supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily2_v1]; +#else + return false; +#endif // FML_OS_IOS +} + static NSArray>* MTLShaderLibraryFromFilePaths( id device, const std::vector& libraries_paths) { diff --git a/impeller/renderer/backend/vulkan/context_vk.cc b/impeller/renderer/backend/vulkan/context_vk.cc index 97c2bdce7e365..a71731d16627a 100644 --- a/impeller/renderer/backend/vulkan/context_vk.cc +++ b/impeller/renderer/backend/vulkan/context_vk.cc @@ -554,7 +554,7 @@ ContextVK::ContextVK( .SetSupportsOffscreenMSAA(true) .SetSupportsSSBO(false) .SetSupportsTextureToTextureBlits(true) - .SetSupportsFramebufferBlending(false) + .SetSupportsFramebufferFetch(false) .SetDefaultColorFormat(PixelFormat::kB8G8R8A8UNormInt) .SetDefaultStencilFormat(PixelFormat::kS8UInt) .Build(); diff --git a/impeller/renderer/device_capabilities.cc b/impeller/renderer/device_capabilities.cc index b98d8432e55f3..9bb9e3702d239 100644 --- a/impeller/renderer/device_capabilities.cc +++ b/impeller/renderer/device_capabilities.cc @@ -10,14 +10,14 @@ IDeviceCapabilities::IDeviceCapabilities(bool has_threading_restrictions, bool supports_offscreen_msaa, bool supports_ssbo, bool supports_texture_to_texture_blits, - bool supports_framebuffer_blending, + bool supports_framebuffer_fetch, PixelFormat default_color_format, PixelFormat default_stencil_format) : has_threading_restrictions_(has_threading_restrictions), supports_offscreen_msaa_(supports_offscreen_msaa), supports_ssbo_(supports_ssbo), supports_texture_to_texture_blits_(supports_texture_to_texture_blits), - supports_framebuffer_blending_(supports_framebuffer_blending), + supports_framebuffer_fetch_(supports_framebuffer_fetch), default_color_format_(default_color_format), default_stencil_format_(default_stencil_format) {} @@ -39,8 +39,8 @@ bool IDeviceCapabilities::SupportsTextureToTextureBlits() const { return supports_texture_to_texture_blits_; } -bool IDeviceCapabilities::SupportsFramebufferBlending() const { - return supports_framebuffer_blending_; +bool IDeviceCapabilities::SupportsFramebufferFetch() const { + return supports_framebuffer_fetch_; } PixelFormat IDeviceCapabilities::GetDefaultColorFormat() const { @@ -80,8 +80,8 @@ DeviceCapabilitiesBuilder::SetSupportsTextureToTextureBlits(bool value) { } DeviceCapabilitiesBuilder& -DeviceCapabilitiesBuilder::SetSupportsFramebufferBlending(bool value) { - supports_framebuffer_blending_ = value; +DeviceCapabilitiesBuilder::SetSupportsFramebufferFetch(bool value) { + supports_framebuffer_fetch_ = value; return *this; } @@ -108,7 +108,7 @@ std::unique_ptr DeviceCapabilitiesBuilder::Build() { supports_offscreen_msaa_, // supports_ssbo_, // supports_texture_to_texture_blits_, // - supports_framebuffer_blending_, // + supports_framebuffer_fetch_, // *default_color_format_, // *default_stencil_format_ // ); diff --git a/impeller/renderer/device_capabilities.h b/impeller/renderer/device_capabilities.h index 83439d5b0cd9e..697b8f5d531a0 100644 --- a/impeller/renderer/device_capabilities.h +++ b/impeller/renderer/device_capabilities.h @@ -23,7 +23,7 @@ class IDeviceCapabilities { bool SupportsTextureToTextureBlits() const; - bool SupportsFramebufferBlending() const; + bool SupportsFramebufferFetch() const; PixelFormat GetDefaultColorFormat() const; @@ -34,7 +34,7 @@ class IDeviceCapabilities { bool supports_offscreen_msaa, bool supports_ssbo, bool supports_texture_to_texture_blits, - bool supports_framebuffer_blending, + bool supports_framebuffer_fetch, PixelFormat default_color_format, PixelFormat default_stencil_format); @@ -44,7 +44,7 @@ class IDeviceCapabilities { bool supports_offscreen_msaa_ = false; bool supports_ssbo_ = false; bool supports_texture_to_texture_blits_ = false; - bool supports_framebuffer_blending_ = false; + bool supports_framebuffer_fetch_ = false; PixelFormat default_color_format_; PixelFormat default_stencil_format_; @@ -65,7 +65,7 @@ class DeviceCapabilitiesBuilder { DeviceCapabilitiesBuilder& SetSupportsTextureToTextureBlits(bool value); - DeviceCapabilitiesBuilder& SetSupportsFramebufferBlending(bool value); + DeviceCapabilitiesBuilder& SetSupportsFramebufferFetch(bool value); DeviceCapabilitiesBuilder& SetDefaultColorFormat(PixelFormat value); @@ -78,7 +78,7 @@ class DeviceCapabilitiesBuilder { bool supports_offscreen_msaa_ = false; bool supports_ssbo_ = false; bool supports_texture_to_texture_blits_ = false; - bool supports_framebuffer_blending_ = false; + bool supports_framebuffer_fetch_ = false; std::optional default_color_format_ = std::nullopt; std::optional default_stencil_format_ = std::nullopt;