forked from flutter/engine
-
Notifications
You must be signed in to change notification settings - Fork 1
/
compositor_context.h
185 lines (146 loc) · 5.88 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
// 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/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 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 AddAdditonalDamage(const SkIRect& damage) {
additional_damage_.join(damage);
}
// Calculates clip rect for current rasterization. This is diff of layer tree
// and previous layer tree + any additional provideddamage.
// If previous layer tree is not specified, clip rect will be nulloptional,
// 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);
// 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;
};
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);
virtual ~ScopedFrame();
SkCanvas* 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_; }
virtual RasterStatus Raster(LayerTree& layer_tree,
bool ignore_raster_cache,
FrameDamage* frame_damage);
private:
CompositorContext& context_;
GrDirectContext* gr_context_;
SkCanvas* canvas_;
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);
};
explicit CompositorContext(
fml::Milliseconds frame_budget = fml::kDefaultFrameBudget);
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);
void OnGrContextCreated();
void OnGrContextDestroyed();
RasterCache& raster_cache() { return raster_cache_; }
TextureRegistry& texture_registry() { return texture_registry_; }
const Counter& frame_count() const { return frame_count_; }
const Stopwatch& raster_time() const { return raster_time_; }
Stopwatch& ui_time() { return ui_time_; }
private:
RasterCache raster_cache_;
TextureRegistry texture_registry_;
Counter frame_count_;
Stopwatch raster_time_;
Stopwatch ui_time_;
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_