From ef2b22c73e7f9b9052e2dde30b51fd6de96e7f0d Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Thu, 1 Feb 2024 15:13:17 -0800 Subject: [PATCH 01/16] [Impeller] Add shared ColorSourceContents render routine. --- impeller/entity/BUILD.gn | 2 + .../entity/contents/contents_rendering.cc | 11 ++ impeller/entity/contents/contents_rendering.h | 113 ++++++++++++++++++ .../entity/contents/solid_color_contents.cc | 40 ++----- impeller/entity/geometry/geometry.cc | 1 + 5 files changed, 136 insertions(+), 31 deletions(-) create mode 100644 impeller/entity/contents/contents_rendering.cc create mode 100644 impeller/entity/contents/contents_rendering.h diff --git a/impeller/entity/BUILD.gn b/impeller/entity/BUILD.gn index b13e8f81526d8..06ecd2c525cc2 100644 --- a/impeller/entity/BUILD.gn +++ b/impeller/entity/BUILD.gn @@ -126,6 +126,8 @@ impeller_component("entity") { "contents/content_context.h", "contents/contents.cc", "contents/contents.h", + "contents/contents_rendering.cc", + "contents/contents_rendering.h", "contents/filters/blend_filter_contents.cc", "contents/filters/blend_filter_contents.h", "contents/filters/border_mask_blur_filter_contents.cc", diff --git a/impeller/entity/contents/contents_rendering.cc b/impeller/entity/contents/contents_rendering.cc new file mode 100644 index 0000000000000..f5463bb1a9967 --- /dev/null +++ b/impeller/entity/contents/contents_rendering.cc @@ -0,0 +1,11 @@ +// 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/contents_rendering.h" + +namespace impeller { + +// + +} // namespace impeller diff --git a/impeller/entity/contents/contents_rendering.h b/impeller/entity/contents/contents_rendering.h new file mode 100644 index 0000000000000..cb68672bc6d5f --- /dev/null +++ b/impeller/entity/contents/contents_rendering.h @@ -0,0 +1,113 @@ +// 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. + +#ifndef FLUTTER_IMPELLER_ENTITY_CONTENTS_CONTENTS_RENDERING_H_ +#define FLUTTER_IMPELLER_ENTITY_CONTENTS_CONTENTS_RENDERING_H_ + +#include +#include + +#include "impeller/entity/contents/clip_contents.h" +#include "impeller/entity/contents/color_source_contents.h" +#include "impeller/entity/contents/content_context.h" +#include "impeller/entity/geometry/geometry.h" +#include "impeller/renderer/pipeline.h" +#include "impeller/renderer/pipeline_descriptor.h" +#include "impeller/renderer/render_pass.h" + +namespace impeller { + +using BindFragmentCallback = std::function; +using PipelineBuilderMethod = std::shared_ptr> ( + impeller::ContentContext::*)(ContentContextOptions) const; + +template +bool DrawGeometry(GeometryResult geometry_result, + const ColorSourceContents& contents, + const ContentContext& renderer, + const Entity& entity, + RenderPass& pass, + const PipelineBuilderMethod& pipeline_builder, + typename VertexShaderT::FrameInfo frame_info, + const BindFragmentCallback& bind_pipeline_callback) { + auto options = OptionsFromPassAndEntity(pass, entity); + + // If overdraw prevention is enabled (like when drawing stroke paths), we + // increment the stencil buffer as we draw, preventing overlapping fragments + // from drawing. Afterwards, we need to append another draw call to clean up + // the stencil buffer (happens below in this method). + if (geometry_result.prevent_overdraw) { + options.stencil_mode = + ContentContextOptions::StencilMode::kLegacyClipIncrement; + } + options.primitive_type = geometry_result.type; + pass.SetVertexBuffer(std::move(geometry_result.vertex_buffer)); + pass.SetStencilReference(entity.GetClipDepth()); + + frame_info.depth = entity.GetShaderClipDepth(); + frame_info.mvp = geometry_result.transform; + + VertexShaderT::BindFrameInfo( + pass, renderer.GetTransientsBuffer().EmplaceUniform(frame_info)); + + std::shared_ptr> pipeline = + (renderer.*pipeline_builder)(options); + pass.SetPipeline(pipeline); + + if (!bind_pipeline_callback(pass)) { + return false; + } + + if (!pass.Draw().ok()) { + return false; + } + + // If we performed overdraw prevention, a subsection of the clip heightmap was + // incremented by 1 in order to self-clip. So simply append a clip restore to + // clean it up. + if (geometry_result.prevent_overdraw) { + auto restore = ClipRestoreContents(); + restore.SetRestoreCoverage(contents.GetCoverage(entity)); + return restore.Render(renderer, entity, pass); + } + return true; +} + +template +bool DrawPositions(const ColorSourceContents& contents, + const ContentContext& renderer, + const Entity& entity, + RenderPass& pass, + const PipelineBuilderMethod& pipeline_builder, + typename VertexShaderT::FrameInfo frame_info, + const BindFragmentCallback& bind_pipeline_callback) { + auto geometry_result = + contents.GetGeometry()->GetPositionBuffer(renderer, entity, pass); + + return DrawGeometry(geometry_result, contents, renderer, + entity, pass, pipeline_builder, frame_info, + bind_pipeline_callback); +} + +template +bool DrawPositionsAndUVs(Rect texture_coverage, + Matrix effect_transform, + const ColorSourceContents& contents, + const ContentContext& renderer, + const Entity& entity, + RenderPass& pass, + const PipelineBuilderMethod& pipeline_builder, + typename VertexShaderT::FrameInfo frame_info, + const BindFragmentCallback& bind_pipeline_callback) { + auto geometry_result = contents.GetGeometry()->GetPositionUVBuffer( + texture_coverage, effect_transform, renderer, entity, pass); + + return DrawGeometry(geometry_result, contents, renderer, + entity, pass, pipeline_builder, frame_info, + bind_pipeline_callback); +} + +} // namespace impeller + +#endif // FLUTTER_IMPELLER_ENTITY_CONTENTS_CONTENTS_RENDERING_H_ diff --git a/impeller/entity/contents/solid_color_contents.cc b/impeller/entity/contents/solid_color_contents.cc index 707e771e79f86..a70bf727a0bdf 100644 --- a/impeller/entity/contents/solid_color_contents.cc +++ b/impeller/entity/contents/solid_color_contents.cc @@ -6,6 +6,7 @@ #include "impeller/entity/contents/clip_contents.h" #include "impeller/entity/contents/content_context.h" +#include "impeller/entity/contents/contents_rendering.h" #include "impeller/entity/entity.h" #include "impeller/entity/geometry/geometry.h" #include "impeller/geometry/path.h" @@ -52,39 +53,16 @@ bool SolidColorContents::Render(const ContentContext& renderer, auto capture = entity.GetCapture().CreateChild("SolidColorContents"); using VS = SolidFillPipeline::VertexShader; - auto geometry_result = - GetGeometry()->GetPositionBuffer(renderer, entity, pass); - - auto options = OptionsFromPassAndEntity(pass, entity); - if (geometry_result.prevent_overdraw) { - options.stencil_mode = - ContentContextOptions::StencilMode::kLegacyClipIncrement; - } - - options.primitive_type = geometry_result.type; - - pass.SetCommandLabel("Solid Fill"); - pass.SetPipeline(renderer.GetSolidFillPipeline(options)); - pass.SetVertexBuffer(std::move(geometry_result.vertex_buffer)); - pass.SetStencilReference(entity.GetClipDepth()); - VS::FrameInfo frame_info; - frame_info.depth = entity.GetShaderClipDepth(); - frame_info.mvp = capture.AddMatrix("Transform", geometry_result.transform); frame_info.color = capture.AddColor("Color", GetColor()).Premultiply(); - VS::BindFrameInfo(pass, - renderer.GetTransientsBuffer().EmplaceUniform(frame_info)); - - if (!pass.Draw().ok()) { - return false; - } - - if (geometry_result.prevent_overdraw) { - auto restore = ClipRestoreContents(); - restore.SetRestoreCoverage(GetCoverage(entity)); - return restore.Render(renderer, entity, pass); - } - return true; + const ColorSourceContents& contents = *this; + + return DrawPositions(contents, renderer, entity, pass, + &ContentContext::GetSolidFillPipeline, frame_info, + [](RenderPass& pass) { + pass.SetCommandLabel("Solid Fill"); + return true; + }); } std::unique_ptr SolidColorContents::Make(const Path& path, diff --git a/impeller/entity/geometry/geometry.cc b/impeller/entity/geometry/geometry.cc index 65b2b43c583c0..fe38adfa86625 100644 --- a/impeller/entity/geometry/geometry.cc +++ b/impeller/entity/geometry/geometry.cc @@ -7,6 +7,7 @@ #include #include +#include "fml/status.h" #include "impeller/entity/contents/content_context.h" #include "impeller/entity/geometry/circle_geometry.h" #include "impeller/entity/geometry/cover_geometry.h" From 24564384a81ee5c3f0e32e6578f2b1e227ec8b21 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Thu, 1 Feb 2024 15:27:48 -0800 Subject: [PATCH 02/16] Move to ColorSourceContents --- impeller/entity/BUILD.gn | 2 - .../entity/contents/color_source_contents.h | 90 ++++++++++++++ .../entity/contents/contents_rendering.cc | 11 -- impeller/entity/contents/contents_rendering.h | 113 ------------------ .../entity/contents/solid_color_contents.cc | 17 ++- 5 files changed, 97 insertions(+), 136 deletions(-) delete mode 100644 impeller/entity/contents/contents_rendering.cc delete mode 100644 impeller/entity/contents/contents_rendering.h diff --git a/impeller/entity/BUILD.gn b/impeller/entity/BUILD.gn index 06ecd2c525cc2..b13e8f81526d8 100644 --- a/impeller/entity/BUILD.gn +++ b/impeller/entity/BUILD.gn @@ -126,8 +126,6 @@ impeller_component("entity") { "contents/content_context.h", "contents/contents.cc", "contents/contents.h", - "contents/contents_rendering.cc", - "contents/contents_rendering.h", "contents/filters/blend_filter_contents.cc", "contents/filters/blend_filter_contents.h", "contents/filters/border_mask_blur_filter_contents.cc", diff --git a/impeller/entity/contents/color_source_contents.h b/impeller/entity/contents/color_source_contents.h index 83fe120aed0fe..2732b417169eb 100644 --- a/impeller/entity/contents/color_source_contents.h +++ b/impeller/entity/contents/color_source_contents.h @@ -5,6 +5,7 @@ #ifndef FLUTTER_IMPELLER_ENTITY_CONTENTS_COLOR_SOURCE_CONTENTS_H_ #define FLUTTER_IMPELLER_ENTITY_CONTENTS_COLOR_SOURCE_CONTENTS_H_ +#include "impeller/entity/contents/clip_contents.h" #include "impeller/entity/contents/contents.h" #include "impeller/entity/geometry/geometry.h" #include "impeller/geometry/matrix.h" @@ -100,6 +101,95 @@ class ColorSourceContents : public Contents { // |Contents| void SetInheritedOpacity(Scalar opacity) override; + protected: + using BindFragmentCallback = std::function; + using PipelineBuilderMethod = std::shared_ptr> ( + impeller::ContentContext::*)(ContentContextOptions) const; + + template + bool DrawGeometry(GeometryResult geometry_result, + const ContentContext& renderer, + const Entity& entity, + RenderPass& pass, + const PipelineBuilderMethod& pipeline_builder, + typename VertexShaderT::FrameInfo frame_info, + const BindFragmentCallback& bind_pipeline_callback) const { + auto options = OptionsFromPassAndEntity(pass, entity); + + // If overdraw prevention is enabled (like when drawing stroke paths), we + // increment the stencil buffer as we draw, preventing overlapping fragments + // from drawing. Afterwards, we need to append another draw call to clean up + // the stencil buffer (happens below in this method). + if (geometry_result.prevent_overdraw) { + options.stencil_mode = + ContentContextOptions::StencilMode::kLegacyClipIncrement; + } + options.primitive_type = geometry_result.type; + pass.SetVertexBuffer(std::move(geometry_result.vertex_buffer)); + pass.SetStencilReference(entity.GetClipDepth()); + + frame_info.depth = entity.GetShaderClipDepth(); + frame_info.mvp = geometry_result.transform; + + VertexShaderT::BindFrameInfo( + pass, renderer.GetTransientsBuffer().EmplaceUniform(frame_info)); + + std::shared_ptr> pipeline = + (renderer.*pipeline_builder)(options); + pass.SetPipeline(pipeline); + + if (!bind_pipeline_callback(pass)) { + return false; + } + + if (!pass.Draw().ok()) { + return false; + } + + // If we performed overdraw prevention, a subsection of the clip heightmap + // was incremented by 1 in order to self-clip. So simply append a clip + // restore to clean it up. + if (geometry_result.prevent_overdraw) { + auto restore = ClipRestoreContents(); + restore.SetRestoreCoverage(GetCoverage(entity)); + return restore.Render(renderer, entity, pass); + } + return true; + } + + template + bool DrawPositions(const ContentContext& renderer, + const Entity& entity, + RenderPass& pass, + const PipelineBuilderMethod& pipeline_builder, + typename VertexShaderT::FrameInfo frame_info, + const BindFragmentCallback& bind_pipeline_callback) const { + auto geometry_result = + GetGeometry()->GetPositionBuffer(renderer, entity, pass); + + return DrawGeometry(geometry_result, renderer, entity, pass, + pipeline_builder, frame_info, + bind_pipeline_callback); + } + + template + bool DrawPositionsAndUVs( + Rect texture_coverage, + Matrix effect_transform, + const ContentContext& renderer, + const Entity& entity, + RenderPass& pass, + const PipelineBuilderMethod& pipeline_builder, + typename VertexShaderT::FrameInfo frame_info, + const BindFragmentCallback& bind_pipeline_callback) const { + auto geometry_result = GetGeometry()->GetPositionUVBuffer( + texture_coverage, effect_transform, renderer, entity, pass); + + return DrawGeometry(geometry_result, renderer, entity, pass, + pipeline_builder, frame_info, + bind_pipeline_callback); + } + private: std::shared_ptr geometry_; Matrix inverse_matrix_; diff --git a/impeller/entity/contents/contents_rendering.cc b/impeller/entity/contents/contents_rendering.cc deleted file mode 100644 index f5463bb1a9967..0000000000000 --- a/impeller/entity/contents/contents_rendering.cc +++ /dev/null @@ -1,11 +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/contents_rendering.h" - -namespace impeller { - -// - -} // namespace impeller diff --git a/impeller/entity/contents/contents_rendering.h b/impeller/entity/contents/contents_rendering.h deleted file mode 100644 index cb68672bc6d5f..0000000000000 --- a/impeller/entity/contents/contents_rendering.h +++ /dev/null @@ -1,113 +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. - -#ifndef FLUTTER_IMPELLER_ENTITY_CONTENTS_CONTENTS_RENDERING_H_ -#define FLUTTER_IMPELLER_ENTITY_CONTENTS_CONTENTS_RENDERING_H_ - -#include -#include - -#include "impeller/entity/contents/clip_contents.h" -#include "impeller/entity/contents/color_source_contents.h" -#include "impeller/entity/contents/content_context.h" -#include "impeller/entity/geometry/geometry.h" -#include "impeller/renderer/pipeline.h" -#include "impeller/renderer/pipeline_descriptor.h" -#include "impeller/renderer/render_pass.h" - -namespace impeller { - -using BindFragmentCallback = std::function; -using PipelineBuilderMethod = std::shared_ptr> ( - impeller::ContentContext::*)(ContentContextOptions) const; - -template -bool DrawGeometry(GeometryResult geometry_result, - const ColorSourceContents& contents, - const ContentContext& renderer, - const Entity& entity, - RenderPass& pass, - const PipelineBuilderMethod& pipeline_builder, - typename VertexShaderT::FrameInfo frame_info, - const BindFragmentCallback& bind_pipeline_callback) { - auto options = OptionsFromPassAndEntity(pass, entity); - - // If overdraw prevention is enabled (like when drawing stroke paths), we - // increment the stencil buffer as we draw, preventing overlapping fragments - // from drawing. Afterwards, we need to append another draw call to clean up - // the stencil buffer (happens below in this method). - if (geometry_result.prevent_overdraw) { - options.stencil_mode = - ContentContextOptions::StencilMode::kLegacyClipIncrement; - } - options.primitive_type = geometry_result.type; - pass.SetVertexBuffer(std::move(geometry_result.vertex_buffer)); - pass.SetStencilReference(entity.GetClipDepth()); - - frame_info.depth = entity.GetShaderClipDepth(); - frame_info.mvp = geometry_result.transform; - - VertexShaderT::BindFrameInfo( - pass, renderer.GetTransientsBuffer().EmplaceUniform(frame_info)); - - std::shared_ptr> pipeline = - (renderer.*pipeline_builder)(options); - pass.SetPipeline(pipeline); - - if (!bind_pipeline_callback(pass)) { - return false; - } - - if (!pass.Draw().ok()) { - return false; - } - - // If we performed overdraw prevention, a subsection of the clip heightmap was - // incremented by 1 in order to self-clip. So simply append a clip restore to - // clean it up. - if (geometry_result.prevent_overdraw) { - auto restore = ClipRestoreContents(); - restore.SetRestoreCoverage(contents.GetCoverage(entity)); - return restore.Render(renderer, entity, pass); - } - return true; -} - -template -bool DrawPositions(const ColorSourceContents& contents, - const ContentContext& renderer, - const Entity& entity, - RenderPass& pass, - const PipelineBuilderMethod& pipeline_builder, - typename VertexShaderT::FrameInfo frame_info, - const BindFragmentCallback& bind_pipeline_callback) { - auto geometry_result = - contents.GetGeometry()->GetPositionBuffer(renderer, entity, pass); - - return DrawGeometry(geometry_result, contents, renderer, - entity, pass, pipeline_builder, frame_info, - bind_pipeline_callback); -} - -template -bool DrawPositionsAndUVs(Rect texture_coverage, - Matrix effect_transform, - const ColorSourceContents& contents, - const ContentContext& renderer, - const Entity& entity, - RenderPass& pass, - const PipelineBuilderMethod& pipeline_builder, - typename VertexShaderT::FrameInfo frame_info, - const BindFragmentCallback& bind_pipeline_callback) { - auto geometry_result = contents.GetGeometry()->GetPositionUVBuffer( - texture_coverage, effect_transform, renderer, entity, pass); - - return DrawGeometry(geometry_result, contents, renderer, - entity, pass, pipeline_builder, frame_info, - bind_pipeline_callback); -} - -} // namespace impeller - -#endif // FLUTTER_IMPELLER_ENTITY_CONTENTS_CONTENTS_RENDERING_H_ diff --git a/impeller/entity/contents/solid_color_contents.cc b/impeller/entity/contents/solid_color_contents.cc index a70bf727a0bdf..61476d660a970 100644 --- a/impeller/entity/contents/solid_color_contents.cc +++ b/impeller/entity/contents/solid_color_contents.cc @@ -4,9 +4,7 @@ #include "solid_color_contents.h" -#include "impeller/entity/contents/clip_contents.h" #include "impeller/entity/contents/content_context.h" -#include "impeller/entity/contents/contents_rendering.h" #include "impeller/entity/entity.h" #include "impeller/entity/geometry/geometry.h" #include "impeller/geometry/path.h" @@ -55,14 +53,13 @@ bool SolidColorContents::Render(const ContentContext& renderer, VS::FrameInfo frame_info; frame_info.color = capture.AddColor("Color", GetColor()).Premultiply(); - const ColorSourceContents& contents = *this; - - return DrawPositions(contents, renderer, entity, pass, - &ContentContext::GetSolidFillPipeline, frame_info, - [](RenderPass& pass) { - pass.SetCommandLabel("Solid Fill"); - return true; - }); + + return ColorSourceContents::DrawPositions( + renderer, entity, pass, &ContentContext::GetSolidFillPipeline, frame_info, + [](RenderPass& pass) { + pass.SetCommandLabel("Solid Fill"); + return true; + }); } std::unique_ptr SolidColorContents::Make(const Path& path, From a27a5f1d97cefb67ab81f123d1cb125d710b8d79 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Wed, 7 Feb 2024 19:00:06 -0800 Subject: [PATCH 03/16] jonah review --- .../entity/contents/color_source_contents.cc | 4 +++ .../entity/contents/color_source_contents.h | 33 ++++++++----------- .../entity/contents/solid_color_contents.cc | 12 ++++--- .../entity/contents/solid_color_contents.h | 3 ++ 4 files changed, 28 insertions(+), 24 deletions(-) diff --git a/impeller/entity/contents/color_source_contents.cc b/impeller/entity/contents/color_source_contents.cc index 18bc16608a037..9924ba806d9af 100644 --- a/impeller/entity/contents/color_source_contents.cc +++ b/impeller/entity/contents/color_source_contents.cc @@ -54,4 +54,8 @@ void ColorSourceContents::SetInheritedOpacity(Scalar opacity) { inherited_opacity_ = opacity; } +bool ColorSourceContents::BindFragmentCallback(RenderPass& pass) const { + return true; +} + } // namespace impeller diff --git a/impeller/entity/contents/color_source_contents.h b/impeller/entity/contents/color_source_contents.h index 2732b417169eb..fdffff2b3fb00 100644 --- a/impeller/entity/contents/color_source_contents.h +++ b/impeller/entity/contents/color_source_contents.h @@ -102,7 +102,8 @@ class ColorSourceContents : public Contents { void SetInheritedOpacity(Scalar opacity) override; protected: - using BindFragmentCallback = std::function; + virtual bool BindFragmentCallback(RenderPass& pass) const; + using PipelineBuilderMethod = std::shared_ptr> ( impeller::ContentContext::*)(ContentContextOptions) const; @@ -112,8 +113,7 @@ class ColorSourceContents : public Contents { const Entity& entity, RenderPass& pass, const PipelineBuilderMethod& pipeline_builder, - typename VertexShaderT::FrameInfo frame_info, - const BindFragmentCallback& bind_pipeline_callback) const { + typename VertexShaderT::FrameInfo frame_info) const { auto options = OptionsFromPassAndEntity(pass, entity); // If overdraw prevention is enabled (like when drawing stroke paths), we @@ -138,7 +138,7 @@ class ColorSourceContents : public Contents { (renderer.*pipeline_builder)(options); pass.SetPipeline(pipeline); - if (!bind_pipeline_callback(pass)) { + if (!BindFragmentCallback(pass)) { return false; } @@ -162,32 +162,27 @@ class ColorSourceContents : public Contents { const Entity& entity, RenderPass& pass, const PipelineBuilderMethod& pipeline_builder, - typename VertexShaderT::FrameInfo frame_info, - const BindFragmentCallback& bind_pipeline_callback) const { + typename VertexShaderT::FrameInfo frame_info) const { auto geometry_result = GetGeometry()->GetPositionBuffer(renderer, entity, pass); return DrawGeometry(geometry_result, renderer, entity, pass, - pipeline_builder, frame_info, - bind_pipeline_callback); + pipeline_builder, frame_info); } template - bool DrawPositionsAndUVs( - Rect texture_coverage, - Matrix effect_transform, - const ContentContext& renderer, - const Entity& entity, - RenderPass& pass, - const PipelineBuilderMethod& pipeline_builder, - typename VertexShaderT::FrameInfo frame_info, - const BindFragmentCallback& bind_pipeline_callback) const { + bool DrawPositionsAndUVs(Rect texture_coverage, + const Matrix& effect_transform, + const ContentContext& renderer, + const Entity& entity, + RenderPass& pass, + const PipelineBuilderMethod& pipeline_builder, + typename VertexShaderT::FrameInfo frame_info) const { auto geometry_result = GetGeometry()->GetPositionUVBuffer( texture_coverage, effect_transform, renderer, entity, pass); return DrawGeometry(geometry_result, renderer, entity, pass, - pipeline_builder, frame_info, - bind_pipeline_callback); + pipeline_builder, frame_info); } private: diff --git a/impeller/entity/contents/solid_color_contents.cc b/impeller/entity/contents/solid_color_contents.cc index 61476d660a970..7f3df05e0791c 100644 --- a/impeller/entity/contents/solid_color_contents.cc +++ b/impeller/entity/contents/solid_color_contents.cc @@ -55,11 +55,13 @@ bool SolidColorContents::Render(const ContentContext& renderer, frame_info.color = capture.AddColor("Color", GetColor()).Premultiply(); return ColorSourceContents::DrawPositions( - renderer, entity, pass, &ContentContext::GetSolidFillPipeline, frame_info, - [](RenderPass& pass) { - pass.SetCommandLabel("Solid Fill"); - return true; - }); + renderer, entity, pass, &ContentContext::GetSolidFillPipeline, + frame_info); +} + +bool SolidColorContents::BindFragmentCallback(RenderPass& pass) const { + pass.SetCommandLabel("Solid Fill"); + return true; } std::unique_ptr SolidColorContents::Make(const Path& path, diff --git a/impeller/entity/contents/solid_color_contents.h b/impeller/entity/contents/solid_color_contents.h index 59358ac68f3f4..e8994dbc7c36d 100644 --- a/impeller/entity/contents/solid_color_contents.h +++ b/impeller/entity/contents/solid_color_contents.h @@ -53,6 +53,9 @@ class SolidColorContents final : public ColorSourceContents { const ColorFilterProc& color_filter_proc) override; private: + // |ColorSourceContents| + bool BindFragmentCallback(RenderPass& pass) const override; + Color color_; SolidColorContents(const SolidColorContents&) = delete; From 7d5cd10394216c0f3d6ef7eec87f12573f93a925 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Thu, 8 Feb 2024 12:43:42 -0800 Subject: [PATCH 04/16] Revert "jonah review" This reverts commit e4f5235af8c032a08d913e5befa0d41ee840eec9. --- .../entity/contents/color_source_contents.cc | 4 --- .../entity/contents/color_source_contents.h | 33 +++++++++++-------- .../entity/contents/solid_color_contents.cc | 12 +++---- .../entity/contents/solid_color_contents.h | 3 -- 4 files changed, 24 insertions(+), 28 deletions(-) diff --git a/impeller/entity/contents/color_source_contents.cc b/impeller/entity/contents/color_source_contents.cc index 9924ba806d9af..18bc16608a037 100644 --- a/impeller/entity/contents/color_source_contents.cc +++ b/impeller/entity/contents/color_source_contents.cc @@ -54,8 +54,4 @@ void ColorSourceContents::SetInheritedOpacity(Scalar opacity) { inherited_opacity_ = opacity; } -bool ColorSourceContents::BindFragmentCallback(RenderPass& pass) const { - return true; -} - } // namespace impeller diff --git a/impeller/entity/contents/color_source_contents.h b/impeller/entity/contents/color_source_contents.h index fdffff2b3fb00..2732b417169eb 100644 --- a/impeller/entity/contents/color_source_contents.h +++ b/impeller/entity/contents/color_source_contents.h @@ -102,8 +102,7 @@ class ColorSourceContents : public Contents { void SetInheritedOpacity(Scalar opacity) override; protected: - virtual bool BindFragmentCallback(RenderPass& pass) const; - + using BindFragmentCallback = std::function; using PipelineBuilderMethod = std::shared_ptr> ( impeller::ContentContext::*)(ContentContextOptions) const; @@ -113,7 +112,8 @@ class ColorSourceContents : public Contents { const Entity& entity, RenderPass& pass, const PipelineBuilderMethod& pipeline_builder, - typename VertexShaderT::FrameInfo frame_info) const { + typename VertexShaderT::FrameInfo frame_info, + const BindFragmentCallback& bind_pipeline_callback) const { auto options = OptionsFromPassAndEntity(pass, entity); // If overdraw prevention is enabled (like when drawing stroke paths), we @@ -138,7 +138,7 @@ class ColorSourceContents : public Contents { (renderer.*pipeline_builder)(options); pass.SetPipeline(pipeline); - if (!BindFragmentCallback(pass)) { + if (!bind_pipeline_callback(pass)) { return false; } @@ -162,27 +162,32 @@ class ColorSourceContents : public Contents { const Entity& entity, RenderPass& pass, const PipelineBuilderMethod& pipeline_builder, - typename VertexShaderT::FrameInfo frame_info) const { + typename VertexShaderT::FrameInfo frame_info, + const BindFragmentCallback& bind_pipeline_callback) const { auto geometry_result = GetGeometry()->GetPositionBuffer(renderer, entity, pass); return DrawGeometry(geometry_result, renderer, entity, pass, - pipeline_builder, frame_info); + pipeline_builder, frame_info, + bind_pipeline_callback); } template - bool DrawPositionsAndUVs(Rect texture_coverage, - const Matrix& effect_transform, - const ContentContext& renderer, - const Entity& entity, - RenderPass& pass, - const PipelineBuilderMethod& pipeline_builder, - typename VertexShaderT::FrameInfo frame_info) const { + bool DrawPositionsAndUVs( + Rect texture_coverage, + Matrix effect_transform, + const ContentContext& renderer, + const Entity& entity, + RenderPass& pass, + const PipelineBuilderMethod& pipeline_builder, + typename VertexShaderT::FrameInfo frame_info, + const BindFragmentCallback& bind_pipeline_callback) const { auto geometry_result = GetGeometry()->GetPositionUVBuffer( texture_coverage, effect_transform, renderer, entity, pass); return DrawGeometry(geometry_result, renderer, entity, pass, - pipeline_builder, frame_info); + pipeline_builder, frame_info, + bind_pipeline_callback); } private: diff --git a/impeller/entity/contents/solid_color_contents.cc b/impeller/entity/contents/solid_color_contents.cc index 7f3df05e0791c..61476d660a970 100644 --- a/impeller/entity/contents/solid_color_contents.cc +++ b/impeller/entity/contents/solid_color_contents.cc @@ -55,13 +55,11 @@ bool SolidColorContents::Render(const ContentContext& renderer, frame_info.color = capture.AddColor("Color", GetColor()).Premultiply(); return ColorSourceContents::DrawPositions( - renderer, entity, pass, &ContentContext::GetSolidFillPipeline, - frame_info); -} - -bool SolidColorContents::BindFragmentCallback(RenderPass& pass) const { - pass.SetCommandLabel("Solid Fill"); - return true; + renderer, entity, pass, &ContentContext::GetSolidFillPipeline, frame_info, + [](RenderPass& pass) { + pass.SetCommandLabel("Solid Fill"); + return true; + }); } std::unique_ptr SolidColorContents::Make(const Path& path, diff --git a/impeller/entity/contents/solid_color_contents.h b/impeller/entity/contents/solid_color_contents.h index e8994dbc7c36d..59358ac68f3f4 100644 --- a/impeller/entity/contents/solid_color_contents.h +++ b/impeller/entity/contents/solid_color_contents.h @@ -53,9 +53,6 @@ class SolidColorContents final : public ColorSourceContents { const ColorFilterProc& color_filter_proc) override; private: - // |ColorSourceContents| - bool BindFragmentCallback(RenderPass& pass) const override; - Color color_; SolidColorContents(const SolidColorContents&) = delete; From 7a230e80652e5eb6bb856bda813d8506b6bb6546 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Thu, 8 Feb 2024 12:45:37 -0800 Subject: [PATCH 05/16] jonah review --- impeller/entity/contents/color_source_contents.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/impeller/entity/contents/color_source_contents.h b/impeller/entity/contents/color_source_contents.h index 2732b417169eb..464cda04ef021 100644 --- a/impeller/entity/contents/color_source_contents.h +++ b/impeller/entity/contents/color_source_contents.h @@ -175,7 +175,7 @@ class ColorSourceContents : public Contents { template bool DrawPositionsAndUVs( Rect texture_coverage, - Matrix effect_transform, + const Matrix& effect_transform, const ContentContext& renderer, const Entity& entity, RenderPass& pass, From fc6be291e1015c5e5752e9d8dbb1818c101ae617 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Thu, 8 Feb 2024 13:32:33 -0800 Subject: [PATCH 06/16] renames and comments --- impeller/entity/contents/color_source_contents.h | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/impeller/entity/contents/color_source_contents.h b/impeller/entity/contents/color_source_contents.h index 464cda04ef021..1a8f64d116ab9 100644 --- a/impeller/entity/contents/color_source_contents.h +++ b/impeller/entity/contents/color_source_contents.h @@ -113,7 +113,7 @@ class ColorSourceContents : public Contents { RenderPass& pass, const PipelineBuilderMethod& pipeline_builder, typename VertexShaderT::FrameInfo frame_info, - const BindFragmentCallback& bind_pipeline_callback) const { + const BindFragmentCallback& bind_fragment_callback) const { auto options = OptionsFromPassAndEntity(pass, entity); // If overdraw prevention is enabled (like when drawing stroke paths), we @@ -128,6 +128,8 @@ class ColorSourceContents : public Contents { pass.SetVertexBuffer(std::move(geometry_result.vertex_buffer)); pass.SetStencilReference(entity.GetClipDepth()); + // Take the pre-populated vertex shader uniform struct and set managed + // values. frame_info.depth = entity.GetShaderClipDepth(); frame_info.mvp = geometry_result.transform; @@ -138,7 +140,11 @@ class ColorSourceContents : public Contents { (renderer.*pipeline_builder)(options); pass.SetPipeline(pipeline); - if (!bind_pipeline_callback(pass)) { + // The reason we need to have a callback mechanism here is that this routine + // may insert draw calls before the main draw call below. For example, for + // sufficiently complex paths we may opt to use stencil-then-cover to avoid + // tessellation. + if (!bind_fragment_callback(pass)) { return false; } From 3b0f19ffd6d1adc0873589dfb349176e07d12e46 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Thu, 8 Feb 2024 13:52:41 -0800 Subject: [PATCH 07/16] Adopt LinearGradientContents --- .../contents/linear_gradient_contents.cc | 164 +++++++----------- 1 file changed, 63 insertions(+), 101 deletions(-) diff --git a/impeller/entity/contents/linear_gradient_contents.cc b/impeller/entity/contents/linear_gradient_contents.cc index cb319b327f43a..0057f76f52a4d 100644 --- a/impeller/entity/contents/linear_gradient_contents.cc +++ b/impeller/entity/contents/linear_gradient_contents.cc @@ -69,64 +69,45 @@ bool LinearGradientContents::RenderTexture(const ContentContext& renderer, using VS = LinearGradientFillPipeline::VertexShader; using FS = LinearGradientFillPipeline::FragmentShader; - auto gradient_data = CreateGradientBuffer(colors_, stops_); - auto gradient_texture = - CreateGradientTexture(gradient_data, renderer.GetContext()); - if (gradient_texture == nullptr) { - return false; - } - - FS::FragInfo frag_info; - frag_info.start_point = start_point_; - frag_info.end_point = end_point_; - frag_info.tile_mode = static_cast(tile_mode_); - frag_info.decal_border_color = decal_border_color_; - frag_info.texture_sampler_y_coord_scale = gradient_texture->GetYCoordScale(); - frag_info.alpha = GetOpacityFactor(); - frag_info.half_texel = Vector2(0.5 / gradient_texture->GetSize().width, - 0.5 / gradient_texture->GetSize().height); - - auto geometry_result = - GetGeometry()->GetPositionBuffer(renderer, entity, pass); - VS::FrameInfo frame_info; - frame_info.depth = entity.GetShaderClipDepth(); - frame_info.mvp = geometry_result.transform; frame_info.matrix = GetInverseEffectTransform(); - auto options = OptionsFromPassAndEntity(pass, entity); - if (geometry_result.prevent_overdraw) { - options.stencil_mode = - ContentContextOptions::StencilMode::kLegacyClipIncrement; - } - options.primitive_type = geometry_result.type; - - SamplerDescriptor sampler_desc; - sampler_desc.min_filter = MinMagFilter::kLinear; - sampler_desc.mag_filter = MinMagFilter::kLinear; - - pass.SetCommandLabel("LinearGradientFill"); - pass.SetStencilReference(entity.GetClipDepth()); - pass.SetPipeline(renderer.GetLinearGradientFillPipeline(options)); - pass.SetVertexBuffer(std::move(geometry_result.vertex_buffer)); - FS::BindTextureSampler( - pass, std::move(gradient_texture), - renderer.GetContext()->GetSamplerLibrary()->GetSampler(sampler_desc)); - VS::BindFrameInfo(pass, - renderer.GetTransientsBuffer().EmplaceUniform(frame_info)); - FS::BindFragInfo(pass, - renderer.GetTransientsBuffer().EmplaceUniform(frag_info)); - - if (!pass.Draw().ok()) { - return false; - } - - if (geometry_result.prevent_overdraw) { - auto restore = ClipRestoreContents(); - restore.SetRestoreCoverage(GetCoverage(entity)); - return restore.Render(renderer, entity, pass); - } - return true; + return ColorSourceContents::DrawPositions( + renderer, entity, pass, &ContentContext::GetLinearGradientFillPipeline, + frame_info, [this, &renderer](RenderPass& pass) { + auto gradient_data = CreateGradientBuffer(colors_, stops_); + auto gradient_texture = + CreateGradientTexture(gradient_data, renderer.GetContext()); + if (gradient_texture == nullptr) { + return false; + } + + FS::FragInfo frag_info; + frag_info.start_point = start_point_; + frag_info.end_point = end_point_; + frag_info.tile_mode = static_cast(tile_mode_); + frag_info.decal_border_color = decal_border_color_; + frag_info.texture_sampler_y_coord_scale = + gradient_texture->GetYCoordScale(); + frag_info.alpha = GetOpacityFactor(); + frag_info.half_texel = + Vector2(0.5 / gradient_texture->GetSize().width, + 0.5 / gradient_texture->GetSize().height); + + pass.SetCommandLabel("LinearGradientFill"); + + SamplerDescriptor sampler_desc; + sampler_desc.min_filter = MinMagFilter::kLinear; + sampler_desc.mag_filter = MinMagFilter::kLinear; + + FS::BindTextureSampler( + pass, std::move(gradient_texture), + renderer.GetContext()->GetSamplerLibrary()->GetSampler( + sampler_desc)); + FS::BindFragInfo( + pass, renderer.GetTransientsBuffer().EmplaceUniform(frag_info)); + return true; + }); } bool LinearGradientContents::RenderSSBO(const ContentContext& renderer, @@ -135,55 +116,36 @@ bool LinearGradientContents::RenderSSBO(const ContentContext& renderer, using VS = LinearGradientSSBOFillPipeline::VertexShader; using FS = LinearGradientSSBOFillPipeline::FragmentShader; - FS::FragInfo frag_info; - frag_info.start_point = start_point_; - frag_info.end_point = end_point_; - frag_info.tile_mode = static_cast(tile_mode_); - frag_info.decal_border_color = decal_border_color_; - frag_info.alpha = GetOpacityFactor(); - - auto& host_buffer = renderer.GetTransientsBuffer(); - auto colors = CreateGradientColors(colors_, stops_); - - frag_info.colors_length = colors.size(); - auto color_buffer = - host_buffer.Emplace(colors.data(), colors.size() * sizeof(StopData), - DefaultUniformAlignment()); - VS::FrameInfo frame_info; - frame_info.depth = entity.GetShaderClipDepth(); - frame_info.mvp = pass.GetOrthographicTransform() * entity.GetTransform(); frame_info.matrix = GetInverseEffectTransform(); - auto geometry_result = - GetGeometry()->GetPositionBuffer(renderer, entity, pass); - auto options = OptionsFromPassAndEntity(pass, entity); - if (geometry_result.prevent_overdraw) { - options.stencil_mode = - ContentContextOptions::StencilMode::kLegacyClipIncrement; - } - options.primitive_type = geometry_result.type; - - pass.SetCommandLabel("LinearGradientSSBOFill"); - pass.SetStencilReference(entity.GetClipDepth()); - pass.SetPipeline(renderer.GetLinearGradientSSBOFillPipeline(options)); - pass.SetVertexBuffer(std::move(geometry_result.vertex_buffer)); - FS::BindFragInfo(pass, - renderer.GetTransientsBuffer().EmplaceUniform(frag_info)); - FS::BindColorData(pass, color_buffer); - VS::BindFrameInfo(pass, - renderer.GetTransientsBuffer().EmplaceUniform(frame_info)); - - if (!pass.Draw().ok()) { - return false; - } - - if (geometry_result.prevent_overdraw) { - auto restore = ClipRestoreContents(); - restore.SetRestoreCoverage(GetCoverage(entity)); - return restore.Render(renderer, entity, pass); - } - return true; + return ColorSourceContents::DrawPositions( + renderer, entity, pass, + &ContentContext::GetLinearGradientSSBOFillPipeline, frame_info, + [this, &renderer](RenderPass& pass) { + FS::FragInfo frag_info; + frag_info.start_point = start_point_; + frag_info.end_point = end_point_; + frag_info.tile_mode = static_cast(tile_mode_); + frag_info.decal_border_color = decal_border_color_; + frag_info.alpha = GetOpacityFactor(); + + auto& host_buffer = renderer.GetTransientsBuffer(); + auto colors = CreateGradientColors(colors_, stops_); + + frag_info.colors_length = colors.size(); + auto color_buffer = + host_buffer.Emplace(colors.data(), colors.size() * sizeof(StopData), + DefaultUniformAlignment()); + + pass.SetCommandLabel("LinearGradientSSBOFill"); + + FS::BindFragInfo( + pass, renderer.GetTransientsBuffer().EmplaceUniform(frag_info)); + FS::BindColorData(pass, color_buffer); + + return true; + }); } bool LinearGradientContents::ApplyColorFilter( From 5c80aff4cb4b71a483d1b651079338c69cf1fcc3 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Thu, 8 Feb 2024 14:52:39 -0800 Subject: [PATCH 08/16] Migrate TiledTextureContents --- .../entity/contents/tiled_texture_contents.cc | 156 ++++++++---------- 1 file changed, 70 insertions(+), 86 deletions(-) diff --git a/impeller/entity/contents/tiled_texture_contents.cc b/impeller/entity/contents/tiled_texture_contents.cc index 732e27ec25d20..8e80546b4fc05 100644 --- a/impeller/entity/contents/tiled_texture_contents.cc +++ b/impeller/entity/contents/tiled_texture_contents.cc @@ -129,107 +129,91 @@ bool TiledTextureContents::Render(const ContentContext& renderer, bool is_external_texture = texture_->GetTextureDescriptor().type == TextureType::kTextureExternalOES; - auto& host_buffer = renderer.GetTransientsBuffer(); - - auto geometry_result = GetGeometry()->GetPositionUVBuffer( - Rect::MakeSize(texture_size), GetInverseEffectTransform(), renderer, - entity, pass); bool uses_emulated_tile_mode = UsesEmulatedTileMode(renderer.GetDeviceCapabilities()); VS::FrameInfo frame_info; - frame_info.depth = entity.GetShaderClipDepth(); - frame_info.mvp = geometry_result.transform; frame_info.texture_sampler_y_coord_scale = texture_->GetYCoordScale(); frame_info.alpha = GetOpacityFactor(); - if (uses_emulated_tile_mode) { - pass.SetCommandLabel("TiledTextureFill"); - } else { - pass.SetCommandLabel("TextureFill"); - } - - pass.SetStencilReference(entity.GetClipDepth()); - - auto options = OptionsFromPassAndEntity(pass, entity); - if (geometry_result.prevent_overdraw) { - options.stencil_mode = - ContentContextOptions::StencilMode::kLegacyClipIncrement; - } - options.primitive_type = geometry_result.type; + PipelineBuilderMethod pipeline_builder; #ifdef IMPELLER_ENABLE_OPENGLES if (is_external_texture) { - pass.SetPipeline(renderer.GetTiledTextureExternalPipeline(options)); + pipeline_builder = &ContentContext::GetTiledTextureExternalPipeline; } else { - pass.SetPipeline(uses_emulated_tile_mode - ? renderer.GetTiledTexturePipeline(options) - : renderer.GetTexturePipeline(options)); + pipeline_builder = uses_emulated_tile_mode + ? &ContentContext::GetTiledTexturePipeline + : &ContentContext::GetTexturePipeline; } #else - pass.SetPipeline(uses_emulated_tile_mode - ? renderer.GetTiledTexturePipeline(options) - : renderer.GetTexturePipeline(options)); + pipeline_builder = uses_emulated_tile_mode + ? &ContentContext::GetTiledTexturePipeline + : &ContentContext::GetTexturePipeline; #endif // IMPELLER_ENABLE_OPENGLES - pass.SetVertexBuffer(std::move(geometry_result.vertex_buffer)); - VS::BindFrameInfo(pass, host_buffer.EmplaceUniform(frame_info)); - - if (is_external_texture) { - FSExternal::FragInfo frag_info; - frag_info.x_tile_mode = static_cast(x_tile_mode_); - frag_info.y_tile_mode = static_cast(y_tile_mode_); - FSExternal::BindFragInfo(pass, host_buffer.EmplaceUniform(frag_info)); - } else if (uses_emulated_tile_mode) { - FS::FragInfo frag_info; - frag_info.x_tile_mode = static_cast(x_tile_mode_); - frag_info.y_tile_mode = static_cast(y_tile_mode_); - FS::BindFragInfo(pass, host_buffer.EmplaceUniform(frag_info)); - } - - if (is_external_texture) { - SamplerDescriptor sampler_desc; - // OES_EGL_image_external states that only CLAMP_TO_EDGE is valid, so we - // emulate all other tile modes here by remapping the texture coordinates. - sampler_desc.width_address_mode = SamplerAddressMode::kClampToEdge; - sampler_desc.height_address_mode = SamplerAddressMode::kClampToEdge; - - // Also, external textures cannot be bound to color filters, so ignore this - // case for now. - FML_DCHECK(!color_filter_) - << "Color filters are not currently supported for external textures."; - - FSExternal::BindSAMPLEREXTERNALOESTextureSampler( - pass, texture_, - renderer.GetContext()->GetSamplerLibrary()->GetSampler(sampler_desc)); - } else { - if (color_filter_) { - auto filtered_texture = CreateFilterTexture(renderer); - if (!filtered_texture) { - return false; - } - FS::BindTextureSampler( - pass, filtered_texture, - renderer.GetContext()->GetSamplerLibrary()->GetSampler( - CreateSamplerDescriptor(renderer.GetDeviceCapabilities()))); - } else { - FS::BindTextureSampler( - pass, texture_, - renderer.GetContext()->GetSamplerLibrary()->GetSampler( - CreateSamplerDescriptor(renderer.GetDeviceCapabilities()))); - } - } - - if (!pass.Draw().ok()) { - return false; - } - - if (geometry_result.prevent_overdraw) { - auto restore = ClipRestoreContents(); - restore.SetRestoreCoverage(GetCoverage(entity)); - return restore.Render(renderer, entity, pass); - } - return true; + return ColorSourceContents::DrawPositionsAndUVs( + Rect::MakeSize(texture_size), GetInverseEffectTransform(), renderer, + entity, pass, pipeline_builder, frame_info, + [this, &renderer, &is_external_texture, + &uses_emulated_tile_mode](RenderPass& pass) { + auto& host_buffer = renderer.GetTransientsBuffer(); + + if (uses_emulated_tile_mode) { + pass.SetCommandLabel("TiledTextureFill"); + } else { + pass.SetCommandLabel("TextureFill"); + } + + if (is_external_texture) { + FSExternal::FragInfo frag_info; + frag_info.x_tile_mode = static_cast(x_tile_mode_); + frag_info.y_tile_mode = static_cast(y_tile_mode_); + FSExternal::BindFragInfo(pass, host_buffer.EmplaceUniform(frag_info)); + } else if (uses_emulated_tile_mode) { + FS::FragInfo frag_info; + frag_info.x_tile_mode = static_cast(x_tile_mode_); + frag_info.y_tile_mode = static_cast(y_tile_mode_); + FS::BindFragInfo(pass, host_buffer.EmplaceUniform(frag_info)); + } + + if (is_external_texture) { + SamplerDescriptor sampler_desc; + // OES_EGL_image_external states that only CLAMP_TO_EDGE is valid, so + // we emulate all other tile modes here by remapping the texture + // coordinates. + sampler_desc.width_address_mode = SamplerAddressMode::kClampToEdge; + sampler_desc.height_address_mode = SamplerAddressMode::kClampToEdge; + + // Also, external textures cannot be bound to color filters, so ignore + // this case for now. + FML_DCHECK(!color_filter_) << "Color filters are not currently " + "supported for external textures."; + + FSExternal::BindSAMPLEREXTERNALOESTextureSampler( + pass, texture_, + renderer.GetContext()->GetSamplerLibrary()->GetSampler( + sampler_desc)); + } else { + if (color_filter_) { + auto filtered_texture = CreateFilterTexture(renderer); + if (!filtered_texture) { + return false; + } + FS::BindTextureSampler( + pass, filtered_texture, + renderer.GetContext()->GetSamplerLibrary()->GetSampler( + CreateSamplerDescriptor(renderer.GetDeviceCapabilities()))); + } else { + FS::BindTextureSampler( + pass, texture_, + renderer.GetContext()->GetSamplerLibrary()->GetSampler( + CreateSamplerDescriptor(renderer.GetDeviceCapabilities()))); + } + } + + return true; + }); } std::optional TiledTextureContents::RenderToSnapshot( From 66072d1ed592a6567ebb0a86b87bde321ab00ffd Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Thu, 8 Feb 2024 16:24:11 -0800 Subject: [PATCH 09/16] Use callback for pipeline --- impeller/entity/contents/color_source_contents.h | 15 +++++++++------ .../entity/contents/linear_gradient_contents.cc | 15 +++++++++++---- impeller/entity/contents/solid_color_contents.cc | 6 +++++- .../entity/contents/tiled_texture_contents.cc | 16 ++++++++++------ 4 files changed, 35 insertions(+), 17 deletions(-) diff --git a/impeller/entity/contents/color_source_contents.h b/impeller/entity/contents/color_source_contents.h index 1a8f64d116ab9..5f83c9035b32f 100644 --- a/impeller/entity/contents/color_source_contents.h +++ b/impeller/entity/contents/color_source_contents.h @@ -105,13 +105,16 @@ class ColorSourceContents : public Contents { using BindFragmentCallback = std::function; using PipelineBuilderMethod = std::shared_ptr> ( impeller::ContentContext::*)(ContentContextOptions) const; + using PipelineBuilderCallback = + std::function>( + ContentContextOptions)>; template bool DrawGeometry(GeometryResult geometry_result, const ContentContext& renderer, const Entity& entity, RenderPass& pass, - const PipelineBuilderMethod& pipeline_builder, + const PipelineBuilderCallback& pipeline_callback, typename VertexShaderT::FrameInfo frame_info, const BindFragmentCallback& bind_fragment_callback) const { auto options = OptionsFromPassAndEntity(pass, entity); @@ -137,7 +140,7 @@ class ColorSourceContents : public Contents { pass, renderer.GetTransientsBuffer().EmplaceUniform(frame_info)); std::shared_ptr> pipeline = - (renderer.*pipeline_builder)(options); + pipeline_callback(options); pass.SetPipeline(pipeline); // The reason we need to have a callback mechanism here is that this routine @@ -167,14 +170,14 @@ class ColorSourceContents : public Contents { bool DrawPositions(const ContentContext& renderer, const Entity& entity, RenderPass& pass, - const PipelineBuilderMethod& pipeline_builder, + const PipelineBuilderCallback& pipeline_callback, typename VertexShaderT::FrameInfo frame_info, const BindFragmentCallback& bind_pipeline_callback) const { auto geometry_result = GetGeometry()->GetPositionBuffer(renderer, entity, pass); return DrawGeometry(geometry_result, renderer, entity, pass, - pipeline_builder, frame_info, + pipeline_callback, frame_info, bind_pipeline_callback); } @@ -185,14 +188,14 @@ class ColorSourceContents : public Contents { const ContentContext& renderer, const Entity& entity, RenderPass& pass, - const PipelineBuilderMethod& pipeline_builder, + const PipelineBuilderCallback& pipeline_callback, typename VertexShaderT::FrameInfo frame_info, const BindFragmentCallback& bind_pipeline_callback) const { auto geometry_result = GetGeometry()->GetPositionUVBuffer( texture_coverage, effect_transform, renderer, entity, pass); return DrawGeometry(geometry_result, renderer, entity, pass, - pipeline_builder, frame_info, + pipeline_callback, frame_info, bind_pipeline_callback); } diff --git a/impeller/entity/contents/linear_gradient_contents.cc b/impeller/entity/contents/linear_gradient_contents.cc index 0057f76f52a4d..10a2a3853bdca 100644 --- a/impeller/entity/contents/linear_gradient_contents.cc +++ b/impeller/entity/contents/linear_gradient_contents.cc @@ -72,9 +72,13 @@ bool LinearGradientContents::RenderTexture(const ContentContext& renderer, VS::FrameInfo frame_info; frame_info.matrix = GetInverseEffectTransform(); + PipelineBuilderCallback pipeline_callback = + [&renderer](ContentContextOptions options) { + return renderer.GetLinearGradientFillPipeline(options); + }; return ColorSourceContents::DrawPositions( - renderer, entity, pass, &ContentContext::GetLinearGradientFillPipeline, - frame_info, [this, &renderer](RenderPass& pass) { + renderer, entity, pass, pipeline_callback, frame_info, + [this, &renderer](RenderPass& pass) { auto gradient_data = CreateGradientBuffer(colors_, stops_); auto gradient_texture = CreateGradientTexture(gradient_data, renderer.GetContext()); @@ -119,9 +123,12 @@ bool LinearGradientContents::RenderSSBO(const ContentContext& renderer, VS::FrameInfo frame_info; frame_info.matrix = GetInverseEffectTransform(); + PipelineBuilderCallback pipeline_callback = + [&renderer](ContentContextOptions options) { + return renderer.GetLinearGradientSSBOFillPipeline(options); + }; return ColorSourceContents::DrawPositions( - renderer, entity, pass, - &ContentContext::GetLinearGradientSSBOFillPipeline, frame_info, + renderer, entity, pass, pipeline_callback, frame_info, [this, &renderer](RenderPass& pass) { FS::FragInfo frag_info; frag_info.start_point = start_point_; diff --git a/impeller/entity/contents/solid_color_contents.cc b/impeller/entity/contents/solid_color_contents.cc index 61476d660a970..a8b46e297052e 100644 --- a/impeller/entity/contents/solid_color_contents.cc +++ b/impeller/entity/contents/solid_color_contents.cc @@ -54,8 +54,12 @@ bool SolidColorContents::Render(const ContentContext& renderer, VS::FrameInfo frame_info; frame_info.color = capture.AddColor("Color", GetColor()).Premultiply(); + PipelineBuilderCallback pipeline_callback = + [&renderer](ContentContextOptions options) { + return renderer.GetSolidFillPipeline(options); + }; return ColorSourceContents::DrawPositions( - renderer, entity, pass, &ContentContext::GetSolidFillPipeline, frame_info, + renderer, entity, pass, pipeline_callback, frame_info, [](RenderPass& pass) { pass.SetCommandLabel("Solid Fill"); return true; diff --git a/impeller/entity/contents/tiled_texture_contents.cc b/impeller/entity/contents/tiled_texture_contents.cc index 8e80546b4fc05..a468927c5c38e 100644 --- a/impeller/entity/contents/tiled_texture_contents.cc +++ b/impeller/entity/contents/tiled_texture_contents.cc @@ -136,15 +136,15 @@ bool TiledTextureContents::Render(const ContentContext& renderer, frame_info.texture_sampler_y_coord_scale = texture_->GetYCoordScale(); frame_info.alpha = GetOpacityFactor(); - PipelineBuilderMethod pipeline_builder; + PipelineBuilderMethod pipeline_method; #ifdef IMPELLER_ENABLE_OPENGLES if (is_external_texture) { - pipeline_builder = &ContentContext::GetTiledTextureExternalPipeline; + pipeline_method = &ContentContext::GetTiledTextureExternalPipeline; } else { - pipeline_builder = uses_emulated_tile_mode - ? &ContentContext::GetTiledTexturePipeline - : &ContentContext::GetTexturePipeline; + pipeline_method = uses_emulated_tile_mode + ? &ContentContext::GetTiledTexturePipeline + : &ContentContext::GetTexturePipeline; } #else pipeline_builder = uses_emulated_tile_mode @@ -152,9 +152,13 @@ bool TiledTextureContents::Render(const ContentContext& renderer, : &ContentContext::GetTexturePipeline; #endif // IMPELLER_ENABLE_OPENGLES + PipelineBuilderCallback pipeline_callback = + [&renderer, &pipeline_method](ContentContextOptions options) { + return (renderer.*pipeline_method)(options); + }; return ColorSourceContents::DrawPositionsAndUVs( Rect::MakeSize(texture_size), GetInverseEffectTransform(), renderer, - entity, pass, pipeline_builder, frame_info, + entity, pass, pipeline_callback, frame_info, [this, &renderer, &is_external_texture, &uses_emulated_tile_mode](RenderPass& pass) { auto& host_buffer = renderer.GetTransientsBuffer(); From 5bd771abca399acd494b17df81745da5934f99ea Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Thu, 8 Feb 2024 18:26:53 -0800 Subject: [PATCH 10/16] Migrate RuntimeEffectContents --- .../contents/linear_gradient_contents.cc | 1 - .../contents/runtime_effect_contents.cc | 329 +++++++++--------- .../entity/contents/tiled_texture_contents.cc | 2 - 3 files changed, 156 insertions(+), 176 deletions(-) diff --git a/impeller/entity/contents/linear_gradient_contents.cc b/impeller/entity/contents/linear_gradient_contents.cc index 10a2a3853bdca..8b7f8ad0bc9f8 100644 --- a/impeller/entity/contents/linear_gradient_contents.cc +++ b/impeller/entity/contents/linear_gradient_contents.cc @@ -5,7 +5,6 @@ #include "linear_gradient_contents.h" #include "impeller/core/formats.h" -#include "impeller/entity/contents/clip_contents.h" #include "impeller/entity/contents/content_context.h" #include "impeller/entity/contents/gradient_generator.h" #include "impeller/entity/entity.h" diff --git a/impeller/entity/contents/runtime_effect_contents.cc b/impeller/entity/contents/runtime_effect_contents.cc index 75eedb80939fb..d51b89bf9e94e 100644 --- a/impeller/entity/contents/runtime_effect_contents.cc +++ b/impeller/entity/contents/runtime_effect_contents.cc @@ -13,7 +13,6 @@ #include "impeller/core/formats.h" #include "impeller/core/runtime_types.h" #include "impeller/core/shader_types.h" -#include "impeller/entity/contents/clip_contents.h" #include "impeller/entity/contents/content_context.h" #include "impeller/entity/runtime_effect.vert.h" #include "impeller/renderer/capabilities.h" @@ -82,18 +81,9 @@ bool RuntimeEffectContents::Render(const ContentContext& renderer, runtime_stage_->GetEntrypoint(), ShaderStage::kFragment); //-------------------------------------------------------------------------- - /// Resolve geometry and content context options. + /// Resolve runtime stage function. /// - auto geometry_result = - GetGeometry()->GetPositionBuffer(renderer, entity, pass); - auto options = OptionsFromPassAndEntity(pass, entity); - if (geometry_result.prevent_overdraw) { - options.stencil_mode = - ContentContextOptions::StencilMode::kLegacyClipIncrement; - } - options.primitive_type = geometry_result.type; - if (function && runtime_stage_->IsDirty()) { renderer.ClearCachedRuntimeEffectPipeline(runtime_stage_->GetEntrypoint()); context->GetPipelineLibrary()->RemovePipelinesWithEntryPoint(function); @@ -145,194 +135,187 @@ bool RuntimeEffectContents::Render(const ContentContext& renderer, using VS = RuntimeEffectVertexShader; - pass.SetCommandLabel("RuntimeEffectContents"); - pass.SetStencilReference(entity.GetClipDepth()); - pass.SetVertexBuffer(std::move(geometry_result.vertex_buffer)); - - //-------------------------------------------------------------------------- - /// Vertex stage uniforms. - /// - - VS::FrameInfo frame_info; - frame_info.depth = entity.GetShaderClipDepth(); - frame_info.mvp = geometry_result.transform; - VS::BindFrameInfo(pass, - renderer.GetTransientsBuffer().EmplaceUniform(frame_info)); - //-------------------------------------------------------------------------- /// Fragment stage uniforms. /// - size_t minimum_sampler_index = 100000000; - size_t buffer_index = 0; - size_t buffer_offset = 0; - std::vector descriptor_set_layouts; - for (const auto& uniform : runtime_stage_->GetUniforms()) { - std::shared_ptr metadata = MakeShaderMetadata(uniform); - - switch (uniform.type) { - case kSampledImage: { - // Sampler uniforms are ordered in the IPLR according to their - // declaration and the uniform location reflects the correct offset to - // be mapped to - except that it may include all proceeding float - // uniforms. For example, a float sampler that comes after 4 float - // uniforms may have a location of 4. To convert to the actual offset we - // need to find the largest location assigned to a float uniform and - // then subtract this from all uniform locations. This is more or less - // the same operation we previously performed in the shader compiler. - minimum_sampler_index = - std::min(minimum_sampler_index, uniform.location); - break; - } - case kFloat: { - FML_DCHECK(renderer.GetContext()->GetBackendType() != - Context::BackendType::kVulkan) - << "Uniform " << uniform.name - << " had unexpected type kFloat for Vulkan backend."; - size_t alignment = - std::max(uniform.bit_width / 8, DefaultUniformAlignment()); - auto buffer_view = renderer.GetTransientsBuffer().Emplace( - uniform_data_->data() + buffer_offset, uniform.GetSize(), - alignment); - - ShaderUniformSlot uniform_slot; - uniform_slot.name = uniform.name.c_str(); - uniform_slot.ext_res_0 = uniform.location; - pass.BindResource(ShaderStage::kFragment, - DescriptorType::kUniformBuffer, uniform_slot, - metadata, buffer_view); - buffer_index++; - buffer_offset += uniform.GetSize(); - break; - } - case kStruct: { - FML_DCHECK(renderer.GetContext()->GetBackendType() == - Context::BackendType::kVulkan); - descriptor_set_layouts.emplace_back(DescriptorSetLayout{ - static_cast(uniform.location), - DescriptorType::kUniformBuffer, - ShaderStage::kFragment, - }); - ShaderUniformSlot uniform_slot; - uniform_slot.name = uniform.name.c_str(); - uniform_slot.binding = uniform.location; - - std::vector uniform_buffer; - uniform_buffer.reserve(uniform.struct_layout.size()); - size_t uniform_byte_index = 0u; - for (const auto& byte_type : uniform.struct_layout) { - if (byte_type == 0) { - uniform_buffer.push_back(0.f); - } else if (byte_type == 1) { - uniform_buffer.push_back(reinterpret_cast( - uniform_data_->data())[uniform_byte_index++]); - } else { - FML_UNREACHABLE(); - } + BindFragmentCallback bind_callback = [this, &renderer, &context, + &descriptor_set_layouts]( + RenderPass& pass) { + size_t minimum_sampler_index = 100000000; + size_t buffer_index = 0; + size_t buffer_offset = 0; + + for (const auto& uniform : runtime_stage_->GetUniforms()) { + std::shared_ptr metadata = MakeShaderMetadata(uniform); + + switch (uniform.type) { + case kSampledImage: { + // Sampler uniforms are ordered in the IPLR according to their + // declaration and the uniform location reflects the correct offset to + // be mapped to - except that it may include all proceeding float + // uniforms. For example, a float sampler that comes after 4 float + // uniforms may have a location of 4. To convert to the actual offset + // we need to find the largest location assigned to a float uniform + // and then subtract this from all uniform locations. This is more or + // less the same operation we previously performed in the shader + // compiler. + minimum_sampler_index = + std::min(minimum_sampler_index, uniform.location); + break; } + case kFloat: { + FML_DCHECK(renderer.GetContext()->GetBackendType() != + Context::BackendType::kVulkan) + << "Uniform " << uniform.name + << " had unexpected type kFloat for Vulkan backend."; + size_t alignment = + std::max(uniform.bit_width / 8, DefaultUniformAlignment()); + auto buffer_view = renderer.GetTransientsBuffer().Emplace( + uniform_data_->data() + buffer_offset, uniform.GetSize(), + alignment); + + ShaderUniformSlot uniform_slot; + uniform_slot.name = uniform.name.c_str(); + uniform_slot.ext_res_0 = uniform.location; + pass.BindResource(ShaderStage::kFragment, + DescriptorType::kUniformBuffer, uniform_slot, + metadata, buffer_view); + buffer_index++; + buffer_offset += uniform.GetSize(); + break; + } + case kStruct: { + FML_DCHECK(renderer.GetContext()->GetBackendType() == + Context::BackendType::kVulkan); + descriptor_set_layouts.emplace_back(DescriptorSetLayout{ + static_cast(uniform.location), + DescriptorType::kUniformBuffer, + ShaderStage::kFragment, + }); + ShaderUniformSlot uniform_slot; + uniform_slot.name = uniform.name.c_str(); + uniform_slot.binding = uniform.location; + + std::vector uniform_buffer; + uniform_buffer.reserve(uniform.struct_layout.size()); + size_t uniform_byte_index = 0u; + for (const auto& byte_type : uniform.struct_layout) { + if (byte_type == 0) { + uniform_buffer.push_back(0.f); + } else if (byte_type == 1) { + uniform_buffer.push_back(reinterpret_cast( + uniform_data_->data())[uniform_byte_index++]); + } else { + FML_UNREACHABLE(); + } + } - size_t alignment = std::max(sizeof(float) * uniform_buffer.size(), - DefaultUniformAlignment()); + size_t alignment = std::max(sizeof(float) * uniform_buffer.size(), + DefaultUniformAlignment()); - auto buffer_view = renderer.GetTransientsBuffer().Emplace( - reinterpret_cast(uniform_buffer.data()), - sizeof(float) * uniform_buffer.size(), alignment); - pass.BindResource(ShaderStage::kFragment, - DescriptorType::kUniformBuffer, uniform_slot, - ShaderMetadata{}, buffer_view); + auto buffer_view = renderer.GetTransientsBuffer().Emplace( + reinterpret_cast(uniform_buffer.data()), + sizeof(float) * uniform_buffer.size(), alignment); + pass.BindResource(ShaderStage::kFragment, + DescriptorType::kUniformBuffer, uniform_slot, + ShaderMetadata{}, buffer_view); + } } } - } - size_t sampler_index = 0; - for (const auto& uniform : runtime_stage_->GetUniforms()) { - std::shared_ptr metadata = MakeShaderMetadata(uniform); + size_t sampler_index = 0; + for (const auto& uniform : runtime_stage_->GetUniforms()) { + std::shared_ptr metadata = MakeShaderMetadata(uniform); - switch (uniform.type) { - case kSampledImage: { - FML_DCHECK(sampler_index < texture_inputs_.size()); - auto& input = texture_inputs_[sampler_index]; + switch (uniform.type) { + case kSampledImage: { + FML_DCHECK(sampler_index < texture_inputs_.size()); + auto& input = texture_inputs_[sampler_index]; - const std::unique_ptr& sampler = - context->GetSamplerLibrary()->GetSampler(input.sampler_descriptor); + const std::unique_ptr& sampler = + context->GetSamplerLibrary()->GetSampler( + input.sampler_descriptor); - SampledImageSlot image_slot; - image_slot.name = uniform.name.c_str(); + SampledImageSlot image_slot; + image_slot.name = uniform.name.c_str(); - uint32_t sampler_binding_location = 0u; - if (!descriptor_set_layouts.empty()) { - sampler_binding_location = descriptor_set_layouts.back().binding + 1; - } + uint32_t sampler_binding_location = 0u; + if (!descriptor_set_layouts.empty()) { + sampler_binding_location = + descriptor_set_layouts.back().binding + 1; + } - descriptor_set_layouts.emplace_back(DescriptorSetLayout{ - sampler_binding_location, - DescriptorType::kSampledImage, - ShaderStage::kFragment, - }); + descriptor_set_layouts.emplace_back(DescriptorSetLayout{ + sampler_binding_location, + DescriptorType::kSampledImage, + ShaderStage::kFragment, + }); - image_slot.binding = sampler_binding_location; - image_slot.texture_index = uniform.location - minimum_sampler_index; - pass.BindResource(ShaderStage::kFragment, DescriptorType::kSampledImage, - image_slot, *metadata, input.texture, sampler); + image_slot.binding = sampler_binding_location; + image_slot.texture_index = uniform.location - minimum_sampler_index; + pass.BindResource(ShaderStage::kFragment, + DescriptorType::kSampledImage, image_slot, + *metadata, input.texture, sampler); - sampler_index++; - break; + sampler_index++; + break; + } + default: + continue; } - default: - continue; } - } + return true; + }; /// Now that the descriptor set layouts are known, get the pipeline. - auto create_callback = - [&]() -> std::shared_ptr> { - PipelineDescriptor desc; - desc.SetLabel("Runtime Stage"); - desc.AddStageEntrypoint( - library->GetFunction(VS::kEntrypointName, ShaderStage::kVertex)); - desc.AddStageEntrypoint(library->GetFunction( - runtime_stage_->GetEntrypoint(), ShaderStage::kFragment)); - auto vertex_descriptor = std::make_shared(); - vertex_descriptor->SetStageInputs(VS::kAllShaderStageInputs, - VS::kInterleavedBufferLayout); - vertex_descriptor->RegisterDescriptorSetLayouts(VS::kDescriptorSetLayouts); - vertex_descriptor->RegisterDescriptorSetLayouts( - descriptor_set_layouts.data(), descriptor_set_layouts.size()); - desc.SetVertexDescriptor(std::move(vertex_descriptor)); - desc.SetColorAttachmentDescriptor( - 0u, {.format = color_attachment_format, .blending_enabled = true}); - - desc.SetStencilAttachmentDescriptors(StencilAttachmentDescriptor{}); - desc.SetStencilPixelFormat(stencil_attachment_format); - - desc.SetDepthStencilAttachmentDescriptor(DepthAttachmentDescriptor{}); - desc.SetDepthPixelFormat(stencil_attachment_format); - - options.ApplyToPipelineDescriptor(desc); - auto pipeline = context->GetPipelineLibrary()->GetPipeline(desc).Get(); - if (!pipeline) { - VALIDATION_LOG << "Failed to get or create runtime effect pipeline."; - return nullptr; - } - return pipeline; - }; - - pass.SetPipeline(renderer.GetCachedRuntimeEffectPipeline( - runtime_stage_->GetEntrypoint(), options, create_callback)); + PipelineBuilderCallback pipeline_callback = [&](ContentContextOptions + options) { + // Pipeline creation callback for the cache handler to call. + auto create_callback = + [&]() -> std::shared_ptr> { + PipelineDescriptor desc; + desc.SetLabel("Runtime Stage"); + desc.AddStageEntrypoint( + library->GetFunction(VS::kEntrypointName, ShaderStage::kVertex)); + desc.AddStageEntrypoint(library->GetFunction( + runtime_stage_->GetEntrypoint(), ShaderStage::kFragment)); + auto vertex_descriptor = std::make_shared(); + vertex_descriptor->SetStageInputs(VS::kAllShaderStageInputs, + VS::kInterleavedBufferLayout); + vertex_descriptor->RegisterDescriptorSetLayouts( + VS::kDescriptorSetLayouts); + vertex_descriptor->RegisterDescriptorSetLayouts( + descriptor_set_layouts.data(), descriptor_set_layouts.size()); + desc.SetVertexDescriptor(std::move(vertex_descriptor)); + desc.SetColorAttachmentDescriptor( + 0u, {.format = color_attachment_format, .blending_enabled = true}); + + desc.SetStencilAttachmentDescriptors(StencilAttachmentDescriptor{}); + desc.SetStencilPixelFormat(stencil_attachment_format); + + desc.SetDepthStencilAttachmentDescriptor(DepthAttachmentDescriptor{}); + desc.SetDepthPixelFormat(stencil_attachment_format); + + options.ApplyToPipelineDescriptor(desc); + auto pipeline = context->GetPipelineLibrary()->GetPipeline(desc).Get(); + if (!pipeline) { + VALIDATION_LOG << "Failed to get or create runtime effect pipeline."; + return nullptr; + } - if (!pass.Draw().ok()) { - return false; - } + return pipeline; + }; + return renderer.GetCachedRuntimeEffectPipeline( + runtime_stage_->GetEntrypoint(), options, create_callback); + }; - if (geometry_result.prevent_overdraw) { - auto restore = ClipRestoreContents(); - restore.SetRestoreCoverage(GetCoverage(entity)); - return restore.Render(renderer, entity, pass); - } - return true; + return ColorSourceContents::DrawPositions(renderer, entity, pass, + pipeline_callback, + VS::FrameInfo{}, bind_callback); } } // namespace impeller diff --git a/impeller/entity/contents/tiled_texture_contents.cc b/impeller/entity/contents/tiled_texture_contents.cc index a468927c5c38e..b30dd118d2f1d 100644 --- a/impeller/entity/contents/tiled_texture_contents.cc +++ b/impeller/entity/contents/tiled_texture_contents.cc @@ -5,9 +5,7 @@ #include "impeller/entity/contents/tiled_texture_contents.h" #include "fml/logging.h" -#include "impeller/entity/contents/clip_contents.h" #include "impeller/entity/contents/content_context.h" -#include "impeller/entity/geometry/geometry.h" #include "impeller/entity/texture_fill.vert.h" #include "impeller/entity/tiled_texture_fill.frag.h" #include "impeller/entity/tiled_texture_fill_external.frag.h" From 34b2caf637cfac72ac149f81fdc6497433ea295c Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Fri, 9 Feb 2024 15:46:56 -0800 Subject: [PATCH 11/16] dastardly ifdef! --- impeller/entity/contents/tiled_texture_contents.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/impeller/entity/contents/tiled_texture_contents.cc b/impeller/entity/contents/tiled_texture_contents.cc index b30dd118d2f1d..5e73d93b96f39 100644 --- a/impeller/entity/contents/tiled_texture_contents.cc +++ b/impeller/entity/contents/tiled_texture_contents.cc @@ -145,9 +145,9 @@ bool TiledTextureContents::Render(const ContentContext& renderer, : &ContentContext::GetTexturePipeline; } #else - pipeline_builder = uses_emulated_tile_mode - ? &ContentContext::GetTiledTexturePipeline - : &ContentContext::GetTexturePipeline; + pipeline_method = uses_emulated_tile_mode + ? &ContentContext::GetTiledTexturePipeline + : &ContentContext::GetTexturePipeline; #endif // IMPELLER_ENABLE_OPENGLES PipelineBuilderCallback pipeline_callback = From 3740ba38a4d6d557736bb60fecacc6168dee6cf4 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Fri, 9 Feb 2024 15:51:06 -0800 Subject: [PATCH 12/16] Jonah review --- .../entity/contents/color_source_contents.h | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/impeller/entity/contents/color_source_contents.h b/impeller/entity/contents/color_source_contents.h index 5f83c9035b32f..b945d4d9686c9 100644 --- a/impeller/entity/contents/color_source_contents.h +++ b/impeller/entity/contents/color_source_contents.h @@ -139,9 +139,7 @@ class ColorSourceContents : public Contents { VertexShaderT::BindFrameInfo( pass, renderer.GetTransientsBuffer().EmplaceUniform(frame_info)); - std::shared_ptr> pipeline = - pipeline_callback(options); - pass.SetPipeline(pipeline); + pass.SetPipeline(pipeline_callback(options)); // The reason we need to have a callback mechanism here is that this routine // may insert draw calls before the main draw call below. For example, for @@ -173,12 +171,12 @@ class ColorSourceContents : public Contents { const PipelineBuilderCallback& pipeline_callback, typename VertexShaderT::FrameInfo frame_info, const BindFragmentCallback& bind_pipeline_callback) const { - auto geometry_result = + GeometryResult geometry_result = GetGeometry()->GetPositionBuffer(renderer, entity, pass); - return DrawGeometry(geometry_result, renderer, entity, pass, - pipeline_callback, frame_info, - bind_pipeline_callback); + return DrawGeometry(std::move(geometry_result), renderer, + entity, pass, pipeline_callback, + frame_info, bind_pipeline_callback); } template @@ -194,9 +192,9 @@ class ColorSourceContents : public Contents { auto geometry_result = GetGeometry()->GetPositionUVBuffer( texture_coverage, effect_transform, renderer, entity, pass); - return DrawGeometry(geometry_result, renderer, entity, pass, - pipeline_callback, frame_info, - bind_pipeline_callback); + return DrawGeometry(std::move(geometry_result), renderer, + entity, pass, pipeline_callback, + frame_info, bind_pipeline_callback); } private: From 7ce4b5804ecbc7cc2eff10eaac12d90565c6ba37 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Fri, 9 Feb 2024 17:48:01 -0800 Subject: [PATCH 13/16] Migrate ConicalGradientContents --- .../contents/conical_gradient_contents.cc | 181 ++++++++---------- 1 file changed, 76 insertions(+), 105 deletions(-) diff --git a/impeller/entity/contents/conical_gradient_contents.cc b/impeller/entity/contents/conical_gradient_contents.cc index 9bd5e1ee61091..de3013d14f3f8 100644 --- a/impeller/entity/contents/conical_gradient_contents.cc +++ b/impeller/entity/contents/conical_gradient_contents.cc @@ -64,62 +64,45 @@ bool ConicalGradientContents::RenderSSBO(const ContentContext& renderer, using VS = ConicalGradientSSBOFillPipeline::VertexShader; using FS = ConicalGradientSSBOFillPipeline::FragmentShader; - FS::FragInfo frag_info; - frag_info.center = center_; - frag_info.radius = radius_; - frag_info.tile_mode = static_cast(tile_mode_); - frag_info.decal_border_color = decal_border_color_; - frag_info.alpha = GetOpacityFactor(); - if (focus_) { - frag_info.focus = focus_.value(); - frag_info.focus_radius = focus_radius_; - } else { - frag_info.focus = center_; - frag_info.focus_radius = 0.0; - } - - auto& host_buffer = renderer.GetTransientsBuffer(); - auto colors = CreateGradientColors(colors_, stops_); - - frag_info.colors_length = colors.size(); - auto color_buffer = - host_buffer.Emplace(colors.data(), colors.size() * sizeof(StopData), - DefaultUniformAlignment()); - VS::FrameInfo frame_info; - frame_info.depth = entity.GetShaderClipDepth(); - frame_info.mvp = pass.GetOrthographicTransform() * entity.GetTransform(); frame_info.matrix = GetInverseEffectTransform(); - auto geometry_result = - GetGeometry()->GetPositionBuffer(renderer, entity, pass); - auto options = OptionsFromPassAndEntity(pass, entity); - if (geometry_result.prevent_overdraw) { - options.stencil_mode = - ContentContextOptions::StencilMode::kLegacyClipIncrement; - } - options.primitive_type = geometry_result.type; - - pass.SetCommandLabel("ConicalGradientSSBOFill"); - pass.SetStencilReference(entity.GetClipDepth()); - pass.SetPipeline(renderer.GetConicalGradientSSBOFillPipeline(options)); - pass.SetVertexBuffer(std::move(geometry_result.vertex_buffer)); - FS::BindFragInfo(pass, - renderer.GetTransientsBuffer().EmplaceUniform(frag_info)); - FS::BindColorData(pass, color_buffer); - VS::BindFrameInfo(pass, - renderer.GetTransientsBuffer().EmplaceUniform(frame_info)); - - if (!pass.Draw().ok()) { - return false; - } - - if (geometry_result.prevent_overdraw) { - auto restore = ClipRestoreContents(); - restore.SetRestoreCoverage(GetCoverage(entity)); - return restore.Render(renderer, entity, pass); - } - return true; + PipelineBuilderCallback pipeline_callback = + [&renderer](ContentContextOptions options) { + return renderer.GetConicalGradientSSBOFillPipeline(options); + }; + return ColorSourceContents::DrawPositions( + renderer, entity, pass, pipeline_callback, frame_info, + [this, &renderer](RenderPass& pass) { + FS::FragInfo frag_info; + frag_info.center = center_; + frag_info.radius = radius_; + frag_info.tile_mode = static_cast(tile_mode_); + frag_info.decal_border_color = decal_border_color_; + frag_info.alpha = GetOpacityFactor(); + if (focus_) { + frag_info.focus = focus_.value(); + frag_info.focus_radius = focus_radius_; + } else { + frag_info.focus = center_; + frag_info.focus_radius = 0.0; + } + + auto& host_buffer = renderer.GetTransientsBuffer(); + auto colors = CreateGradientColors(colors_, stops_); + + frag_info.colors_length = colors.size(); + auto color_buffer = + host_buffer.Emplace(colors.data(), colors.size() * sizeof(StopData), + DefaultUniformAlignment()); + + FS::BindFragInfo( + pass, renderer.GetTransientsBuffer().EmplaceUniform(frag_info)); + FS::BindColorData(pass, color_buffer); + + pass.SetCommandLabel("ConicalGradientSSBOFill"); + return true; + }); } bool ConicalGradientContents::RenderTexture(const ContentContext& renderer, @@ -135,64 +118,52 @@ bool ConicalGradientContents::RenderTexture(const ContentContext& renderer, return false; } - FS::FragInfo frag_info; - frag_info.center = center_; - frag_info.radius = radius_; - frag_info.tile_mode = static_cast(tile_mode_); - frag_info.decal_border_color = decal_border_color_; - frag_info.texture_sampler_y_coord_scale = gradient_texture->GetYCoordScale(); - frag_info.alpha = GetOpacityFactor(); - frag_info.half_texel = Vector2(0.5 / gradient_texture->GetSize().width, - 0.5 / gradient_texture->GetSize().height); - if (focus_) { - frag_info.focus = focus_.value(); - frag_info.focus_radius = focus_radius_; - } else { - frag_info.focus = center_; - frag_info.focus_radius = 0.0; - } - auto geometry_result = GetGeometry()->GetPositionBuffer(renderer, entity, pass); VS::FrameInfo frame_info; - frame_info.depth = entity.GetShaderClipDepth(); - frame_info.mvp = geometry_result.transform; frame_info.matrix = GetInverseEffectTransform(); - pass.SetCommandLabel("ConicalGradientFill"); - pass.SetStencilReference(entity.GetClipDepth()); - - auto options = OptionsFromPassAndEntity(pass, entity); - if (geometry_result.prevent_overdraw) { - options.stencil_mode = - ContentContextOptions::StencilMode::kLegacyClipIncrement; - } - options.primitive_type = geometry_result.type; - pass.SetPipeline(renderer.GetConicalGradientFillPipeline(options)); - - pass.SetVertexBuffer(std::move(geometry_result.vertex_buffer)); - FS::BindFragInfo(pass, - renderer.GetTransientsBuffer().EmplaceUniform(frag_info)); - SamplerDescriptor sampler_desc; - sampler_desc.min_filter = MinMagFilter::kLinear; - sampler_desc.mag_filter = MinMagFilter::kLinear; - FS::BindTextureSampler( - pass, gradient_texture, - renderer.GetContext()->GetSamplerLibrary()->GetSampler(sampler_desc)); - VS::BindFrameInfo(pass, - renderer.GetTransientsBuffer().EmplaceUniform(frame_info)); - - if (!pass.Draw().ok()) { - return false; - } - - if (geometry_result.prevent_overdraw) { - auto restore = ClipRestoreContents(); - restore.SetRestoreCoverage(GetCoverage(entity)); - return restore.Render(renderer, entity, pass); - } - return true; + PipelineBuilderCallback pipeline_callback = + [&renderer](ContentContextOptions options) { + return renderer.GetConicalGradientFillPipeline(options); + }; + return ColorSourceContents::DrawPositions( + renderer, entity, pass, pipeline_callback, frame_info, + [this, &renderer, &gradient_texture](RenderPass& pass) { + FS::FragInfo frag_info; + frag_info.center = center_; + frag_info.radius = radius_; + frag_info.tile_mode = static_cast(tile_mode_); + frag_info.decal_border_color = decal_border_color_; + frag_info.texture_sampler_y_coord_scale = + gradient_texture->GetYCoordScale(); + frag_info.alpha = GetOpacityFactor(); + frag_info.half_texel = + Vector2(0.5 / gradient_texture->GetSize().width, + 0.5 / gradient_texture->GetSize().height); + if (focus_) { + frag_info.focus = focus_.value(); + frag_info.focus_radius = focus_radius_; + } else { + frag_info.focus = center_; + frag_info.focus_radius = 0.0; + } + + pass.SetCommandLabel("ConicalGradientFill"); + + FS::BindFragInfo( + pass, renderer.GetTransientsBuffer().EmplaceUniform(frag_info)); + SamplerDescriptor sampler_desc; + sampler_desc.min_filter = MinMagFilter::kLinear; + sampler_desc.mag_filter = MinMagFilter::kLinear; + FS::BindTextureSampler( + pass, gradient_texture, + renderer.GetContext()->GetSamplerLibrary()->GetSampler( + sampler_desc)); + + return true; + }); } bool ConicalGradientContents::ApplyColorFilter( From ffd2196a158a224d4c59f3e28be7f68e57c81891 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Fri, 9 Feb 2024 17:54:25 -0800 Subject: [PATCH 14/16] Migrate RadialGradientContents --- .../contents/radial_gradient_contents.cc | 154 +++++++----------- 1 file changed, 63 insertions(+), 91 deletions(-) diff --git a/impeller/entity/contents/radial_gradient_contents.cc b/impeller/entity/contents/radial_gradient_contents.cc index 8bed872c08a65..d60130ced04ea 100644 --- a/impeller/entity/contents/radial_gradient_contents.cc +++ b/impeller/entity/contents/radial_gradient_contents.cc @@ -70,55 +70,38 @@ bool RadialGradientContents::RenderSSBO(const ContentContext& renderer, using VS = RadialGradientSSBOFillPipeline::VertexShader; using FS = RadialGradientSSBOFillPipeline::FragmentShader; - FS::FragInfo frag_info; - frag_info.center = center_; - frag_info.radius = radius_; - frag_info.tile_mode = static_cast(tile_mode_); - frag_info.decal_border_color = decal_border_color_; - frag_info.alpha = GetOpacityFactor(); - - auto& host_buffer = renderer.GetTransientsBuffer(); - auto colors = CreateGradientColors(colors_, stops_); - - frag_info.colors_length = colors.size(); - auto color_buffer = - host_buffer.Emplace(colors.data(), colors.size() * sizeof(StopData), - DefaultUniformAlignment()); - VS::FrameInfo frame_info; - frame_info.depth = entity.GetShaderClipDepth(); - frame_info.mvp = pass.GetOrthographicTransform() * entity.GetTransform(); frame_info.matrix = GetInverseEffectTransform(); - auto geometry_result = - GetGeometry()->GetPositionBuffer(renderer, entity, pass); - auto options = OptionsFromPassAndEntity(pass, entity); - if (geometry_result.prevent_overdraw) { - options.stencil_mode = - ContentContextOptions::StencilMode::kLegacyClipIncrement; - } - options.primitive_type = geometry_result.type; - - pass.SetCommandLabel("RadialGradientSSBOFill"); - pass.SetPipeline(renderer.GetRadialGradientSSBOFillPipeline(options)); - pass.SetStencilReference(entity.GetClipDepth()); - pass.SetVertexBuffer(std::move(geometry_result.vertex_buffer)); - FS::BindFragInfo(pass, - renderer.GetTransientsBuffer().EmplaceUniform(frag_info)); - FS::BindColorData(pass, color_buffer); - VS::BindFrameInfo(pass, - renderer.GetTransientsBuffer().EmplaceUniform(frame_info)); - - if (!pass.Draw().ok()) { - return false; - } - - if (geometry_result.prevent_overdraw) { - auto restore = ClipRestoreContents(); - restore.SetRestoreCoverage(GetCoverage(entity)); - return restore.Render(renderer, entity, pass); - } - return true; + PipelineBuilderCallback pipeline_callback = + [&renderer](ContentContextOptions options) { + return renderer.GetRadialGradientSSBOFillPipeline(options); + }; + return ColorSourceContents::DrawPositions( + renderer, entity, pass, pipeline_callback, frame_info, + [this, &renderer](RenderPass& pass) { + FS::FragInfo frag_info; + frag_info.center = center_; + frag_info.radius = radius_; + frag_info.tile_mode = static_cast(tile_mode_); + frag_info.decal_border_color = decal_border_color_; + frag_info.alpha = GetOpacityFactor(); + + auto& host_buffer = renderer.GetTransientsBuffer(); + auto colors = CreateGradientColors(colors_, stops_); + + frag_info.colors_length = colors.size(); + auto color_buffer = + host_buffer.Emplace(colors.data(), colors.size() * sizeof(StopData), + DefaultUniformAlignment()); + + pass.SetCommandLabel("RadialGradientSSBOFill"); + FS::BindFragInfo( + pass, renderer.GetTransientsBuffer().EmplaceUniform(frag_info)); + FS::BindColorData(pass, color_buffer); + + return true; + }); } bool RadialGradientContents::RenderTexture(const ContentContext& renderer, @@ -134,57 +117,46 @@ bool RadialGradientContents::RenderTexture(const ContentContext& renderer, return false; } - FS::FragInfo frag_info; - frag_info.center = center_; - frag_info.radius = radius_; - frag_info.tile_mode = static_cast(tile_mode_); - frag_info.decal_border_color = decal_border_color_; - frag_info.texture_sampler_y_coord_scale = gradient_texture->GetYCoordScale(); - frag_info.alpha = GetOpacityFactor(); - frag_info.half_texel = Vector2(0.5 / gradient_texture->GetSize().width, - 0.5 / gradient_texture->GetSize().height); - - auto geometry_result = - GetGeometry()->GetPositionBuffer(renderer, entity, pass); - VS::FrameInfo frame_info; - frame_info.depth = entity.GetShaderClipDepth(); - frame_info.mvp = geometry_result.transform; frame_info.matrix = GetInverseEffectTransform(); - auto options = OptionsFromPassAndEntity(pass, entity); - if (geometry_result.prevent_overdraw) { - options.stencil_mode = - ContentContextOptions::StencilMode::kLegacyClipIncrement; - } - options.primitive_type = geometry_result.type; - - SamplerDescriptor sampler_desc; - sampler_desc.min_filter = MinMagFilter::kLinear; - sampler_desc.mag_filter = MinMagFilter::kLinear; - - pass.SetCommandLabel("RadialGradientFill"); - pass.SetPipeline(renderer.GetRadialGradientFillPipeline(options)); - pass.SetStencilReference(entity.GetClipDepth()); - pass.SetVertexBuffer(std::move(geometry_result.vertex_buffer)); - FS::BindFragInfo(pass, - renderer.GetTransientsBuffer().EmplaceUniform(frag_info)); - FS::BindTextureSampler( - pass, gradient_texture, - renderer.GetContext()->GetSamplerLibrary()->GetSampler(sampler_desc)); VS::BindFrameInfo(pass, renderer.GetTransientsBuffer().EmplaceUniform(frame_info)); - if (!pass.Draw().ok()) { - return false; - } - - if (geometry_result.prevent_overdraw) { - auto restore = ClipRestoreContents(); - restore.SetRestoreCoverage(GetCoverage(entity)); - return restore.Render(renderer, entity, pass); - } - return true; + PipelineBuilderCallback pipeline_callback = + [&renderer](ContentContextOptions options) { + return renderer.GetRadialGradientFillPipeline(options); + }; + return ColorSourceContents::DrawPositions( + renderer, entity, pass, pipeline_callback, frame_info, + [this, &renderer, &gradient_texture](RenderPass& pass) { + FS::FragInfo frag_info; + frag_info.center = center_; + frag_info.radius = radius_; + frag_info.tile_mode = static_cast(tile_mode_); + frag_info.decal_border_color = decal_border_color_; + frag_info.texture_sampler_y_coord_scale = + gradient_texture->GetYCoordScale(); + frag_info.alpha = GetOpacityFactor(); + frag_info.half_texel = + Vector2(0.5 / gradient_texture->GetSize().width, + 0.5 / gradient_texture->GetSize().height); + + SamplerDescriptor sampler_desc; + sampler_desc.min_filter = MinMagFilter::kLinear; + sampler_desc.mag_filter = MinMagFilter::kLinear; + + pass.SetCommandLabel("RadialGradientFill"); + + FS::BindFragInfo( + pass, renderer.GetTransientsBuffer().EmplaceUniform(frag_info)); + FS::BindTextureSampler( + pass, gradient_texture, + renderer.GetContext()->GetSamplerLibrary()->GetSampler( + sampler_desc)); + + return true; + }); } bool RadialGradientContents::ApplyColorFilter( From ccd8718acadd8921468c2be994e2d60e65268b31 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Fri, 9 Feb 2024 18:00:31 -0800 Subject: [PATCH 15/16] Migrate SweepGradientContents --- .../contents/sweep_gradient_contents.cc | 162 +++++++----------- 1 file changed, 66 insertions(+), 96 deletions(-) diff --git a/impeller/entity/contents/sweep_gradient_contents.cc b/impeller/entity/contents/sweep_gradient_contents.cc index 29fbe935eaa6e..af43454ae9c2d 100644 --- a/impeller/entity/contents/sweep_gradient_contents.cc +++ b/impeller/entity/contents/sweep_gradient_contents.cc @@ -76,57 +76,42 @@ bool SweepGradientContents::RenderSSBO(const ContentContext& renderer, using VS = SweepGradientSSBOFillPipeline::VertexShader; using FS = SweepGradientSSBOFillPipeline::FragmentShader; - FS::FragInfo frag_info; - frag_info.center = center_; - frag_info.bias = bias_; - frag_info.scale = scale_; - frag_info.tile_mode = static_cast(tile_mode_); - frag_info.decal_border_color = decal_border_color_; - frag_info.alpha = GetOpacityFactor(); - - auto& host_buffer = renderer.GetTransientsBuffer(); - auto colors = CreateGradientColors(colors_, stops_); - - frag_info.colors_length = colors.size(); - auto color_buffer = - host_buffer.Emplace(colors.data(), colors.size() * sizeof(StopData), - DefaultUniformAlignment()); - VS::FrameInfo frame_info; - frame_info.depth = entity.GetShaderClipDepth(); - frame_info.mvp = pass.GetOrthographicTransform() * entity.GetTransform(); frame_info.matrix = GetInverseEffectTransform(); - - auto geometry_result = - GetGeometry()->GetPositionBuffer(renderer, entity, pass); - - auto options = OptionsFromPassAndEntity(pass, entity); - if (geometry_result.prevent_overdraw) { - options.stencil_mode = - ContentContextOptions::StencilMode::kLegacyClipIncrement; - } - options.primitive_type = geometry_result.type; - - pass.SetCommandLabel("SweepGradientSSBOFill"); - pass.SetStencilReference(entity.GetClipDepth()); - pass.SetPipeline(renderer.GetSweepGradientSSBOFillPipeline(options)); - pass.SetVertexBuffer(std::move(geometry_result.vertex_buffer)); - FS::BindFragInfo(pass, - renderer.GetTransientsBuffer().EmplaceUniform(frag_info)); - FS::BindColorData(pass, color_buffer); VS::BindFrameInfo(pass, renderer.GetTransientsBuffer().EmplaceUniform(frame_info)); - if (!pass.Draw().ok()) { - return false; - } - - if (geometry_result.prevent_overdraw) { - auto restore = ClipRestoreContents(); - restore.SetRestoreCoverage(GetCoverage(entity)); - return restore.Render(renderer, entity, pass); - } - return true; + PipelineBuilderCallback pipeline_callback = + [&renderer](ContentContextOptions options) { + return renderer.GetSweepGradientSSBOFillPipeline(options); + }; + return ColorSourceContents::DrawPositions( + renderer, entity, pass, pipeline_callback, frame_info, + [this, &renderer](RenderPass& pass) { + FS::FragInfo frag_info; + frag_info.center = center_; + frag_info.bias = bias_; + frag_info.scale = scale_; + frag_info.tile_mode = static_cast(tile_mode_); + frag_info.decal_border_color = decal_border_color_; + frag_info.alpha = GetOpacityFactor(); + + auto& host_buffer = renderer.GetTransientsBuffer(); + auto colors = CreateGradientColors(colors_, stops_); + + frag_info.colors_length = colors.size(); + auto color_buffer = + host_buffer.Emplace(colors.data(), colors.size() * sizeof(StopData), + DefaultUniformAlignment()); + + pass.SetCommandLabel("SweepGradientSSBOFill"); + + FS::BindFragInfo( + pass, renderer.GetTransientsBuffer().EmplaceUniform(frag_info)); + FS::BindColorData(pass, color_buffer); + + return true; + }); } bool SweepGradientContents::RenderTexture(const ContentContext& renderer, @@ -142,59 +127,44 @@ bool SweepGradientContents::RenderTexture(const ContentContext& renderer, return false; } - FS::FragInfo frag_info; - frag_info.center = center_; - frag_info.bias = bias_; - frag_info.scale = scale_; - frag_info.texture_sampler_y_coord_scale = gradient_texture->GetYCoordScale(); - frag_info.tile_mode = static_cast(tile_mode_); - frag_info.decal_border_color = decal_border_color_; - frag_info.alpha = GetOpacityFactor(); - frag_info.half_texel = Vector2(0.5 / gradient_texture->GetSize().width, - 0.5 / gradient_texture->GetSize().height); - - auto geometry_result = - GetGeometry()->GetPositionBuffer(renderer, entity, pass); - VS::FrameInfo frame_info; - frame_info.depth = entity.GetShaderClipDepth(); - frame_info.mvp = geometry_result.transform; frame_info.matrix = GetInverseEffectTransform(); - auto options = OptionsFromPassAndEntity(pass, entity); - if (geometry_result.prevent_overdraw) { - options.stencil_mode = - ContentContextOptions::StencilMode::kLegacyClipIncrement; - } - options.primitive_type = geometry_result.type; - - SamplerDescriptor sampler_desc; - sampler_desc.min_filter = MinMagFilter::kLinear; - sampler_desc.mag_filter = MinMagFilter::kLinear; - - pass.SetCommandLabel("SweepGradientFill"); - pass.SetStencilReference(entity.GetClipDepth()); - pass.SetPipeline(renderer.GetSweepGradientFillPipeline(options)); - pass.SetVertexBuffer(std::move(geometry_result.vertex_buffer)); - - FS::BindFragInfo(pass, - renderer.GetTransientsBuffer().EmplaceUniform(frag_info)); - VS::BindFrameInfo(pass, - renderer.GetTransientsBuffer().EmplaceUniform(frame_info)); - FS::BindTextureSampler( - pass, gradient_texture, - renderer.GetContext()->GetSamplerLibrary()->GetSampler(sampler_desc)); - - if (!pass.Draw().ok()) { - return false; - } - - if (geometry_result.prevent_overdraw) { - auto restore = ClipRestoreContents(); - restore.SetRestoreCoverage(GetCoverage(entity)); - return restore.Render(renderer, entity, pass); - } - return true; + PipelineBuilderCallback pipeline_callback = + [&renderer](ContentContextOptions options) { + return renderer.GetSweepGradientFillPipeline(options); + }; + return ColorSourceContents::DrawPositions( + renderer, entity, pass, pipeline_callback, frame_info, + [this, &renderer, &gradient_texture](RenderPass& pass) { + FS::FragInfo frag_info; + frag_info.center = center_; + frag_info.bias = bias_; + frag_info.scale = scale_; + frag_info.texture_sampler_y_coord_scale = + gradient_texture->GetYCoordScale(); + frag_info.tile_mode = static_cast(tile_mode_); + frag_info.decal_border_color = decal_border_color_; + frag_info.alpha = GetOpacityFactor(); + frag_info.half_texel = + Vector2(0.5 / gradient_texture->GetSize().width, + 0.5 / gradient_texture->GetSize().height); + + SamplerDescriptor sampler_desc; + sampler_desc.min_filter = MinMagFilter::kLinear; + sampler_desc.mag_filter = MinMagFilter::kLinear; + + pass.SetCommandLabel("SweepGradientFill"); + + FS::BindFragInfo( + pass, renderer.GetTransientsBuffer().EmplaceUniform(frag_info)); + FS::BindTextureSampler( + pass, gradient_texture, + renderer.GetContext()->GetSamplerLibrary()->GetSampler( + sampler_desc)); + + return true; + }); } bool SweepGradientContents::ApplyColorFilter( From 7fcc25632e7b7ba79ab6136219d3c97cd46ee844 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Tue, 13 Feb 2024 14:43:49 -0800 Subject: [PATCH 16/16] Resolve the pipeline after running the fragment bind callback --- impeller/entity/contents/color_source_contents.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/impeller/entity/contents/color_source_contents.h b/impeller/entity/contents/color_source_contents.h index b945d4d9686c9..f3f7281301f14 100644 --- a/impeller/entity/contents/color_source_contents.h +++ b/impeller/entity/contents/color_source_contents.h @@ -139,8 +139,6 @@ class ColorSourceContents : public Contents { VertexShaderT::BindFrameInfo( pass, renderer.GetTransientsBuffer().EmplaceUniform(frame_info)); - pass.SetPipeline(pipeline_callback(options)); - // The reason we need to have a callback mechanism here is that this routine // may insert draw calls before the main draw call below. For example, for // sufficiently complex paths we may opt to use stencil-then-cover to avoid @@ -149,6 +147,8 @@ class ColorSourceContents : public Contents { return false; } + pass.SetPipeline(pipeline_callback(options)); + if (!pass.Draw().ok()) { return false; }