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/layer.h" |
6 | |
7 | #include "flutter/flow/paint_utils.h" |
8 | #include "third_party/skia/include/core/SkColorFilter.h" |
9 | |
10 | namespace flutter { |
11 | |
12 | Layer::Layer() |
13 | : paint_bounds_(SkRect::MakeEmpty()), |
14 | unique_id_(NextUniqueID()), |
15 | needs_system_composite_(false) {} |
16 | |
17 | Layer::~Layer() = default; |
18 | |
19 | uint64_t Layer::NextUniqueID() { |
20 | static std::atomic<uint64_t> nextID(1); |
21 | uint64_t id; |
22 | do { |
23 | id = nextID.fetch_add(1); |
24 | } while (id == 0); // 0 is reserved for an invalid id. |
25 | return id; |
26 | } |
27 | |
28 | void Layer::Preroll(PrerollContext* context, const SkMatrix& matrix) {} |
29 | |
30 | Layer::AutoPrerollSaveLayerState::AutoPrerollSaveLayerState( |
31 | PrerollContext* preroll_context, |
32 | bool save_layer_is_active, |
33 | bool layer_itself_performs_readback) |
34 | : preroll_context_(preroll_context), |
35 | save_layer_is_active_(save_layer_is_active), |
36 | layer_itself_performs_readback_(layer_itself_performs_readback) { |
37 | if (save_layer_is_active_) { |
38 | prev_surface_needs_readback_ = preroll_context_->surface_needs_readback; |
39 | preroll_context_->surface_needs_readback = false; |
40 | } |
41 | } |
42 | |
43 | Layer::AutoPrerollSaveLayerState Layer::AutoPrerollSaveLayerState::Create( |
44 | PrerollContext* preroll_context, |
45 | bool save_layer_is_active, |
46 | bool layer_itself_performs_readback) { |
47 | return Layer::AutoPrerollSaveLayerState(preroll_context, save_layer_is_active, |
48 | layer_itself_performs_readback); |
49 | } |
50 | |
51 | Layer::AutoPrerollSaveLayerState::~AutoPrerollSaveLayerState() { |
52 | if (save_layer_is_active_) { |
53 | preroll_context_->surface_needs_readback = |
54 | (prev_surface_needs_readback_ || layer_itself_performs_readback_); |
55 | } |
56 | } |
57 | |
58 | #if defined(LEGACY_FUCHSIA_EMBEDDER) |
59 | |
60 | void Layer::CheckForChildLayerBelow(PrerollContext* context) { |
61 | // If there is embedded Fuchsia content in the scene (a ChildSceneLayer), |
62 | // PhysicalShapeLayers that appear above the embedded content will be turned |
63 | // into their own Scenic layers. |
64 | child_layer_exists_below_ = context->child_scene_layer_exists_below; |
65 | if (child_layer_exists_below_) { |
66 | set_needs_system_composite(true); |
67 | } |
68 | } |
69 | |
70 | void Layer::UpdateScene(SceneUpdateContext& context) { |
71 | FML_DCHECK(needs_system_composite()); |
72 | FML_DCHECK(child_layer_exists_below_); |
73 | |
74 | SceneUpdateContext::Frame frame( |
75 | context, SkRRect::MakeRect(paint_bounds()), SK_ColorTRANSPARENT, |
76 | SkScalarRoundToInt(context.alphaf() * 255), "flutter::Layer" ); |
77 | |
78 | frame.AddPaintLayer(this); |
79 | } |
80 | |
81 | #endif |
82 | |
83 | Layer::AutoSaveLayer::AutoSaveLayer(const PaintContext& paint_context, |
84 | const SkRect& bounds, |
85 | const SkPaint* paint) |
86 | : paint_context_(paint_context), bounds_(bounds) { |
87 | paint_context_.internal_nodes_canvas->saveLayer(bounds_, paint); |
88 | } |
89 | |
90 | Layer::AutoSaveLayer::AutoSaveLayer(const PaintContext& paint_context, |
91 | const SkCanvas::SaveLayerRec& layer_rec) |
92 | : paint_context_(paint_context), bounds_(*layer_rec.fBounds) { |
93 | paint_context_.internal_nodes_canvas->saveLayer(layer_rec); |
94 | } |
95 | |
96 | Layer::AutoSaveLayer Layer::AutoSaveLayer::Create( |
97 | const PaintContext& paint_context, |
98 | const SkRect& bounds, |
99 | const SkPaint* paint) { |
100 | return Layer::AutoSaveLayer(paint_context, bounds, paint); |
101 | } |
102 | |
103 | Layer::AutoSaveLayer Layer::AutoSaveLayer::Create( |
104 | const PaintContext& paint_context, |
105 | const SkCanvas::SaveLayerRec& layer_rec) { |
106 | return Layer::AutoSaveLayer(paint_context, layer_rec); |
107 | } |
108 | |
109 | Layer::AutoSaveLayer::~AutoSaveLayer() { |
110 | if (paint_context_.checkerboard_offscreen_layers) { |
111 | DrawCheckerboard(paint_context_.internal_nodes_canvas, bounds_); |
112 | } |
113 | paint_context_.internal_nodes_canvas->restore(); |
114 | } |
115 | |
116 | } // namespace flutter |
117 | |