Flutter Engine
 
Loading...
Searching...
No Matches
flutter::DisplayList Class Reference

#include <display_list.h>

Inheritance diagram for flutter::DisplayList:

Classes

class  Iterator
 Iterator utility class used for the |DisplayListbegin| and |DisplayListend| methods. It implements just the basic methods to enable iteration-style for loops. More...
 

Public Member Functions

 DisplayList ()
 
 ~DisplayList ()
 
void Dispatch (DlOpReceiver &ctx) const
 
void Dispatch (DlOpReceiver &ctx, const DlRect &cull_rect) const
 
void Dispatch (DlOpReceiver &ctx, const DlIRect &cull_rect) const
 
size_t bytes (bool nested=true) const
 
uint32_t op_count (bool nested=false) const
 
uint32_t total_depth () const
 
uint32_t unique_id () const
 
const DlRectGetBounds () const
 
bool has_rtree () const
 
sk_sp< const DlRTreertree () const
 
bool Equals (const DisplayList *other) const
 
bool Equals (const DisplayList &other) const
 
bool Equals (const sk_sp< const DisplayList > &other) const
 
bool can_apply_group_opacity () const
 
bool isUIThreadSafe () const
 
bool modifies_transparent_black () const
 Indicates if there are any rendering operations in this DisplayList that will modify a surface of transparent black pixels.
 
const DisplayListStorageGetStorage () const
 
bool root_has_backdrop_filter () const
 Indicates if there are any saveLayer operations at the root surface level of the DisplayList that use a backdrop filter.
 
bool root_is_unbounded () const
 Indicates if a rendering operation at the root level of the DisplayList had an unbounded result, not otherwise limited by a clip operation.
 
DlBlendMode max_root_blend_mode () const
 Indicates the maximum DlBlendMode used on any rendering op in the root surface of the DisplayList.
 
DlIndex GetRecordCount () const
 Return the number of stored records in the DisplayList.
 
Iterator begin () const
 Return an iterator to the start of the stored records, enabling the iteration form of a for loop.
 
Iterator end () const
 Return an iterator to the end of the stored records, enabling the iteration form of a for loop.
 
bool Dispatch (DlOpReceiver &receiver, DlIndex index) const
 Dispatch a single stored operation by its index.
 
DisplayListOpType GetOpType (DlIndex index) const
 Return an enum describing the specific op type stored at the indicated index.
 
DisplayListOpCategory GetOpCategory (DlIndex index) const
 Return an enum describing the general category of the operation record stored at the indicated index.
 
std::vector< DlIndexGetCulledIndices (const DlRect &cull_rect) const
 Return a vector of valid indices for records stored in the DisplayList that must be dispatched if you are restricted to the indicated cull_rect.
 

Static Public Member Functions

static DisplayListOpCategory GetOpCategory (DisplayListOpType type)
 Return an enum describing the general category of the operation record with the given type.
 

Friends

class DisplayListBuilder
 

Detailed Description

Definition at line 266 of file display_list.h.

Constructor & Destructor Documentation

◆ DisplayList()

flutter::DisplayList::DisplayList ( )

Definition at line 18 of file display_list.cc.

19 : op_count_(0),
20 nested_byte_count_(0),
21 nested_op_count_(0),
22 total_depth_(0),
23 unique_id_(0),
24 can_apply_group_opacity_(true),
25 is_ui_thread_safe_(true),
26 modifies_transparent_black_(false),
27 root_has_backdrop_filter_(false),
28 root_is_unbounded_(false),
29 max_root_blend_mode_(DlBlendMode::kClear) {
30 FML_DCHECK(offsets_.size() == 0u);
31 FML_DCHECK(storage_.size() == 0u);
32}
size_t size() const
Returns the currently allocated size.
Definition dl_storage.h:27
#define FML_DCHECK(condition)
Definition logging.h:122

References FML_DCHECK, and flutter::DisplayListStorage::size().

Referenced by bytes().

