1 // Copyright 2017 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef CC_TILES_CHECKER_IMAGE_TRACKER_H_
6 #define CC_TILES_CHECKER_IMAGE_TRACKER_H_
9 #include <unordered_map>
12 #include "base/memory/raw_ptr.h"
13 #include "cc/cc_export.h"
14 #include "cc/paint/image_id.h"
15 #include "cc/tiles/image_controller.h"
16 #include "third_party/abseil-cpp/absl/types/optional.h"
17 #include "third_party/skia/include/core/SkImage.h"
21 class CC_EXPORT CheckerImageTrackerClient {
23 virtual ~CheckerImageTrackerClient() = default;
25 virtual void NeedsInvalidationForCheckerImagedTiles() = 0;
28 // CheckerImageTracker is used to track the set of images in a frame which are
29 // decoded asynchronously, using the ImageDecodeService, from the rasterization
30 // of tiles which depend on them. Once decoded, these images are stored for
31 // invalidation on the next sync tree. TakeImagesToInvalidateOnSyncTree will
32 // return this set and maintain a copy to keeps these images locked until the
33 // sync tree is activated.
34 // Note: It is illegal to call TakeImagesToInvalidateOnSyncTree for the next
35 // sync tree until the previous tree is activated.
36 class CC_EXPORT CheckerImageTracker {
38 // The priority type for a decode. Note we use int to specify a decreasing
39 // order of priority with higher values.
40 enum DecodeType : int {
41 // Priority for images on tiles being rasterized (visible or pre-paint).
43 // Lowest priority for images on tiles in pre-decode region. These are tiles
44 // which are beyond the pre-paint region, but have their images decoded.
50 struct CC_EXPORT ImageDecodeRequest {
51 ImageDecodeRequest(PaintImage paint_image, DecodeType type);
52 PaintImage paint_image;
56 CheckerImageTracker(ImageController* image_controller,
57 CheckerImageTrackerClient* client,
58 bool enable_checker_imaging,
59 size_t min_image_bytes_to_checker);
60 CheckerImageTracker(const CheckerImageTracker&) = delete;
61 ~CheckerImageTracker();
63 CheckerImageTracker& operator=(const CheckerImageTracker&) = delete;
65 // Returns true if the decode for |image| will be deferred to the image decode
66 // service and it should be be skipped during raster.
67 bool ShouldCheckerImage(const DrawImage& image, WhichTree tree);
69 // Provides a prioritized queue of images to decode.
70 using ImageDecodeQueue = std::vector<ImageDecodeRequest>;
71 void ScheduleImageDecodeQueue(ImageDecodeQueue image_decode_queue);
73 // Disables scheduling any decode work by the tracker.
74 void SetNoDecodesAllowed();
76 // The max decode priority type that is allowed to run.
77 void SetMaxDecodePriorityAllowed(DecodeType decode_type);
79 // Returns the set of images to invalidate on the sync tree.
80 const PaintImageIdFlatSet& TakeImagesToInvalidateOnSyncTree();
82 // Called when the sync tree is activated. Each call to
83 // TakeImagesToInvalidateOnSyncTree() must be followed by this when the
84 // invalidated sync tree is activated.
85 void DidActivateSyncTree();
87 // Called to reset the tracker state on navigation. This will release all
88 // cached images. Setting |can_clear_decode_policy_tracking| will also result
89 // in re-checkering any images already decoded by the tracker.
90 void ClearTracker(bool can_clear_decode_policy_tracking);
92 // Informs the tracker to not checker the given image. This can be used to opt
93 // out of the checkering behavior for certain images, such as ones that were
94 // decoded using the img.decode api.
95 // Note that if the image is already being checkered, then it will continue to
96 // do so. This call is meant to be issued prior to the image appearing during
98 void DisallowCheckeringForImage(const PaintImage& image);
100 void set_force_disabled(bool force_disabled) {
101 force_disabled_ = force_disabled;
104 void UpdateImageDecodingHints(
105 base::flat_map<PaintImage::Id, PaintImage::DecodingMode>
108 bool has_locked_decodes_for_testing() const {
109 return !image_id_to_decode_.empty();
112 int decode_priority_allowed_for_testing() const {
113 return decode_priority_allowed_;
115 bool no_decodes_allowed_for_testing() const {
116 return decode_priority_allowed_ == kNoDecodeAllowedPriority;
118 PaintImage::DecodingMode get_decoding_mode_hint_for_testing(
120 CHECK(decoding_mode_map_.find(id) != decoding_mode_map_.end());
121 return decoding_mode_map_[id];
125 static const int kNoDecodeAllowedPriority;
127 enum class DecodePolicy {
128 // The image can be decoded asynchronously from raster. When set, the image
129 // is always skipped during rasterization of content that includes this
130 // image until it has been decoded using the decode service.
132 // The image has been decoded asynchronously once and should now be
133 // synchronously rasterized with the content or the image has been
134 // permanently vetoed from being decoded async.
138 // Contains the information to construct a DrawImage from PaintImage when
139 // queuing the image decode.
141 DecodePolicy policy = DecodePolicy::SYNC;
142 bool use_dark_mode = false;
143 PaintFlags::FilterQuality filter_quality = PaintFlags::FilterQuality::kNone;
144 SkSize scale = SkSize::MakeEmpty();
145 TargetColorParams target_color_params;
146 size_t frame_index = PaintImage::kDefaultFrameIndex;
149 // Wrapper to unlock an image decode requested from the ImageController on
151 class ScopedDecodeHolder {
153 ScopedDecodeHolder(ImageController* controller,
154 ImageController::ImageDecodeRequestId request_id)
155 : controller_(controller), request_id_(request_id) {}
156 ScopedDecodeHolder(const ScopedDecodeHolder&) = delete;
157 ~ScopedDecodeHolder() { controller_->UnlockImageDecode(request_id_); }
159 ScopedDecodeHolder& operator=(const ScopedDecodeHolder&) = delete;
162 raw_ptr<ImageController> controller_;
163 ImageController::ImageDecodeRequestId request_id_;
166 void DidFinishImageDecode(PaintImage::Id image_id,
167 ImageController::ImageDecodeRequestId request_id,
168 ImageController::ImageDecodeResult result);
170 // Called when the next request in the |image_decode_queue_| should be
171 // scheduled with the image decode service.
172 void ScheduleNextImageDecode();
173 void UpdateDecodeState(const DrawImage& draw_image,
174 PaintImage::Id paint_image_id,
175 DecodeState* decode_state);
177 raw_ptr<ImageController> image_controller_;
178 raw_ptr<CheckerImageTrackerClient> client_;
179 const bool enable_checker_imaging_;
180 const size_t min_image_bytes_to_checker_;
182 // Disables checkering of all images if set. As opposed to
183 // |enable_checker_imaging_|, this setting can be toggled.
184 bool force_disabled_ = false;
186 // A set of images which have been decoded and are pending invalidation for
187 // raster on the checkered tiles.
188 PaintImageIdFlatSet images_pending_invalidation_;
190 // A set of images which were invalidated on the current sync tree.
191 PaintImageIdFlatSet invalidated_images_on_current_sync_tree_;
193 // The queue of images pending decode. We maintain a queue to ensure that the
194 // order in which images are decoded is aligned with the priority of the tiles
195 // dependent on these images.
196 ImageDecodeQueue image_decode_queue_;
198 // The max decode type that is allowed to run, if decodes are allowed to run.
199 int decode_priority_allowed_ = kNoDecodeAllowedPriority;
201 // The currently outstanding image decode that has been scheduled with the
202 // decode service. There can be only one outstanding decode at a time.
203 absl::optional<PaintImage> outstanding_image_decode_;
205 // A map of ImageId to its DecodePolicy.
206 std::unordered_map<PaintImage::Id, DecodeState> image_async_decode_state_;
208 // A map of image id to image decode request id for images to be unlocked.
209 std::unordered_map<PaintImage::Id, std::unique_ptr<ScopedDecodeHolder>>
212 base::flat_map<PaintImage::Id, PaintImage::DecodingMode> decoding_mode_map_;
214 base::WeakPtrFactory<CheckerImageTracker> weak_factory_{this};
219 #endif // CC_TILES_CHECKER_IMAGE_TRACKER_H_