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

Side by Side Diff: cc/tiles/software_image_decode_cache.cc

Issue 2669933002: cc: Optimize ImageDecodeCacheKey::FromDrawImage. (Closed)
Patch Set: 8k->4k Created 3 years, 10 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/BUILD.gn ('k') | cc/tiles/software_image_decode_cache_perftest.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 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
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
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
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
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
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
OLDNEW
« no previous file with comments | « cc/BUILD.gn ('k') | cc/tiles/software_image_decode_cache_perftest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698