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

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

Issue 2797583002: cc: Add color space to image decode caches (Closed)
Patch Set: Fix perf test compile Created 3 years, 8 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
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 593 matching lines...) Expand 10 before | Expand all | Expand 10 after
604 SkSize::Make(0, 0), 604 SkSize::Make(0, 0),
605 next_tracing_id_.GetNext()); 605 next_tracing_id_.GetNext());
606 } 606 }
607 607
608 std::unique_ptr<SoftwareImageDecodeCache::DecodedImage> 608 std::unique_ptr<SoftwareImageDecodeCache::DecodedImage>
609 SoftwareImageDecodeCache::GetSubrectImageDecode(const ImageKey& key, 609 SoftwareImageDecodeCache::GetSubrectImageDecode(const ImageKey& key,
610 sk_sp<const SkImage> image) { 610 sk_sp<const SkImage> image) {
611 // Construct a key to use in GetDecodedImageForDrawInternal(). 611 // Construct a key to use in GetDecodedImageForDrawInternal().
612 // This allows us to reuse an image in any cache if available. 612 // This allows us to reuse an image in any cache if available.
613 gfx::Rect full_image_rect(image->width(), image->height()); 613 gfx::Rect full_image_rect(image->width(), image->height());
614 DrawImage original_size_draw_image(std::move(image), 614 DrawImage original_size_draw_image(
615 gfx::RectToSkIRect(full_image_rect), 615 std::move(image), gfx::RectToSkIRect(full_image_rect),
616 kNone_SkFilterQuality, SkMatrix::I()); 616 kNone_SkFilterQuality, SkMatrix::I(), key.target_color_space());
617 ImageKey original_size_key = 617 ImageKey original_size_key =
618 ImageKey::FromDrawImage(original_size_draw_image); 618 ImageKey::FromDrawImage(original_size_draw_image);
619 // Sanity checks. 619 // Sanity checks.
620 DCHECK(original_size_key.can_use_original_decode()) 620 DCHECK(original_size_key.can_use_original_decode())
621 << original_size_key.ToString(); 621 << original_size_key.ToString();
622 DCHECK(full_image_rect.size() == original_size_key.target_size()); 622 DCHECK(full_image_rect.size() == original_size_key.target_size());
623 623
624 auto decoded_draw_image = GetDecodedImageForDrawInternal( 624 auto decoded_draw_image = GetDecodedImageForDrawInternal(
625 original_size_key, original_size_draw_image); 625 original_size_key, original_size_draw_image);
626 AutoDrawWithImageFinished auto_finish_draw(this, original_size_draw_image, 626 AutoDrawWithImageFinished auto_finish_draw(this, original_size_draw_image,
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
660 SkSize::Make(-key.src_rect().x(), -key.src_rect().y()), 660 SkSize::Make(-key.src_rect().x(), -key.src_rect().y()),
661 next_tracing_id_.GetNext())); 661 next_tracing_id_.GetNext()));
662 } 662 }
663 663
664 std::unique_ptr<SoftwareImageDecodeCache::DecodedImage> 664 std::unique_ptr<SoftwareImageDecodeCache::DecodedImage>
665 SoftwareImageDecodeCache::GetScaledImageDecode(const ImageKey& key, 665 SoftwareImageDecodeCache::GetScaledImageDecode(const ImageKey& key,
666 sk_sp<const SkImage> image) { 666 sk_sp<const SkImage> image) {
667 // Construct a key to use in GetDecodedImageForDrawInternal(). 667 // Construct a key to use in GetDecodedImageForDrawInternal().
668 // This allows us to reuse an image in any cache if available. 668 // This allows us to reuse an image in any cache if available.
669 gfx::Rect full_image_rect(image->width(), image->height()); 669 gfx::Rect full_image_rect(image->width(), image->height());
670 DrawImage original_size_draw_image(std::move(image), 670 DrawImage original_size_draw_image(
671 gfx::RectToSkIRect(full_image_rect), 671 std::move(image), gfx::RectToSkIRect(full_image_rect),
672 kNone_SkFilterQuality, SkMatrix::I()); 672 kNone_SkFilterQuality, SkMatrix::I(), key.target_color_space());
673 ImageKey original_size_key = 673 ImageKey original_size_key =
674 ImageKey::FromDrawImage(original_size_draw_image); 674 ImageKey::FromDrawImage(original_size_draw_image);
675 // Sanity checks. 675 // Sanity checks.
676 DCHECK(original_size_key.can_use_original_decode()) 676 DCHECK(original_size_key.can_use_original_decode())
677 << original_size_key.ToString(); 677 << original_size_key.ToString();
678 DCHECK(full_image_rect.size() == original_size_key.target_size()); 678 DCHECK(full_image_rect.size() == original_size_key.target_size());
679 679
680 auto decoded_draw_image = GetDecodedImageForDrawInternal( 680 auto decoded_draw_image = GetDecodedImageForDrawInternal(
681 original_size_key, original_size_draw_image); 681 original_size_key, original_size_draw_image);
682 AutoDrawWithImageFinished auto_finish_draw(this, original_size_draw_image, 682 AutoDrawWithImageFinished auto_finish_draw(this, original_size_draw_image,
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after
956 // we're enlarging the image in both dimensions. 956 // we're enlarging the image in both dimensions.
957 if (quality == kMedium_SkFilterQuality) { 957 if (quality == kMedium_SkFilterQuality) {
958 if (!image.matrix_is_decomposable() || 958 if (!image.matrix_is_decomposable() ||
959 (scale.width() >= 1.f && scale.height() >= 1.f)) { 959 (scale.width() >= 1.f && scale.height() >= 1.f)) {
960 quality = kLow_SkFilterQuality; 960 quality = kLow_SkFilterQuality;
961 } 961 }
962 } 962 }
963 963
964 bool can_use_original_decode = 964 bool can_use_original_decode =
965 quality == kLow_SkFilterQuality || quality == kNone_SkFilterQuality; 965 quality == kLow_SkFilterQuality || quality == kNone_SkFilterQuality;
966
967 // Disallow using the original decode if it does not match the target color
968 // space.
969 if (image.target_color_space().IsValid()) {
vmpstr 2017/04/04 01:16:43 Hmm, right now the check whether we can use the or
ccameron 2017/04/04 06:41:10 I renamed can_use_original_decode to can_use_origi
970 sk_sp<SkColorSpace> target_sk_color_space =
971 image.target_color_space().ToSkColorSpace();
972 can_use_original_decode &= SkColorSpace::Equals(
973 image.image()->colorSpace(), target_sk_color_space.get());
974 }
975
966 bool should_use_subrect = false; 976 bool should_use_subrect = false;
967 if (can_use_original_decode && 977 if (can_use_original_decode &&
968 (image.image()->width() >= kMinDimensionToSubrect || 978 (image.image()->width() >= kMinDimensionToSubrect ||
969 image.image()->height() >= kMinDimensionToSubrect)) { 979 image.image()->height() >= kMinDimensionToSubrect)) {
970 base::CheckedNumeric<size_t> checked_original_size = 4u; 980 base::CheckedNumeric<size_t> checked_original_size = 4u;
971 checked_original_size *= image.image()->width(); 981 checked_original_size *= image.image()->width();
972 checked_original_size *= image.image()->height(); 982 checked_original_size *= image.image()->height();
973 size_t original_size = checked_original_size.ValueOrDefault( 983 size_t original_size = checked_original_size.ValueOrDefault(
974 std::numeric_limits<size_t>::max()); 984 std::numeric_limits<size_t>::max());
975 985
(...skipping 21 matching lines...) Expand all
997 } 1007 }
998 1008
999 if (quality == kMedium_SkFilterQuality && !target_size.IsEmpty()) { 1009 if (quality == kMedium_SkFilterQuality && !target_size.IsEmpty()) {
1000 SkSize mip_target_size = 1010 SkSize mip_target_size =
1001 MipMapUtil::GetScaleAdjustmentForSize(src_rect.size(), target_size); 1011 MipMapUtil::GetScaleAdjustmentForSize(src_rect.size(), target_size);
1002 target_size.set_width(src_rect.width() * mip_target_size.width()); 1012 target_size.set_width(src_rect.width() * mip_target_size.width());
1003 target_size.set_height(src_rect.height() * mip_target_size.height()); 1013 target_size.set_height(src_rect.height() * mip_target_size.height());
1004 } 1014 }
1005 1015
1006 return ImageDecodeCacheKey(image.image()->uniqueID(), src_rect, target_size, 1016 return ImageDecodeCacheKey(image.image()->uniqueID(), src_rect, target_size,
1007 quality, can_use_original_decode, 1017 image.target_color_space(), quality,
1008 should_use_subrect); 1018 can_use_original_decode, should_use_subrect);
1009 } 1019 }
1010 1020
1011 ImageDecodeCacheKey::ImageDecodeCacheKey(uint32_t image_id, 1021 ImageDecodeCacheKey::ImageDecodeCacheKey(
1012 const gfx::Rect& src_rect, 1022 uint32_t image_id,
1013 const gfx::Size& target_size, 1023 const gfx::Rect& src_rect,
1014 SkFilterQuality filter_quality, 1024 const gfx::Size& target_size,
1015 bool can_use_original_decode, 1025 const gfx::ColorSpace& target_color_space,
1016 bool should_use_subrect) 1026 SkFilterQuality filter_quality,
1027 bool can_use_original_decode,
1028 bool should_use_subrect)
1017 : image_id_(image_id), 1029 : image_id_(image_id),
1018 src_rect_(src_rect), 1030 src_rect_(src_rect),
1019 target_size_(target_size), 1031 target_size_(target_size),
1032 target_color_space_(target_color_space),
1020 filter_quality_(filter_quality), 1033 filter_quality_(filter_quality),
1021 can_use_original_decode_(can_use_original_decode), 1034 can_use_original_decode_(can_use_original_decode),
1022 should_use_subrect_(should_use_subrect) { 1035 should_use_subrect_(should_use_subrect) {
1023 if (can_use_original_decode_) { 1036 if (can_use_original_decode_) {
1024 hash_ = std::hash<uint32_t>()(image_id_); 1037 hash_ = std::hash<uint32_t>()(image_id_);
1025 } else { 1038 } else {
1026 // TODO(vmpstr): This is a mess. Maybe it's faster to just search the vector 1039 // TODO(vmpstr): This is a mess. Maybe it's faster to just search the vector
vmpstr 2017/04/04 01:16:43 You probably need to add to this mess, since other
ccameron 2017/04/04 06:41:10 Added it to both sides of the if(), cause can_use_
1027 // always (forwards or backwards to account for LRU). 1040 // always (forwards or backwards to account for LRU).
1028 uint64_t src_rect_hash = base::HashInts( 1041 uint64_t src_rect_hash = base::HashInts(
1029 static_cast<uint64_t>(base::HashInts(src_rect_.x(), src_rect_.y())), 1042 static_cast<uint64_t>(base::HashInts(src_rect_.x(), src_rect_.y())),
1030 static_cast<uint64_t>( 1043 static_cast<uint64_t>(
1031 base::HashInts(src_rect_.width(), src_rect_.height()))); 1044 base::HashInts(src_rect_.width(), src_rect_.height())));
1032 1045
1033 uint64_t target_size_hash = 1046 uint64_t target_size_hash =
1034 base::HashInts(target_size_.width(), target_size_.height()); 1047 base::HashInts(target_size_.width(), target_size_.height());
1035 1048
1036 hash_ = base::HashInts(base::HashInts(src_rect_hash, target_size_hash), 1049 hash_ = base::HashInts(base::HashInts(src_rect_hash, target_size_hash),
1037 base::HashInts(image_id_, filter_quality_)); 1050 base::HashInts(image_id_, filter_quality_));
1038 } 1051 }
1039 } 1052 }
1040 1053
1041 ImageDecodeCacheKey::ImageDecodeCacheKey(const ImageDecodeCacheKey& other) = 1054 ImageDecodeCacheKey::ImageDecodeCacheKey(const ImageDecodeCacheKey& other) =
1042 default; 1055 default;
1043 1056
1044 std::string ImageDecodeCacheKey::ToString() const { 1057 std::string ImageDecodeCacheKey::ToString() const {
1045 std::ostringstream str; 1058 std::ostringstream str;
1046 str << "id[" << image_id_ << "] src_rect[" << src_rect_.x() << "," 1059 str << "id[" << image_id_ << "] src_rect[" << src_rect_.x() << ","
1047 << src_rect_.y() << " " << src_rect_.width() << "x" << src_rect_.height() 1060 << src_rect_.y() << " " << src_rect_.width() << "x" << src_rect_.height()
1048 << "] target_size[" << target_size_.width() << "x" 1061 << "] target_size[" << target_size_.width() << "x"
1049 << target_size_.height() << "] filter_quality[" << filter_quality_ 1062 << target_size_.height() << "] target_color_space"
1063 << target_color_space_.ToString() << " filter_quality[" << filter_quality_
1050 << "] can_use_original_decode [" << can_use_original_decode_ 1064 << "] can_use_original_decode [" << can_use_original_decode_
1051 << "] should_use_subrect [" << should_use_subrect_ << "] hash [" << hash_ 1065 << "] should_use_subrect [" << should_use_subrect_ << "] hash [" << hash_
1052 << "]"; 1066 << "]";
1053 return str.str(); 1067 return str.str();
1054 } 1068 }
1055 1069
1056 // DecodedImage 1070 // DecodedImage
1057 SoftwareImageDecodeCache::DecodedImage::DecodedImage( 1071 SoftwareImageDecodeCache::DecodedImage::DecodedImage(
1058 const SkImageInfo& info, 1072 const SkImageInfo& info,
1059 std::unique_ptr<base::DiscardableMemory> memory, 1073 std::unique_ptr<base::DiscardableMemory> memory,
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
1177 } 1191 }
1178 } 1192 }
1179 } 1193 }
1180 1194
1181 void SoftwareImageDecodeCache::OnPurgeMemory() { 1195 void SoftwareImageDecodeCache::OnPurgeMemory() {
1182 base::AutoLock lock(lock_); 1196 base::AutoLock lock(lock_);
1183 ReduceCacheUsageUntilWithinLimit(0); 1197 ReduceCacheUsageUntilWithinLimit(0);
1184 } 1198 }
1185 1199
1186 } // namespace cc 1200 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698