◆ ~DisplayList()

flutter::DisplayList::~DisplayList ( )

Definition at line 66 of file display_list.cc.

66 {
67 DisposeOps(storage_, offsets_);
68}

Member Function Documentation

◆ begin()

Iterator flutter::DisplayList::begin ( ) const
inline

Return an iterator to the start of the stored records, enabling the iteration form of a for loop.

Each stored record represents a dispatchable operation that will be sent to a |DlOpReceiver| by the |Dispatch| method. You can directly simulate the |Dispatch| method using a simple for loop on the indices:

{ for (DlIndex i : *display_list) { display_list->Dispatch(my_receiver, i); } }

See also
|end|
|GetCulledIndices|

Definition at line 404 of file display_list.h.

404{ return Iterator(0u); }

◆ bytes()

size_t flutter::DisplayList::bytes ( bool  nested = true) const
inline

Definition at line 279 of file display_list.h.

279 {
280 return sizeof(DisplayList) + storage_.size() +
281 (nested ? nested_byte_count_ : 0);
282 }

References DisplayList(), and flutter::DisplayListStorage::size().

◆ can_apply_group_opacity()

bool flutter::DisplayList::can_apply_group_opacity ( ) const
inline

Definition at line 303 of file display_list.h.

303{ return can_apply_group_opacity_; }

Referenced by flutter::DisplayListLayer::Preroll().

◆ Dispatch() [1/4]

void flutter::DisplayList::Dispatch ( DlOpReceiver ctx) const

Definition at line 182 of file display_list.cc.

182 {
183 const uint8_t* base = storage_.base();
184 for (size_t offset : offsets_) {
185 DispatchOneOp(receiver, base + offset);
186 }
187}
uint8_t * base()
Returns a pointer to the base of the storage.
Definition dl_storage.h:23

References flutter::DisplayListStorage::base().

Referenced by flutter::DisplayListGLComplexityCalculator::Compute(), flutter::DisplayListMetalComplexityCalculator::Compute(), Dispatch(), Dispatch(), and std::operator<<().

◆ Dispatch() [2/4]

void flutter::DisplayList::Dispatch ( DlOpReceiver ctx,
const DlIRect cull_rect 
) const

Definition at line 189 of file display_list.cc.

190 {
191 Dispatch(receiver, DlRect::Make(cull_rect));
192}
void Dispatch(DlOpReceiver &ctx) const
static constexpr std::enable_if_t< std::is_floating_point_v< FT >, TRect > Make(const TRect< U > &rect)
Definition rect.h:157

References Dispatch(), and impeller::TRect< Scalar >::Make().

◆ Dispatch() [3/4]

void flutter::DisplayList::Dispatch ( DlOpReceiver ctx,
const DlRect cull_rect 
) const

Definition at line 194 of file display_list.cc.

195 {
196 if (cull_rect.IsEmpty()) {
197 return;
198 }
199 if (!has_rtree() || cull_rect.Contains(GetBounds())) {
200 Dispatch(receiver);
201 } else {
202 auto op_indices = GetCulledIndices(cull_rect);
203 const uint8_t* base = storage_.base();
204 for (DlIndex index : op_indices) {
205 DispatchOneOp(receiver, base + offsets_[index]);
206 }
207 }
208}
const DlRect & GetBounds() const
bool has_rtree() const
std::vector< DlIndex > GetCulledIndices(const DlRect &cull_rect) const
Return a vector of valid indices for records stored in the DisplayList that must be dispatched if you...
uint32_t DlIndex

References flutter::DisplayListStorage::base(), impeller::TRect< T >::Contains(), Dispatch(), GetBounds(), GetCulledIndices(), has_rtree(), and impeller::TRect< T >::IsEmpty().

◆ Dispatch() [4/4]

bool flutter::DisplayList::Dispatch ( DlOpReceiver receiver,
DlIndex  index 
) const

Dispatch a single stored operation by its index.

