Flutter Engine
The Flutter Engine
display_list.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_DISPLAY_LIST_DISPLAY_LIST_H_
6#define FLUTTER_DISPLAY_LIST_DISPLAY_LIST_H_
7
8#include <memory>
9#include <optional>
10
11#include "flutter/display_list/dl_blend_mode.h"
12#include "flutter/display_list/dl_sampling_options.h"
13#include "flutter/display_list/geometry/dl_rtree.h"
14#include "flutter/fml/logging.h"
15
16// The Flutter DisplayList mechanism encapsulates a persistent sequence of
17// rendering operations.
18//
19// This file contains the definitions for:
20// DisplayList: the base class that holds the information about the
21// sequence of operations and can dispatch them to a DlOpReceiver
22// DlOpReceiver: a pure virtual interface which can be implemented to field
23// the requests for purposes such as sending them to an SkCanvas
24// or detecting various rendering optimization scenarios
25// DisplayListBuilder: a class for constructing a DisplayList from DlCanvas
26// method calls and which can act as a DlOpReceiver as well
27//
28// Other files include various class definitions for dealing with display
29// lists, such as:
30// skia/dl_sk_*.h: classes to interact between SkCanvas and DisplayList
31// (SkCanvas->DisplayList adapter and vice versa)
32//
33// display_list_utils.h: various utility classes to ease implementing
34// a DlOpReceiver, including NOP implementations of
35// the attribute, clip, and transform methods,
36// classes to track attributes, clips, and transforms
37// and a class to compute the bounds of a DisplayList
38// Any class implementing DlOpReceiver can inherit from
39// these utility classes to simplify its creation
40//
41// The Flutter DisplayList mechanism is used in a similar manner to the Skia
42// SkPicture mechanism.
43//
44// A DisplayList must be created using a DisplayListBuilder using its stateless
45// methods inherited from DlCanvas.
46//
47// A DisplayList can be read back by implementing the DlOpReceiver virtual
48// methods (with help from some of the classes in the utils file) and
49// passing an instance to the Dispatch() method, or it can be rendered
50// to Skia using a DlSkCanvasDispatcher.
51//
52// The mechanism is inspired by the SkLiteDL class that is not directly
53// supported by Skia, but has been recommended as a basis for custom
54// display lists for a number of their customers.
55
56namespace flutter {
57
58#define FOR_EACH_DISPLAY_LIST_OP(V) \
59 V(SetAntiAlias) \
60 V(SetInvertColors) \
61 \
62 V(SetStrokeCap) \
63 V(SetStrokeJoin) \
64 \
65 V(SetStyle) \
66 V(SetStrokeWidth) \
67 V(SetStrokeMiter) \
68 \
69 V(SetColor) \
70 V(SetBlendMode) \
71 \
72 V(ClearColorFilter) \
73 V(SetPodColorFilter) \
74 \
75 V(ClearColorSource) \
76 V(SetPodColorSource) \
77 V(SetImageColorSource) \
78 V(SetRuntimeEffectColorSource) \
79 \
80 V(ClearImageFilter) \
81 V(SetPodImageFilter) \
82 V(SetSharedImageFilter) \
83 \
84 V(ClearMaskFilter) \
85 V(SetPodMaskFilter) \
86 \
87 V(Save) \
88 V(SaveLayer) \
89 V(SaveLayerBackdrop) \
90 V(Restore) \
91 \
92 V(Translate) \
93 V(Scale) \
94 V(Rotate) \
95 V(Skew) \
96 V(Transform2DAffine) \
97 V(TransformFullPerspective) \
98 V(TransformReset) \
99 \
100 V(ClipIntersectRect) \
101 V(ClipIntersectRRect) \
102 V(ClipIntersectPath) \
103 V(ClipDifferenceRect) \
104 V(ClipDifferenceRRect) \
105 V(ClipDifferencePath) \
106 \
107 V(DrawPaint) \
108 V(DrawColor) \
109 \
110 V(DrawLine) \
111 V(DrawDashedLine) \
112 V(DrawRect) \
113 V(DrawOval) \
114 V(DrawCircle) \
115 V(DrawRRect) \
116 V(DrawDRRect) \
117 V(DrawArc) \
118 V(DrawPath) \
119 \
120 V(DrawPoints) \
121 V(DrawLines) \
122 V(DrawPolygon) \
123 V(DrawVertices) \
124 \
125 V(DrawImage) \
126 V(DrawImageWithAttr) \
127 V(DrawImageRect) \
128 V(DrawImageNine) \
129 V(DrawImageNineWithAttr) \
130 V(DrawAtlas) \
131 V(DrawAtlasCulled) \
132 \
133 V(DrawDisplayList) \
134 V(DrawTextBlob) \
135 V(DrawTextFrame) \
136 \
137 V(DrawShadow) \
138 V(DrawShadowTransparentOccluder)
139
140#define DL_OP_TO_ENUM_VALUE(name) k##name,
143#ifdef IMPELLER_ENABLE_3D
144 DL_OP_TO_ENUM_VALUE(SetSceneColorSource)
145#endif // IMPELLER_ENABLE_3D
146};
147#undef DL_OP_TO_ENUM_VALUE
148
149class DlOpReceiver;
150class DisplayListBuilder;
151
153 public:
156
160 : flags_(options->flags_) {}
161
164 options.fRendersWithAttributes = fRendersWithAttributes;
165 options.fBoundsFromCaller = fBoundsFromCaller;
166 return options;
167 }
168
172 options.fRendersWithAttributes = true;
173 return options;
174 }
175
179 options.fCanDistributeOpacity = true;
180 return options;
181 }
182
183 // Returns true iff the bounds for the saveLayer operation were provided
184 // by the caller, otherwise the bounds will have been computed by the
185 // DisplayListBuilder and provided for reference.
186 bool bounds_from_caller() const { return fBoundsFromCaller; }
189 options.fBoundsFromCaller = true;
190 return options;
191 }
194 options.fBoundsFromCaller = false;
195 return options;
196 }
198
199 // Returns true iff the bounds for the saveLayer do not fully cover the
200 // contained rendering operations. This will only occur if the original
201 // caller supplied bounds and those bounds were not a strict superset
202 // of the content bounds computed by the DisplayListBuilder.
203 bool content_is_clipped() const { return fContentIsClipped; }
206 options.fContentIsClipped = true;
207 return options;
208 }
209
213 options.fHasBackdropFilter = true;
214 return options;
215 }
216
218 flags_ = other.flags_;
219 return *this;
220 }
221 bool operator==(const SaveLayerOptions& other) const {
222 return flags_ == other.flags_;
223 }
224 bool operator!=(const SaveLayerOptions& other) const {
225 return flags_ != other.flags_;
226 }
227
228 private:
229 union {
230 struct {
233 unsigned fBoundsFromCaller : 1;
234 unsigned fContentIsClipped : 1;
235 unsigned fHasBackdropFilter : 1;
236 };
237 uint32_t flags_;
238 };
239};
240
241// Manages a buffer allocated with malloc.
243 public:
246
247 uint8_t* get() { return ptr_.get(); }
248
249 const uint8_t* get() const { return ptr_.get(); }
250
251 void realloc(size_t count) {
252 ptr_.reset(static_cast<uint8_t*>(std::realloc(ptr_.release(), count)));
253 FML_CHECK(ptr_);
254 }
255
256 private:
257 struct FreeDeleter {
258 void operator()(uint8_t* p) { std::free(p); }
259 };
260 std::unique_ptr<uint8_t, FreeDeleter> ptr_;
261};
262
263class Culler;
264
265// The base class that contains a sequence of rendering operations
266// for dispatch to a DlOpReceiver. These objects must be instantiated
267// through an instance of DisplayListBuilder::build().
268class DisplayList : public SkRefCnt {
269 public:
270 DisplayList();
271
272 ~DisplayList();
273
274 void Dispatch(DlOpReceiver& ctx) const;
275 void Dispatch(DlOpReceiver& ctx, const SkRect& cull_rect) const;
276 void Dispatch(DlOpReceiver& ctx, const SkIRect& cull_rect) const;
277
278 // From historical behavior, SkPicture always included nested bytes,
279 // but nested ops are only included if requested. The defaults used
280 // here for these accessors follow that pattern.
281 size_t bytes(bool nested = true) const {
282 return sizeof(DisplayList) + byte_count_ +
283 (nested ? nested_byte_count_ : 0);
284 }
285
286 uint32_t op_count(bool nested = false) const {
287 return op_count_ + (nested ? nested_op_count_ : 0);
288 }
289
290 uint32_t total_depth() const { return total_depth_; }
291
292 uint32_t unique_id() const { return unique_id_; }
293
294 const SkRect& bounds() const { return bounds_; }
295
296 bool has_rtree() const { return rtree_ != nullptr; }
297 sk_sp<const DlRTree> rtree() const { return rtree_; }
298
299 bool Equals(const DisplayList* other) const;
300 bool Equals(const DisplayList& other) const { return Equals(&other); }
301 bool Equals(const sk_sp<const DisplayList>& other) const {
302 return Equals(other.get());
303 }
304
305 bool can_apply_group_opacity() const { return can_apply_group_opacity_; }
306 bool isUIThreadSafe() const { return is_ui_thread_safe_; }
307
308 /// @brief Indicates if there are any rendering operations in this
309 /// DisplayList that will modify a surface of transparent black
310 /// pixels.
311 ///
312 /// This condition can be used to determine whether to create a cleared
313 /// surface, render a DisplayList into it, and then composite the
314 /// result into a scene. It is not uncommon for code in the engine to
315 /// come across such degenerate DisplayList objects when slicing up a
316 /// frame between platform views.
318 return modifies_transparent_black_;
319 }
320
321 const DisplayListStorage& GetStorage() const { return storage_; }
322
323 /// @brief Indicates if there are any saveLayer operations at the root
324 /// surface level of the DisplayList that use a backdrop filter.
325 ///
326 /// This condition can be used to determine what kind of surface to create
327 /// for the root layer into which to render the DisplayList as some GPUs
328 /// can support surfaces that do or do not support the readback that would
329 /// be required for the backdrop filter to do its work.
330 bool root_has_backdrop_filter() const { return root_has_backdrop_filter_; }
331
332 /// @brief Indicates the maximum DlBlendMode used on any rendering op
333 /// in the root surface of the DisplayList.
334 ///
335 /// This condition can be used to determine what kind of surface to create
336 /// for the root layer into which to render the DisplayList as some GPUs
337 /// can support surfaces that do or do not support the readback that would
338 /// be required for the indicated blend mode to do its work.
339 DlBlendMode max_root_blend_mode() const { return max_root_blend_mode_; }
340
341 private:
343 size_t byte_count,
344 uint32_t op_count,
345 size_t nested_byte_count,
346 uint32_t nested_op_count,
347 uint32_t total_depth,
348 const SkRect& bounds,
350 bool is_ui_thread_safe,
355
356 static uint32_t next_unique_id();
357
358 static void DisposeOps(const uint8_t* ptr, const uint8_t* end);
359
360 const DisplayListStorage storage_;
361 const size_t byte_count_;
362 const uint32_t op_count_;
363
364 const size_t nested_byte_count_;
365 const uint32_t nested_op_count_;
366
367 const uint32_t total_depth_;
368
369 const uint32_t unique_id_;
370 const SkRect bounds_;
371
372 const bool can_apply_group_opacity_;
373 const bool is_ui_thread_safe_;
374 const bool modifies_transparent_black_;
375 const bool root_has_backdrop_filter_;
376 const DlBlendMode max_root_blend_mode_;
377
378 const sk_sp<const DlRTree> rtree_;
379
380 void Dispatch(DlOpReceiver& ctx,
381 const uint8_t* ptr,
382 const uint8_t* end,
383 Culler& culler) const;
384
385 friend class DisplayListBuilder;
386};
387
388} // namespace flutter
389
390#endif // FLUTTER_DISPLAY_LIST_DISPLAY_LIST_H_
const char * options
int count
Definition: FontMgrTest.cpp:50
void realloc(size_t count)
Definition: display_list.h:251
DisplayListStorage(DisplayListStorage &&)=default
const uint8_t * get() const
Definition: display_list.h:249
bool Equals(const sk_sp< const DisplayList > &other) const
Definition: display_list.h:301
bool root_has_backdrop_filter() const
Indicates if there are any saveLayer operations at the root surface level of the DisplayList that use...
Definition: display_list.h:330
bool Equals(const DisplayList &other) const
Definition: display_list.h:300
const SkRect & bounds() const
Definition: display_list.h:294
uint32_t unique_id() const
Definition: display_list.h:292
const DisplayListStorage & GetStorage() const
Definition: display_list.h:321
bool modifies_transparent_black() const
Indicates if there are any rendering operations in this DisplayList that will modify a surface of tra...
Definition: display_list.h:317
bool can_apply_group_opacity() const
Definition: display_list.h:305
DlBlendMode max_root_blend_mode() const
Indicates the maximum DlBlendMode used on any rendering op in the root surface of the DisplayList.
Definition: display_list.h:339
bool Equals(const DisplayList *other) const
uint32_t total_depth() const
Definition: display_list.h:290
size_t bytes(bool nested=true) const
Definition: display_list.h:281
bool isUIThreadSafe() const
Definition: display_list.h:306
bool has_rtree() const
Definition: display_list.h:296
uint32_t op_count(bool nested=false) const
Definition: display_list.h:286
void Dispatch(DlOpReceiver &ctx) const
sk_sp< const DlRTree > rtree() const
Definition: display_list.h:297
Internal API for rendering recorded display lists to backends.
bool content_is_clipped() const
Definition: display_list.h:203
bool operator!=(const SaveLayerOptions &other) const
Definition: display_list.h:224
static const SaveLayerOptions kNoAttributes
Definition: display_list.h:155
SaveLayerOptions with_renders_with_attributes() const
Definition: display_list.h:170
SaveLayerOptions & operator=(const SaveLayerOptions &other)
Definition: display_list.h:217
SaveLayerOptions with_can_distribute_opacity() const
Definition: display_list.h:177
bool renders_with_attributes() const
Definition: display_list.h:169
bool operator==(const SaveLayerOptions &other) const
Definition: display_list.h:221
SaveLayerOptions with_bounds_from_caller() const
Definition: display_list.h:187
SaveLayerOptions(const SaveLayerOptions *options)
Definition: display_list.h:159
bool bounds_from_caller() const
Definition: display_list.h:186
bool bounds_were_calculated() const
Definition: display_list.h:197
SaveLayerOptions with_contains_backdrop_filter() const
Definition: display_list.h:211
SaveLayerOptions without_bounds_from_caller() const
Definition: display_list.h:192
static const SaveLayerOptions kWithAttributes
Definition: display_list.h:154
SaveLayerOptions without_optimizations() const
Definition: display_list.h:162
bool contains_backdrop_filter() const
Definition: display_list.h:210
SaveLayerOptions with_content_is_clipped() const
Definition: display_list.h:204
SaveLayerOptions(const SaveLayerOptions &options)
Definition: display_list.h:158
bool can_distribute_opacity() const
Definition: display_list.h:176
T * get() const
Definition: SkRefCnt.h:303
#define FOR_EACH_DISPLAY_LIST_OP(V)
Definition: display_list.h:58
#define DL_OP_TO_ENUM_VALUE(name)
Definition: display_list.h:140
#define FML_CHECK(condition)
Definition: logging.h:85
void * realloc(void *ptr, size_t size)
Definition: allocation.cc:27
Definition: SkRect.h:32