Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 #include "cc/tiles/software_image_decode_cache.h" | 5 #include "cc/tiles/software_image_decode_cache.h" |
| 6 | 6 |
| 7 #include <inttypes.h> | 7 #include <inttypes.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <algorithm> | 10 #include <algorithm> |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 44 // differently. | 44 // differently. |
| 45 const size_t kNormalMaxItemsInCache = 1000; | 45 const size_t kNormalMaxItemsInCache = 1000; |
| 46 const size_t kThrottledMaxItemsInCache = 100; | 46 const size_t kThrottledMaxItemsInCache = 100; |
| 47 const size_t kSuspendedMaxItemsInCache = 0; | 47 const size_t kSuspendedMaxItemsInCache = 0; |
| 48 | 48 |
| 49 // If the size of the original sized image breaches kMemoryRatioToSubrect but we | 49 // If the size of the original sized image breaches kMemoryRatioToSubrect but we |
| 50 // don't need to scale the image, consider caching only the needed subrect. | 50 // don't need to scale the image, consider caching only the needed subrect. |
| 51 // The second part that much be true is that we cache only the needed subrect if | 51 // The second part that much be true is that we cache only the needed subrect if |
| 52 // the total size needed for the subrect is at most kMemoryRatioToSubrect * | 52 // the total size needed for the subrect is at most kMemoryRatioToSubrect * |
| 53 // (size needed for the full original image). | 53 // (size needed for the full original image). |
| 54 // Note that at least one of the dimensions has to be at least | |
| 55 // kMinDimensionToSubrect before an image can breach the threshold. | |
| 54 const size_t kMemoryThresholdToSubrect = 64 * 1024 * 1024; | 56 const size_t kMemoryThresholdToSubrect = 64 * 1024 * 1024; |
| 57 const int kMinDimensionToSubrect = 4 * 1024; | |
| 55 const float kMemoryRatioToSubrect = 0.5f; | 58 const float kMemoryRatioToSubrect = 0.5f; |
| 56 | 59 |
| 57 class AutoRemoveKeyFromTaskMap { | 60 class AutoRemoveKeyFromTaskMap { |
| 58 public: | 61 public: |
| 59 AutoRemoveKeyFromTaskMap( | 62 AutoRemoveKeyFromTaskMap( |
| 60 std::unordered_map<SoftwareImageDecodeCache::ImageKey, | 63 std::unordered_map<SoftwareImageDecodeCache::ImageKey, |
| 61 scoped_refptr<TileTask>, | 64 scoped_refptr<TileTask>, |
| 62 SoftwareImageDecodeCache::ImageKeyHash>* task_map, | 65 SoftwareImageDecodeCache::ImageKeyHash>* task_map, |
| 63 const SoftwareImageDecodeCache::ImageKey& key) | 66 const SoftwareImageDecodeCache::ImageKey& key) |
| 64 : task_map_(task_map), key_(key) {} | 67 : task_map_(task_map), key_(key) {} |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 169 success); | 172 success); |
| 170 case TilePriority::SOON: | 173 case TilePriority::SOON: |
| 171 UMA_HISTOGRAM_BOOLEAN("Renderer4.LockExistingCachedImage.Software.SOON", | 174 UMA_HISTOGRAM_BOOLEAN("Renderer4.LockExistingCachedImage.Software.SOON", |
| 172 success); | 175 success); |
| 173 case TilePriority::EVENTUALLY: | 176 case TilePriority::EVENTUALLY: |
| 174 UMA_HISTOGRAM_BOOLEAN( | 177 UMA_HISTOGRAM_BOOLEAN( |
| 175 "Renderer4.LockExistingCachedImage.Software.EVENTUALLY", success); | 178 "Renderer4.LockExistingCachedImage.Software.EVENTUALLY", success); |
| 176 } | 179 } |
| 177 } | 180 } |
| 178 | 181 |
| 182 gfx::Rect GetSrcRect(const DrawImage& image) { | |
|
enne (OOO)
2017/02/02 00:36:41
Does this end up being cheaper than the code that
ericrk
2017/02/02 00:37:56
Can we just store this on DrawImage rather than sr
vmpstr
2017/02/02 00:52:45
Hmm, I'm a little hesitant to do this, since there
vmpstr
2017/02/02 00:52:45
This alone speeds up the test by about 25%. There
ericrk
2017/02/02 22:21:28
I see, the full computations aren't needed everywh
| |
| 183 const SkIRect& src_rect = image.src_rect(); | |
|
ericrk
2017/02/02 00:37:56
DrawImage::src_rect() returns a "const SkIRect", n
vmpstr
2017/02/02 00:52:45
Done, the perf results are comparable.
ericrk
2017/02/02 22:21:28
Done.
| |
| 184 int x = std::max(0, src_rect.x()); | |
| 185 int y = std::max(0, src_rect.y()); | |
| 186 int right = std::min(image.image()->width(), src_rect.right()); | |
| 187 int bottom = std::min(image.image()->height(), src_rect.bottom()); | |
| 188 if (x >= right || y >= bottom) | |
| 189 return gfx::Rect(); | |
| 190 return gfx::Rect(x, y, right - x, bottom - y); | |
| 191 } | |
| 192 | |
| 179 } // namespace | 193 } // namespace |
| 180 | 194 |
| 181 SoftwareImageDecodeCache::SoftwareImageDecodeCache( | 195 SoftwareImageDecodeCache::SoftwareImageDecodeCache( |
| 182 ResourceFormat format, | 196 ResourceFormat format, |
| 183 size_t locked_memory_limit_bytes) | 197 size_t locked_memory_limit_bytes) |
| 184 : decoded_images_(ImageMRUCache::NO_AUTO_EVICT), | 198 : decoded_images_(ImageMRUCache::NO_AUTO_EVICT), |
| 185 at_raster_decoded_images_(ImageMRUCache::NO_AUTO_EVICT), | 199 at_raster_decoded_images_(ImageMRUCache::NO_AUTO_EVICT), |
| 186 locked_images_budget_(locked_memory_limit_bytes), | 200 locked_images_budget_(locked_memory_limit_bytes), |
| 187 format_(format), | 201 format_(format), |
| 188 max_items_in_cache_(kNormalMaxItemsInCache) { | 202 max_items_in_cache_(kNormalMaxItemsInCache) { |
| (...skipping 702 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 891 #endif // DCHECK_IS_ON() | 905 #endif // DCHECK_IS_ON() |
| 892 } | 906 } |
| 893 | 907 |
| 894 // SoftwareImageDecodeCacheKey | 908 // SoftwareImageDecodeCacheKey |
| 895 ImageDecodeCacheKey ImageDecodeCacheKey::FromDrawImage(const DrawImage& image) { | 909 ImageDecodeCacheKey ImageDecodeCacheKey::FromDrawImage(const DrawImage& image) { |
| 896 const SkSize& scale = image.scale(); | 910 const SkSize& scale = image.scale(); |
| 897 // If the src_rect falls outside of the image, we need to clip it since | 911 // If the src_rect falls outside of the image, we need to clip it since |
| 898 // otherwise we might end up with uninitialized memory in the decode process. | 912 // otherwise we might end up with uninitialized memory in the decode process. |
| 899 // Note that the scale is still unchanged and the target size is now a | 913 // Note that the scale is still unchanged and the target size is now a |
| 900 // function of the new src_rect. | 914 // function of the new src_rect. |
| 901 gfx::Rect src_rect = gfx::IntersectRects( | 915 const gfx::Rect& src_rect = GetSrcRect(image); |
| 902 gfx::SkIRectToRect(image.src_rect()), | |
| 903 gfx::Rect(image.image()->width(), image.image()->height())); | |
| 904 | |
| 905 gfx::Size target_size( | 916 gfx::Size target_size( |
| 906 SkScalarRoundToInt(std::abs(src_rect.width() * scale.width())), | 917 SkScalarRoundToInt(std::abs(src_rect.width() * scale.width())), |
| 907 SkScalarRoundToInt(std::abs(src_rect.height() * scale.height()))); | 918 SkScalarRoundToInt(std::abs(src_rect.height() * scale.height()))); |
| 908 | 919 |
| 909 // Start with the quality that was requested. | 920 // Start with the quality that was requested. |
| 910 SkFilterQuality quality = image.filter_quality(); | 921 SkFilterQuality quality = image.filter_quality(); |
| 911 | 922 |
| 912 // If we're not going to do a scale, we can use low filter quality. Note that | 923 // If we're not going to do a scale, we can use low filter quality. Note that |
| 913 // checking if the sizes are the same is better than checking if scale is 1.f, | 924 // checking if the sizes are the same is better than checking if scale is 1.f, |
| 914 // because even non-1 scale can result in the same (rounded) width/height. | 925 // because even non-1 scale can result in the same (rounded) width/height. |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 943 if (quality == kMedium_SkFilterQuality) { | 954 if (quality == kMedium_SkFilterQuality) { |
| 944 if (!image.matrix_is_decomposable() || | 955 if (!image.matrix_is_decomposable() || |
| 945 (scale.width() >= 1.f && scale.height() >= 1.f)) { | 956 (scale.width() >= 1.f && scale.height() >= 1.f)) { |
| 946 quality = kLow_SkFilterQuality; | 957 quality = kLow_SkFilterQuality; |
| 947 } | 958 } |
| 948 } | 959 } |
| 949 | 960 |
| 950 bool can_use_original_decode = | 961 bool can_use_original_decode = |
| 951 quality == kLow_SkFilterQuality || quality == kNone_SkFilterQuality; | 962 quality == kLow_SkFilterQuality || quality == kNone_SkFilterQuality; |
| 952 bool should_use_subrect = false; | 963 bool should_use_subrect = false; |
| 953 if (can_use_original_decode) { | 964 if (can_use_original_decode && |
| 965 (image.image()->width() >= kMinDimensionToSubrect || | |
| 966 image.image()->height() >= kMinDimensionToSubrect)) { | |
| 954 base::CheckedNumeric<size_t> checked_original_size = 4u; | 967 base::CheckedNumeric<size_t> checked_original_size = 4u; |
| 955 checked_original_size *= image.image()->width(); | 968 checked_original_size *= image.image()->width(); |
| 956 checked_original_size *= image.image()->height(); | 969 checked_original_size *= image.image()->height(); |
| 957 size_t original_size = checked_original_size.ValueOrDefault( | 970 size_t original_size = checked_original_size.ValueOrDefault( |
| 958 std::numeric_limits<size_t>::max()); | 971 std::numeric_limits<size_t>::max()); |
| 959 | 972 |
| 960 base::CheckedNumeric<size_t> checked_src_rect_size = 4u; | 973 base::CheckedNumeric<size_t> checked_src_rect_size = 4u; |
| 961 checked_src_rect_size *= src_rect.width(); | 974 checked_src_rect_size *= src_rect.width(); |
| 962 checked_src_rect_size *= src_rect.height(); | 975 checked_src_rect_size *= src_rect.height(); |
| 963 size_t src_rect_size = checked_src_rect_size.ValueOrDefault( | 976 size_t src_rect_size = checked_src_rect_size.ValueOrDefault( |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1157 break; | 1170 break; |
| 1158 case base::MemoryState::UNKNOWN: | 1171 case base::MemoryState::UNKNOWN: |
| 1159 NOTREACHED(); | 1172 NOTREACHED(); |
| 1160 return; | 1173 return; |
| 1161 } | 1174 } |
| 1162 } | 1175 } |
| 1163 ReduceCacheUsage(); | 1176 ReduceCacheUsage(); |
| 1164 } | 1177 } |
| 1165 | 1178 |
| 1166 } // namespace cc | 1179 } // namespace cc |
| OLD | NEW |