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
10namespace flutter {
11
12Layer::Layer()
13 : paint_bounds_(SkRect::MakeEmpty()),
14 unique_id_(NextUniqueID()),
15 needs_system_composite_(false) {}
16
17Layer::~Layer() = default;
18
19uint64_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
28void Layer::Preroll(PrerollContext* context, const SkMatrix& matrix) {}
29
30Layer::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
43Layer::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
51Layer::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
60void 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
70void 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
83Layer::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
90Layer::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
96Layer::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
103Layer::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
109Layer::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