forked from flutter/engine
-
Notifications
You must be signed in to change notification settings - Fork 0
/
layer.h
220 lines (182 loc) · 7.97 KB
/
layer.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef FLUTTER_FLOW_LAYERS_LAYER_H_
#define FLUTTER_FLOW_LAYERS_LAYER_H_
#include <memory>
#include <vector>
#include "flutter/common/graphics/texture.h"
#include "flutter/flow/embedded_views.h"
#include "flutter/flow/instrumentation.h"
#include "flutter/flow/raster_cache.h"
#include "flutter/fml/build_config.h"
#include "flutter/fml/compiler_specific.h"
#include "flutter/fml/logging.h"
#include "flutter/fml/macros.h"
#include "flutter/fml/trace_event.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkColor.h"
#include "third_party/skia/include/core/SkColorFilter.h"
#include "third_party/skia/include/core/SkMatrix.h"
#include "third_party/skia/include/core/SkPath.h"
#include "third_party/skia/include/core/SkPicture.h"
#include "third_party/skia/include/core/SkRRect.h"
#include "third_party/skia/include/core/SkRect.h"
#include "third_party/skia/include/utils/SkNWayCanvas.h"
#if defined(LEGACY_FUCHSIA_EMBEDDER)
#include "flutter/flow/scene_update_context.h" //nogncheck
#include "lib/ui/scenic/cpp/resources.h" //nogncheck
#include "lib/ui/scenic/cpp/session.h" //nogncheck
#endif
namespace flutter {
static constexpr SkRect kGiantRect = SkRect::MakeLTRB(-1E9F, -1E9F, 1E9F, 1E9F);
// This should be an exact copy of the Clip enum in painting.dart.
enum Clip { none, hardEdge, antiAlias, antiAliasWithSaveLayer };
struct PrerollContext {
RasterCache* raster_cache;
GrDirectContext* gr_context;
ExternalViewEmbedder* view_embedder;
MutatorsStack& mutators_stack;
SkColorSpace* dst_color_space;
SkRect cull_rect;
bool surface_needs_readback;
// These allow us to paint in the end of subtree Preroll.
const Stopwatch& raster_time;
const Stopwatch& ui_time;
TextureRegistry& texture_registry;
const bool checkerboard_offscreen_layers;
const float frame_device_pixel_ratio;
// These allow us to track properties like elevation, opacity, and the
// prescence of a platform view during Preroll.
bool has_platform_view = false;
#if defined(LEGACY_FUCHSIA_EMBEDDER)
// True if, during the traversal so far, we have seen a child_scene_layer.
// Informs whether a layer needs to be system composited.
bool child_scene_layer_exists_below = false;
#endif
};
// Represents a single composited layer. Created on the UI thread but then
// subquently used on the Rasterizer thread.
class Layer {
public:
Layer();
virtual ~Layer();
virtual void Preroll(PrerollContext* context, const SkMatrix& matrix);
// Used during Preroll by layers that employ a saveLayer to manage the
// PrerollContext settings with values affected by the saveLayer mechanism.
// This object must be created before calling Preroll on the children to
// set up the state for the children and then restore the state upon
// destruction.
class AutoPrerollSaveLayerState {
public:
[[nodiscard]] static AutoPrerollSaveLayerState Create(
PrerollContext* preroll_context,
bool save_layer_is_active = true,
bool layer_itself_performs_readback = false);
~AutoPrerollSaveLayerState();
private:
AutoPrerollSaveLayerState(PrerollContext* preroll_context,
bool save_layer_is_active,
bool layer_itself_performs_readback);
PrerollContext* preroll_context_;
bool save_layer_is_active_;
bool layer_itself_performs_readback_;
bool prev_surface_needs_readback_;
};
struct PaintContext {
// When splitting the scene into multiple canvases (e.g when embedding
// a platform view on iOS) during the paint traversal we apply the non leaf
// flow layers to all canvases, and leaf layers just to the "current"
// canvas. Applying the non leaf layers to all canvases ensures that when
// we switch a canvas (when painting a PlatformViewLayer) the next canvas
// has the exact same state as the current canvas.
// The internal_nodes_canvas is a SkNWayCanvas which is used by non leaf
// and applies the operations to all canvases.
// The leaf_nodes_canvas is the "current" canvas and is used by leaf
// layers.
SkCanvas* internal_nodes_canvas;
SkCanvas* leaf_nodes_canvas;
GrDirectContext* gr_context;
ExternalViewEmbedder* view_embedder;
const Stopwatch& raster_time;
const Stopwatch& ui_time;
TextureRegistry& texture_registry;
const RasterCache* raster_cache;
const bool checkerboard_offscreen_layers;
const float frame_device_pixel_ratio;
};
// Calls SkCanvas::saveLayer and restores the layer upon destruction. Also
// draws a checkerboard over the layer if that is enabled in the PaintContext.
class AutoSaveLayer {
public:
[[nodiscard]] static AutoSaveLayer Create(const PaintContext& paint_context,
const SkRect& bounds,
const SkPaint* paint);
[[nodiscard]] static AutoSaveLayer Create(
const PaintContext& paint_context,
const SkCanvas::SaveLayerRec& layer_rec);
~AutoSaveLayer();
private:
AutoSaveLayer(const PaintContext& paint_context,
const SkRect& bounds,
const SkPaint* paint);
AutoSaveLayer(const PaintContext& paint_context,
const SkCanvas::SaveLayerRec& layer_rec);
const PaintContext& paint_context_;
const SkRect bounds_;
};
virtual void Paint(PaintContext& context) const = 0;
#if defined(LEGACY_FUCHSIA_EMBEDDER)
// Updates the system composited scene.
virtual void UpdateScene(std::shared_ptr<SceneUpdateContext> context);
virtual void CheckForChildLayerBelow(PrerollContext* context);
#endif
bool needs_system_composite() const { return needs_system_composite_; }
void set_needs_system_composite(bool value) {
needs_system_composite_ = value;
}
// Returns the paint bounds in the layer's local coordinate system
// as determined during Preroll(). The bounds should include any
// transform, clip or distortions performed by the layer itself,
// but not any similar modifications inherited from its ancestors.
const SkRect& paint_bounds() const { return paint_bounds_; }
// This must be set by the time Preroll() returns otherwise the layer will
// be assumed to have empty paint bounds (paints no content).
// The paint bounds should be independent of the context outside of this
// layer as the layer may be painted under different conditions than
// the Preroll context. The most common example of this condition is
// that we might Preroll the layer with a cull_rect established by a
// clip layer above it but then we might be asked to paint anyway if
// another layer above us needs to cache its children. During the
// paint operation that arises due to the caching, the clip will
// be the bounds of the layer needing caching, not the cull_rect
// that we saw in the overall Preroll operation.
void set_paint_bounds(const SkRect& paint_bounds) {
paint_bounds_ = paint_bounds;
}
// Determines if the layer has any content.
bool is_empty() const { return paint_bounds_.isEmpty(); }
// Determines if the Paint() method is necessary based on the properties
// of the indicated PaintContext object.
bool needs_painting(PaintContext& context) const {
// Workaround for Skia bug (quickReject does not reject empty bounds).
// https://bugs.chromium.org/p/skia/issues/detail?id=10951
if (paint_bounds_.isEmpty()) {
return false;
}
return !context.leaf_nodes_canvas->quickReject(paint_bounds_);
}
uint64_t unique_id() const { return unique_id_; }
protected:
#if defined(LEGACY_FUCHSIA_EMBEDDER)
bool child_layer_exists_below_ = false;
#endif
private:
SkRect paint_bounds_;
uint64_t unique_id_;
bool needs_system_composite_;
static uint64_t NextUniqueID();
FML_DISALLOW_COPY_AND_ASSIGN(Layer);
};
} // namespace flutter
#endif // FLUTTER_FLOW_LAYERS_LAYER_H_