Flutter Engine
flutter::ContainerLayer Class Reference

#include <container_layer.h>

Inheritance diagram for flutter::ContainerLayer:
flutter::Layer flutter::ClipShapeLayer< SkPath > flutter::ClipShapeLayer< SkRect > flutter::ClipShapeLayer< SkRRect > flutter::BackdropFilterLayer flutter::ClipShapeLayer< T > flutter::ColorFilterLayer flutter::ImageFilterLayer flutter::OpacityLayer flutter::PhysicalShapeLayer flutter::ShaderMaskLayer flutter::TransformLayer

Public Member Functions

 ContainerLayer ()
 
void Diff (DiffContext *context, const Layer *old_layer) override
 
void PreservePaintRegion (DiffContext *context) override
 
virtual void Add (std::shared_ptr< Layer > layer)
 
void Preroll (PrerollContext *context, const SkMatrix &matrix) override
 
void Paint (PaintContext &context) const override
 
const std::vector< std::shared_ptr< Layer > > & layers () const
 
virtual void DiffChildren (DiffContext *context, const ContainerLayer *old_layer)
 
void PaintChildren (PaintContext &context) const
 
const ContainerLayeras_container_layer () const override
 
const SkRect & child_paint_bounds () const
 
- Public Member Functions inherited from flutter::Layer
 Layer ()
 
virtual ~Layer ()
 
void AssignOldLayer (Layer *old_layer)
 
virtual bool IsReplacing (DiffContext *context, const Layer *old_layer) const
 
bool subtree_has_platform_view () const
 
void set_subtree_has_platform_view (bool value)
 
const SkRect & paint_bounds () const
 
void set_paint_bounds (const SkRect &paint_bounds)
 
bool is_empty () const
 
bool needs_painting (PaintContext &context) const
 
uint64_t original_layer_id () const
 
uint64_t unique_id () const
 
virtual const DisplayListLayeras_display_list_layer () const
 
virtual const TextureLayeras_texture_layer () const
 
virtual const PerformanceOverlayLayeras_performance_overlay_layer () const
 
virtual const testing::MockLayeras_mock_layer () const
 

Protected Member Functions

void PrerollChildren (PrerollContext *context, const SkMatrix &child_matrix, SkRect *child_paint_bounds)
 

Static Protected Member Functions

static void TryToPrepareRasterCache (PrerollContext *context, Layer *layer, const SkMatrix &matrix, RasterCacheLayerStrategy strategy)
 

Detailed Description

Definition at line 14 of file container_layer.h.

Constructor & Destructor Documentation

◆ ContainerLayer()

flutter::ContainerLayer::ContainerLayer ( )

Definition at line 11 of file container_layer.cc.

11 : child_paint_bounds_(SkRect::MakeEmpty()) {}

Member Function Documentation

◆ Add()

void flutter::ContainerLayer::Add ( std::shared_ptr< Layer layer)
virtual

Definition at line 106 of file container_layer.cc.

Referenced by flutter::testing::TEST_F().

106  {
107  layers_.emplace_back(std::move(layer));
108 }

◆ as_container_layer()

const ContainerLayer* flutter::ContainerLayer::as_container_layer ( ) const
inlineoverridevirtual

Reimplemented from flutter::Layer.

Definition at line 31 of file container_layer.h.

31 { return this; }

◆ child_paint_bounds()

◆ Diff()

void flutter::ContainerLayer::Diff ( DiffContext context,
const Layer old_layer 
)
overridevirtual

Reimplemented from flutter::Layer.

Reimplemented in flutter::OpacityLayer, flutter::ClipShapeLayer< SkRect >, flutter::ClipShapeLayer< SkPath >, flutter::ClipShapeLayer< SkRRect >, flutter::PhysicalShapeLayer, flutter::ShaderMaskLayer, flutter::TransformLayer, and flutter::ImageFilterLayer.

Definition at line 13 of file container_layer.cc.

References flutter::DiffContext::CurrentSubtreeRegion(), DiffChildren(), and flutter::DiffContext::SetLayerPaintRegion().

Referenced by flutter::testing::DiffContextTest::DiffLayerTree().

13  {
14  auto old_container = static_cast<const ContainerLayer*>(old_layer);
15  DiffContext::AutoSubtreeRestore subtree(context);
16  DiffChildren(context, old_container);
17  context->SetLayerPaintRegion(this, context->CurrentSubtreeRegion());
18 }
virtual void DiffChildren(DiffContext *context, const ContainerLayer *old_layer)

