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