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 593 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |