Flutter Impeller
clip_contents.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include <optional>
6 
7 #include "fml/logging.h"
11 #include "impeller/entity/entity.h"
14 
15 namespace impeller {
16 
17 /*******************************************************************************
18  ******* ClipContents
19  ******************************************************************************/
20 
21 ClipContents::ClipContents() = default;
22 
23 ClipContents::~ClipContents() = default;
24 
25 void ClipContents::SetGeometry(std::unique_ptr<Geometry> geometry) {
26  geometry_ = std::move(geometry);
27 }
28 
30  clip_op_ = clip_op;
31 }
32 
33 std::optional<Rect> ClipContents::GetCoverage(const Entity& entity) const {
34  return std::nullopt;
35 };
36 
38  const Entity& entity,
39  const std::optional<Rect>& current_stencil_coverage) const {
40  if (!current_stencil_coverage.has_value()) {
41  return {.type = StencilCoverage::Type::kAppend, .coverage = std::nullopt};
42  }
43  switch (clip_op_) {
45  // This can be optimized further by considering cases when the bounds of
46  // the current stencil will shrink.
47  return {.type = StencilCoverage::Type::kAppend,
48  .coverage = current_stencil_coverage};
50  if (!geometry_) {
51  return {.type = StencilCoverage::Type::kAppend,
52  .coverage = std::nullopt};
53  }
54  auto coverage = geometry_->GetCoverage(entity.GetTransformation());
55  if (!coverage.has_value() || !current_stencil_coverage.has_value()) {
56  return {.type = StencilCoverage::Type::kAppend,
57  .coverage = std::nullopt};
58  }
59  return {
60  .type = StencilCoverage::Type::kAppend,
61  .coverage = current_stencil_coverage->Intersection(coverage.value()),
62  };
63  }
64  FML_UNREACHABLE();
65 }
66 
68  const Entity& entity,
69  const std::optional<Rect>& stencil_coverage) const {
70  return true;
71 }
72 
73 bool ClipContents::CanInheritOpacity(const Entity& entity) const {
74  return true;
75 }
76 
78 
79 bool ClipContents::Render(const ContentContext& renderer,
80  const Entity& entity,
81  RenderPass& pass) const {
82  using VS = ClipPipeline::VertexShader;
83 
84  VS::FrameInfo info;
85 
86  Command cmd;
87 
88  auto options = OptionsFromPass(pass);
89  options.blend_mode = BlendMode::kDestination;
90  cmd.stencil_reference = entity.GetStencilDepth();
91  options.stencil_compare = CompareFunction::kEqual;
92  options.stencil_operation = StencilOperation::kIncrementClamp;
93 
94  if (clip_op_ == Entity::ClipOperation::kDifference) {
95  {
96  DEBUG_COMMAND_INFO(cmd, "Difference Clip (Increment)");
97 
98  auto points = Rect(Size(pass.GetRenderTargetSize())).GetPoints();
99  auto vertices =
101  .AddVertices({{points[0]}, {points[1]}, {points[2]}, {points[3]}})
102  .CreateVertexBuffer(pass.GetTransientsBuffer());
103  cmd.BindVertices(vertices);
104 
106  VS::BindFrameInfo(cmd, pass.GetTransientsBuffer().EmplaceUniform(info));
107 
108  options.primitive_type = PrimitiveType::kTriangleStrip;
109  cmd.pipeline = renderer.GetClipPipeline(options);
110  pass.AddCommand(Command(cmd));
111  }
112 
113  {
114  DEBUG_COMMAND_INFO(cmd, "Difference Clip (Punch)");
115 
116  cmd.stencil_reference = entity.GetStencilDepth() + 1;
117  options.stencil_compare = CompareFunction::kEqual;
118  options.stencil_operation = StencilOperation::kDecrementClamp;
119  }
120  } else {
121  DEBUG_COMMAND_INFO(cmd, "Intersect Clip");
122  options.stencil_compare = CompareFunction::kEqual;
123  options.stencil_operation = StencilOperation::kIncrementClamp;
124  }
125 
126  auto geometry_result = geometry_->GetPositionBuffer(renderer, entity, pass);
127  options.primitive_type = geometry_result.type;
128  cmd.pipeline = renderer.GetClipPipeline(options);
129 
130  auto allocator = renderer.GetContext()->GetResourceAllocator();
131  cmd.BindVertices(geometry_result.vertex_buffer);
132 
133  info.mvp = geometry_result.transform;
134  VS::BindFrameInfo(cmd, pass.GetTransientsBuffer().EmplaceUniform(info));
135 
136  pass.AddCommand(std::move(cmd));
137  return true;
138 }
139 
140 /*******************************************************************************
141  ******* ClipRestoreContents
142  ******************************************************************************/
143 
145 
147 
149  std::optional<Rect> restore_coverage) {
150  restore_coverage_ = restore_coverage;
151 }
152 
154  const Entity& entity) const {
155  return std::nullopt;
156 };
157 
159  const Entity& entity,
160  const std::optional<Rect>& current_stencil_coverage) const {
161  return {.type = StencilCoverage::Type::kRestore, .coverage = std::nullopt};
162 }
163 
165  const Entity& entity,
166  const std::optional<Rect>& stencil_coverage) const {
167  return true;
168 }
169 
171  return true;
172 }
173 
175 
177  const Entity& entity,
178  RenderPass& pass) const {
179  using VS = ClipPipeline::VertexShader;
180 
181  Command cmd;
182  DEBUG_COMMAND_INFO(cmd, "Restore Clip");
183  auto options = OptionsFromPass(pass);
184  options.blend_mode = BlendMode::kDestination;
185  options.stencil_compare = CompareFunction::kLess;
186  options.stencil_operation = StencilOperation::kSetToReferenceValue;
187  options.primitive_type = PrimitiveType::kTriangleStrip;
188  cmd.pipeline = renderer.GetClipPipeline(options);
189  cmd.stencil_reference = entity.GetStencilDepth();
190 
191  // Create a rect that covers either the given restore area, or the whole
192  // render target texture.
193  auto ltrb = restore_coverage_.value_or(Rect(Size(pass.GetRenderTargetSize())))
194  .GetLTRB();
196  vtx_builder.AddVertices({
197  {Point(ltrb[0], ltrb[1])},
198  {Point(ltrb[2], ltrb[1])},
199  {Point(ltrb[0], ltrb[3])},
200  {Point(ltrb[2], ltrb[3])},
201  });
202  cmd.BindVertices(vtx_builder.CreateVertexBuffer(pass.GetTransientsBuffer()));
203 
204  VS::FrameInfo info;
206  VS::BindFrameInfo(cmd, pass.GetTransientsBuffer().EmplaceUniform(info));
207 
208  pass.AddCommand(std::move(cmd));
209  return true;
210 }
211 
212 }; // namespace impeller
impeller::ClipRestoreContents::ShouldRender
bool ShouldRender(const Entity &entity, const std::optional< Rect > &stencil_coverage) const override
Definition: clip_contents.cc:164
impeller::Entity::ClipOperation::kIntersect
@ kIntersect
impeller::ClipRestoreContents::GetStencilCoverage
StencilCoverage GetStencilCoverage(const Entity &entity, const std::optional< Rect > &current_stencil_coverage) const override
Given the current screen space bounding rectangle of the stencil, return the expected stencil coverag...
Definition: clip_contents.cc:158
impeller::OptionsFromPass
ContentContextOptions OptionsFromPass(const RenderPass &pass)
Definition: contents.cc:20
impeller::Command
An object used to specify work to the GPU along with references to resources the GPU will used when d...
Definition: command.h:99
DEBUG_COMMAND_INFO
#define DEBUG_COMMAND_INFO(obj, arg)
Definition: command.h:31
impeller::Entity::GetStencilDepth
uint32_t GetStencilDepth() const
Definition: entity.cc:89
impeller::ClipRestoreContents::ClipRestoreContents
ClipRestoreContents()
impeller::Entity::ClipOperation::kDifference
@ kDifference
impeller::Scalar
float Scalar
Definition: scalar.h:15
impeller::ClipRestoreContents::GetCoverage
std::optional< Rect > GetCoverage(const Entity &entity) const override
Get the screen space bounding rectangle that this contents affects.
Definition: clip_contents.cc:153
entity.h
impeller::ClipRestoreContents::CanInheritOpacity
bool CanInheritOpacity(const Entity &entity) const override
Whether or not this contents can accept the opacity peephole optimization.
Definition: clip_contents.cc:170
formats.h
impeller::ContentContext::GetClipPipeline
std::shared_ptr< Pipeline< PipelineDescriptor > > GetClipPipeline(ContentContextOptions opts) const
Definition: content_context.h:486
impeller::ClipContents::SetGeometry
void SetGeometry(std::unique_ptr< Geometry > geometry)
Definition: clip_contents.cc:25
impeller::ClipContents::SetClipOperation
void SetClipOperation(Entity::ClipOperation clip_op)
Definition: clip_contents.cc:29
impeller::ClipRestoreContents::SetRestoreCoverage
void SetRestoreCoverage(std::optional< Rect > coverage)
The area on the pass texture where this clip restore will be applied. If unset, the entire pass textu...
Definition: clip_contents.cc:148
impeller::VertexBufferBuilder::AddVertices
VertexBufferBuilder & AddVertices(std::initializer_list< VertexType_ > vertices)
Definition: vertex_buffer_builder.h:64
impeller::Size
TSize< Scalar > Size
Definition: size.h:135
impeller::ClipRestoreContents::~ClipRestoreContents
~ClipRestoreContents()
impeller::PrimitiveType::kTriangleStrip
@ kTriangleStrip
impeller::TRect::GetPoints
constexpr std::array< TPoint< T >, 4 > GetPoints() const
Get the points that represent the 4 corners of this rectangle. The order is: Top left,...
Definition: rect.h:187
impeller::Entity::GetTransformation
const Matrix & GetTransformation() const
Definition: entity.cc:49
impeller::Entity
Definition: entity.h:21
impeller::RenderPass::GetRenderTargetSize
ISize GetRenderTargetSize() const
Definition: render_pass.cc:30
impeller::ClipContents::ClipContents
ClipContents()
impeller::Point
TPoint< Scalar > Point
Definition: point.h:306
render_pass.h
impeller::Contents::StencilCoverage
Definition: contents.h:39
impeller::ClipRestoreContents::Render
bool Render(const ContentContext &renderer, const Entity &entity, RenderPass &pass) const override
Definition: clip_contents.cc:176
impeller::StencilOperation::kSetToReferenceValue
@ kSetToReferenceValue
Reset the stencil value to the reference value.
impeller::BlendMode::kDestination
@ kDestination
impeller::ClipContents::~ClipContents
~ClipContents()
impeller::ClipContents::GetCoverage
std::optional< Rect > GetCoverage(const Entity &entity) const override
Get the screen space bounding rectangle that this contents affects.
Definition: clip_contents.cc:33
impeller::ContentContext::GetContext
std::shared_ptr< Context > GetContext() const
Definition: content_context.cc:440
impeller::VertexBufferBuilder
Definition: vertex_buffer_builder.h:23
impeller::ClipRestoreContents::SetInheritedOpacity
void SetInheritedOpacity(Scalar opacity) override
Inherit the provided opacity.
Definition: clip_contents.cc:174
clip_contents.h
impeller::ClipContents::GetStencilCoverage
StencilCoverage GetStencilCoverage(const Entity &entity, const std::optional< Rect > &current_stencil_coverage) const override
Given the current screen space bounding rectangle of the stencil, return the expected stencil coverag...
Definition: clip_contents.cc:37
impeller::Rect
TRect< Scalar > Rect
Definition: rect.h:306
impeller::StencilOperation::kIncrementClamp
@ kIncrementClamp
Increment the current stencil value by 1. Clamp it to the maximum.
impeller::ClipContents::Render
bool Render(const ContentContext &renderer, const Entity &entity, RenderPass &pass) const override
Definition: clip_contents.cc:79
impeller::VertexBufferBuilder::CreateVertexBuffer
VertexBuffer CreateVertexBuffer(HostBuffer &host_buffer) const
Definition: vertex_buffer_builder.h:78
impeller::CompareFunction::kLess
@ kLess
Comparison test passes if new_value < current_value.
impeller::RenderPass
Render passes encode render commands directed as one specific render target into an underlying comman...
Definition: render_pass.h:27
impeller::Command::stencil_reference
uint32_t stencil_reference
Definition: command.h:152
content_context.h
impeller::StencilOperation::kDecrementClamp
@ kDecrementClamp
Decrement the current stencil value by 1. Clamp it to zero.
impeller::ClipContents::ShouldRender
bool ShouldRender(const Entity &entity, const std::optional< Rect > &stencil_coverage) const override
Definition: clip_contents.cc:67
impeller::HostBuffer::EmplaceUniform
BufferView EmplaceUniform(const UniformType &uniform)
Emplace uniform data onto the host buffer. Ensure that backend specific uniform alignment requirement...
Definition: host_buffer.h:43
impeller::ClipContents::CanInheritOpacity
bool CanInheritOpacity(const Entity &entity) const override
Whether or not this contents can accept the opacity peephole optimization.
Definition: clip_contents.cc:73
impeller::Contents::StencilCoverage::type
Type type
Definition: contents.h:42
impeller::Matrix::MakeOrthographic
static constexpr Matrix MakeOrthographic(TSize< T > size)
Definition: matrix.h:448
impeller::Entity::ClipOperation
ClipOperation
Definition: entity.h:59
impeller::ClipContents::SetInheritedOpacity
void SetInheritedOpacity(Scalar opacity) override
Inherit the provided opacity.
Definition: clip_contents.cc:77
impeller::CompareFunction::kEqual
@ kEqual
Comparison test passes if new_value == current_value.
impeller::Command::BindVertices
bool BindVertices(const VertexBuffer &buffer)
Specify the vertex and index buffer to use for this command.
Definition: command.cc:15
impeller::Command::pipeline
std::shared_ptr< Pipeline< PipelineDescriptor > > pipeline
Definition: command.h:103
impeller::RenderPipelineT::VertexShader
VertexShader_ VertexShader
Definition: pipeline.h:90
impeller::RenderPass::AddCommand
bool AddCommand(Command &&command)
Record a command for subsequent encoding to the underlying command buffer. No work is encoded into th...
Definition: render_pass.cc:46
impeller
Definition: aiks_context.cc:10
impeller::ContentContext
Definition: content_context.h:344
impeller::RenderPass::GetTransientsBuffer
HostBuffer & GetTransientsBuffer()
Definition: render_pass.cc:34
vertex_buffer_builder.h