Flutter Engine
 
Loading...
Searching...
No Matches
display_list_layer.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
6
7#include <utility>
8
14
15namespace flutter {
16
18 sk_sp<DisplayList> display_list,
19 bool is_complex,
20 bool will_change)
21 : offset_(offset), display_list_(std::move(display_list)) {
22 if (display_list_) {
23 bounds_ = display_list_->GetBounds().Shift(offset_.x, offset_.y);
24#if !SLIMPELLER
25 display_list_raster_cache_item_ = DisplayListRasterCacheItem::Make(
26 display_list_, ToSkPoint(offset_), is_complex, will_change);
27#endif // !SLIMPELLER
28 }
29}
30
32 const Layer* layer) const {
33 // Only return true for identical display lists; This way
34 // ContainerLayer::DiffChildren can detect when a display list layer
35 // got inserted between other display list layers
36 auto old_layer = layer->as_display_list_layer();
37 return old_layer != nullptr && offset_ == old_layer->offset_ &&
38 Compare(context->statistics(), this, old_layer);
39}
40
41void DisplayListLayer::Diff(DiffContext* context, const Layer* old_layer) {
42 DiffContext::AutoSubtreeRestore subtree(context);
43 if (!context->IsSubtreeDirty()) {
44#ifndef NDEBUG
45 FML_DCHECK(old_layer);
46 auto prev = old_layer->as_display_list_layer();
47 DiffContext::Statistics dummy_statistics;
48 // IsReplacing has already determined that the display list is same
49 FML_DCHECK(prev->offset_ == offset_ &&
50 Compare(dummy_statistics, this, prev));
51#endif
52 }
54 if (context->has_raster_cache()) {
56 }
57 context->AddLayerBounds(display_list()->GetBounds());
58 context->SetLayerPaintRegion(this, context->CurrentSubtreeRegion());
59}
60
61bool DisplayListLayer::Compare(DiffContext::Statistics& statistics,
62 const DisplayListLayer* l1,
63 const DisplayListLayer* l2) {
64 const auto& dl1 = l1->display_list_;
65 const auto& dl2 = l2->display_list_;
66 if (dl1.get() == dl2.get()) {
67 statistics.AddSameInstancePicture();
68 return true;
69 }
70 const auto op_cnt_1 = dl1->op_count();
71 const auto op_cnt_2 = dl2->op_count();
72 const auto op_bytes_1 = dl1->bytes();
73 const auto op_bytes_2 = dl2->bytes();
74 if (op_cnt_1 != op_cnt_2 || op_bytes_1 != op_bytes_2 ||
75 dl1->GetBounds() != dl2->GetBounds()) {
76 statistics.AddNewPicture();
77 return false;
78 }
79
80 if (op_bytes_1 > kMaxBytesToCompare) {
82 return false;
83 }
84
85 statistics.AddDeepComparePicture();
86
87 auto res = dl1->Equals(*dl2);
88 if (res) {
90 } else {
91 statistics.AddNewPicture();
92 }
93 return res;
94}
95
97 DisplayList* disp_list = display_list();
98
99#if !SLIMPELLER
100 AutoCache cache = AutoCache(display_list_raster_cache_item_.get(), context,
101 context->state_stack.matrix());
102#endif // !SLIMPELLER
103 if (disp_list->can_apply_group_opacity()) {
105 }
106 set_paint_bounds(bounds_);
107}
108
110 FML_DCHECK(display_list_);
111 FML_DCHECK(needs_painting(context));
112
113 auto mutator = context.state_stack.save();
114 mutator.translate(offset_.x, offset_.y);
115
116#if !SLIMPELLER
117 if (context.raster_cache) {
118 // Always apply the integral transform in the presence of a raster cache
119 // whether or not we successfully draw from the cache
120 mutator.integralTransform();
121
122 if (display_list_raster_cache_item_) {
123 DlPaint paint;
124 if (display_list_raster_cache_item_->Draw(
125 context, context.state_stack.fill(paint))) {
126 TRACE_EVENT_INSTANT0("flutter", "raster cache hit");
127 return;
128 }
129 }
130 }
131#endif // !SLIMPELLER
132
133 DlScalar opacity = context.state_stack.outstanding_opacity();
134 context.canvas->DrawDisplayList(display_list_, opacity);
135}
136
137} // namespace flutter
void WillPaintWithIntegralTransform()
void SetLayerPaintRegion(const Layer *layer, const PaintRegion &region)
Statistics & statistics()
PaintRegion CurrentSubtreeRegion() const
bool has_raster_cache() const
bool IsSubtreeDirty() const
void AddLayerBounds(const DlRect &rect)
void PushTransform(const DlMatrix &transform)
bool can_apply_group_opacity() const
DisplayListLayer(const DlPoint &offset, sk_sp< DisplayList > display_list, bool is_complex, bool will_change)
bool IsReplacing(DiffContext *context, const Layer *layer) const override
void Preroll(PrerollContext *frame) override
void Diff(DiffContext *context, const Layer *old_layer) override
DisplayList * display_list() const
static constexpr size_t kMaxBytesToCompare
void Paint(PaintContext &context) const override
static std::unique_ptr< DisplayListRasterCacheItem > Make(const sk_sp< DisplayList > &, const SkPoint &offset, bool is_complex, bool will_change)
virtual void DrawDisplayList(const sk_sp< DisplayList > display_list, DlScalar opacity=SK_Scalar1)=0
void set_paint_bounds(const DlRect &paint_bounds)
Definition layer.h:209
bool needs_painting(PaintContext &context) const
Definition layer.h:218
virtual const DisplayListLayer * as_display_list_layer() const
Definition layer.h:245
void translate(DlScalar tx, DlScalar ty)
DlScalar outstanding_opacity() const
void fill(MutatorsStack *mutators)
const DlMatrix matrix() const
static constexpr int kCallerCanApplyOpacity
#define FML_DCHECK(condition)
Definition logging.h:122
impeller::Scalar DlScalar
const SkPoint & ToSkPoint(const DlPoint &point)
Definition ref_ptr.h:261
DlCanvas * canvas
Definition layer.h:92
LayerStateStack & state_stack
Definition layer.h:91
LayerStateStack & state_stack
Definition layer.h:49
static constexpr Matrix MakeTranslation(const Vector3 &t)
Definition matrix.h:95
#define TRACE_EVENT_INSTANT0(category_group, name)