Flutter Engine
 
Loading...
Searching...
No Matches
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 <utility>
13#include <vector>
14
37
38namespace impeller {
39
41 size_t backdrop_count = 0;
42 bool all_filters_equal = true;
43 std::shared_ptr<Texture> texture_slot;
44 // A single snapshot of the backdrop filter that is used when there are
45 // multiple backdrops that share an identical filter.
46 std::optional<Snapshot> shared_filter_snapshot;
47 std::shared_ptr<flutter::DlImageFilter> last_backdrop;
48};
49
52 uint32_t clip_depth = 0u;
53 size_t clip_height = 0u;
54 // The number of clips tracked for this canvas stack entry.
55 size_t num_clips = 0u;
58 // Whether all entities in the current save should be skipped.
59 bool skipping = false;
60 // Whether subpass coverage was rounded out to pixel coverage, or if false
61 // truncated.
62 bool did_round_out = false;
63};
64
65enum class PointStyle {
66 /// @brief Points are drawn as squares.
67 kRound,
68
69 /// @brief Points are drawn as circles.
70 kSquare,
71};
72
73/// Controls the behavior of the source rectangle given to DrawImageRect.
75 /// @brief Faster, but may sample outside the bounds of the source rectangle.
76 kFast,
77
78 /// @brief Sample only within the source rectangle. May be slower.
79 kStrict,
80};
81
82/// Specifies how much to trust the bounds rectangle provided for a list
83/// of contents. Used by both |EntityPass| and |Canvas::SaveLayer|.
85 /// @brief The caller makes no claims related to the size of the bounds.
87
88 /// @brief The caller claims the bounds are a reasonably tight estimate
89 /// of the coverage of the contents and should contain all of the
90 /// contents.
92
93 /// @brief The caller claims the bounds are a subset of an estimate of
94 /// the reasonably tight bounds but likely clips off some of the
95 /// contents.
97};
98
100 public:
102 std::unique_ptr<EntityPassTarget> p_entity_pass_target);
103
105
106 /// Whether or not the clear color texture can still be updated.
107 bool IsApplyingClearColor() const;
108
110
112
113 private:
114 std::unique_ptr<EntityPassTarget> entity_pass_target_;
115 std::unique_ptr<InlinePassContext> inline_pass_context_;
116};
117
118class Canvas {
119 public:
120 static constexpr uint32_t kMaxDepth = 1 << 24;
121
122 using BackdropFilterProc = std::function<std::shared_ptr<FilterContents>(
124 const Matrix& effect_transform,
125 Entity::RenderingMode rendering_mode)>;
126
127 Canvas(ContentContext& renderer,
128 const RenderTarget& render_target,
129 bool is_onscreen,
130 bool requires_readback);
131
132 explicit Canvas(ContentContext& renderer,
133 const RenderTarget& render_target,
134 bool is_onscreen,
135 bool requires_readback,
136 Rect cull_rect);
137
138 explicit Canvas(ContentContext& renderer,
139 const RenderTarget& render_target,
140 bool is_onscreen,
141 bool requires_readback,
142 IRect32 cull_rect);
143
144 ~Canvas() = default;
145
146 /// @brief Update the backdrop data used to group together backdrop filters
147 /// within the same layer
148 void SetBackdropData(std::unordered_map<int64_t, BackdropData> backdrop_data,
149 size_t backdrop_count);
150
151 /// @brief Return the culling bounds of the current render target, or nullopt
152 /// if there is no coverage.
153 std::optional<Rect> GetLocalCoverageLimit() const;
154
155 void Save(uint32_t total_content_depth = kMaxDepth);
156
157 void SaveLayer(
158 const Paint& paint,
159 std::optional<Rect> bounds = std::nullopt,
160 const flutter::DlImageFilter* backdrop_filter = nullptr,
162 uint32_t total_content_depth = kMaxDepth,
163 bool can_distribute_opacity = false,
164 std::optional<int64_t> backdrop_id = std::nullopt);
165
166 bool Restore();
167
168 size_t GetSaveCount() const;
169
170 void RestoreToCount(size_t count);
171
172 const Matrix& GetCurrentTransform() const;
173
174 void ResetTransform();
175
176 void Transform(const Matrix& transform);
177
178 void Concat(const Matrix& transform);
179
180 void PreConcat(const Matrix& transform);
181
182 void Translate(const Vector3& offset);
183
184 void Scale(const Vector2& scale);
185
186 void Scale(const Vector3& scale);
187
188 void Skew(Scalar sx, Scalar sy);
189
190 void Rotate(Radians radians);
191
192 void DrawPath(const flutter::DlPath& path, const Paint& paint);
193
194 void DrawPaint(const Paint& paint);
195
196 void DrawLine(const Point& p0,
197 const Point& p1,
198 const Paint& paint,
199 bool reuse_depth = false);
200
201 void DrawDashedLine(const Point& p0,
202 const Point& p1,
203 Scalar on_length,
204 Scalar off_length,
205 const Paint& paint);
206
207 void DrawRect(const Rect& rect, const Paint& paint);
208
209 void DrawOval(const Rect& rect, const Paint& paint);
210
211 void DrawArc(const Arc& arc, const Paint& paint);
212
213 void DrawRoundRect(const RoundRect& rect, const Paint& paint);
214
215 void DrawDiffRoundRect(const RoundRect& outer,
216 const RoundRect& inner,
217 const Paint& paint);
218
219 void DrawRoundSuperellipse(const RoundSuperellipse& rse, const Paint& paint);
220
221 void DrawCircle(const Point& center, Scalar radius, const Paint& paint);
222
223 void DrawPoints(const Point points[],
224 uint32_t count,
225 Scalar radius,
226 const Paint& paint,
227 PointStyle point_style);
228
229 void DrawImage(const std::shared_ptr<Texture>& image,
230 Point offset,
231 const Paint& paint,
232 const SamplerDescriptor& sampler = {});
233
234 void DrawImageRect(
235 const std::shared_ptr<Texture>& image,
236 Rect source,
237 Rect dest,
238 const Paint& paint,
239 const SamplerDescriptor& sampler = {},
241
242 void DrawTextFrame(const std::shared_ptr<TextFrame>& text_frame,
243 Point position,
244 const Paint& paint);
245
246 void DrawVertices(const std::shared_ptr<VerticesGeometry>& vertices,
247 BlendMode blend_mode,
248 const Paint& paint);
249
250 void DrawAtlas(const std::shared_ptr<AtlasContents>& atlas_contents,
251 const Paint& paint);
252
253 void ClipGeometry(const Geometry& geometry,
254 Entity::ClipOperation clip_op,
255 bool is_aa = true);
256
257 void EndReplay();
258
259 uint64_t GetOpDepth() const { return current_depth_; }
260
261 uint64_t GetMaxOpDepth() const { return transform_stack_.back().clip_depth; }
262
267
268 // Visible for testing.
269 bool RequiresReadback() const { return requires_readback_; }
270
271 // Whether the current device has the capabilities to blit an offscreen
272 // texture into the onscreen.
273 //
274 // This requires the availibility of the blit framebuffer command, but is
275 // disabled for GLES. A simple glBlitFramebuffer does not support resolving
276 // different sample counts which may be present in GLES when using MSAA.
277 //
278 // Visible for testing.
279 bool SupportsBlitToOnscreen() const;
280
281 /// For picture snapshots we need addition steps to verify that final mipmaps
282 /// are generated.
283 bool EnsureFinalMipmapGeneration() const;
284
285 private:
286 class RRectLikeBlurShape {
287 public:
288 virtual ~RRectLikeBlurShape() = default;
289 virtual std::shared_ptr<SolidRRectLikeBlurContents> BuildBlurContent() = 0;
290 virtual Geometry& BuildGeometry(Rect rect, Scalar radius) = 0;
291 };
292
293 class RRectBlurShape : public RRectLikeBlurShape {
294 public:
295 std::shared_ptr<SolidRRectLikeBlurContents> BuildBlurContent() override;
296 Geometry& BuildGeometry(Rect rect, Scalar radius) override;
297
298 private:
299 std::optional<RoundRectGeometry> geom_; // optional stack allocation
300 };
301
302 class RSuperellipseBlurShape : public RRectLikeBlurShape {
303 public:
304 std::shared_ptr<SolidRRectLikeBlurContents> BuildBlurContent() override;
305 Geometry& BuildGeometry(Rect rect, Scalar radius) override;
306
307 private:
308 std::optional<RoundSuperellipseGeometry>
309 geom_; // optional stack allocation
310 };
311
312 ContentContext& renderer_;
313 RenderTarget render_target_;
314 const bool is_onscreen_;
315 bool requires_readback_;
316 EntityPassClipStack clip_coverage_stack_;
317
318 std::deque<CanvasStackEntry> transform_stack_;
319 std::optional<Rect> initial_cull_rect_;
320 std::vector<LazyRenderingConfig> render_passes_;
321 std::vector<SaveLayerState> save_layer_state_;
322
323 /// Backdrop layers identified by an optional backdrop id.
324 ///
325 /// This is not the same as the [backdrop_count_] below as not
326 /// all backdrop filters will have an identified backdrop id. The
327 /// backdrop_count_ is also mutated during rendering.
328 std::unordered_map<int64_t, BackdropData> backdrop_data_;
329
330 /// The remaining number of backdrop filters.
331 ///
332 /// This value is decremented while rendering. When it reaches 0, then
333 /// the FlipBackdrop can use the onscreen render target instead of
334 /// another offscreen.
335 ///
336 /// This optimization is disabled on devices that do not support framebuffer
337 /// fetch (iOS Simulator and certain OpenGLES devices).
338 size_t backdrop_count_ = 0u;
339
340 // All geometry objects created for regular draws can be stack allocated,
341 // but clip geometries must be cached for record/replay for backdrop filters
342 // and so must be kept alive longer.
343 std::vector<std::unique_ptr<Geometry>> clip_geometry_;
344
345 uint64_t current_depth_ = 0u;
346
347 Point GetGlobalPassPosition() const;
348
349 // clip depth of the previous save or 0.
350 size_t GetClipHeightFloor() const;
351
352 /// @brief Whether all entites should be skipped until a corresponding
353 /// restore.
354 bool IsSkipping() const;
355
356 /// @brief Skip all rendering/clipping entities until next restore.
357 void SkipUntilMatchingRestore(size_t total_content_depth);
358
359 void SetupRenderPass();
360
361 /// @brief Ends the current render pass, saving the result as a texture, and
362 /// thenrestart it with the backdrop cleared to the previous contents.
363 ///
364 /// The returned texture is used as the input for backdrop filters and
365 /// emulated advanced blends. Returns nullptr if there was a validation
366 /// failure.
367 ///
368 /// [should_remove_texture] defaults to false. If true, the render target
369 /// texture is removed from the entity pass target. This allows the texture to
370 /// be cached by the canvas dispatcher for usage in the backdrop filter reuse
371 /// mechanism.
372 ///
373 /// [should_use_onscreen] defaults to false. If true, the results are flipped
374 /// to the onscreen render target. This will set requires_readback_ to false.
375 /// This action is only safe to perform when there are no more backdrop
376 /// filters or advanced blends, or no more backdrop filters and the device
377 /// supports framebuffer fetch.
378 std::shared_ptr<Texture> FlipBackdrop(Point global_pass_position,
379 bool should_remove_texture = false,
380 bool should_use_onscreen = false,
381 bool post_depth_increment = false);
382
383 bool BlitToOnscreen(bool is_onscreen = false);
384
385 size_t GetClipHeight() const;
386
387 void Initialize(std::optional<Rect> cull_rect);
388
389 void Reset();
390
391 void AddRenderEntityWithFiltersToCurrentPass(Entity& entity,
392 const Geometry* geometry,
393 const Paint& paint,
394 bool reuse_depth = false);
395
396 void AddRenderEntityToCurrentPass(Entity& entity, bool reuse_depth = false);
397
398 bool AttemptDrawAntialiasedCircle(const Point& center,
399 Scalar radius,
400 const Paint& paint);
401
402 bool AttemptDrawBlurredRRect(const Rect& rect,
403 Size corner_radii,
404 const Paint& paint);
405
406 bool AttemptDrawBlurredRSuperellipse(const Rect& rect,
407 Size corner_radii,
408 const Paint& paint);
409
410 bool AttemptDrawBlurredRRectLike(const Rect& rect,
411 Size corner_radii,
412 const Paint& paint,
413 RRectLikeBlurShape& shape);
414
415 /// For simple DrawImageRect calls, optimize any draws with a color filter
416 /// into the corresponding atlas draw.
417 ///
418 /// Returns whether not the optimization was applied.
419 bool AttemptColorFilterOptimization(const std::shared_ptr<Texture>& image,
420 Rect source,
421 Rect dest,
422 const Paint& paint,
423 const SamplerDescriptor& sampler,
424 SourceRectConstraint src_rect_constraint);
425
426 bool AttemptBlurredTextOptimization(
427 const std::shared_ptr<TextFrame>& text_frame,
428 const std::shared_ptr<TextContents>& text_contents,
429 Entity& entity,
430 const Paint& paint);
431
432 RenderPass& GetCurrentRenderPass() const;
433
434 Canvas(const Canvas&) = delete;
435
436 Canvas& operator=(const Canvas&) = delete;
437};
438
439} // namespace impeller
440
441#endif // FLUTTER_IMPELLER_DISPLAY_LIST_CANVAS_H_
void ClipGeometry(const Geometry &geometry, Entity::ClipOperation clip_op, bool is_aa=true)
Definition canvas.cc:861
static constexpr uint32_t kMaxDepth
Definition canvas.h:120
void SetBackdropData(std::unordered_map< int64_t, BackdropData > backdrop_data, size_t backdrop_count)
Update the backdrop data used to group together backdrop filters within the same layer.
Definition canvas.cc:1927
Canvas(ContentContext &renderer, const RenderTarget &render_target, bool is_onscreen, bool requires_readback)
Definition canvas.cc:199
bool RequiresReadback() const
Definition canvas.h:269
~Canvas()=default
Definition canvas.cc:48
void DrawRoundSuperellipse(const RoundSuperellipse &rse, const Paint &paint)
Definition canvas.cc:812
std::optional< Rect > GetLocalCoverageLimit() const
Return the culling bounds of the current render target, or nullopt if there is no coverage.
Definition canvas.cc:1237
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, std::optional< int64_t > backdrop_id=std::nullopt)
Definition canvas.cc:1274
const Matrix & GetCurrentTransform() const
Definition canvas.cc:273
void DrawVertices(const std::shared_ptr< VerticesGeometry > &vertices, BlendMode blend_mode, const Paint &paint)
Definition canvas.cc:1040
void DrawOval(const Rect &rect, const Paint &paint)
Definition canvas.cc:680
void DrawImageRect(const std::shared_ptr< Texture > &image, Rect source, Rect dest, const Paint &paint, const SamplerDescriptor &sampler={}, SourceRectConstraint src_rect_constraint=SourceRectConstraint::kFast)
Definition canvas.cc:975
void RestoreToCount(size_t count)
Definition canvas.cc:320
size_t GetSaveCount() const
Definition canvas.cc:312
void Concat(const Matrix &transform)
Definition canvas.cc:257
void Transform(const Matrix &transform)
Definition canvas.cc:269
uint64_t GetMaxOpDepth() const
Definition canvas.h:261
void DrawDashedLine(const Point &p0, const Point &p1, Scalar on_length, Scalar off_length, const Paint &paint)
Definition canvas.cc:636
void DrawDiffRoundRect(const RoundRect &outer, const RoundRect &inner, const Paint &paint)
Definition canvas.cc:796
void DrawPath(const flutter::DlPath &path, const Paint &paint)
Definition canvas.cc:328
std::function< std::shared_ptr< FilterContents >(FilterInput::Ref, const Matrix &effect_transform, Entity::RenderingMode rendering_mode)> BackdropFilterProc
Definition canvas.h:125
void PreConcat(const Matrix &transform)
Definition canvas.cc:261
void Rotate(Radians radians)
Definition canvas.cc:293
void DrawPoints(const Point points[], uint32_t count, Scalar radius, const Paint &paint, PointStyle point_style)
Definition canvas.cc:943
void ResetTransform()
Definition canvas.cc:265
void DrawTextFrame(const std::shared_ptr< TextFrame > &text_frame, Point position, const Paint &paint)
Definition canvas.cc:1704
void DrawImage(const std::shared_ptr< Texture > &image, Point offset, const Paint &paint, const SamplerDescriptor &sampler={})
Definition canvas.cc:961
void DrawPaint(const Paint &paint)
Definition canvas.cc:342
void DrawRoundRect(const RoundRect &rect, const Paint &paint)
Definition canvas.cc:764
void Skew(Scalar sx, Scalar sy)
Definition canvas.cc:289
void Scale(const Vector2 &scale)
Definition canvas.cc:281
uint64_t GetOpDepth() const
Definition canvas.h:259
void Save(uint32_t total_content_depth=kMaxDepth)
Definition canvas.cc:1220
bool SupportsBlitToOnscreen() const
Definition canvas.cc:2050
void DrawRect(const Rect &rect, const Paint &paint)
Definition canvas.cc:662
bool EnsureFinalMipmapGeneration() const
Definition canvas.cc:2108
void DrawAtlas(const std::shared_ptr< AtlasContents > &atlas_contents, const Paint &paint)
Definition canvas.cc:1154
void DrawLine(const Point &p0, const Point &p1, const Paint &paint, bool reuse_depth=false)
Definition canvas.cc:614
void Translate(const Vector3 &offset)
Definition canvas.cc:277
void DrawCircle(const Point &center, Scalar radius, const Paint &paint)
Definition canvas.cc:834
void DrawArc(const Arc &arc, const Paint &paint)
Definition canvas.cc:709
std::shared_ptr< FilterInput > Ref
bool IsApplyingClearColor() const
Whether or not the clear color texture can still be updated.
Definition canvas.cc:2162
EntityPassTarget * GetEntityPassTarget() const
Definition canvas.cc:2166
LazyRenderingConfig(LazyRenderingConfig &&)=default
InlinePassContext * GetInlinePassContext() const
Definition canvas.cc:2170
FlutterVulkanImage * image
float Scalar
Definition scalar.h:19
SourceRectConstraint
Controls the behavior of the source rectangle given to DrawImageRect.
Definition canvas.h:74
@ kStrict
Sample only within the source rectangle. May be slower.
@ kFast
Faster, but may sample outside the bounds of the source rectangle.
TRect< Scalar > Rect
Definition rect.h:788
PointStyle
Definition canvas.h:65
@ kRound
Points are drawn as squares.
@ kSquare
Points are drawn as circles.
TPoint< Scalar > Point
Definition point.h:327
BlendMode
Definition color.h:58
ContentBoundsPromise
Definition canvas.h:84
@ kUnknown
The caller makes no claims related to the size of the bounds.
@ kMayClipContents
The caller claims the bounds are a subset of an estimate of the reasonably tight bounds but likely cl...
@ kContainsContents
The caller claims the bounds are a reasonably tight estimate of the coverage of the contents and shou...
TSize< Scalar > Size
Definition size.h:159
std::shared_ptr< Texture > texture_slot
Definition canvas.h:43
std::shared_ptr< flutter::DlImageFilter > last_backdrop
Definition canvas.h:47
std::optional< Snapshot > shared_filter_snapshot
Definition canvas.h:46
Definition canvas.h:50
size_t clip_height
Definition canvas.h:53
bool did_round_out
Definition canvas.h:62
Entity::RenderingMode rendering_mode
Definition canvas.h:57
Scalar distributed_opacity
Definition canvas.h:56
bool skipping
Definition canvas.h:59
size_t num_clips
Definition canvas.h:55
Matrix transform
Definition canvas.h:51
uint32_t clip_depth
Definition canvas.h:52
A 4x4 matrix using column-major storage.
Definition matrix.h:37
std::vector< Point > points