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_SOFTWARE_IMAGE_DECODE_CONTROLLER_H_ | 5 #ifndef CC_TILES_SOFTWARE_IMAGE_DECODE_CACHE_H_ |
6 #define CC_TILES_SOFTWARE_IMAGE_DECODE_CONTROLLER_H_ | 6 #define CC_TILES_SOFTWARE_IMAGE_DECODE_CACHE_H_ |
7 | 7 |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include <memory> | 10 #include <memory> |
11 #include <unordered_map> | 11 #include <unordered_map> |
12 #include <unordered_set> | 12 #include <unordered_set> |
13 | 13 |
14 #include "base/atomic_sequence_num.h" | 14 #include "base/atomic_sequence_num.h" |
15 #include "base/containers/mru_cache.h" | 15 #include "base/containers/mru_cache.h" |
16 #include "base/hash.h" | 16 #include "base/hash.h" |
17 #include "base/memory/discardable_memory_allocator.h" | 17 #include "base/memory/discardable_memory_allocator.h" |
18 #include "base/memory/memory_coordinator_client.h" | 18 #include "base/memory/memory_coordinator_client.h" |
19 #include "base/memory/ref_counted.h" | 19 #include "base/memory/ref_counted.h" |
20 #include "base/numerics/safe_math.h" | 20 #include "base/numerics/safe_math.h" |
21 #include "base/threading/thread_checker.h" | 21 #include "base/threading/thread_checker.h" |
22 #include "base/trace_event/memory_dump_provider.h" | 22 #include "base/trace_event/memory_dump_provider.h" |
23 #include "cc/base/cc_export.h" | 23 #include "cc/base/cc_export.h" |
24 #include "cc/playback/decoded_draw_image.h" | 24 #include "cc/playback/decoded_draw_image.h" |
25 #include "cc/playback/draw_image.h" | 25 #include "cc/playback/draw_image.h" |
26 #include "cc/resources/resource_format.h" | 26 #include "cc/resources/resource_format.h" |
27 #include "cc/tiles/image_decode_controller.h" | 27 #include "cc/tiles/image_decode_cache.h" |
28 #include "third_party/skia/include/core/SkRefCnt.h" | 28 #include "third_party/skia/include/core/SkRefCnt.h" |
29 #include "ui/gfx/geometry/rect.h" | 29 #include "ui/gfx/geometry/rect.h" |
30 | 30 |
31 namespace cc { | 31 namespace cc { |
32 | 32 |
33 // ImageDecodeControllerKey is a class that gets a cache key out of a given draw | 33 // ImageDecodeCacheKey is a class that gets a cache key out of a given draw |
34 // image. That is, this key uniquely identifies an image in the cache. Note that | 34 // image. That is, this key uniquely identifies an image in the cache. Note that |
35 // it's insufficient to use SkImage's unique id, since the same image can appear | 35 // it's insufficient to use SkImage's unique id, since the same image can appear |
36 // in the cache multiple times at different scales and filter qualities. | 36 // in the cache multiple times at different scales and filter qualities. |
37 class CC_EXPORT ImageDecodeControllerKey { | 37 class CC_EXPORT ImageDecodeCacheKey { |
38 public: | 38 public: |
39 static ImageDecodeControllerKey FromDrawImage(const DrawImage& image); | 39 static ImageDecodeCacheKey FromDrawImage(const DrawImage& image); |
40 | 40 |
41 ImageDecodeControllerKey(const ImageDecodeControllerKey& other); | 41 ImageDecodeCacheKey(const ImageDecodeCacheKey& other); |
42 | 42 |
43 bool operator==(const ImageDecodeControllerKey& other) const { | 43 bool operator==(const ImageDecodeCacheKey& other) const { |
44 // The image_id always has to be the same. However, after that all original | 44 // The image_id always has to be the same. However, after that all original |
45 // decodes are the same, so if we can use the original decode, return true. | 45 // decodes are the same, so if we can use the original decode, return true. |
46 // If not, then we have to compare every field. | 46 // If not, then we have to compare every field. |
47 return image_id_ == other.image_id_ && | 47 return image_id_ == other.image_id_ && |
48 can_use_original_decode_ == other.can_use_original_decode_ && | 48 can_use_original_decode_ == other.can_use_original_decode_ && |
49 (can_use_original_decode_ || | 49 (can_use_original_decode_ || |
50 (src_rect_ == other.src_rect_ && | 50 (src_rect_ == other.src_rect_ && |
51 target_size_ == other.target_size_ && | 51 target_size_ == other.target_size_ && |
52 filter_quality_ == other.filter_quality_)); | 52 filter_quality_ == other.filter_quality_)); |
53 } | 53 } |
54 | 54 |
55 bool operator!=(const ImageDecodeControllerKey& other) const { | 55 bool operator!=(const ImageDecodeCacheKey& other) const { |
56 return !(*this == other); | 56 return !(*this == other); |
57 } | 57 } |
58 | 58 |
59 uint32_t image_id() const { return image_id_; } | 59 uint32_t image_id() const { return image_id_; } |
60 SkFilterQuality filter_quality() const { return filter_quality_; } | 60 SkFilterQuality filter_quality() const { return filter_quality_; } |
61 gfx::Rect src_rect() const { return src_rect_; } | 61 gfx::Rect src_rect() const { return src_rect_; } |
62 gfx::Size target_size() const { return target_size_; } | 62 gfx::Size target_size() const { return target_size_; } |
63 | 63 |
64 bool can_use_original_decode() const { return can_use_original_decode_; } | 64 bool can_use_original_decode() const { return can_use_original_decode_; } |
65 bool should_use_subrect() const { return should_use_subrect_; } | 65 bool should_use_subrect() const { return should_use_subrect_; } |
66 size_t get_hash() const { return hash_; } | 66 size_t get_hash() const { return hash_; } |
67 | 67 |
68 // Helper to figure out how much memory the locked image represented by this | 68 // Helper to figure out how much memory the locked image represented by this |
69 // key would take. | 69 // key would take. |
70 size_t locked_bytes() const { | 70 size_t locked_bytes() const { |
71 // TODO(vmpstr): Handle formats other than RGBA. | 71 // TODO(vmpstr): Handle formats other than RGBA. |
72 base::CheckedNumeric<size_t> result = 4; | 72 base::CheckedNumeric<size_t> result = 4; |
73 result *= target_size_.width(); | 73 result *= target_size_.width(); |
74 result *= target_size_.height(); | 74 result *= target_size_.height(); |
75 return result.ValueOrDefault(std::numeric_limits<size_t>::max()); | 75 return result.ValueOrDefault(std::numeric_limits<size_t>::max()); |
76 } | 76 } |
77 | 77 |
78 std::string ToString() const; | 78 std::string ToString() const; |
79 | 79 |
80 private: | 80 private: |
81 ImageDecodeControllerKey(uint32_t image_id, | 81 ImageDecodeCacheKey(uint32_t image_id, |
82 const gfx::Rect& src_rect, | 82 const gfx::Rect& src_rect, |
83 const gfx::Size& size, | 83 const gfx::Size& size, |
84 SkFilterQuality filter_quality, | 84 SkFilterQuality filter_quality, |
85 bool can_use_original_decode, | 85 bool can_use_original_decode, |
86 bool should_use_subrect); | 86 bool should_use_subrect); |
87 | 87 |
88 uint32_t image_id_; | 88 uint32_t image_id_; |
89 gfx::Rect src_rect_; | 89 gfx::Rect src_rect_; |
90 gfx::Size target_size_; | 90 gfx::Size target_size_; |
91 SkFilterQuality filter_quality_; | 91 SkFilterQuality filter_quality_; |
92 bool can_use_original_decode_; | 92 bool can_use_original_decode_; |
93 bool should_use_subrect_; | 93 bool should_use_subrect_; |
94 size_t hash_; | 94 size_t hash_; |
95 }; | 95 }; |
96 | 96 |
97 // Hash function for the above ImageDecodeControllerKey. | 97 // Hash function for the above ImageDecodeCacheKey. |
98 struct ImageDecodeControllerKeyHash { | 98 struct ImageDecodeCacheKeyHash { |
99 size_t operator()(const ImageDecodeControllerKey& key) const { | 99 size_t operator()(const ImageDecodeCacheKey& key) const { |
100 return key.get_hash(); | 100 return key.get_hash(); |
101 } | 101 } |
102 }; | 102 }; |
103 | 103 |
104 class CC_EXPORT SoftwareImageDecodeController | 104 class CC_EXPORT SoftwareImageDecodeCache |
105 : public ImageDecodeController, | 105 : public ImageDecodeCache, |
106 public base::trace_event::MemoryDumpProvider, | 106 public base::trace_event::MemoryDumpProvider, |
107 public base::MemoryCoordinatorClient { | 107 public base::MemoryCoordinatorClient { |
108 public: | 108 public: |
109 using ImageKey = ImageDecodeControllerKey; | 109 using ImageKey = ImageDecodeCacheKey; |
110 using ImageKeyHash = ImageDecodeControllerKeyHash; | 110 using ImageKeyHash = ImageDecodeCacheKeyHash; |
111 | 111 |
112 SoftwareImageDecodeController(ResourceFormat format, | 112 SoftwareImageDecodeCache(ResourceFormat format, |
113 size_t locked_memory_limit_bytes); | 113 size_t locked_memory_limit_bytes); |
114 ~SoftwareImageDecodeController() override; | 114 ~SoftwareImageDecodeCache() override; |
115 | 115 |
116 // ImageDecodeController overrides. | 116 // ImageDecodeCache overrides. |
117 bool GetTaskForImageAndRef(const DrawImage& image, | 117 bool GetTaskForImageAndRef(const DrawImage& image, |
118 const TracingInfo& tracing_info, | 118 const TracingInfo& tracing_info, |
119 scoped_refptr<TileTask>* task) override; | 119 scoped_refptr<TileTask>* task) override; |
120 void UnrefImage(const DrawImage& image) override; | 120 void UnrefImage(const DrawImage& image) override; |
121 DecodedDrawImage GetDecodedImageForDraw(const DrawImage& image) override; | 121 DecodedDrawImage GetDecodedImageForDraw(const DrawImage& image) override; |
122 void DrawWithImageFinished(const DrawImage& image, | 122 void DrawWithImageFinished(const DrawImage& image, |
123 const DecodedDrawImage& decoded_image) override; | 123 const DecodedDrawImage& decoded_image) override; |
124 void ReduceCacheUsage() override; | 124 void ReduceCacheUsage() override; |
125 // Software doesn't keep outstanding images pinned, so this is a no-op. | 125 // Software doesn't keep outstanding images pinned, so this is a no-op. |
126 void SetShouldAggressivelyFreeResources( | 126 void SetShouldAggressivelyFreeResources( |
(...skipping 27 matching lines...) Expand all Loading... |
154 | 154 |
155 const SkSize& src_rect_offset() const { return src_rect_offset_; } | 155 const SkSize& src_rect_offset() const { return src_rect_offset_; } |
156 | 156 |
157 bool is_locked() const { return locked_; } | 157 bool is_locked() const { return locked_; } |
158 bool Lock(); | 158 bool Lock(); |
159 void Unlock(); | 159 void Unlock(); |
160 | 160 |
161 const base::DiscardableMemory* memory() const { return memory_.get(); } | 161 const base::DiscardableMemory* memory() const { return memory_.get(); } |
162 | 162 |
163 // An ID which uniquely identifies this DecodedImage within the image decode | 163 // An ID which uniquely identifies this DecodedImage within the image decode |
164 // controller. Used in memory tracing. | 164 // cache. Used in memory tracing. |
165 uint64_t tracing_id() const { return tracing_id_; } | 165 uint64_t tracing_id() const { return tracing_id_; } |
166 // Mark this image as being used in either a draw or as a source for a | 166 // Mark this image as being used in either a draw or as a source for a |
167 // scaled image. Either case represents this decode as being valuable and | 167 // scaled image. Either case represents this decode as being valuable and |
168 // not wasted. | 168 // not wasted. |
169 void mark_used() { usage_stats_.used = true; } | 169 void mark_used() { usage_stats_.used = true; } |
170 | 170 |
171 private: | 171 private: |
172 struct UsageStats { | 172 struct UsageStats { |
173 // We can only create a decoded image in a locked state, so the initial | 173 // We can only create a decoded image in a locked state, so the initial |
174 // lock count is 1. | 174 // lock count is 1. |
(...skipping 23 matching lines...) Expand all Loading... |
198 void SubtractUsage(size_t usage); | 198 void SubtractUsage(size_t usage); |
199 void ResetUsage(); | 199 void ResetUsage(); |
200 size_t total_limit_bytes() const { return limit_bytes_; } | 200 size_t total_limit_bytes() const { return limit_bytes_; } |
201 size_t GetCurrentUsageSafe() const; | 201 size_t GetCurrentUsageSafe() const; |
202 | 202 |
203 private: | 203 private: |
204 size_t limit_bytes_; | 204 size_t limit_bytes_; |
205 base::CheckedNumeric<size_t> current_usage_bytes_; | 205 base::CheckedNumeric<size_t> current_usage_bytes_; |
206 }; | 206 }; |
207 | 207 |
208 using ImageMRUCache = base::HashingMRUCache<ImageKey, | 208 using ImageMRUCache = base:: |
209 std::unique_ptr<DecodedImage>, | 209 HashingMRUCache<ImageKey, std::unique_ptr<DecodedImage>, ImageKeyHash>; |
210 ImageKeyHash>; | |
211 | 210 |
212 // Looks for the key in the cache and returns true if it was found and was | 211 // Looks for the key in the cache and returns true if it was found and was |
213 // successfully locked (or if it was already locked). Note that if this | 212 // successfully locked (or if it was already locked). Note that if this |
214 // function returns true, then a ref count is increased for the image. | 213 // function returns true, then a ref count is increased for the image. |
215 bool LockDecodedImageIfPossibleAndRef(const ImageKey& key); | 214 bool LockDecodedImageIfPossibleAndRef(const ImageKey& key); |
216 | 215 |
217 // Actually decode the image. Note that this function can (and should) be | 216 // Actually decode the image. Note that this function can (and should) be |
218 // called with no lock acquired, since it can do a lot of work. Note that it | 217 // called with no lock acquired, since it can do a lot of work. Note that it |
219 // can also return nullptr to indicate the decode failed. | 218 // can also return nullptr to indicate the decode failed. |
220 std::unique_ptr<DecodedImage> DecodeImageInternal( | 219 std::unique_ptr<DecodedImage> DecodeImageInternal( |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
288 | 287 |
289 ResourceFormat format_; | 288 ResourceFormat format_; |
290 size_t max_items_in_cache_; | 289 size_t max_items_in_cache_; |
291 | 290 |
292 // Used to uniquely identify DecodedImages for memory traces. | 291 // Used to uniquely identify DecodedImages for memory traces. |
293 base::AtomicSequenceNumber next_tracing_id_; | 292 base::AtomicSequenceNumber next_tracing_id_; |
294 }; | 293 }; |
295 | 294 |
296 } // namespace cc | 295 } // namespace cc |
297 | 296 |
298 #endif // CC_TILES_SOFTWARE_IMAGE_DECODE_CONTROLLER_H_ | 297 #endif // CC_TILES_SOFTWARE_IMAGE_DECODE_CACHE_H_ |
OLD | NEW |