Each stored record represents a dispatchable operation that will be sent to a |DlOpReceiver| by the |Dispatch| method. You can use this method to dispatch a single operation to your receiver with an index between |0u| (inclusive) and |GetRecordCount()| (exclusive), as in:

{ for (DlIndex i = 0u; i < display_list->GetRecordCount(); i++) { display_list->Dispatch(my_receiver, i); } }

If the index is out of the range of the stored records, this method will not call any methods on the receiver and return false. You can check the return value for true if you want to make sure you are using valid indices.

See also
|GetRecordCount|
|begin|
|end|
|GetCulledIndices|

Definition at line 385 of file display_list.cc.

385 {
386 // Assert unsigned type so we can eliminate >= 0 comparison
387 static_assert(std::is_unsigned_v<DlIndex>);
388 if (index >= offsets_.size()) {
389 return false;
390 }
391
392 size_t offset = offsets_[index];
393 FML_DCHECK(offset < storage_.size());
394 auto ptr = storage_.base() + offset;
395
396 DispatchOneOp(receiver, ptr);
397
398 return true;
399}

References flutter::DisplayListStorage::base(), FML_DCHECK, and flutter::DisplayListStorage::size().

◆ end()

Iterator flutter::DisplayList::end ( ) const
inline

Return an iterator to the end of the stored records, enabling the iteration form of a for loop.

Each stored record represents a dispatchable operation that will be sent to a |DlOpReceiver| by the |Dispatch| method. You can directly simulate the |Dispatch| method using a simple for loop on the indices:

{ for (DlIndex i : *display_list) { display_list->Dispatch(my_receiver, i); } }

See also
|begin|
|GetCulledIndices|

Definition at line 421 of file display_list.h.

421{ return Iterator(offsets_.size()); }

◆ Equals() [1/3]

bool flutter::DisplayList::Equals ( const DisplayList other) const
inline

Definition at line 298 of file display_list.h.

298{ return Equals(&other); }
bool Equals(const DisplayList *other) const

References Equals().

Referenced by Equals().

◆ Equals() [2/3]

bool flutter::DisplayList::Equals ( const DisplayList other) const

Definition at line 466 of file display_list.cc.

466 {
467 if (this == other) {
468 return true;
469 }
470 if (offsets_.size() != other->offsets_.size() ||
471 storage_.size() != other->storage_.size() ||
472 op_count_ != other->op_count_) {
473 return false;
474 }
475 if (storage_.base() == other->storage_.base()) {
476 return true;
477 }
478 return CompareOps(storage_, offsets_, other->storage_, other->offsets_);
479}
static bool CompareOps(const DisplayListStorage &storageA, const std::vector< size_t > &offsetsA, const DisplayListStorage &storageB, const std::vector< size_t > &offsetsB)

References flutter::DisplayListStorage::base(), flutter::CompareOps(), and flutter::DisplayListStorage::size().

Referenced by flutter::testing::DisplayListsEQ_Verbose(), flutter::testing::DisplayListsNE_Verbose(), and Equals().

◆ Equals() [3/3]

bool flutter::DisplayList::Equals ( const sk_sp< const DisplayList > &  other) const
inline

Definition at line 299 of file display_list.h.

299 {
300 return Equals(other.get());
301 }

References Equals().

◆ GetBounds()

const DlRect & flutter::DisplayList::GetBounds ( ) const
inline

Definition at line 292 of file display_list.h.

292{ return bounds_; }

Referenced by Dispatch(), and flutter::IsDisplayListWorthRasterizing().

◆ GetCulledIndices()

std::vector< DlIndex > flutter::DisplayList::GetCulledIndices ( const DlRect cull_rect) const

Return a vector of valid indices for records stored in the DisplayList that must be dispatched if you are restricted to the indicated cull_rect.

This method can be used along with indexed dispatching to implement RTree culling while still maintaining control over planning of operations to be rendered, as in:

{ std::vector<DlIndex> indices = display_list->GetCulledIndices(cull-rect); for (DlIndex i : indices) { display_list->Dispatch(my_receiver, i); } }

