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
cc / tiles / checker_image_tracker.h [blame]
// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CC_TILES_CHECKER_IMAGE_TRACKER_H_
#define CC_TILES_CHECKER_IMAGE_TRACKER_H_
#include <memory>
#include <optional>
#include <unordered_map>
#include <vector>
#include "base/containers/contains.h"
#include "base/memory/raw_ptr.h"
#include "cc/cc_export.h"
#include "cc/paint/image_id.h"
#include "cc/tiles/image_controller.h"
#include "third_party/skia/include/core/SkImage.h"
namespace cc {
class CC_EXPORT CheckerImageTrackerClient {
public:
virtual ~CheckerImageTrackerClient() = default;
virtual void NeedsInvalidationForCheckerImagedTiles() = 0;
};
// CheckerImageTracker is used to track the set of images in a frame which are
// decoded asynchronously, using the ImageDecodeService, from the rasterization
// of tiles which depend on them. Once decoded, these images are stored for
// invalidation on the next sync tree. TakeImagesToInvalidateOnSyncTree will
// return this set and maintain a copy to keeps these images locked until the
// sync tree is activated.
// Note: It is illegal to call TakeImagesToInvalidateOnSyncTree for the next
// sync tree until the previous tree is activated.
class CC_EXPORT CheckerImageTracker {
public:
// The priority type for a decode. Note we use int to specify a decreasing
// order of priority with higher values.
enum DecodeType : int {
// Priority for images on tiles being rasterized (visible or pre-paint).
kRaster = 0,
// Lowest priority for images on tiles in pre-decode region. These are tiles
// which are beyond the pre-paint region, but have their images decoded.
kPreDecode = 1,
kLast = kPreDecode
};
struct CC_EXPORT ImageDecodeRequest {
ImageDecodeRequest(PaintImage paint_image, DecodeType type);
PaintImage paint_image;
DecodeType type;
};
CheckerImageTracker(ImageController* image_controller,
CheckerImageTrackerClient* client,
bool enable_checker_imaging,
size_t min_image_bytes_to_checker);
CheckerImageTracker(const CheckerImageTracker&) = delete;
~CheckerImageTracker();
CheckerImageTracker& operator=(const CheckerImageTracker&) = delete;
// Returns true if the decode for |image| will be deferred to the image decode
// service and it should be be skipped during raster.
bool ShouldCheckerImage(const DrawImage& image, WhichTree tree);
// Provides a prioritized queue of images to decode.
using ImageDecodeQueue = std::vector<ImageDecodeRequest>;
void ScheduleImageDecodeQueue(ImageDecodeQueue image_decode_queue);
// Disables scheduling any decode work by the tracker.
void SetNoDecodesAllowed();
// The max decode priority type that is allowed to run.
void SetMaxDecodePriorityAllowed(DecodeType decode_type);
// Returns the set of images to invalidate on the sync tree.
const PaintImageIdFlatSet& TakeImagesToInvalidateOnSyncTree();
// Called when the sync tree is activated. Each call to
// TakeImagesToInvalidateOnSyncTree() must be followed by this when the
// invalidated sync tree is activated.
void DidActivateSyncTree();
// Called to reset the tracker state on navigation. This will release all
// cached images. Setting |can_clear_decode_policy_tracking| will also result
// in re-checkering any images already decoded by the tracker.
void ClearTracker(bool can_clear_decode_policy_tracking);
// Informs the tracker to not checker the given image. This can be used to opt
// out of the checkering behavior for certain images, such as ones that were
// decoded using the img.decode api.
// Note that if the image is already being checkered, then it will continue to
// do so. This call is meant to be issued prior to the image appearing during
// raster.
void DisallowCheckeringForImage(const PaintImage& image);
void set_force_disabled(bool force_disabled) {
force_disabled_ = force_disabled;
}
void UpdateImageDecodingHints(
base::flat_map<PaintImage::Id, PaintImage::DecodingMode>
decoding_mode_map);
bool has_locked_decodes_for_testing() const {
return !image_id_to_decode_.empty();
}
int decode_priority_allowed_for_testing() const {
return decode_priority_allowed_;
}
bool no_decodes_allowed_for_testing() const {
return decode_priority_allowed_ == kNoDecodeAllowedPriority;
}
PaintImage::DecodingMode get_decoding_mode_hint_for_testing(
PaintImage::Id id) {
DCHECK(base::Contains(decoding_mode_map_, id));
return decoding_mode_map_[id];
}
private:
static const int kNoDecodeAllowedPriority;
enum class DecodePolicy {
// The image can be decoded asynchronously from raster. When set, the image
// is always skipped during rasterization of content that includes this
// image until it has been decoded using the decode service.
ASYNC,
// The image has been decoded asynchronously once and should now be
// synchronously rasterized with the content or the image has been
// permanently vetoed from being decoded async.
SYNC
};
// Contains the information to construct a DrawImage from PaintImage when
// queuing the image decode.
struct DecodeState {
DecodePolicy policy = DecodePolicy::SYNC;
bool use_dark_mode = false;
PaintFlags::FilterQuality filter_quality = PaintFlags::FilterQuality::kNone;
SkSize scale = SkSize::MakeEmpty();
TargetColorParams target_color_params;
size_t frame_index = PaintImage::kDefaultFrameIndex;
};
// Wrapper to unlock an image decode requested from the ImageController on
// destruction.
class ScopedDecodeHolder {
public:
ScopedDecodeHolder(ImageController* controller,
ImageController::ImageDecodeRequestId request_id)
: controller_(controller), request_id_(request_id) {}
ScopedDecodeHolder(const ScopedDecodeHolder&) = delete;
~ScopedDecodeHolder() { controller_->UnlockImageDecode(request_id_); }
ScopedDecodeHolder& operator=(const ScopedDecodeHolder&) = delete;
private:
raw_ptr<ImageController> controller_;
ImageController::ImageDecodeRequestId request_id_;
};
void DidFinishImageDecode(PaintImage::Id image_id,
ImageController::ImageDecodeRequestId request_id,
ImageController::ImageDecodeResult result);
// Called when the next request in the |image_decode_queue_| should be
// scheduled with the image decode service.
void ScheduleNextImageDecode();
void UpdateDecodeState(const DrawImage& draw_image,
PaintImage::Id paint_image_id,
DecodeState* decode_state);
raw_ptr<ImageController> image_controller_;
raw_ptr<CheckerImageTrackerClient> client_;
const bool enable_checker_imaging_;
const size_t min_image_bytes_to_checker_;
// Disables checkering of all images if set. As opposed to
// |enable_checker_imaging_|, this setting can be toggled.
bool force_disabled_ = false;
// A set of images which have been decoded and are pending invalidation for
// raster on the checkered tiles.
PaintImageIdFlatSet images_pending_invalidation_;
// A set of images which were invalidated on the current sync tree.
PaintImageIdFlatSet invalidated_images_on_current_sync_tree_;
// The queue of images pending decode. We maintain a queue to ensure that the
// order in which images are decoded is aligned with the priority of the tiles
// dependent on these images.
ImageDecodeQueue image_decode_queue_;
// The max decode type that is allowed to run, if decodes are allowed to run.
int decode_priority_allowed_ = kNoDecodeAllowedPriority;
// The currently outstanding image decode that has been scheduled with the
// decode service. There can be only one outstanding decode at a time.
std::optional<PaintImage> outstanding_image_decode_;
// A map of ImageId to its DecodePolicy.
std::unordered_map<PaintImage::Id, DecodeState> image_async_decode_state_;
// A map of image id to image decode request id for images to be unlocked.
std::unordered_map<PaintImage::Id, std::unique_ptr<ScopedDecodeHolder>>
image_id_to_decode_;
base::flat_map<PaintImage::Id, PaintImage::DecodingMode> decoding_mode_map_;
base::WeakPtrFactory<CheckerImageTracker> weak_factory_{this};
};
} // namespace cc
#endif // CC_TILES_CHECKER_IMAGE_TRACKER_H_