Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(38)

Side by Side Diff: cc/tiles/gpu_image_decode_controller.h

Issue 2107883003: Revert of Add display-resolution caching to GPU IDC (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@drt
Patch Set: Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « cc/test/geometry_test_utils.h ('k') | cc/tiles/gpu_image_decode_controller.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef CC_TILES_GPU_IMAGE_DECODE_CONTROLLER_H_ 5 #ifndef CC_TILES_GPU_IMAGE_DECODE_CONTROLLER_H_
6 #define CC_TILES_GPU_IMAGE_DECODE_CONTROLLER_H_ 6 #define CC_TILES_GPU_IMAGE_DECODE_CONTROLLER_H_
7 7
8 #include <memory> 8 #include <memory>
9 #include <unordered_map> 9 #include <unordered_map>
10 #include <vector> 10 #include <vector>
11 11
12 #include "base/containers/mru_cache.h" 12 #include "base/containers/mru_cache.h"
13 #include "base/memory/discardable_memory.h" 13 #include "base/memory/discardable_memory.h"
14 #include "base/synchronization/lock.h" 14 #include "base/synchronization/lock.h"
15 #include "base/trace_event/memory_dump_provider.h" 15 #include "base/trace_event/memory_dump_provider.h"
16 #include "cc/base/cc_export.h" 16 #include "cc/base/cc_export.h"
17 #include "cc/resources/resource_format.h" 17 #include "cc/resources/resource_format.h"
18 #include "cc/tiles/image_decode_controller.h" 18 #include "cc/tiles/image_decode_controller.h"
19 #include "third_party/skia/include/core/SkRefCnt.h" 19 #include "third_party/skia/include/core/SkRefCnt.h"
20 20
21 class SkImageTextureData; 21 class SkImageTextureData;
22 22
23 namespace cc { 23 namespace cc {
24 24
25 class ContextProvider; 25 class ContextProvider;
26 26
27 // OVERVIEW:
28 //
29 // GpuImageDecodeController handles the decode and upload of images that will 27 // GpuImageDecodeController handles the decode and upload of images that will
30 // be used by Skia's GPU raster path. It also maintains a cache of these 28 // be used by Skia's GPU raster path. It also maintains a cache of these
31 // decoded/uploaded images for later re-use. 29 // decoded/uploaded images for later re-use.
32 // 30 //
33 // Generally, when an image is required for raster, GpuImageDecodeController 31 // Generally, when an image is required for raster, GpuImageDecodeController
34 // creates two tasks, one to decode the image, and one to upload the image to 32 // creates two tasks, one to decode the image, and one to upload the image to
35 // the GPU. These tasks are completed before the raster task which depends on 33 // the GPU. These tasks are completed before the raster task which depends on
36 // the image. We need to seperate decode and upload tasks, as decode can occur 34 // the image. We need to seperate decode and upload tasks, as decode can occur
37 // simultaneously on multiple threads, while upload requires the GL context 35 // simultaneously on multiple threads, while upload requires the GL context
38 // lock must happen on our non-concurrent raster thread. 36 // lock must happen on our non-concurrent raster thread.
39 // 37 //
40 // Decoded and Uploaded image data share a single cache entry. Depending on how 38 // Decoded and Uploaded image data share a single cache entry. Depending on how
41 // far we've progressed, this cache entry may contain CPU-side decoded data, 39 // far we've progressed, this cache entry may contain CPU-side decoded data,
42 // GPU-side uploaded data, or both. Because CPU-side decoded data is stored in 40 // GPU-side uploaded data, or both. Because CPU-side decoded data is stored in
43 // discardable memory, and is only locked for short periods of time (until the 41 // discardable memory, and is only locked for short periods of time (until the
44 // upload completes), this memory is not counted against our sized cache 42 // upload completes), this memory is not counted against our sized cache
45 // limits. Uploaded GPU memory, being non-discardable, always counts against 43 // limits. Uploaded GPU memory, being non-discardable, always counts against
46 // our limits. 44 // our limits.
47 // 45 //
48 // In cases where the number of images needed exceeds our cache limits, we 46 // In cases where the number of images needed exceeds our cache limits, we
49 // operate in an "at-raster" mode. In this mode, there are no decode/upload 47 // operate in an "at-raster" mode. In this mode, there are no decode/upload
50 // tasks, and images are decoded/uploaded as needed, immediately before being 48 // tasks, and images are decoded/uploaded as needed, immediately before being
51 // used in raster. Cache entries for at-raster tasks are marked as such, which 49 // used in raster. Cache entries for at-raster tasks are marked as such, which
52 // prevents future tasks from taking a dependency on them and extending their 50 // prevents future tasks from taking a dependency on them and extending their
53 // lifetime longer than is necessary. 51 // lifetime longer than is necessary.
54 //
55 // RASTER-SCALE CACHING:
56 //
57 // In order to save memory, images which are going to be scaled may be uploaded
58 // at lower than original resolution. In these cases, we may later need to
59 // re-upload the image at a higher resolution. To handle multiple images of
60 // different scales being in use at the same time, we have a two-part caching
61 // system.
62 //
63 // The first cache, |persistent_cache_|, stores one ImageData per image id.
64 // These ImageDatas are not necessarily associated with a given DrawImage, and
65 // are saved (persisted) even when their ref-count reaches zero (assuming they
66 // fit in the current memory budget). This allows for future re-use of image
67 // resources.
68 //
69 // The second cache, |in_use_cache_|, stores one image data per DrawImage -
70 // this may be the same ImageData that is in the persistent_cache_. These
71 // cache entries are more transient and are deleted as soon as all refs to the
72 // given DrawImage are released (the image is no longer in-use).
73 //
74 // For examples of raster-scale caching, see https://goo.gl/0zCd9Z
75 //
76 // REF COUNTING:
77 //
78 // In dealing with the two caches in GpuImageDecodeController, there are three
79 // ref-counting concepts in use:
80 // 1) ImageData upload/decode ref-counts.
81 // These ref-counts represent the overall number of references to the
82 // upload or decode portion of an ImageData. These ref-counts control
83 // both whether the upload/decode data can be freed, as well as whether an
84 // ImageData can be removed from the |persistent_cache_|. ImageDatas are
85 // only removed from the |persistent_cache_| if their upload/decode
86 // ref-counts are zero or if they are orphaned and replaced by a new entry.
87 // 2) InUseCacheEntry ref-counts.
88 // These ref-counts represent the number of references to an
89 // InUseCacheEntry from a specific DrawImage. When the InUseCacheEntry's
90 // ref-count reaches 0 it will be deleted.
91 // 3) scoped_refptr ref-counts.
92 // Because both the persistent_cache_ and the in_use_cache_ point at the
93 // same ImageDatas (and may need to keep these ImageDatas alive independent
94 // of each other), they hold ImageDatas by scoped_refptr. The scoped_refptr
95 // keeps an ImageData alive while it is present in either the
96 // |persistent_cache_| or |in_use_cache_|.
97 //
98 class CC_EXPORT GpuImageDecodeController 52 class CC_EXPORT GpuImageDecodeController
99 : public ImageDecodeController, 53 : public ImageDecodeController,
100 public base::trace_event::MemoryDumpProvider { 54 public base::trace_event::MemoryDumpProvider {
101 public: 55 public:
102 explicit GpuImageDecodeController(ContextProvider* context, 56 explicit GpuImageDecodeController(ContextProvider* context,
103 ResourceFormat decode_format, 57 ResourceFormat decode_format,
104 size_t max_gpu_image_bytes); 58 size_t max_gpu_image_bytes);
105 ~GpuImageDecodeController() override; 59 ~GpuImageDecodeController() override;
106 60
107 // ImageDecodeController overrides. 61 // ImageDecodeController overrides.
(...skipping 24 matching lines...) Expand all
132 void OnImageUploadTaskCompleted(const DrawImage& image); 86 void OnImageUploadTaskCompleted(const DrawImage& image);
133 87
134 // For testing only. 88 // For testing only.
135 void SetCachedItemLimitForTesting(size_t limit) { 89 void SetCachedItemLimitForTesting(size_t limit) {
136 cached_items_limit_ = limit; 90 cached_items_limit_ = limit;
137 } 91 }
138 void SetCachedBytesLimitForTesting(size_t limit) { 92 void SetCachedBytesLimitForTesting(size_t limit) {
139 cached_bytes_limit_ = limit; 93 cached_bytes_limit_ = limit;
140 } 94 }
141 size_t GetBytesUsedForTesting() const { return bytes_used_; } 95 size_t GetBytesUsedForTesting() const { return bytes_used_; }
142 size_t GetDrawImageSizeForTesting(const DrawImage& image);
143 void SetImageDecodingFailedForTesting(const DrawImage& image); 96 void SetImageDecodingFailedForTesting(const DrawImage& image);
144 bool DiscardableIsLockedForTesting(const DrawImage& image); 97 bool DiscardableIsLockedForTesting(const DrawImage& image);
145 98
146 private: 99 private:
147 enum class DecodedDataMode { GPU, CPU }; 100 enum class DecodedDataMode { GPU, CPU };
148 101
149 // Stores the CPU-side decoded bits of an image and supporting fields. 102 // Stores the CPU-side decoded bits of an image and supporting fields.
150 struct DecodedImageData { 103 struct DecodedImageData {
151 DecodedImageData(); 104 DecodedImageData();
152 ~DecodedImageData(); 105 ~DecodedImageData();
153 106
154 bool is_locked() const { return is_locked_; } 107 bool is_locked() const { return is_locked_; }
155 bool Lock(); 108 bool Lock();
156 void Unlock(); 109 void Unlock();
157 void SetLockedData(std::unique_ptr<base::DiscardableMemory> data); 110 void SetLockedData(std::unique_ptr<base::DiscardableMemory> data);
158 void ResetData(); 111 void ResetData();
159 base::DiscardableMemory* data() const { return data_.get(); } 112 base::DiscardableMemory* data() const { return data_.get(); }
113
160 void mark_used() { usage_stats_.used = true; } 114 void mark_used() { usage_stats_.used = true; }
161 115
116 // May be null if image not yet decoded.
162 uint32_t ref_count = 0; 117 uint32_t ref_count = 0;
163 // Set to true if the image was corrupt and could not be decoded. 118 // Set to true if the image was corrupt and could not be decoded.
164 bool decode_failure = false; 119 bool decode_failure = false;
165 // If non-null, this is the pending decode task for this image.
166 scoped_refptr<TileTask> task;
167 120
168 private: 121 private:
169 struct UsageStats { 122 struct UsageStats {
170 int lock_count = 1; 123 int lock_count = 1;
171 bool used = false; 124 bool used = false;
172 bool first_lock_wasted = false; 125 bool first_lock_wasted = false;
173 }; 126 };
174 127
175 void ReportUsageStats() const; 128 void ReportUsageStats() const;
176 129
(...skipping 12 matching lines...) Expand all
189 142
190 void mark_used() { usage_stats_.used = true; } 143 void mark_used() { usage_stats_.used = true; }
191 void notify_ref_reached_zero() { 144 void notify_ref_reached_zero() {
192 if (++usage_stats_.ref_reached_zero_count == 1) 145 if (++usage_stats_.ref_reached_zero_count == 1)
193 usage_stats_.first_ref_wasted = !usage_stats_.used; 146 usage_stats_.first_ref_wasted = !usage_stats_.used;
194 } 147 }
195 148
196 // True if the image is counting against our memory limits. 149 // True if the image is counting against our memory limits.
197 bool budgeted = false; 150 bool budgeted = false;
198 uint32_t ref_count = 0; 151 uint32_t ref_count = 0;
199 // If non-null, this is the pending upload task for this image.
200 scoped_refptr<TileTask> task;
201 152
202 private: 153 private:
203 struct UsageStats { 154 struct UsageStats {
204 bool used = false; 155 bool used = false;
205 bool first_ref_wasted = false; 156 bool first_ref_wasted = false;
206 int ref_reached_zero_count = 0; 157 int ref_reached_zero_count = 0;
207 }; 158 };
208 159
209 void ReportUsageStats() const; 160 void ReportUsageStats() const;
210 161
211 // May be null if image not yet uploaded / prepared. 162 // May be null if image not yet uploaded / prepared.
212 sk_sp<SkImage> image_; 163 sk_sp<SkImage> image_;
213 UsageStats usage_stats_; 164 UsageStats usage_stats_;
214 }; 165 };
215 166
216 struct ImageData : public base::RefCounted<ImageData> { 167 struct ImageData {
217 ImageData(DecodedDataMode mode, 168 ImageData(DecodedDataMode mode, size_t size);
218 size_t size, 169 ~ImageData();
219 int upload_scale_mip_level,
220 SkFilterQuality upload_scale_filter_quality);
221 170
222 const DecodedDataMode mode; 171 const DecodedDataMode mode;
223 const size_t size; 172 const size_t size;
224 bool is_at_raster = false; 173 bool is_at_raster = false;
225 174
226 // Variables used to identify/track multiple scale levels of a single image.
227 int upload_scale_mip_level = 0;
228 SkFilterQuality upload_scale_filter_quality = kNone_SkFilterQuality;
229 // If true, this image is no longer in our |persistent_cache_| and will be
230 // deleted as soon as its ref count reaches zero.
231 bool is_orphaned = false;
232
233 DecodedImageData decode; 175 DecodedImageData decode;
234 UploadedImageData upload; 176 UploadedImageData upload;
235
236 private:
237 friend class base::RefCounted<ImageData>;
238 ~ImageData();
239 }; 177 };
240 178
241 // A ref-count and ImageData, used to associate the ImageData with a specific 179 using ImageDataMRUCache =
242 // DrawImage in the |in_use_cache_|. 180 base::MRUCache<uint32_t, std::unique_ptr<ImageData>>;
243 struct InUseCacheEntry {
244 explicit InUseCacheEntry(scoped_refptr<ImageData> image_data);
245 InUseCacheEntry(const InUseCacheEntry& other);
246 InUseCacheEntry(InUseCacheEntry&& other);
247 ~InUseCacheEntry();
248
249 uint32_t ref_count = 0;
250 scoped_refptr<ImageData> image_data;
251 };
252
253 // Uniquely identifies (without collisions) a specific DrawImage for use in
254 // the |in_use_cache_|.
255 using InUseCacheKey = uint64_t;
256 181
257 // All private functions should only be called while holding |lock_|. Some 182 // All private functions should only be called while holding |lock_|. Some
258 // functions also require the |context_| lock. These are indicated by 183 // functions also require the |context_| lock. These are indicated by
259 // additional comments. 184 // additional comments.
260 185
261 // Similar to GetTaskForImageAndRef, but gets the dependent decode task 186 // Similar to GetTaskForImageAndRef, but gets the dependent decode task
262 // rather than the upload task, if necessary. 187 // rather than the upload task, if necessary.
263 scoped_refptr<TileTask> GetImageDecodeTaskAndRef( 188 scoped_refptr<TileTask> GetImageDecodeTaskAndRef(
264 const DrawImage& image, 189 const DrawImage& image,
265 const TracingInfo& tracing_info); 190 const TracingInfo& tracing_info);
266 191
267 void RefImageDecode(const DrawImage& draw_image); 192 void RefImageDecode(const DrawImage& draw_image);
268 void UnrefImageDecode(const DrawImage& draw_image); 193 void UnrefImageDecode(const DrawImage& draw_image);
269 void RefImage(const DrawImage& draw_image); 194 void RefImage(const DrawImage& draw_image);
270 void UnrefImageInternal(const DrawImage& draw_image); 195 void UnrefImageInternal(const DrawImage& draw_image);
271 196 void RefCountChanged(ImageData* image_data);
272 // Called any time the ownership of an object changed. This includes changes
273 // to ref-count or to orphaned status.
274 void OwnershipChanged(ImageData* image_data);
275 197
276 // Ensures that the cache can hold an element of |required_size|, freeing 198 // Ensures that the cache can hold an element of |required_size|, freeing
277 // unreferenced cache entries if necessary to make room. 199 // unreferenced cache entries if necessary to make room.
278 bool EnsureCapacity(size_t required_size); 200 bool EnsureCapacity(size_t required_size);
279 bool CanFitSize(size_t size) const; 201 bool CanFitSize(size_t size) const;
280 bool ExceedsPreferredCount() const; 202 bool ExceedsPreferredCount() const;
281 203
282 void DecodeImageIfNecessary(const DrawImage& draw_image, 204 void DecodeImageIfNecessary(const DrawImage& draw_image,
283 ImageData* image_data); 205 ImageData* image_data);
284 206
285 scoped_refptr<GpuImageDecodeController::ImageData> CreateImageData( 207 std::unique_ptr<GpuImageDecodeController::ImageData> CreateImageData(
286 const DrawImage& image); 208 const DrawImage& image);
287 SkImageInfo CreateImageInfoForDrawImage(const DrawImage& draw_image, 209 SkImageInfo CreateImageInfoForDrawImage(const DrawImage& draw_image) const;
288 int upload_scale_mip_level) const;
289
290 // Finds the ImageData that should be used for the given DrawImage. Looks
291 // first in the |in_use_cache_|, and then in the |persistent_cache_|.
292 ImageData* GetImageDataForDrawImage(const DrawImage& image);
293
294 // Returns true if the given ImageData can be used to draw the specified
295 // DrawImage.
296 bool IsCompatible(const ImageData* image_data,
297 const DrawImage& draw_image) const;
298 210
299 // The following two functions also require the |context_| lock to be held. 211 // The following two functions also require the |context_| lock to be held.
300 void UploadImageIfNecessary(const DrawImage& draw_image, 212 void UploadImageIfNecessary(const DrawImage& draw_image,
301 ImageData* image_data); 213 ImageData* image_data);
302 void DeletePendingImages(); 214 void DeletePendingImages();
303 215
304 const ResourceFormat format_; 216 const ResourceFormat format_;
305 ContextProvider* context_; 217 ContextProvider* context_;
306 sk_sp<GrContextThreadSafeProxy> context_threadsafe_proxy_; 218 sk_sp<GrContextThreadSafeProxy> context_threadsafe_proxy_;
307 219
308 // All members below this point must only be accessed while holding |lock_|. 220 // All members below this point must only be accessed while holding |lock_|.
309 base::Lock lock_; 221 base::Lock lock_;
310 222
311 // |persistent_cache_| represents the long-lived cache, keeping a certain 223 std::unordered_map<uint32_t, scoped_refptr<TileTask>>
312 // budget of ImageDatas alive even when their ref count reaches zero. 224 pending_image_upload_tasks_;
313 using PersistentCache = base::MRUCache<uint32_t, scoped_refptr<ImageData>>; 225 std::unordered_map<uint32_t, scoped_refptr<TileTask>>
314 PersistentCache persistent_cache_; 226 pending_image_decode_tasks_;
315 227
316 // |in_use_cache_| represents the in-use (short-lived) cache. Entries are 228 ImageDataMRUCache image_data_;
317 // cleaned up as soon as their ref count reaches zero.
318 using InUseCache = std::unordered_map<InUseCacheKey, InUseCacheEntry>;
319 InUseCache in_use_cache_;
320 229
321 size_t cached_items_limit_; 230 size_t cached_items_limit_;
322 size_t cached_bytes_limit_; 231 size_t cached_bytes_limit_;
323 size_t bytes_used_; 232 size_t bytes_used_;
324 const size_t max_gpu_image_bytes_; 233 const size_t max_gpu_image_bytes_;
325 234
326 // We can't release GPU backed SkImages without holding the context lock, 235 // We can't release GPU backed SkImages without holding the context lock,
327 // so we add them to this list and defer deletion until the next time the lock 236 // so we add them to this list and defer deletion until the next time the lock
328 // is held. 237 // is held.
329 std::vector<sk_sp<SkImage>> images_pending_deletion_; 238 std::vector<sk_sp<SkImage>> images_pending_deletion_;
330 }; 239 };
331 240
332 } // namespace cc 241 } // namespace cc
333 242
334 #endif // CC_TILES_GPU_IMAGE_DECODE_CONTROLLER_H_ 243 #endif // CC_TILES_GPU_IMAGE_DECODE_CONTROLLER_H_
OLDNEW
« no previous file with comments | « cc/test/geometry_test_utils.h ('k') | cc/tiles/gpu_image_decode_controller.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698