| Flutter Impeller |

canvas.h
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 #ifndef FLUTTER_IMPELLER_DISPLAY_LIST_CANVAS_H_
6 #define FLUTTER_IMPELLER_DISPLAY_LIST_CANVAS_H_
7
8 #include <deque>
9 #include <functional>
10 #include <memory>
11 #include <optional>
12 #include <vector>
13
14 #include "display_list/effects/dl_image_filter.h"
15 #include "impeller/core/sampler_descriptor.h"
16 #include "impeller/display_list/paint.h"
17 #include "impeller/entity/contents/atlas_contents.h"
18 #include "impeller/entity/entity.h"
19 #include "impeller/entity/entity_pass_clip_stack.h"
20 #include "impeller/entity/geometry/geometry.h"
21 #include "impeller/entity/geometry/vertices_geometry.h"
22 #include "impeller/entity/inline_pass_context.h"
23 #include "impeller/geometry/matrix.h"
24 #include "impeller/geometry/path.h"
25 #include "impeller/geometry/point.h"
26 #include "impeller/geometry/vector.h"
27 #include "impeller/typographer/text_frame.h"
28
29 namespace impeller {
30
31 struct CanvasStackEntry {
32 Matrix transform;
33 uint32_t clip_depth = 0u;
34 size_t clip_height = 0u;
35 // The number of clips tracked for this canvas stack entry.
36 size_t num_clips = 0u;
37 Scalar distributed_opacity = 1.0f;
38 Entity::RenderingMode rendering_mode = Entity::RenderingMode::kDirect;
39 // Whether all entities in the current save should be skipped.
40 bool skipping = false;
41 // Whether subpass coverage was rounded out to pixel coverage, or if false
42 // truncated.
43 bool did_round_out = false;
44 };
45
46 enum class PointStyle {
47 /// @brief Points are drawn as squares.
48 kRound,
49
50 /// @brief Points are drawn as circles.
51 kSquare,
52 };
53
54 /// Controls the behavior of the source rectangle given to DrawImageRect.
55 enum class SourceRectConstraint {
56 /// @brief Faster, but may sample outside the bounds of the source rectangle.
57 kFast,
58
59 /// @brief Sample only within the source rectangle. May be slower.
60 kStrict,
61 };
62
63 /// Specifies how much to trust the bounds rectangle provided for a list
64 /// of contents. Used by both |EntityPass| and |Canvas::SaveLayer|.
65 enum class ContentBoundsPromise {
66 /// @brief The caller makes no claims related to the size of the bounds.
67 kUnknown,
68
69 /// @brief The caller claims the bounds are a reasonably tight estimate
70 /// of the coverage of the contents and should contain all of the
71 /// contents.
72 kContainsContents,
73
74 /// @brief The caller claims the bounds are a subset of an estimate of
75 /// the reasonably tight bounds but likely clips off some of the
76 /// contents.
77 kMayClipContents,
78 };
79
80 struct LazyRenderingConfig {
81 std::unique_ptr<EntityPassTarget> entity_pass_target;
82 std::unique_ptr<InlinePassContext> inline_pass_context;
83
84 /// Whether or not the clear color texture can still be updated.
85 bool IsApplyingClearColor() const { return !inline_pass_context->IsActive(); }
86
87 LazyRenderingConfig(ContentContext& renderer,
88 std::unique_ptr<EntityPassTarget> p_entity_pass_target)
89 : entity_pass_target(std::move(p_entity_pass_target)) {
90 inline_pass_context =
91 std::make_unique<InlinePassContext>(renderer, *entity_pass_target, 0);
92 }
93
94 LazyRenderingConfig(ContentContext& renderer,
95 std::unique_ptr<EntityPassTarget> entity_pass_target,
96 std::unique_ptr<InlinePassContext> inline_pass_context)
97 : entity_pass_target(std::move(entity_pass_target)),
98 inline_pass_context(std::move(inline_pass_context)) {}
99 };
100
101 class Canvas {
102 public:
103 static constexpr uint32_t kMaxDepth = 1 << 24;
104
105 using BackdropFilterProc = std::function<std::shared_ptr<FilterContents>(
106 FilterInput::Ref,
107 const Matrix& effect_transform,
108 Entity::RenderingMode rendering_mode)>;
109
110 Canvas(ContentContext& renderer,
111 RenderTarget& render_target,
112 bool requires_readback);
113
114 explicit Canvas(ContentContext& renderer,
115 RenderTarget& render_target,
116 bool requires_readback,
117 Rect cull_rect);
118
119 explicit Canvas(ContentContext& renderer,
120 RenderTarget& render_target,
121 bool requires_readback,
122 IRect cull_rect);
123
124 ~Canvas() = default;
125
126 /// @brief Return the culling bounds of the current render target, or nullopt
127 /// if there is no coverage.
128 std::optional<Rect> GetLocalCoverageLimit() const;
129
130 void Save(uint32_t total_content_depth = kMaxDepth);
131
132 void SaveLayer(
133 const Paint& paint,
134 std::optional<Rect> bounds = std::nullopt,
135 const flutter::DlImageFilter* backdrop_filter = nullptr,
136 ContentBoundsPromise bounds_promise = ContentBoundsPromise::kUnknown,
137 uint32_t total_content_depth = kMaxDepth,
138 bool can_distribute_opacity = false);
139
140 bool Restore();
141
142 size_t GetSaveCount() const;
143
144 void RestoreToCount(size_t count);
145
146 const Matrix& GetCurrentTransform() const;
147
148 void ResetTransform();
149
150 void Transform(const Matrix& transform);
151
152 void Concat(const Matrix& transform);
153
154 void PreConcat(const Matrix& transform);
155
156 void Translate(const Vector3& offset);
157
158 void Scale(const Vector2& scale);
159
160 void Scale(const Vector3& scale);
161
162 void Skew(Scalar sx, Scalar sy);
163
164 void Rotate(Radians radians);
165
166 void DrawPath(const Path& path, const Paint& paint);
167
168 void DrawPaint(const Paint& paint);
169
170 void DrawLine(const Point& p0,
171 const Point& p1,
172 const Paint& paint,
173 bool reuse_depth = false);
174
175 void DrawRect(const Rect& rect, const Paint& paint);
176
177 void DrawOval(const Rect& rect, const Paint& paint);
178
179 void DrawRRect(const Rect& rect,
180 const Size& corner_radii,
181 const Paint& paint);
182
183 void DrawCircle(const Point& center, Scalar radius, const Paint& paint);
184
185 void DrawPoints(std::vector<Point> points,
186 Scalar radius,
187 const Paint& paint,
188 PointStyle point_style);
189
190 void DrawImage(const std::shared_ptr<Texture>& image,
191 Point offset,
192 const Paint& paint,
193 SamplerDescriptor sampler = {});
194
195 void DrawImageRect(
196 const std::shared_ptr<Texture>& image,
197 Rect source,
198 Rect dest,
199 const Paint& paint,
200 SamplerDescriptor sampler = {},
201 SourceRectConstraint src_rect_constraint = SourceRectConstraint::kFast);
202
203 void DrawTextFrame(const std::shared_ptr<TextFrame>& text_frame,
204 Point position,
205 const Paint& paint);
206
207 void DrawVertices(const std::shared_ptr<VerticesGeometry>& vertices,
208 BlendMode blend_mode,
209 const Paint& paint);
210
211 void DrawAtlas(const std::shared_ptr<AtlasContents>& atlas_contents,
212 const Paint& paint);
213
214 void ClipGeometry(std::unique_ptr<Geometry> geometry,
215 Entity::ClipOperation clip_op);
216
217 void EndReplay();
218
219 uint64_t GetOpDepth() const { return current_depth_; }
220
221 uint64_t GetMaxOpDepth() const { return transform_stack_.back().clip_depth; }
222
223 struct SaveLayerState {
224 Paint paint;
225 Rect coverage;
226 };
227
228 private:
229 ContentContext& renderer_;
230 RenderTarget& render_target_;
231 const bool requires_readback_;
232 EntityPassClipStack clip_coverage_stack_;
233
234 std::deque<CanvasStackEntry> transform_stack_;
235 std::optional<Rect> initial_cull_rect_;
236 std::vector<LazyRenderingConfig> render_passes_;
237 std::vector<SaveLayerState> save_layer_state_;
238
239 // All geometry objects created for regular draws can be stack allocated,
240 // but clip geometries must be cached for record/replay for backdrop filters
241 // and so must be kept alive longer.
242 std::vector<std::unique_ptr<Geometry>> clip_geometry_;
243
244 uint64_t current_depth_ = 0u;
245
246 Point GetGlobalPassPosition() const;
247
248 // clip depth of the previous save or 0.
249 size_t GetClipHeightFloor() const;
250
251 /// @brief Whether all entites should be skipped until a corresponding
252 /// restore.
253 bool IsSkipping() const;
254
255 /// @brief Skip all rendering/clipping entities until next restore.
256 void SkipUntilMatchingRestore(size_t total_content_depth);
257
258 void SetupRenderPass();
259
260 bool BlitToOnscreen();
261
262 size_t GetClipHeight() const;
263
264 void Initialize(std::optional<Rect> cull_rect);
265
266 void Reset();
267
268 void AddRenderEntityWithFiltersToCurrentPass(Entity& entity,
269 const Geometry* geometry,
270 const Paint& paint,
271 bool reuse_depth = false);
272
273 void AddRenderEntityToCurrentPass(Entity& entity, bool reuse_depth = false);
274
275 void AddClipEntityToCurrentPass(Entity& entity);
276
277 void RestoreClip();
278
279 bool AttemptDrawBlurredRRect(const Rect& rect,
280 Size corner_radii,
281 const Paint& paint);
282
283 Canvas(const Canvas&) = delete;
284
285 Canvas& operator=(const Canvas&) = delete;
286 };
287
288 } // namespace impeller
289
290 #endif // FLUTTER_IMPELLER_DISPLAY_LIST_CANVAS_H_
impeller::Canvas::DrawPoints
void DrawPoints(std::vector< Point > points, Scalar radius, const Paint &paint, PointStyle point_style)
Definition: canvas.cc:685
impeller::LazyRenderingConfig::IsApplyingClearColor
bool IsApplyingClearColor() const
Whether or not the clear color texture can still be updated.
Definition: canvas.h:85
impeller::CanvasStackEntry::distributed_opacity
Scalar distributed_opacity
Definition: canvas.h:37
impeller::CanvasStackEntry::skipping
bool skipping
Definition: canvas.h:40
impeller::Canvas::DrawRRect
void DrawRRect(const Rect &rect, const Size &corner_radii, const Paint &paint)
Definition: canvas.cc:607
point.h
impeller::Scalar
float Scalar
Definition: scalar.h:18
impeller::Canvas::RestoreToCount
void RestoreToCount(size_t count)
Definition: canvas.cc:378
impeller::SourceRectConstraint::kFast
@ kFast
Faster, but may sample outside the bounds of the source rectangle.
impeller::ContentBoundsPromise::kMayClipContents
@ kMayClipContents
The caller claims the bounds are a subset of an estimate of the reasonably tight bounds but likely cl...
geometry.h
entity.h
impeller::CanvasStackEntry
Definition: canvas.h:31
impeller::Paint
Definition: paint.h:26
impeller::Canvas::Skew
void Skew(Scalar sx, Scalar sy)
Definition: canvas.cc:347
impeller::BlendMode
BlendMode
Definition: color.h:58
impeller::LazyRenderingConfig
Definition: canvas.h:80
impeller::Canvas::SaveLayer
void SaveLayer(const Paint &paint, std::optional< Rect > bounds=std::nullopt, const flutter::DlImageFilter *backdrop_filter=nullptr, ContentBoundsPromise bounds_promise=ContentBoundsPromise::kUnknown, uint32_t total_content_depth=kMaxDepth, bool can_distribute_opacity=false)
Definition: canvas.cc:986
impeller::PointStyle
PointStyle
Definition: canvas.h:46
impeller::Canvas::DrawTextFrame
void DrawTextFrame(const std::shared_ptr< TextFrame > &text_frame, Point position, const Paint &paint)
Definition: canvas.cc:1313
impeller::Canvas
Definition: canvas.h:101
impeller::PointStyle::kRound
@ kRound
Points are drawn as squares.
impeller::FilterInput::Ref
std::shared_ptr< FilterInput > Ref
Definition: filter_input.h:32
impeller::Canvas::ResetTransform
void ResetTransform()
Definition: canvas.cc:323
impeller::Canvas::DrawVertices
void DrawVertices(const std::shared_ptr< VerticesGeometry > &vertices, BlendMode blend_mode, const Paint &paint)
Definition: canvas.cc:762
impeller::ContentBoundsPromise
ContentBoundsPromise
Definition: canvas.h:65
impeller::ContentBoundsPromise::kUnknown
@ kUnknown
The caller makes no claims related to the size of the bounds.
impeller::CanvasStackEntry::num_clips
size_t num_clips
Definition: canvas.h:36
impeller::LazyRenderingConfig::LazyRenderingConfig
LazyRenderingConfig(ContentContext &renderer, std::unique_ptr< EntityPassTarget > p_entity_pass_target)
Definition: canvas.h:87
impeller::CanvasStackEntry::rendering_mode
Entity::RenderingMode rendering_mode
Definition: canvas.h:38
impeller::Canvas::DrawRect
void DrawRect(const Rect &rect, const Paint &paint)
Definition: canvas.cc:559
offset
SeparatedVector2 offset
Definition: stroke_path_geometry.cc:304
impeller::Canvas::GetCurrentTransform
const Matrix & GetCurrentTransform() const
Definition: canvas.cc:331
impeller::Canvas::Concat
void Concat(const Matrix &transform)
Definition: canvas.cc:315
impeller::CanvasStackEntry::clip_height
size_t clip_height
Definition: canvas.h:34
impeller::SamplerDescriptor
Definition: sampler_descriptor.h:15
matrix.h
impeller::Canvas::GetMaxOpDepth
uint64_t GetMaxOpDepth() const
Definition: canvas.h:221
impeller::Entity
Definition: entity.h:20
impeller::Canvas::SaveLayerState
Definition: canvas.h:223
impeller::SourceRectConstraint::kStrict
@ kStrict
Sample only within the source rectangle. May be slower.
impeller::TSize< Scalar >
impeller::PointStyle::kSquare
@ kSquare
Points are drawn as circles.
impeller::Point
TPoint< Scalar > Point
Definition: point.h:327
impeller::Canvas::Scale
void Scale(const Vector2 &scale)
Definition: canvas.cc:339
impeller::LazyRenderingConfig::LazyRenderingConfig
LazyRenderingConfig(ContentContext &renderer, std::unique_ptr< EntityPassTarget > entity_pass_target, std::unique_ptr< InlinePassContext > inline_pass_context)
Definition: canvas.h:94
impeller::Path
Paths are lightweight objects that describe a collection of linear, quadratic, or cubic segments....
Definition: path.h:52
impeller::Canvas::GetLocalCoverageLimit
std::optional< Rect > GetLocalCoverageLimit() const
Return the culling bounds of the current render target, or nullopt if there is no coverage.
Definition: canvas.cc:955
impeller::Canvas::Canvas
Canvas(ContentContext &renderer, RenderTarget &render_target, bool requires_readback)
Definition: canvas.cc:263
impeller::LazyRenderingConfig::inline_pass_context
std::unique_ptr< InlinePassContext > inline_pass_context
Definition: canvas.h:82
transform
Matrix transform
Definition: gaussian_blur_filter_contents.cc:213
impeller::Canvas::SaveLayerState::coverage
Rect coverage
Definition: canvas.h:225
impeller::Canvas::~Canvas
~Canvas()=default
impeller::Canvas::DrawCircle
void DrawCircle(const Point &center, Scalar radius, const Paint &paint)
Definition: canvas.cc:632
impeller::SourceRectConstraint
SourceRectConstraint
Controls the behavior of the source rectangle given to DrawImageRect.
Definition: canvas.h:55
impeller::Canvas::Restore
bool Restore()
Definition: canvas.cc:1138
impeller::Radians
Definition: scalar.h:43
impeller::Entity::RenderingMode::kDirect
@ kDirect
impeller::CanvasStackEntry::clip_depth
uint32_t clip_depth
Definition: canvas.h:33
impeller::RenderTarget
Definition: render_target.h:38
impeller::Canvas::DrawPath
void DrawPath(const Path &path, const Paint &paint)
Definition: canvas.cc:386
impeller::Canvas::DrawPaint
void DrawPaint(const Paint &paint)
Definition: canvas.cc:401
impeller::Canvas::GetSaveCount
size_t GetSaveCount() const
Definition: canvas.cc:370
impeller::Canvas::DrawImageRect
void DrawImageRect(const std::shared_ptr< Texture > &image, Rect source, Rect dest, const Paint &paint, SamplerDescriptor sampler={}, SourceRectConstraint src_rect_constraint=SourceRectConstraint::kFast)
Definition: canvas.cc:716
vertices_geometry.h
impeller::Canvas::DrawAtlas
void DrawAtlas(const std::shared_ptr< AtlasContents > &atlas_contents, const Paint &paint)
Definition: canvas.cc:872
entity_pass_clip_stack.h
impeller::Canvas::ClipGeometry
void ClipGeometry(std::unique_ptr< Geometry > geometry, Entity::ClipOperation clip_op)
Definition: canvas.cc:655
impeller::Canvas::GetOpDepth
uint64_t GetOpDepth() const
Definition: canvas.h:219
impeller::Canvas::DrawImage
void DrawImage(const std::shared_ptr< Texture > &image, Point offset, const Paint &paint, SamplerDescriptor sampler={})
Definition: canvas.cc:702
impeller::Canvas::PreConcat
void PreConcat(const Matrix &transform)
Definition: canvas.cc:319
impeller::Canvas::BackdropFilterProc
std::function< std::shared_ptr< FilterContents >(FilterInput::Ref, const Matrix &effect_transform, Entity::RenderingMode rendering_mode)> BackdropFilterProc
Definition: canvas.h:108
atlas_contents.h
sampler_descriptor.h
impeller::CanvasStackEntry::transform
Matrix transform
Definition: canvas.h:32
impeller::Canvas::DrawOval
void DrawOval(const Rect &rect, const Paint &paint)
Definition: canvas.cc:577
impeller::Geometry
Definition: geometry.h:55
impeller::Canvas::Rotate
void Rotate(Radians radians)
Definition: canvas.cc:351
vector.h
std
Definition: comparable.h:95
impeller::Canvas::SaveLayerState::paint
Paint paint
Definition: canvas.h:224
impeller::TPoint< Scalar >
impeller::Canvas::Transform
void Transform(const Matrix &transform)
Definition: canvas.cc:327
impeller::Canvas::DrawLine
void DrawLine(const Point &p0, const Point &p1, const Paint &paint, bool reuse_depth=false)
Definition: canvas.cc:546
impeller::Canvas::Save
void Save(uint32_t total_content_depth=kMaxDepth)
Definition: canvas.cc:938
scale
const Scalar scale
Definition: stroke_path_geometry.cc:301
impeller::Entity::ClipOperation
ClipOperation
Definition: entity.h:61
impeller::EntityPassClipStack
A class that tracks all clips that have been recorded in the current entity pass stencil.
Definition: entity_pass_clip_stack.h:24
impeller::LazyRenderingConfig::entity_pass_target
std::unique_ptr< EntityPassTarget > entity_pass_target
Definition: canvas.h:81
impeller::Entity::RenderingMode
RenderingMode
Definition: entity.h:27
impeller::Canvas::EndReplay
void EndReplay()
Definition: canvas.cc:1643
text_frame.h
impeller::CanvasStackEntry::did_round_out
bool did_round_out
Definition: canvas.h:43
path.h
paint.h
impeller::ContentBoundsPromise::kContainsContents
@ kContainsContents
The caller claims the bounds are a reasonably tight estimate of the coverage of the contents and shou...
impeller
Definition: allocation.cc:12
impeller::ContentContext
Definition: content_context.h:366
impeller::TRect< Scalar >
impeller::Matrix
A 4x4 matrix using column-major storage.
Definition: matrix.h:37
impeller::Vector3
Definition: vector.h:20
inline_pass_context.h
impeller::Canvas::Translate
void Translate(const Vector3 &offset)
Definition: canvas.cc:335
impeller::Canvas::kMaxDepth
static constexpr uint32_t kMaxDepth
Definition: canvas.h:103