forked from flutter/engine
-
Notifications
You must be signed in to change notification settings - Fork 2
/
compositor_context.h
213 lines (169 loc) · 6.87 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
// 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/instrumentation.h"
#include "flutter/flow/layer_snapshot_store.h"
#include "flutter/flow/raster_cache.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;
enum class RasterStatus {
// Frame has been successfully rasterized.
kSuccess,
// Frame is submitted twice. 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 is dropped and a new frame with the same layer tree is
// 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,
kSkipAndRetry,
// Frame has been successfully rasterized, but "there are additional items in
// the pipeline waiting to be consumed. This is currently
// only used when thread configuration change occurs.
kEnqueuePipeline,
// Failed to rasterize the frame.
kFailed,
// Layer tree was discarded due to LayerTreeDiscardCallback or inability to
// access the GPU.
kDiscarded,
// Drawing was yielded to allow the correct thread to draw as a result of the
// RasterThreadMerger.
kYielded,
};
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);
// 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_ ? std::make_optional(damage_->buffer_damage) : std::nullopt;
}
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;
};
class CompositorContext {
public:
class ScopedFrame {
public:
ScopedFrame(CompositorContext& context,
GrDirectContext* gr_context,
SkCanvas* canvas,
ExternalViewEmbedder* view_embedder,
const SkMatrix& root_surface_transformation,
bool instrumentation_enabled,
bool surface_supports_readback,
fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger,
DisplayListBuilder* display_list_builder,
impeller::AiksContext* aiks_context);
virtual ~ScopedFrame();
SkCanvas* canvas() { return canvas_; }
DisplayListBuilder* display_list_builder() const {
return display_list_builder_;
}
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:
CompositorContext& context_;
GrDirectContext* gr_context_;
SkCanvas* canvas_;
DisplayListBuilder* display_list_builder_;
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,
SkCanvas* canvas,
ExternalViewEmbedder* view_embedder,
const SkMatrix& root_surface_transformation,
bool instrumentation_enabled,
bool surface_supports_readback,
fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger,
DisplayListBuilder* display_list_builder,
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);
FML_DISALLOW_COPY_AND_ASSIGN(CompositorContext);
};
} // namespace flutter
#endif // FLUTTER_FLOW_COMPOSITOR_CONTEXT_H_