The indices returned in the vector will automatically deal with including or culling related operations such as attributes, clips and transforms that will provide state for any rendering operations selected by the culling checks.

See also
|GetOpType| for a more detailed description of the records primarily for debugging use
|Dispatch(receiver, index)|

Definition at line 370 of file display_list.cc.

371 {
372 std::vector<DlIndex> indices;
373 if (!cull_rect.IsEmpty()) {
374 if (rtree_) {
375 std::vector<int> rect_indices;
376 rtree_->search(cull_rect, &rect_indices);
377 RTreeResultsToIndexVector(indices, rect_indices);
378 } else {
379 FillAllIndices(indices, offsets_.size());
380 }
381 }
382 return indices;
383}
static void FillAllIndices(std::vector< DlIndex > &indices, DlIndex size)

References flutter::FillAllIndices(), and impeller::TRect< T >::IsEmpty().

Referenced by Dispatch().

◆ GetOpCategory() [1/2]

DisplayListOpCategory flutter::DisplayList::GetOpCategory ( DisplayListOpType  type)
static

Return an enum describing the general category of the operation record with the given type.

See also
|GetOpType| for a more detailed description of the records primarily for debugging use

Definition at line 260 of file display_list.cc.

260 {
261 switch (type) {
262 case DisplayListOpType::kSetAntiAlias:
263 case DisplayListOpType::kSetInvertColors:
264 case DisplayListOpType::kSetStrokeCap:
265 case DisplayListOpType::kSetStrokeJoin:
266 case DisplayListOpType::kSetStyle:
267 case DisplayListOpType::kSetStrokeWidth:
268 case DisplayListOpType::kSetStrokeMiter:
269 case DisplayListOpType::kSetColor:
270 case DisplayListOpType::kSetBlendMode:
271 case DisplayListOpType::kClearColorFilter:
272 case DisplayListOpType::kSetPodColorFilter:
273 case DisplayListOpType::kClearColorSource:
274 case DisplayListOpType::kSetPodColorSource:
275 case DisplayListOpType::kSetImageColorSource:
276 case DisplayListOpType::kSetRuntimeEffectColorSource:
277 case DisplayListOpType::kClearImageFilter:
278 case DisplayListOpType::kSetPodImageFilter:
279 case DisplayListOpType::kSetSharedImageFilter:
280 case DisplayListOpType::kClearMaskFilter:
281 case DisplayListOpType::kSetPodMaskFilter:
283
284 case DisplayListOpType::kSave:
286 case DisplayListOpType::kSaveLayer:
287 case DisplayListOpType::kSaveLayerBackdrop:
289 case DisplayListOpType::kRestore:
291
292 case DisplayListOpType::kTranslate:
293 case DisplayListOpType::kScale:
294 case DisplayListOpType::kRotate:
295 case DisplayListOpType::kSkew:
296 case DisplayListOpType::kTransform2DAffine:
297 case DisplayListOpType::kTransformFullPerspective:
298 case DisplayListOpType::kTransformReset:
300
301 case DisplayListOpType::kClipIntersectRect:
302 case DisplayListOpType::kClipIntersectOval:
303 case DisplayListOpType::kClipIntersectRoundRect:
304 case DisplayListOpType::kClipIntersectRoundSuperellipse:
305 case DisplayListOpType::kClipIntersectPath:
306 case DisplayListOpType::kClipDifferenceRect:
307 case DisplayListOpType::kClipDifferenceOval:
308 case DisplayListOpType::kClipDifferenceRoundRect:
309 case DisplayListOpType::kClipDifferenceRoundSuperellipse:
310 case DisplayListOpType::kClipDifferencePath:
312
313 case DisplayListOpType::kDrawPaint:
314 case DisplayListOpType::kDrawColor:
315 case DisplayListOpType::kDrawLine:
316 case DisplayListOpType::kDrawDashedLine:
317 case DisplayListOpType::kDrawRect:
318 case DisplayListOpType::kDrawOval:
319 case DisplayListOpType::kDrawCircle:
320 case DisplayListOpType::kDrawRoundRect:
321 case DisplayListOpType::kDrawDiffRoundRect:
322 case DisplayListOpType::kDrawRoundSuperellipse:
323 case DisplayListOpType::kDrawArc:
324 case DisplayListOpType::kDrawPath:
325 case DisplayListOpType::kDrawPoints:
326 case DisplayListOpType::kDrawLines:
327 case DisplayListOpType::kDrawPolygon:
328 case DisplayListOpType::kDrawVertices:
329 case DisplayListOpType::kDrawImage:
330 case DisplayListOpType::kDrawImageWithAttr:
331 case DisplayListOpType::kDrawImageRect:
332 case DisplayListOpType::kDrawImageNine:
333 case DisplayListOpType::kDrawImageNineWithAttr:
334 case DisplayListOpType::kDrawAtlas:
335 case DisplayListOpType::kDrawAtlasCulled:
336 case DisplayListOpType::kDrawText:
337 case DisplayListOpType::kDrawShadow:
338 case DisplayListOpType::kDrawShadowTransparentOccluder:
340
341 case DisplayListOpType::kDrawDisplayList:
343
346 }
347}
GLenum type

