Flutter Engine
container_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 
5 #include "flutter/flow/layers/container_layer.h"
6 
7 #include <optional>
8 
9 namespace flutter {
10 
12 
13 void ContainerLayer::Add(std::shared_ptr<Layer> layer) {
14  layers_.emplace_back(std::move(layer));
15 }
16 
17 void ContainerLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) {
18  TRACE_EVENT0("flutter", "ContainerLayer::Preroll");
19 
20  SkRect child_paint_bounds = SkRect::MakeEmpty();
21  PrerollChildren(context, matrix, &child_paint_bounds);
22  set_paint_bounds(child_paint_bounds);
23 }
24 
25 void ContainerLayer::Paint(PaintContext& context) const {
27 
28  PaintChildren(context);
29 }
30 
32  const SkMatrix& child_matrix,
33  SkRect* child_paint_bounds) {
34 #if defined(LEGACY_FUCHSIA_EMBEDDER)
35  // If there is embedded Fuchsia content in the scene (a ChildSceneLayer),
36  // Layers that appear above the embedded content will be turned into their own
37  // Scenic layers.
38  child_layer_exists_below_ = context->child_scene_layer_exists_below;
39  context->child_scene_layer_exists_below = false;
40 #endif
41 
42  // Platform views have no children, so context->has_platform_view should
43  // always be false.
44  FML_DCHECK(!context->has_platform_view);
45  bool child_has_platform_view = false;
46  for (auto& layer : layers_) {
47  // Reset context->has_platform_view to false so that layers aren't treated
48  // as if they have a platform view based on one being previously found in a
49  // sibling tree.
50  context->has_platform_view = false;
51 
52  layer->Preroll(context, child_matrix);
53 
54  if (layer->needs_system_composite()) {
56  }
57  child_paint_bounds->join(layer->paint_bounds());
58 
59  child_has_platform_view =
60  child_has_platform_view || context->has_platform_view;
61  }
62 
63  context->has_platform_view = child_has_platform_view;
64 
65 #if defined(LEGACY_FUCHSIA_EMBEDDER)
66  if (child_layer_exists_below_) {
68  }
69  context->child_scene_layer_exists_below =
70  context->child_scene_layer_exists_below || child_layer_exists_below_;
71 #endif
72 }
73 
76 
77  // Intentionally not tracing here as there should be no self-time
78  // and the trace event on this common function has a small overhead.
79  for (auto& layer : layers_) {
80  if (layer->needs_painting()) {
81  layer->Paint(context);
82  }
83  }
84 }
85 
87  Layer* layer,
88  const SkMatrix& matrix) {
89  if (!context->has_platform_view && context->raster_cache &&
90  SkRect::Intersects(context->cull_rect, layer->paint_bounds())) {
91  context->raster_cache->Prepare(context, layer, matrix);
92  }
93 }
94 
95 #if defined(LEGACY_FUCHSIA_EMBEDDER)
96 
97 void ContainerLayer::CheckForChildLayerBelow(PrerollContext* context) {
98  // All ContainerLayers make the check in PrerollChildren.
99 }
100 
101 void ContainerLayer::UpdateScene(std::shared_ptr<SceneUpdateContext> context) {
102  UpdateSceneChildren(context);
103 }
104 
105 void ContainerLayer::UpdateSceneChildren(
106  std::shared_ptr<SceneUpdateContext> context) {
108 
109  std::optional<SceneUpdateContext::Frame> frame;
110  if (child_layer_exists_below_) {
111  frame.emplace(
112  context, SkRRect::MakeRect(paint_bounds()), SK_ColorTRANSPARENT,
113  SkScalarRoundToInt(context->alphaf() * 255), "flutter::ContainerLayer");
114  frame->AddPaintLayer(this);
115  }
116 
117  for (auto& layer : layers_) {
118  if (layer->needs_system_composite()) {
119  layer->UpdateScene(context);
120  }
121  }
122 }
123 
124 #endif
125 
127  // Ensure the layer has only one direct child.
128  //
129  // Any children will actually be added as children of this empty
130  // ContainerLayer which can be accessed via ::GetContainerLayer().
131  // If only one child is ever added to this layer then that child
132  // will become the layer returned from ::GetCacheableChild().
133  // If multiple child layers are added, then this implicit container
134  // child becomes the cacheable child, but at the potential cost of
135  // not being as stable in the raster cache from frame to frame.
136  ContainerLayer::Add(std::make_shared<ContainerLayer>());
137 }
138 
139 void MergedContainerLayer::Add(std::shared_ptr<Layer> layer) {
140  GetChildContainer()->Add(std::move(layer));
141 }
142 
144  FML_DCHECK(layers().size() == 1);
145 
146  return static_cast<ContainerLayer*>(layers()[0].get());
147 }
148 
150  ContainerLayer* child_container = GetChildContainer();
151  if (child_container->layers().size() == 1) {
152  return child_container->layers()[0].get();
153  }
154 
155  return child_container;
156 }
157 
158 } // namespace flutter
void Add(std::shared_ptr< Layer > layer) override
#define TRACE_EVENT0(category_group, name)
Definition: trace_event.h:75
#define FML_DCHECK(condition)
Definition: logging.h:86
constexpr std::size_t size(T(&array)[N])
Definition: size.h:13
const std::vector< std::shared_ptr< Layer > > & layers() const
void PrerollChildren(PrerollContext *context, const SkMatrix &child_matrix, SkRect *child_paint_bounds)
bool Prepare(GrDirectContext *context, SkPicture *picture, const SkMatrix &transformation_matrix, SkColorSpace *dst_color_space, bool is_complex, bool will_change)
void Paint(PaintContext &context) const override
Layer * GetCacheableChild() const
Returns the best choice for a Layer object that can be used in RasterCache operations to cache the ch...
ContainerLayer * GetChildContainer() const
Returns the ContainerLayer used to hold all of the children of the MergedContainerLayer. Note that this may not be the best layer to use for caching the children.
bool needs_system_composite() const
Definition: layer.h:161
bool needs_painting() const
Definition: layer.h:174
const SkRect & paint_bounds() const
Definition: layer.h:166
virtual void Add(std::shared_ptr< Layer > layer)
void Preroll(PrerollContext *context, const SkMatrix &matrix) override
void set_paint_bounds(const SkRect &paint_bounds)
Definition: layer.h:170
RasterCache * raster_cache
Definition: layer.h:44
void set_needs_system_composite(bool value)
Definition: layer.h:162
static void TryToPrepareRasterCache(PrerollContext *context, Layer *layer, const SkMatrix &matrix)
void PaintChildren(PaintContext &context) const