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 namespace flutter {
8
ContainerLayer()9 ContainerLayer::ContainerLayer() {}
10
11 ContainerLayer::~ContainerLayer() = default;
12
Add(std::shared_ptr<Layer> layer)13 void ContainerLayer::Add(std::shared_ptr<Layer> layer) {
14 layer->set_parent(this);
15 layers_.push_back(std::move(layer));
16 }
17
Preroll(PrerollContext * context,const SkMatrix & matrix)18 void ContainerLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) {
19 TRACE_EVENT0("flutter", "ContainerLayer::Preroll");
20
21 SkRect child_paint_bounds = SkRect::MakeEmpty();
22 PrerollChildren(context, matrix, &child_paint_bounds);
23 set_paint_bounds(child_paint_bounds);
24 }
25
PrerollChildren(PrerollContext * context,const SkMatrix & child_matrix,SkRect * child_paint_bounds)26 void ContainerLayer::PrerollChildren(PrerollContext* context,
27 const SkMatrix& child_matrix,
28 SkRect* child_paint_bounds) {
29 MergeParentHole();
30 for (auto& layer : layers_) {
31 layer->Preroll(context, child_matrix);
32
33 if (layer->needs_system_composite()) {
34 set_needs_system_composite(true);
35 }
36 child_paint_bounds->join(layer->paint_bounds());
37 }
38 }
39
PaintChildren(PaintContext & context) const40 void ContainerLayer::PaintChildren(PaintContext& context) const {
41 FML_DCHECK(needs_painting());
42
43 // Intentionally not tracing here as there should be no self-time
44 // and the trace event on this common function has a small overhead.
45 for (auto& layer : layers_) {
46 if (layer->needs_painting()) {
47 layer->Paint(context);
48 }
49 }
50 }
51
MarkHole(int hole_id,const SkRect & rect)52 void ContainerLayer::MarkHole(int hole_id, const SkRect& rect) {
53 hole_regions_.try_emplace(hole_id, rect);
54 SkRect dst_rect = MapRect(rect);
55 auto* parent_layer = parent();
56 if (parent_layer != nullptr) {
57 parent_layer->MarkHole(hole_id, dst_rect);
58 }
59 }
60
RemoveHole(int hole_id)61 void ContainerLayer::RemoveHole(int hole_id) {
62 hole_regions_.erase(hole_id);
63 for (auto& layer : layers_) {
64 if (layer->IsContainer()) {
65 auto* containerLayer = static_cast<ContainerLayer*>(layer.get());
66 containerLayer->RemoveHole(hole_id);
67 }
68 }
69 }
70
MergeParentHole()71 void ContainerLayer::MergeParentHole() {
72 auto* parent_layer = parent();
73 if (!parent_layer) {
74 return;
75 }
76 for (const auto& [id, rect] : parent_layer->HoleRegions()) {
77 hole_regions_.try_emplace(id, rect);
78 }
79 }
80
81 #if defined(OS_FUCHSIA)
82
UpdateScene(SceneUpdateContext & context)83 void ContainerLayer::UpdateScene(SceneUpdateContext& context) {
84 UpdateSceneChildren(context);
85 }
86
UpdateSceneChildren(SceneUpdateContext & context)87 void ContainerLayer::UpdateSceneChildren(SceneUpdateContext& context) {
88 FML_DCHECK(needs_system_composite());
89
90 // Paint all of the layers which need to be drawn into the container.
91 // These may be flattened down to a containing
92 for (auto& layer : layers_) {
93 if (layer->needs_system_composite()) {
94 layer->UpdateScene(context);
95 }
96 }
97 }
98
99 #endif // defined(OS_FUCHSIA)
100
101 } // namespace flutter
102