OLD | NEW |
---|---|
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 // | |
27 // GpuImageDecodeController handles the decode and upload of images that will | 29 // GpuImageDecodeController handles the decode and upload of images that will |
28 // be used by Skia's GPU raster path. It also maintains a cache of these | 30 // be used by Skia's GPU raster path. It also maintains a cache of these |
29 // decoded/uploaded images for later re-use. | 31 // decoded/uploaded images for later re-use. |
30 // | 32 // |
31 // Generally, when an image is required for raster, GpuImageDecodeController | 33 // Generally, when an image is required for raster, GpuImageDecodeController |
32 // creates two tasks, one to decode the image, and one to upload the image to | 34 // creates two tasks, one to decode the image, and one to upload the image to |
33 // the GPU. These tasks are completed before the raster task which depends on | 35 // the GPU. These tasks are completed before the raster task which depends on |
34 // the image. We need to seperate decode and upload tasks, as decode can occur | 36 // the image. We need to seperate decode and upload tasks, as decode can occur |
35 // simultaneously on multiple threads, while upload requires the GL context | 37 // simultaneously on multiple threads, while upload requires the GL context |
36 // lock must happen on our non-concurrent raster thread. | 38 // lock must happen on our non-concurrent raster thread. |
37 // | 39 // |
38 // Decoded and Uploaded image data share a single cache entry. Depending on how | 40 // Decoded and Uploaded image data share a single cache entry. Depending on how |
39 // far we've progressed, this cache entry may contain CPU-side decoded data, | 41 // far we've progressed, this cache entry may contain CPU-side decoded data, |
40 // GPU-side uploaded data, or both. Because CPU-side decoded data is stored in | 42 // GPU-side uploaded data, or both. Because CPU-side decoded data is stored in |
41 // discardable memory, and is only locked for short periods of time (until the | 43 // discardable memory, and is only locked for short periods of time (until the |
42 // upload completes), this memory is not counted against our sized cache | 44 // upload completes), this memory is not counted against our sized cache |
43 // limits. Uploaded GPU memory, being non-discardable, always counts against | 45 // limits. Uploaded GPU memory, being non-discardable, always counts against |
44 // our limits. | 46 // our limits. |
45 // | 47 // |
46 // In cases where the number of images needed exceeds our cache limits, we | 48 // In cases where the number of images needed exceeds our cache limits, we |
47 // operate in an "at-raster" mode. In this mode, there are no decode/upload | 49 // operate in an "at-raster" mode. In this mode, there are no decode/upload |
48 // tasks, and images are decoded/uploaded as needed, immediately before being | 50 // tasks, and images are decoded/uploaded as needed, immediately before being |
49 // used in raster. Cache entries for at-raster tasks are marked as such, which | 51 // used in raster. Cache entries for at-raster tasks are marked as such, which |
50 // prevents future tasks from taking a dependency on them and extending their | 52 // prevents future tasks from taking a dependency on them and extending their |
51 // lifetime longer than is necessary. | 53 // 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 // Consider the following two cases, which show the cache-usage patterns. | |
75 // | |
76 // Case 1: Larger (1x) scale used before smaller (0.5x) scale. | |
77 // | |
78 // Step 1: Create/Find Tasks and ImageData for 1x Scale (GetTaskForImageAndRef) | |
79 // 1a: No existing cache data exists, 1x ImageData created | |
80 // 1b: 1x ImageData cached in |persistent_cache_| with image's unique ID as | |
81 // key. | |
82 // 1c: 1x ImageData cached in |in_use_cache_| with 1x Scale key. | |
83 // 1d: 1x Decode task created, cached in 1x ImageData. | |
84 // 1e: 1x Upload task created, cached in 1x ImageData. | |
85 // | |
86 // ╔═══════════════════╗ ╔══════════════════════╗ | |
87 // ║ Persistent Cache ║ ║ In-Use Cache ║ | |
88 // ╟───────┬───────────╢ ╟───────────┬──────────╢ | |
89 // ║ image │ 1x ║ ║ 1x Scale │ 1x ║ | |
90 // ║ ID Key│ ImageData ║ ║ Key │ ImageData║ | |
91 // ╚═══════╧═══════════╝ ╚═══════════╧══════════╝ | |
92 // | |
93 // Step 2: Create/Find Tasks and ImageData for 0.5x Scale | |
94 // 2a: Find 1x ImageData in |persistent_cache_|. 0.5x scale can use this. | |
95 // 2b: 1x ImageData cached in |in_use_cache_| with 0.5x scale key. | |
96 // | |
97 // ╔═══════════════════╗ ╔══════════════════════╗ | |
98 // ║ Persistent Cache ║ ║ In-Use Cache ║ | |
99 // ╟───────┬───────────╢ ╟───────────┬──────────╢ | |
100 // ║ image │ 1x ║ ║ 1x Scale │ 1x ║ | |
101 // ║ ID Key│ ImageData ║ ║ Key │ ImageData║ | |
102 // ╚═══════╧═══════════╝ ╟───────────┼──────────╢ | |
103 // ║ 0.5x Scale│ 1x ║ | |
104 // ║ Key │ ImageData║ | |
105 // ╚═══════════╧══════════╝ | |
106 // | |
107 // Step 4: Draw 1x Scale | |
108 // 1x scale looked up in |in_use_cache_| via 1x key. | |
109 // | |
110 // Step 5: Draw 0.5x Scale | |
111 // 1x scale looked up in |in_use_cache_| via 0.5x key. | |
112 // | |
113 // Step 6: Finished, refs released | |
114 // Tasks are deleted from ImageData. | |
115 // Entries are deleted from |in_use_cache_|. | |
116 // 1x scale preserved in |persistent_cache_|. | |
117 // | |
118 // ╔═══════════════════╗ ╔════════════════════╗ | |
119 // ║ Persistent Cache ║ ║ In-Use Cache ║ | |
120 // ╟───────┬───────────╢ ╚════════════════════╝ | |
121 // ║ image │ 1x ║ | |
122 // ║ ID Key│ ImageData ║ | |
123 // ╚═══════╧═══════════╝ | |
124 // | |
125 // Case 2: Smaller (0.5x) scale used before larger (1x) scale. | |
126 // | |
127 // Step 1: Create/Find Tasks and ImageData for 0.5x Scale | |
128 // (GetTaskForImageAndRef) | |
129 // 1a: No existing cache data exists, 0.5x ImageData created | |
130 // 1b: 0.5x ImageData cached in |persistent_cache_| with image's unique ID | |
131 // as key. | |
132 // 1c: 0.5x ImageData cached in |in_use_cache_| with 0.5x Scale key. | |
133 // 1d: 0.5x Decode task created, cached in 0.5x ImageData. | |
134 // 1e: 0.5x Upload task created, cached in 0.5x ImageData. | |
135 // | |
136 // ╔═══════════════════╗ ╔══════════════════════╗ | |
137 // ║ Persistent Cache ║ ║ In-Use Cache ║ | |
138 // ╟───────┬───────────╢ ╟───────────┬──────────╢ | |
139 // ║ image │ 0.5 ║ ║ 0.5x Scale│ 0.5x ║ | |
140 // ║ ID Key│ ImageData ║ ║ Key │ ImageData║ | |
141 // ╚═══════╧═══════════╝ ╚═══════════╧══════════╝ | |
142 // | |
143 // Step 2: Create/Find Tasks and ImageData for 1x Scale | |
144 // 2a: Find 0.5x ImageData in |persistent_cache_|. 1x scale can't use this. | |
145 // 2b: The 0.5x scale in the persistent cache is about to be replaced by the | |
146 // 1x scale. Remove it from the persistent_cache_. Note that the 0.5x | |
147 // scale is still kept alive in the |in_use_cache_|. | |
148 // 2c: 1x ImageData created | |
149 // 2d: 1x ImageData cached in |persistent_cache_| with image's unique ID as | |
150 // key. | |
151 // 2e: 1x ImageData cached in |in_use_cache_| with 1x Scale key. | |
152 // 2f: 1x Decode task created, cached in 1x ImageData. | |
153 // 2g: 1x Upload task created, cached in 1x ImageData. | |
154 // | |
155 // ╔═══════════════════╗ ╔══════════════════════╗ | |
156 // ║ Persistent Cache ║ ║ In-Use Cache ║ | |
157 // ╟───────┬───────────╢ ╟───────────┬──────────╢ | |
158 // ║ image │ 1x ║ ║ 1x Scale │ 1x ║ | |
159 // ║ ID Key│ ImageData ║ ║ Key │ ImageData║ | |
160 // ╚═══════╧═══════════╝ ╟───────────┼──────────╢ | |
161 // ║ 0.5x Scale│ 0.5x ║ | |
162 // ║ Key │ ImageData║ | |
163 // ╚═══════════╧══════════╝ | |
164 // | |
165 // Step 4: Draw 0.5x Scale | |
166 // 0.5x scale looked up in |in_use_cache_| via 0.5x key. | |
167 // | |
168 // Step 5: Draw 1x Scale | |
169 // 1x scale looked up in |in_use_cache_| via 1x key. | |
170 // | |
171 // Step 6: Finished, refs released | |
172 // Tasks are deleted from ImageDatas. | |
173 // Entries are deleted from |in_use_cache_|. | |
174 // 1x scale preserved in |persistent_cache_|. | |
175 // | |
176 // ╔═══════════════════╗ ╔════════════════════╗ | |
177 // ║ Persistent Cache ║ ║ In-Use Cache ║ | |
178 // ╟───────┬───────────╢ ╚════════════════════╝ | |
179 // ║ image │ 1x ║ | |
180 // ║ ID Key│ ImageData ║ | |
181 // ╚═══════╧═══════════╝ | |
182 // | |
183 // REF COUNTING: | |
184 // | |
185 // In dealing with the two caches in GpuImageDecodeController, there are three | |
186 // ref-counting concepts in use: | |
187 // 1) ImageData upload/decode ref-counts. | |
188 // These ref-counts represent the overall number of references to the | |
189 // upload or decode portion of an ImageData. These ref-counts control | |
190 // both whether the upload/decode data can be freed, as well as whether an | |
191 // ImageData can be removed from the |persistent_cache_|. ImageDatas are | |
192 // only removed from the |persistent_cache_| if their upload/decode | |
193 // ref-counts are zero or if they are orphaned and replaced by a new entry. | |
194 // 2) InUseCacheEntry ref-counts. | |
195 // These ref-counts represent the number of references to an | |
196 // InUseCacheEntry from a specific DrawImage. When the InUseCacheEntry's | |
197 // ref-count reaches 0 it will be deleted. | |
198 // 3) scoped_refptr ref-counts. | |
199 // Because both the persistent_cache_ and the in_use_cache_ point at the | |
200 // same ImageDatas (and may need to keep these ImageDatas alive independent | |
201 // of each other), they hold ImageDatas by scoped_refptr. The scoped_refptr | |
202 // keeps an ImageData alive while it is present in either the | |
203 // |persistent_cache_| or |in_use_cache_|. | |
204 // | |
52 class CC_EXPORT GpuImageDecodeController | 205 class CC_EXPORT GpuImageDecodeController |
53 : public ImageDecodeController, | 206 : public ImageDecodeController, |
54 public base::trace_event::MemoryDumpProvider { | 207 public base::trace_event::MemoryDumpProvider { |
55 public: | 208 public: |
56 explicit GpuImageDecodeController(ContextProvider* context, | 209 explicit GpuImageDecodeController(ContextProvider* context, |
57 ResourceFormat decode_format, | 210 ResourceFormat decode_format, |
58 size_t max_gpu_image_bytes); | 211 size_t max_gpu_image_bytes); |
59 ~GpuImageDecodeController() override; | 212 ~GpuImageDecodeController() override; |
60 | 213 |
61 // ImageDecodeController overrides. | 214 // ImageDecodeController overrides. |
(...skipping 24 matching lines...) Expand all Loading... | |
86 void OnImageUploadTaskCompleted(const DrawImage& image); | 239 void OnImageUploadTaskCompleted(const DrawImage& image); |
87 | 240 |
88 // For testing only. | 241 // For testing only. |
89 void SetCachedItemLimitForTesting(size_t limit) { | 242 void SetCachedItemLimitForTesting(size_t limit) { |
90 cached_items_limit_ = limit; | 243 cached_items_limit_ = limit; |
91 } | 244 } |
92 void SetCachedBytesLimitForTesting(size_t limit) { | 245 void SetCachedBytesLimitForTesting(size_t limit) { |
93 cached_bytes_limit_ = limit; | 246 cached_bytes_limit_ = limit; |
94 } | 247 } |
95 size_t GetBytesUsedForTesting() const { return bytes_used_; } | 248 size_t GetBytesUsedForTesting() const { return bytes_used_; } |
249 size_t GetDrawImageSizeForTesting(const DrawImage& image); | |
96 void SetImageDecodingFailedForTesting(const DrawImage& image); | 250 void SetImageDecodingFailedForTesting(const DrawImage& image); |
97 bool DiscardableIsLockedForTesting(const DrawImage& image); | 251 bool DiscardableIsLockedForTesting(const DrawImage& image); |
98 | 252 |
99 private: | 253 private: |
100 enum class DecodedDataMode { GPU, CPU }; | 254 enum class DecodedDataMode { GPU, CPU }; |
101 | 255 |
102 // Stores the CPU-side decoded bits of an image and supporting fields. | 256 // Stores the CPU-side decoded bits of an image and supporting fields. |
103 struct DecodedImageData { | 257 struct DecodedImageData { |
104 DecodedImageData(); | 258 DecodedImageData(); |
105 ~DecodedImageData(); | 259 ~DecodedImageData(); |
106 | 260 |
107 bool is_locked() const { return is_locked_; } | 261 bool is_locked() const { return is_locked_; } |
108 bool Lock(); | 262 bool Lock(); |
109 void Unlock(); | 263 void Unlock(); |
110 void SetLockedData(std::unique_ptr<base::DiscardableMemory> data); | 264 void SetLockedData(std::unique_ptr<base::DiscardableMemory> data); |
111 void ResetData(); | 265 void ResetData(); |
112 base::DiscardableMemory* data() const { return data_.get(); } | 266 base::DiscardableMemory* data() const { return data_.get(); } |
113 | |
114 void mark_used() { usage_stats_.used = true; } | 267 void mark_used() { usage_stats_.used = true; } |
115 | 268 |
116 // May be null if image not yet decoded. | |
117 uint32_t ref_count = 0; | 269 uint32_t ref_count = 0; |
118 // Set to true if the image was corrupt and could not be decoded. | 270 // Set to true if the image was corrupt and could not be decoded. |
119 bool decode_failure = false; | 271 bool decode_failure = false; |
272 // If non-null, this is the pending decode task for this image. | |
273 scoped_refptr<TileTask> task; | |
120 | 274 |
121 private: | 275 private: |
122 struct UsageStats { | 276 struct UsageStats { |
123 int lock_count = 1; | 277 int lock_count = 1; |
124 bool used = false; | 278 bool used = false; |
125 bool first_lock_wasted = false; | 279 bool first_lock_wasted = false; |
126 }; | 280 }; |
127 | 281 |
128 void ReportUsageStats() const; | 282 void ReportUsageStats() const; |
129 | 283 |
(...skipping 12 matching lines...) Expand all Loading... | |
142 | 296 |
143 void mark_used() { usage_stats_.used = true; } | 297 void mark_used() { usage_stats_.used = true; } |
144 void notify_ref_reached_zero() { | 298 void notify_ref_reached_zero() { |
145 if (++usage_stats_.ref_reached_zero_count == 1) | 299 if (++usage_stats_.ref_reached_zero_count == 1) |
146 usage_stats_.first_ref_wasted = !usage_stats_.used; | 300 usage_stats_.first_ref_wasted = !usage_stats_.used; |
147 } | 301 } |
148 | 302 |
149 // True if the image is counting against our memory limits. | 303 // True if the image is counting against our memory limits. |
150 bool budgeted = false; | 304 bool budgeted = false; |
151 uint32_t ref_count = 0; | 305 uint32_t ref_count = 0; |
306 // If non-null, this is the pending upload task for this image. | |
307 scoped_refptr<TileTask> task; | |
152 | 308 |
153 private: | 309 private: |
154 struct UsageStats { | 310 struct UsageStats { |
155 bool used = false; | 311 bool used = false; |
156 bool first_ref_wasted = false; | 312 bool first_ref_wasted = false; |
157 int ref_reached_zero_count = 0; | 313 int ref_reached_zero_count = 0; |
158 }; | 314 }; |
159 | 315 |
160 void ReportUsageStats() const; | 316 void ReportUsageStats() const; |
161 | 317 |
162 // May be null if image not yet uploaded / prepared. | 318 // May be null if image not yet uploaded / prepared. |
163 sk_sp<SkImage> image_; | 319 sk_sp<SkImage> image_; |
164 UsageStats usage_stats_; | 320 UsageStats usage_stats_; |
165 }; | 321 }; |
166 | 322 |
167 struct ImageData { | 323 struct ImageData : public base::RefCounted<ImageData> { |
168 ImageData(DecodedDataMode mode, size_t size); | 324 ImageData(DecodedDataMode mode, |
169 ~ImageData(); | 325 size_t size, |
326 int upload_scale_mip_level, | |
327 SkFilterQuality upload_scale_filter_quality); | |
170 | 328 |
171 const DecodedDataMode mode; | 329 const DecodedDataMode mode; |
172 const size_t size; | 330 const size_t size; |
173 bool is_at_raster = false; | 331 bool is_at_raster = false; |
174 | 332 |
333 // Variables used to identify/track multiple scale levels of a single image. | |
334 int upload_scale_mip_level = 0; | |
335 SkFilterQuality upload_scale_filter_quality = kNone_SkFilterQuality; | |
336 bool is_orphaned = false; | |
vmpstr
2016/06/22 21:33:35
Add a comment here about what orphaned is
ericrk
2016/06/23 18:16:55
Done.
| |
337 | |
175 DecodedImageData decode; | 338 DecodedImageData decode; |
176 UploadedImageData upload; | 339 UploadedImageData upload; |
340 | |
341 private: | |
342 friend class base::RefCounted<ImageData>; | |
343 ~ImageData(); | |
177 }; | 344 }; |
178 | 345 |
179 using ImageDataMRUCache = | 346 // A ref-count and ImageData, used to associate the ImageData with a specific |
180 base::MRUCache<uint32_t, std::unique_ptr<ImageData>>; | 347 // DrawImage in the |in_use_cache_|. |
348 struct InUseCacheEntry { | |
349 explicit InUseCacheEntry(scoped_refptr<ImageData> image_data); | |
350 InUseCacheEntry(const InUseCacheEntry& other); | |
351 InUseCacheEntry(InUseCacheEntry&& other); | |
352 ~InUseCacheEntry(); | |
353 | |
354 uint32_t ref_count = 0; | |
355 scoped_refptr<ImageData> image_data; | |
356 }; | |
357 | |
358 // Uniquely identifies (without collisions) a specific DrawImage for use in | |
359 // the |in_use_cache_|. | |
360 using InUseCacheKey = uint64_t; | |
181 | 361 |
182 // All private functions should only be called while holding |lock_|. Some | 362 // All private functions should only be called while holding |lock_|. Some |
183 // functions also require the |context_| lock. These are indicated by | 363 // functions also require the |context_| lock. These are indicated by |
184 // additional comments. | 364 // additional comments. |
185 | 365 |
186 // Similar to GetTaskForImageAndRef, but gets the dependent decode task | 366 // Similar to GetTaskForImageAndRef, but gets the dependent decode task |
187 // rather than the upload task, if necessary. | 367 // rather than the upload task, if necessary. |
188 scoped_refptr<TileTask> GetImageDecodeTaskAndRef( | 368 scoped_refptr<TileTask> GetImageDecodeTaskAndRef( |
189 const DrawImage& image, | 369 const DrawImage& image, |
190 const TracingInfo& tracing_info); | 370 const TracingInfo& tracing_info); |
191 | 371 |
192 void RefImageDecode(const DrawImage& draw_image); | 372 void RefImageDecode(const DrawImage& draw_image); |
193 void UnrefImageDecode(const DrawImage& draw_image); | 373 void UnrefImageDecode(const DrawImage& draw_image); |
194 void RefImage(const DrawImage& draw_image); | 374 void RefImage(const DrawImage& draw_image); |
195 void UnrefImageInternal(const DrawImage& draw_image); | 375 void UnrefImageInternal(const DrawImage& draw_image); |
196 void RefCountChanged(ImageData* image_data); | 376 |
377 // Called any time the ownership of an object changed. This includes changes | |
378 // to ref-count or to orphaned status. | |
379 void OwnershipChanged(ImageData* image_data); | |
197 | 380 |
198 // Ensures that the cache can hold an element of |required_size|, freeing | 381 // Ensures that the cache can hold an element of |required_size|, freeing |
199 // unreferenced cache entries if necessary to make room. | 382 // unreferenced cache entries if necessary to make room. |
200 bool EnsureCapacity(size_t required_size); | 383 bool EnsureCapacity(size_t required_size); |
201 bool CanFitSize(size_t size) const; | 384 bool CanFitSize(size_t size) const; |
202 bool ExceedsPreferredCount() const; | 385 bool ExceedsPreferredCount() const; |
203 | 386 |
204 void DecodeImageIfNecessary(const DrawImage& draw_image, | 387 void DecodeImageIfNecessary(const DrawImage& draw_image, |
205 ImageData* image_data); | 388 ImageData* image_data); |
206 | 389 |
207 std::unique_ptr<GpuImageDecodeController::ImageData> CreateImageData( | 390 scoped_refptr<GpuImageDecodeController::ImageData> CreateImageData( |
208 const DrawImage& image); | 391 const DrawImage& image); |
209 SkImageInfo CreateImageInfoForDrawImage(const DrawImage& draw_image) const; | 392 SkImageInfo CreateImageInfoForDrawImage(const DrawImage& draw_image, |
393 int upload_scale_mip_level) const; | |
394 | |
395 // Finds the ImageData that should be used for the given DrawImage. Looks | |
396 // first in the |in_use_cache_|, and then in the |persistent_cache_|. | |
397 ImageData* GetImageDataForDrawImage(const DrawImage& image); | |
398 | |
399 // Returns true if the given ImageData can be used to draw the specified | |
400 // DrawImage. | |
401 bool IsCompatibleWithDrawImage(const ImageData* image_data, | |
vmpstr
2016/06/22 21:33:35
I think "IsCompatible" is good enough, but maybe t
ericrk
2016/06/23 18:16:55
sure.
| |
402 const DrawImage& draw_image) const; | |
210 | 403 |
211 // The following two functions also require the |context_| lock to be held. | 404 // The following two functions also require the |context_| lock to be held. |
212 void UploadImageIfNecessary(const DrawImage& draw_image, | 405 void UploadImageIfNecessary(const DrawImage& draw_image, |
213 ImageData* image_data); | 406 ImageData* image_data); |
214 void DeletePendingImages(); | 407 void DeletePendingImages(); |
215 | 408 |
216 const ResourceFormat format_; | 409 const ResourceFormat format_; |
217 ContextProvider* context_; | 410 ContextProvider* context_; |
218 sk_sp<GrContextThreadSafeProxy> context_threadsafe_proxy_; | 411 sk_sp<GrContextThreadSafeProxy> context_threadsafe_proxy_; |
219 | 412 |
220 // All members below this point must only be accessed while holding |lock_|. | 413 // All members below this point must only be accessed while holding |lock_|. |
221 base::Lock lock_; | 414 base::Lock lock_; |
222 | 415 |
223 std::unordered_map<uint32_t, scoped_refptr<TileTask>> | 416 // |persistent_cache_| represents the long-lived cache, keeping a certain |
224 pending_image_upload_tasks_; | 417 // budget of ImageDatas alive even when their ref count reaches zero. |
225 std::unordered_map<uint32_t, scoped_refptr<TileTask>> | 418 using ImageDataMRUCache = base::MRUCache<uint32_t, scoped_refptr<ImageData>>; |
226 pending_image_decode_tasks_; | 419 ImageDataMRUCache persistent_cache_; |
227 | 420 |
228 ImageDataMRUCache image_data_; | 421 // |in_use_cache_| represents the in-use (short-lived) cache. Entries are |
422 // cleaned up as soon as their ref count reaches zero. | |
423 std::unordered_map<InUseCacheKey, InUseCacheEntry> in_use_cache_; | |
229 | 424 |
230 size_t cached_items_limit_; | 425 size_t cached_items_limit_; |
231 size_t cached_bytes_limit_; | 426 size_t cached_bytes_limit_; |
232 size_t bytes_used_; | 427 size_t bytes_used_; |
233 const size_t max_gpu_image_bytes_; | 428 const size_t max_gpu_image_bytes_; |
234 | 429 |
235 // We can't release GPU backed SkImages without holding the context lock, | 430 // We can't release GPU backed SkImages without holding the context lock, |
236 // so we add them to this list and defer deletion until the next time the lock | 431 // so we add them to this list and defer deletion until the next time the lock |
237 // is held. | 432 // is held. |
238 std::vector<sk_sp<SkImage>> images_pending_deletion_; | 433 std::vector<sk_sp<SkImage>> images_pending_deletion_; |
239 }; | 434 }; |
240 | 435 |
241 } // namespace cc | 436 } // namespace cc |
242 | 437 |
243 #endif // CC_TILES_GPU_IMAGE_DECODE_CONTROLLER_H_ | 438 #endif // CC_TILES_GPU_IMAGE_DECODE_CONTROLLER_H_ |
OLD | NEW |