◆ DiffChildren()

void flutter::ContainerLayer::DiffChildren ( DiffContext context,
const ContainerLayer old_layer 
)
virtual

Definition at line 27 of file container_layer.cc.

References flutter::DiffContext::AddDamage(), flutter::DiffContext::AddExistingPaintRegion(), FML_DCHECK, flutter::DiffContext::GetOldLayerPaintRegion(), flutter::Layer::IsReplacing(), flutter::DiffContext::IsSubtreeDirty(), and flutter::DiffContext::MarkSubtreeDirty().

Referenced by flutter::BackdropFilterLayer::Diff(), flutter::ColorFilterLayer::Diff(), flutter::ImageFilterLayer::Diff(), Diff(), flutter::TransformLayer::Diff(), flutter::ShaderMaskLayer::Diff(), flutter::PhysicalShapeLayer::Diff(), flutter::ClipShapeLayer< SkRRect >::Diff(), flutter::OpacityLayer::Diff(), and layers().

28  {
29  if (context->IsSubtreeDirty()) {
30  for (auto& layer : layers_) {
31  layer->Diff(context, nullptr);
32  }
33  return;
34  }
35  FML_DCHECK(old_layer);
36 
37  const auto& prev_layers = old_layer->layers_;
38 
39  // first mismatched element
40  int new_children_top = 0;
41  int old_children_top = 0;
42 
43  // last mismatched element
44  int new_children_bottom = layers_.size() - 1;
45  int old_children_bottom = prev_layers.size() - 1;
46 
47  while ((old_children_top <= old_children_bottom) &&
48  (new_children_top <= new_children_bottom)) {
49  if (!layers_[new_children_top]->IsReplacing(
50  context, prev_layers[old_children_top].get())) {
51  break;
52  }
53  ++new_children_top;
54  ++old_children_top;
55  }
56 
57  while ((old_children_top <= old_children_bottom) &&
58  (new_children_top <= new_children_bottom)) {
59  if (!layers_[new_children_bottom]->IsReplacing(
60  context, prev_layers[old_children_bottom].get())) {
61  break;
62  }
63  --new_children_bottom;
64  --old_children_bottom;
65  }
66 
67  // old layers that don't match
68  for (int i = old_children_top; i <= old_children_bottom; ++i) {
69  auto layer = prev_layers[i];
70  context->AddDamage(context->GetOldLayerPaintRegion(layer.get()));
71  }
72 
73  for (int i = 0; i < static_cast<int>(layers_.size()); ++i) {
74  if (i < new_children_top || i > new_children_bottom) {
75  int i_prev =
76  i < new_children_top ? i : prev_layers.size() - (layers_.size() - i);
77  auto layer = layers_[i];
78  auto prev_layer = prev_layers[i_prev];
79  auto paint_region = context->GetOldLayerPaintRegion(prev_layer.get());
80  if (layer == prev_layer && !paint_region.has_readback() &&
81  !paint_region.has_texture()) {
82  // for retained layers, stop processing the subtree and add existing
83  // region; We know current subtree is not dirty (every ancestor up to
84  // here matches) so the retained subtree will render identically to
85  // previous frame; We can only do this if there is no readback in the
86  // subtree. Layers that do readback must be able to register readback
87  // inside Diff
88  context->AddExistingPaintRegion(paint_region);
89 
90  // While we don't need to diff retained layers, we still need to
91  // associate their paint region with current layer tree so that we can
92  // retrieve it in next frame diff
93  layer->PreservePaintRegion(context);
94  } else {
95  layer->Diff(context, prev_layer.get());
96  }
97  } else {
98  DiffContext::AutoSubtreeRestore subtree(context);
99  context->MarkSubtreeDirty();
100  auto layer = layers_[i];
101  layer->Diff(context, nullptr);
102  }
103  }
104 }
#define FML_DCHECK(condition)
Definition: logging.h:86
virtual bool IsReplacing(DiffContext *context, const Layer *old_layer) const
Definition: layer.h:123

◆ layers()

const std::vector<std::shared_ptr<Layer> >& flutter::ContainerLayer::layers ( ) const
inline

Definition at line 26 of file container_layer.h.

