| 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 |