References flutter::kAttribute, flutter::kClip, flutter::kInvalidCategory, flutter::kInvalidOp, flutter::kRendering, flutter::kRestore, flutter::kSave, flutter::kSaveLayer, flutter::kSubDisplayList, flutter::kTransform, and type.

◆ GetOpCategory() [2/2]

DisplayListOpCategory flutter::DisplayList::GetOpCategory ( DlIndex  index) const

Return an enum describing the general category of the operation record stored at the indicated index.

The categories are general and stable and can be used fairly safely in production code to plan how to dispatch or reorder ops during final rendering.

See also
|GetOpType| for a more detailed description of the records primarily for debugging use

Definition at line 256 of file display_list.cc.

256 {
257 return GetOpCategory(GetOpType(index));
258}
DisplayListOpType GetOpType(DlIndex index) const
Return an enum describing the specific op type stored at the indicated index.
DisplayListOpCategory GetOpCategory(DlIndex index) const
Return an enum describing the general category of the operation record stored at the indicated index.

References GetOpCategory(), and GetOpType().

Referenced by GetOpCategory(), and flutter::testing::DisplayListGeneralReceiver::RecordByType().

◆ GetOpType()

DisplayListOpType flutter::DisplayList::GetOpType ( DlIndex  index) const

Return an enum describing the specific op type stored at the indicated index.

The specific types of the records are subject to change without notice as the DisplayList code is developed and optimized. These values are useful mostly for debugging purposes and should not be used in production code.

See also
|GetOpCategory| for a more stable description of the records

Definition at line 349 of file display_list.cc.

349 {
350 // Assert unsigned type so we can eliminate >= 0 comparison
351 static_assert(std::is_unsigned_v<DlIndex>);
352 if (index >= offsets_.size()) {
354 }
355
356 size_t offset = offsets_[index];
357 FML_DCHECK(offset < storage_.size());
358 auto ptr = storage_.base() + offset;
359 auto op = reinterpret_cast<const DLOp*>(ptr);
360 return op->type;
361}

References flutter::DisplayListStorage::base(), FML_DCHECK, flutter::kInvalidOp, flutter::DisplayListStorage::size(), and flutter::DLOp::type.

Referenced by GetOpCategory().

◆ GetRecordCount()

DlIndex flutter::DisplayList::GetRecordCount ( ) const
inline

Return the number of stored records in the DisplayList.

Each stored record represents a dispatchable operation that will be sent to a |DlOpReceiver| by the |Dispatch| method. You can directly simulate the |Dispatch| method using a simple for loop on the indices:

