forked from flutter/engine
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcompositor_context.h
222 lines (175 loc) · 7.54 KB
/
compositor_context.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
221
222
// 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_COMPOSITOR_CONTEXT_H_
#define FLUTTER_FLOW_COMPOSITOR_CONTEXT_H_
#include <memory>
#include <string>
#include "flutter/common/graphics/texture.h"
#include "flutter/flow/diff_context.h"
#include "flutter/flow/embedded_views.h"
#include "flutter/flow/layer_snapshot_store.h"
#include "flutter/flow/raster_cache.h"
#include "flutter/flow/stopwatch.h"
#include "flutter/fml/macros.h"
#include "flutter/fml/raster_thread_merger.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/gpu/GrDirectContext.h"
namespace flutter {
class LayerTree;
// The result status of CompositorContext::ScopedFrame::Raster.
enum class RasterStatus {
// Frame has been successfully rasterized.
kSuccess,
// Frame has been submited, but must be submitted again. This is only used
// on Android when switching the background surface to FlutterImageView.
//
// On Android, the first frame doesn't make the image available
// to the ImageReader right away. The second frame does.
//
// TODO(egarciad): https://github.com/flutter/flutter/issues/65652
kResubmit,
// Frame has be dropped and a new frame with the same layer tree must be
// attempted.
//
// This is currently used to wait for the thread merger to merge
// the raster and platform threads.
//
// Since the thread merger may be disabled, the system will proceed
// with separate threads for rasterization and platform tasks,
// potentially leading to different performance characteristics.
kSkipAndRetry,
};
class FrameDamage {
public:
// Sets previous layer tree for calculating frame damage. If not set, entire
// frame will be repainted.
void SetPreviousLayerTree(const LayerTree* prev_layer_tree) {
prev_layer_tree_ = prev_layer_tree;
}
// Adds additional damage (accumulated for double / triple buffering).
// This is area that will be repainted alongside any changed part.
void AddAdditionalDamage(const SkIRect& damage) {
additional_damage_.join(damage);
}
// Specifies clip rect alignment.
void SetClipAlignment(int horizontal, int vertical) {
horizontal_clip_alignment_ = horizontal;
vertical_clip_alignment_ = vertical;
}
// Calculates clip rect for current rasterization. This is diff of layer tree
// and previous layer tree + any additional provided damage.
// If previous layer tree is not specified, clip rect will be nullopt,
// but the paint region of layer_tree will be calculated so that it can be
// used for diffing of subsequent frames.
std::optional<SkRect> ComputeClipRect(flutter::LayerTree& layer_tree,
bool has_raster_cache,
bool impeller_enabled);
// See Damage::frame_damage.
std::optional<SkIRect> GetFrameDamage() const {
return damage_ ? std::make_optional(damage_->frame_damage) : std::nullopt;
}
// See Damage::buffer_damage.
std::optional<SkIRect> GetBufferDamage() {
return (damage_ && !ignore_damage_)
? std::make_optional(damage_->buffer_damage)
: std::nullopt;
}
// Remove reported buffer_damage to inform clients that a partial repaint
// should not be performed on this frame.
// frame_damage is required to correctly track accumulated damage for
// subsequent frames.
void Reset() { ignore_damage_ = true; }
private:
SkIRect additional_damage_ = SkIRect::MakeEmpty();
std::optional<Damage> damage_;
const LayerTree* prev_layer_tree_ = nullptr;
int vertical_clip_alignment_ = 1;
int horizontal_clip_alignment_ = 1;
bool ignore_damage_ = false;
};
class CompositorContext {
public:
class ScopedFrame {
public:
ScopedFrame(CompositorContext& context,
GrDirectContext* gr_context,
DlCanvas* canvas,
ExternalViewEmbedder* view_embedder,
const SkMatrix& root_surface_transformation,
bool instrumentation_enabled,
bool surface_supports_readback,
fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger,
impeller::AiksContext* aiks_context);
virtual ~ScopedFrame();
DlCanvas* canvas() { return canvas_; }
ExternalViewEmbedder* view_embedder() { return view_embedder_; }
CompositorContext& context() const { return context_; }
const SkMatrix& root_surface_transformation() const {
return root_surface_transformation_;
}
bool surface_supports_readback() { return surface_supports_readback_; }
GrDirectContext* gr_context() const { return gr_context_; }
impeller::AiksContext* aiks_context() const { return aiks_context_; }
virtual RasterStatus Raster(LayerTree& layer_tree,
bool ignore_raster_cache,
FrameDamage* frame_damage);
private:
void PaintLayerTreeSkia(flutter::LayerTree& layer_tree,
std::optional<SkRect> clip_rect,
bool needs_save_layer,
bool ignore_raster_cache);
void PaintLayerTreeImpeller(flutter::LayerTree& layer_tree,
std::optional<SkRect> clip_rect,
bool ignore_raster_cache);
CompositorContext& context_;
GrDirectContext* gr_context_;
DlCanvas* canvas_;
impeller::AiksContext* aiks_context_;
ExternalViewEmbedder* view_embedder_;
const SkMatrix& root_surface_transformation_;
const bool instrumentation_enabled_;
const bool surface_supports_readback_;
fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger_;
FML_DISALLOW_COPY_AND_ASSIGN(ScopedFrame);
};
CompositorContext();
explicit CompositorContext(Stopwatch::RefreshRateUpdater& updater);
virtual ~CompositorContext();
virtual std::unique_ptr<ScopedFrame> AcquireFrame(
GrDirectContext* gr_context,
DlCanvas* canvas,
ExternalViewEmbedder* view_embedder,
const SkMatrix& root_surface_transformation,
bool instrumentation_enabled,
bool surface_supports_readback,
fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger,
impeller::AiksContext* aiks_context);
void OnGrContextCreated();
void OnGrContextDestroyed();
RasterCache& raster_cache() { return raster_cache_; }
std::shared_ptr<TextureRegistry> texture_registry() {
return texture_registry_;
}
const Stopwatch& raster_time() const { return raster_time_; }
Stopwatch& ui_time() { return ui_time_; }
LayerSnapshotStore& snapshot_store() { return layer_snapshot_store_; }
private:
RasterCache raster_cache_;
std::shared_ptr<TextureRegistry> texture_registry_;
Stopwatch raster_time_;
Stopwatch ui_time_;
LayerSnapshotStore layer_snapshot_store_;
/// Only used by default constructor of `CompositorContext`.
FixedRefreshRateUpdater fixed_refresh_rate_updater_;
void BeginFrame(ScopedFrame& frame, bool enable_instrumentation);
void EndFrame(ScopedFrame& frame, bool enable_instrumentation);
/// @brief Whether Impeller shouild attempt a partial repaint.
/// The Impeller backend requires an additional blit pass, which may
/// not be worthwhile if the damage region is large.
static bool ShouldPerformPartialRepaint(std::optional<SkRect> damage_rect,
SkISize layer_tree_size);
FML_DISALLOW_COPY_AND_ASSIGN(CompositorContext);
};
} // namespace flutter
#endif // FLUTTER_FLOW_COMPOSITOR_CONTEXT_H_