References DiffChildren(), and PaintChildren().

Referenced by flutter::RasterCache::Prepare(), and flutter::OpacityLayer::Preroll().

26 { return layers_; }

◆ Paint()

void flutter::ContainerLayer::Paint ( PaintContext context) const
overridevirtual

Implements flutter::Layer.

Reimplemented in flutter::ClipShapeLayer< SkRect >, flutter::ClipShapeLayer< SkPath >, flutter::ClipShapeLayer< SkRRect >, flutter::OpacityLayer, flutter::PhysicalShapeLayer, flutter::ShaderMaskLayer, flutter::TransformLayer, and flutter::ImageFilterLayer.

Definition at line 118 of file container_layer.cc.

References FML_DCHECK, flutter::Layer::needs_painting(), and PaintChildren().

118  {
119  FML_DCHECK(needs_painting(context));
120 
121  PaintChildren(context);
122 }
#define FML_DCHECK(condition)
Definition: logging.h:86
bool needs_painting(PaintContext &context) const
Definition: layer.h:333
void PaintChildren(PaintContext &context) const

◆ PaintChildren()

void flutter::ContainerLayer::PaintChildren ( PaintContext context) const

Definition at line 176 of file container_layer.cc.

Referenced by layers(), flutter::BackdropFilterLayer::Paint(), flutter::ColorFilterLayer::Paint(), flutter::ImageFilterLayer::Paint(), flutter::TransformLayer::Paint(), flutter::ShaderMaskLayer::Paint(), Paint(), flutter::PhysicalShapeLayer::Paint(), flutter::OpacityLayer::Paint(), flutter::ClipShapeLayer< SkRRect >::Paint(), and flutter::RasterCache::RasterizeLayer().

176  {
177  // We can no longer call FML_DCHECK here on the needs_painting(context)
178  // condition as that test is only valid for the PaintContext that
179  // is initially handed to a layer's Paint() method. By the time the
180  // layer calls PaintChildren(), though, it may have modified the
181  // PaintContext so the test doesn't work in this "context".
182 
183  // Intentionally not tracing here as there should be no self-time
184  // and the trace event on this common function has a small overhead.
185  for (auto& layer : layers_) {
186  if (layer->needs_painting(context)) {
187  layer->Paint(context);
188  }
189  }
190 }

◆ Preroll()

void flutter::ContainerLayer::Preroll ( PrerollContext context,
const SkMatrix &  matrix 
)
overridevirtual

Reimplemented from flutter::Layer.

Reimplemented in flutter::ClipShapeLayer< SkRect >, flutter::ClipShapeLayer< SkPath >, flutter::ClipShapeLayer< SkRRect >, flutter::OpacityLayer, flutter::PhysicalShapeLayer, flutter::ShaderMaskLayer, flutter::TransformLayer, and flutter::ImageFilterLayer.

Definition at line 110 of file container_layer.cc.

References child_paint_bounds(), PrerollChildren(), flutter::Layer::set_paint_bounds(), and TRACE_EVENT0.

Referenced by flutter::ColorFilterLayer::Preroll(), flutter::ShaderMaskLayer::Preroll(), and flutter::OpacityLayer::Preroll().

110  {
111  TRACE_EVENT0("flutter", "ContainerLayer::Preroll");
112 
113  SkRect child_paint_bounds = SkRect::MakeEmpty();
114  PrerollChildren(context, matrix, &child_paint_bounds);
115  set_paint_bounds(child_paint_bounds);
116 }
#define TRACE_EVENT0(category_group, name)
Definition: trace_event.h:90
void PrerollChildren(PrerollContext *context, const SkMatrix &child_matrix, SkRect *child_paint_bounds)
const SkRect & child_paint_bounds() const
void set_paint_bounds(const SkRect &paint_bounds)
Definition: layer.h:324

◆ PrerollChildren()

void flutter::ContainerLayer::PrerollChildren ( PrerollContext context,
const SkMatrix &  child_matrix,
SkRect *  child_paint_bounds 
)
protected

Definition at line 131 of file container_layer.cc.

References child_paint_bounds(), FML_DCHECK, flutter::PrerollContext::has_platform_view, flutter::PrerollContext::has_texture_layer, flutter::safe_intersection_test(), flutter::Layer::set_subtree_has_platform_view(), and flutter::PrerollContext::subtree_can_inherit_opacity.