{ for (DlIndex i = 0u; i < display_list->GetRecordCount(); i++) { display_list->Dispatch(my_receiver, i); } }

See also
|Dispatch(receiver, index)|
|begin|
|end|
|GetCulledIndices|

Definition at line 387 of file display_list.h.

387{ return offsets_.size(); }

◆ GetStorage()

const DisplayListStorage & flutter::DisplayList::GetStorage ( ) const
inline

Definition at line 319 of file display_list.h.

319{ return storage_; }

◆ has_rtree()

bool flutter::DisplayList::has_rtree ( ) const
inline

Definition at line 294 of file display_list.h.

294{ return rtree_ != nullptr; }

Referenced by Dispatch().

◆ isUIThreadSafe()

bool flutter::DisplayList::isUIThreadSafe ( ) const
inline

Definition at line 304 of file display_list.h.

304{ return is_ui_thread_safe_; }

◆ max_root_blend_mode()

DlBlendMode flutter::DisplayList::max_root_blend_mode ( ) const
inline

Indicates the maximum DlBlendMode used on any rendering op in the root surface of the DisplayList.

This condition can be used to determine what kind of surface to create for the root layer into which to render the DisplayList as some GPUs can support surfaces that do or do not support the readback that would be required for the indicated blend mode to do its work.

Definition at line 349 of file display_list.h.

349{ return max_root_blend_mode_; }

◆ modifies_transparent_black()

bool flutter::DisplayList::modifies_transparent_black ( ) const
inline

Indicates if there are any rendering operations in this DisplayList that will modify a surface of transparent black pixels.

This condition can be used to determine whether to create a cleared surface, render a DisplayList into it, and then composite the result into a scene. It is not uncommon for code in the engine to come across such degenerate DisplayList objects when slicing up a frame between platform views.

Definition at line 315 of file display_list.h.

315 {
316 return modifies_transparent_black_;
317 }

◆ op_count()

uint32_t flutter::DisplayList::op_count ( bool  nested = false) const
inline

Definition at line 284 of file display_list.h.

284 {
285 return op_count_ + (nested ? nested_op_count_ : 0);
286 }

Referenced by flutter::DisplayListNaiveComplexityCalculator::Compute().

◆ root_has_backdrop_filter()

bool flutter::DisplayList::root_has_backdrop_filter ( ) const
inline

Indicates if there are any saveLayer operations at the root surface level of the DisplayList that use a backdrop filter.

This condition can be used to determine what kind of surface to create for the root layer into which to render the DisplayList as some GPUs can support surfaces that do or do not support the readback that would be required for the backdrop filter to do its work.

Definition at line 328 of file display_list.h.

328{ return root_has_backdrop_filter_; }

◆ root_is_unbounded()

bool flutter::DisplayList::root_is_unbounded ( ) const
inline

Indicates if a rendering operation at the root level of the DisplayList had an unbounded result, not otherwise limited by a clip operation.

This condition can occur in a number of situations. The most common situation is when there is a drawPaint or drawColor rendering operation which fills out the entire drawable surface unless it is bounded by a clip. Other situations include an operation rendered through an ImageFilter that cannot compute the resulting bounds or when an unclipped backdrop filter is applied by a save layer.

Definition at line 340 of file display_list.h.

340{ return root_is_unbounded_; }

◆ rtree()

sk_sp< const DlRTree > flutter::DisplayList::rtree ( ) const
inline

Definition at line 295 of file display_list.h.

295{ return rtree_; }

◆ total_depth()

uint32_t flutter::DisplayList::total_depth ( ) const
inline

Definition at line 288 of file display_list.h.

288{ return total_depth_; }

◆ unique_id()

uint32_t flutter::DisplayList::unique_id ( ) const
inline

Definition at line 290 of file display_list.h.

290{ return unique_id_; }

Friends And Related Symbol Documentation

◆ DisplayListBuilder

friend class DisplayListBuilder
friend

Definition at line 550 of file display_list.h.


The documentation for this class was generated from the following files: