Flutter Impeller
paint_pass_delegate.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 
6 
14 
15 namespace impeller {
16 
17 /// PaintPassDelegate
18 /// ----------------------------------------------
19 
20 PaintPassDelegate::PaintPassDelegate(Paint paint) : paint_(std::move(paint)) {}
21 
22 // |EntityPassDelgate|
24 
25 // |EntityPassDelgate|
27  return paint_.blend_mode == BlendMode::kDestination;
28 }
29 
30 // |EntityPassDelgate|
32  return false;
33 }
34 
35 // |EntityPassDelgate|
37  std::shared_ptr<Texture> target,
38  const Matrix& effect_transform) {
39  auto contents = TextureContents::MakeRect(Rect::MakeSize(target->GetSize()));
40  contents->SetTexture(target);
41  contents->SetLabel("Subpass");
42  contents->SetSourceRect(Rect::MakeSize(target->GetSize()));
43  contents->SetOpacity(paint_.color.alpha);
44  contents->SetDeferApplyingOpacity(true);
45 
46  return paint_.WithFiltersForSubpassTarget(std::move(contents),
47  effect_transform);
48 }
49 
50 // |EntityPassDelgate|
51 std::shared_ptr<FilterContents> PaintPassDelegate::WithImageFilter(
52  const FilterInput::Variant& input,
53  const Matrix& effect_transform) const {
54  return paint_.WithImageFilter(input, effect_transform,
56 }
57 
58 /// OpacityPeepholePassDelegate
59 /// ----------------------------------------------
60 
62  : paint_(std::move(paint)) {}
63 
64 // |EntityPassDelgate|
66 
67 // |EntityPassDelgate|
69  return paint_.blend_mode == BlendMode::kDestination;
70 }
71 
72 // |EntityPassDelgate|
74  EntityPass* entity_pass) {
75  // Passes with absorbed clips can not be safely collapsed.
76  if (entity_pass->GetBoundsLimit().has_value()) {
77  return false;
78  }
79 
80  // OpacityPeepholePassDelegate will only get used if the pass's blend mode is
81  // SourceOver, so no need to check here.
82  if (paint_.color.alpha <= 0.0 || paint_.color.alpha >= 1.0 ||
83  paint_.image_filter || paint_.color_filter) {
84  return false;
85  }
86 
87  // Note: determing whether any coverage intersects has quadradic complexity in
88  // the number of rectangles, and depending on whether or not we cache at
89  // different levels of the entity tree may end up cubic. In the interest of
90  // proving whether or not this optimization is valuable, we only consider very
91  // simple peephole optimizations here - where there is a single drawing
92  // command wrapped in save layer. This would indicate something like an
93  // Opacity or FadeTransition wrapping a very simple widget, like in the
94  // CupertinoPicker.
95  if (entity_pass->GetElementCount() > 3) {
96  // Single paint command with a save layer would be:
97  // 1. clip
98  // 2. draw command
99  // 3. restore.
100  return false;
101  }
102  bool all_can_accept = true;
103  std::vector<Rect> all_coverages;
104  auto had_subpass = entity_pass->IterateUntilSubpass(
105  [&all_coverages, &all_can_accept](Entity& entity) {
106  auto contents = entity.GetContents();
107  if (!entity.CanInheritOpacity()) {
108  all_can_accept = false;
109  return false;
110  }
111  auto maybe_coverage = contents->GetCoverage(entity);
112  if (maybe_coverage.has_value()) {
113  auto coverage = maybe_coverage.value();
114  for (const auto& cv : all_coverages) {
115  if (cv.IntersectsWithRect(coverage)) {
116  all_can_accept = false;
117  return false;
118  }
119  }
120  all_coverages.push_back(coverage);
121  }
122  return true;
123  });
124  if (had_subpass || !all_can_accept) {
125  return false;
126  }
127  auto alpha = paint_.color.alpha;
128  entity_pass->IterateUntilSubpass([&alpha](Entity& entity) {
129  entity.SetInheritedOpacity(alpha);
130  return true;
131  });
132  return true;
133 }
134 
135 // |EntityPassDelgate|
136 std::shared_ptr<Contents>
137 OpacityPeepholePassDelegate::CreateContentsForSubpassTarget(
138  std::shared_ptr<Texture> target,
139  const Matrix& effect_transform) {
140  auto contents = TextureContents::MakeRect(Rect::MakeSize(target->GetSize()));
141  contents->SetLabel("Subpass");
142  contents->SetTexture(target);
143  contents->SetSourceRect(Rect::MakeSize(target->GetSize()));
144  contents->SetOpacity(paint_.color.alpha);
145  contents->SetDeferApplyingOpacity(true);
146 
147  return paint_.WithFiltersForSubpassTarget(std::move(contents),
148  effect_transform);
149 }
150 
151 // |EntityPassDelgate|
152 std::shared_ptr<FilterContents> OpacityPeepholePassDelegate::WithImageFilter(
153  const FilterInput::Variant& input,
154  const Matrix& effect_transform) const {
155  return paint_.WithImageFilter(input, effect_transform,
156  Entity::RenderingMode::kSubpass);
157 }
158 
159 } // namespace impeller
impeller::PaintPassDelegate::CreateContentsForSubpassTarget
std::shared_ptr< Contents > CreateContentsForSubpassTarget(std::shared_ptr< Texture > target, const Matrix &effect_transform) override
Definition: paint_pass_delegate.cc:36
contents.h
texture_contents.h
impeller::Paint
Definition: paint.h:25
impeller::Paint::color
Color color
Definition: paint.h:54
paint_pass_delegate.h
impeller::EntityPass::IterateUntilSubpass
bool IterateUntilSubpass(const std::function< bool(Entity &)> &iterator)
Iterate entities in this pass up until the first subpass is found. This is useful for limiting look-a...
Definition: entity_pass.cc:1073
formats.h
impeller::Color::alpha
Scalar alpha
Definition: color.h:141
path_builder.h
impeller::Entity::CanInheritOpacity
bool CanInheritOpacity() const
Definition: entity.cc:105
impeller::Entity
Definition: entity.h:21
impeller::Paint::color_filter
std::shared_ptr< ColorFilter > color_filter
Definition: paint.h:67
impeller::EntityPass::GetBoundsLimit
std::optional< Rect > GetBoundsLimit() const
Get the bounds limit, which is provided by the user when creating a SaveLayer.
Definition: entity_pass.cc:73
impeller::BlendMode::kDestination
@ kDestination
impeller::EntityPass
Definition: entity_pass.h:26
impeller::EntityPass::GetElementCount
size_t GetElementCount() const
Return the number of elements on this pass.
Definition: entity_pass.cc:1091
impeller::PaintPassDelegate::CanCollapseIntoParentPass
bool CanCollapseIntoParentPass(EntityPass *entity_pass) override
Whether or not this entity pass can be collapsed into the parent. If true, this method may modify the...
Definition: paint_pass_delegate.cc:31
impeller::OpacityPeepholePassDelegate::OpacityPeepholePassDelegate
OpacityPeepholePassDelegate(Paint paint)
Definition: paint_pass_delegate.cc:61
impeller::Entity::GetContents
const std::shared_ptr< Contents > & GetContents() const
Definition: entity.cc:81
impeller::FilterInput::Variant
std::variant< std::shared_ptr< FilterContents >, std::shared_ptr< Contents >, std::shared_ptr< Texture >, Rect > Variant
Definition: filter_input.h:36
entity_pass.h
impeller::OpacityPeepholePassDelegate::CanCollapseIntoParentPass
bool CanCollapseIntoParentPass(EntityPass *entity_pass) override
Whether or not this entity pass can be collapsed into the parent. If true, this method may modify the...
Definition: paint_pass_delegate.cc:73
impeller::Entity::RenderingMode::kSubpass
@ kSubpass
sampler_descriptor.h
impeller::Paint::WithImageFilter
std::shared_ptr< FilterContents > WithImageFilter(const FilterInput::Variant &input, const Matrix &effect_transform, Entity::RenderingMode rendering_mode) const
Definition: paint.cc:92
impeller::TRect< Scalar >::MakeSize
constexpr static TRect MakeSize(const TSize< U > &size)
Definition: rect.h:52
std
Definition: comparable.h:98
impeller::PaintPassDelegate::PaintPassDelegate
PaintPassDelegate(Paint paint)
Definition: paint_pass_delegate.cc:20
impeller::OpacityPeepholePassDelegate::~OpacityPeepholePassDelegate
~OpacityPeepholePassDelegate() override
impeller::PaintPassDelegate::WithImageFilter
std::shared_ptr< FilterContents > WithImageFilter(const FilterInput::Variant &input, const Matrix &effect_transform) const override
Definition: paint_pass_delegate.cc:51
impeller::PaintPassDelegate::~PaintPassDelegate
~PaintPassDelegate() override
color.h
impeller::PaintPassDelegate::CanElide
bool CanElide() override
Definition: paint_pass_delegate.cc:26
impeller::TextureContents::MakeRect
static std::shared_ptr< TextureContents > MakeRect(Rect destination)
A common case factory that marks the texture contents as having a destination rectangle....
Definition: texture_contents.cc:28
impeller
Definition: aiks_context.cc:10
impeller::Matrix
A 4x4 matrix using column-major storage.
Definition: matrix.h:36
impeller::Paint::WithFiltersForSubpassTarget
std::shared_ptr< Contents > WithFiltersForSubpassTarget(std::shared_ptr< Contents > input, const Matrix &effect_transform=Matrix()) const
Wrap this paint's configured filters to the given contents of subpass target.
Definition: paint.cc:71
impeller::Paint::blend_mode
BlendMode blend_mode
Definition: paint.h:63
impeller::Paint::image_filter
std::shared_ptr< ImageFilter > image_filter
Definition: paint.h:66
impeller::OpacityPeepholePassDelegate::CanElide
bool CanElide() override
Definition: paint_pass_delegate.cc:68