Referenced by child_paint_bounds(), flutter::BackdropFilterLayer::Preroll(), flutter::ImageFilterLayer::Preroll(), flutter::TransformLayer::Preroll(), flutter::PhysicalShapeLayer::Preroll(), Preroll(), and flutter::ClipShapeLayer< SkRRect >::Preroll().

133  {
134  // Platform views have no children, so context->has_platform_view should
135  // always be false.
136  FML_DCHECK(!context->has_platform_view);
137  bool child_has_platform_view = false;
138  bool child_has_texture_layer = false;
139  bool subtree_can_inherit_opacity = context->subtree_can_inherit_opacity;
140 
141  for (auto& layer : layers_) {
142  // Reset context->has_platform_view to false so that layers aren't treated
143  // as if they have a platform view based on one being previously found in a
144  // sibling tree.
145  context->has_platform_view = false;
146  // Initialize the "inherit opacity" flag to false and allow the layer to
147  // override the answer during its |Preroll|
148  context->subtree_can_inherit_opacity = false;
149 
150  layer->Preroll(context, child_matrix);
151 
152  subtree_can_inherit_opacity =
153  subtree_can_inherit_opacity && context->subtree_can_inherit_opacity;
154  if (subtree_can_inherit_opacity &&
155  safe_intersection_test(child_paint_bounds, layer->paint_bounds())) {
156  // This will allow inheritance by a linear sequence of non-overlapping
157  // children, but will fail with a grid or other arbitrary 2D layout.
158  // See https://github.com/flutter/flutter/issues/93899
159  subtree_can_inherit_opacity = false;
160  }
161  child_paint_bounds->join(layer->paint_bounds());
162 
163  child_has_platform_view =
164  child_has_platform_view || context->has_platform_view;
165  child_has_texture_layer =
166  child_has_texture_layer || context->has_texture_layer;
167  }
168 
169  context->has_platform_view = child_has_platform_view;
170  context->has_texture_layer = child_has_texture_layer;
171  context->subtree_can_inherit_opacity = subtree_can_inherit_opacity;
172  set_subtree_has_platform_view(child_has_platform_view);
173  child_paint_bounds_ = *child_paint_bounds;
174 }
void set_subtree_has_platform_view(bool value)
Definition: layer.h:303
#define FML_DCHECK(condition)
Definition: logging.h:86
static bool safe_intersection_test(const SkRect *rect1, const SkRect &rect2)
const SkRect & child_paint_bounds() const

◆ PreservePaintRegion()

void flutter::ContainerLayer::PreservePaintRegion ( DiffContext context)
overridevirtual

Reimplemented from flutter::Layer.

Definition at line 20 of file container_layer.cc.

References flutter::Layer::PreservePaintRegion().

20  {
22  for (auto& layer : layers_) {
23  layer->PreservePaintRegion(context);
24  }
25 }
virtual void PreservePaintRegion(DiffContext *context)
Definition: layer.h:133

◆ TryToPrepareRasterCache()

void flutter::ContainerLayer::TryToPrepareRasterCache ( PrerollContext context,
Layer layer,
const SkMatrix &  matrix,
RasterCacheLayerStrategy  strategy 
)
staticprotected

Definition at line 192 of file container_layer.cc.

References flutter::PrerollContext::cull_rect, flutter::PrerollContext::has_platform_view, flutter::PrerollContext::has_texture_layer, flutter::Layer::paint_bounds(), flutter::RasterCache::Prepare(), flutter::PrerollContext::raster_cache, and flutter::RasterCache::Touch().

Referenced by child_paint_bounds(), flutter::ImageFilterLayer::Preroll(), flutter::ColorFilterLayer::Preroll(), flutter::ShaderMaskLayer::Preroll(), flutter::OpacityLayer::Preroll(), and flutter::ClipShapeLayer< SkRRect >::Preroll().

196  {
197  if (!context->has_platform_view && !context->has_texture_layer &&
198  context->raster_cache &&
199  SkRect::Intersects(context->cull_rect, layer->paint_bounds())) {
200  context->raster_cache->Prepare(context, layer, matrix, strategy);
201  } else if (context->raster_cache) {
202  // Don't evict raster cache entry during partial repaint
203  context->raster_cache->Touch(layer, matrix, strategy);
204  }
205 }

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