| 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 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 131 DrawImage image_; | 131 DrawImage image_; |
| 132 SoftwareImageDecodeCache::DecodeTaskType task_type_; | 132 SoftwareImageDecodeCache::DecodeTaskType task_type_; |
| 133 const ImageDecodeCache::TracingInfo tracing_info_; | 133 const ImageDecodeCache::TracingInfo tracing_info_; |
| 134 | 134 |
| 135 DISALLOW_COPY_AND_ASSIGN(ImageDecodeTaskImpl); | 135 DISALLOW_COPY_AND_ASSIGN(ImageDecodeTaskImpl); |
| 136 }; | 136 }; |
| 137 | 137 |
| 138 SkSize GetScaleAdjustment(const ImageDecodeCacheKey& key) { | 138 SkSize GetScaleAdjustment(const ImageDecodeCacheKey& key) { |
| 139 // If the requested filter quality did not require scale, then the adjustment | 139 // If the requested filter quality did not require scale, then the adjustment |
| 140 // is identity. | 140 // is identity. |
| 141 if (key.can_use_original_decode() || key.should_use_subrect()) { | 141 if (key.can_use_original_size_decode() || key.should_use_subrect()) { |
| 142 return SkSize::Make(1.f, 1.f); | 142 return SkSize::Make(1.f, 1.f); |
| 143 } else if (key.filter_quality() == kMedium_SkFilterQuality) { | 143 } else if (key.filter_quality() == kMedium_SkFilterQuality) { |
| 144 return MipMapUtil::GetScaleAdjustmentForSize(key.src_rect().size(), | 144 return MipMapUtil::GetScaleAdjustmentForSize(key.src_rect().size(), |
| 145 key.target_size()); | 145 key.target_size()); |
| 146 } else { | 146 } else { |
| 147 float x_scale = | 147 float x_scale = |
| 148 key.target_size().width() / static_cast<float>(key.src_rect().width()); | 148 key.target_size().width() / static_cast<float>(key.src_rect().width()); |
| 149 float y_scale = key.target_size().height() / | 149 float y_scale = key.target_size().height() / |
| 150 static_cast<float>(key.src_rect().height()); | 150 static_cast<float>(key.src_rect().height()); |
| 151 return SkSize::Make(x_scale, y_scale); | 151 return SkSize::Make(x_scale, y_scale); |
| (...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 593 "read pixels"); | 593 "read pixels"); |
| 594 bool result = image->readPixels(decoded_info, decoded_pixels->data(), | 594 bool result = image->readPixels(decoded_info, decoded_pixels->data(), |
| 595 decoded_info.minRowBytes(), 0, 0, | 595 decoded_info.minRowBytes(), 0, 0, |
| 596 SkImage::kDisallow_CachingHint); | 596 SkImage::kDisallow_CachingHint); |
| 597 | 597 |
| 598 if (!result) { | 598 if (!result) { |
| 599 decoded_pixels->Unlock(); | 599 decoded_pixels->Unlock(); |
| 600 return nullptr; | 600 return nullptr; |
| 601 } | 601 } |
| 602 } | 602 } |
| 603 |
| 604 // TODO(ccameron,msarett): Convert image to target color space. |
| 605 // http://crbug.com/706613 |
| 606 |
| 603 return base::MakeUnique<DecodedImage>(decoded_info, std::move(decoded_pixels), | 607 return base::MakeUnique<DecodedImage>(decoded_info, std::move(decoded_pixels), |
| 604 SkSize::Make(0, 0), | 608 SkSize::Make(0, 0), |
| 605 next_tracing_id_.GetNext()); | 609 next_tracing_id_.GetNext()); |
| 606 } | 610 } |
| 607 | 611 |
| 608 std::unique_ptr<SoftwareImageDecodeCache::DecodedImage> | 612 std::unique_ptr<SoftwareImageDecodeCache::DecodedImage> |
| 609 SoftwareImageDecodeCache::GetSubrectImageDecode(const ImageKey& key, | 613 SoftwareImageDecodeCache::GetSubrectImageDecode(const ImageKey& key, |
| 610 sk_sp<const SkImage> image) { | 614 sk_sp<const SkImage> image) { |
| 611 // Construct a key to use in GetDecodedImageForDrawInternal(). | 615 // Construct a key to use in GetDecodedImageForDrawInternal(). |
| 612 // This allows us to reuse an image in any cache if available. | 616 // This allows us to reuse an image in any cache if available. |
| 613 gfx::Rect full_image_rect(image->width(), image->height()); | 617 gfx::Rect full_image_rect(image->width(), image->height()); |
| 614 DrawImage original_size_draw_image(std::move(image), | 618 DrawImage original_size_draw_image( |
| 615 gfx::RectToSkIRect(full_image_rect), | 619 std::move(image), gfx::RectToSkIRect(full_image_rect), |
| 616 kNone_SkFilterQuality, SkMatrix::I()); | 620 kNone_SkFilterQuality, SkMatrix::I(), key.target_color_space()); |
| 617 ImageKey original_size_key = | 621 ImageKey original_size_key = |
| 618 ImageKey::FromDrawImage(original_size_draw_image); | 622 ImageKey::FromDrawImage(original_size_draw_image); |
| 619 // Sanity checks. | 623 // Sanity checks. |
| 620 DCHECK(original_size_key.can_use_original_decode()) | 624 DCHECK(original_size_key.can_use_original_size_decode()) |
| 621 << original_size_key.ToString(); | 625 << original_size_key.ToString(); |
| 622 DCHECK(full_image_rect.size() == original_size_key.target_size()); | 626 DCHECK(full_image_rect.size() == original_size_key.target_size()); |
| 623 | 627 |
| 624 auto decoded_draw_image = GetDecodedImageForDrawInternal( | 628 auto decoded_draw_image = GetDecodedImageForDrawInternal( |
| 625 original_size_key, original_size_draw_image); | 629 original_size_key, original_size_draw_image); |
| 626 AutoDrawWithImageFinished auto_finish_draw(this, original_size_draw_image, | 630 AutoDrawWithImageFinished auto_finish_draw(this, original_size_draw_image, |
| 627 decoded_draw_image); | 631 decoded_draw_image); |
| 628 if (!decoded_draw_image.image()) | 632 if (!decoded_draw_image.image()) |
| 629 return nullptr; | 633 return nullptr; |
| 630 | 634 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 648 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), | 652 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), |
| 649 "SoftwareImageDecodeCache::GetSubrectImageDecode - " | 653 "SoftwareImageDecodeCache::GetSubrectImageDecode - " |
| 650 "read pixels"); | 654 "read pixels"); |
| 651 bool result = decoded_draw_image.image()->readPixels( | 655 bool result = decoded_draw_image.image()->readPixels( |
| 652 subrect_info, subrect_pixels->data(), subrect_info.minRowBytes(), | 656 subrect_info, subrect_pixels->data(), subrect_info.minRowBytes(), |
| 653 key.src_rect().x(), key.src_rect().y(), SkImage::kDisallow_CachingHint); | 657 key.src_rect().x(), key.src_rect().y(), SkImage::kDisallow_CachingHint); |
| 654 // We have a decoded image, and we're reading into already allocated memory. | 658 // We have a decoded image, and we're reading into already allocated memory. |
| 655 // This should never fail. | 659 // This should never fail. |
| 656 DCHECK(result); | 660 DCHECK(result); |
| 657 } | 661 } |
| 662 |
| 663 // TODO(ccameron,msarett): Convert image to target color space. |
| 664 // http://crbug.com/706613 |
| 665 |
| 658 return base::WrapUnique( | 666 return base::WrapUnique( |
| 659 new DecodedImage(subrect_info, std::move(subrect_pixels), | 667 new DecodedImage(subrect_info, std::move(subrect_pixels), |
| 660 SkSize::Make(-key.src_rect().x(), -key.src_rect().y()), | 668 SkSize::Make(-key.src_rect().x(), -key.src_rect().y()), |
| 661 next_tracing_id_.GetNext())); | 669 next_tracing_id_.GetNext())); |
| 662 } | 670 } |
| 663 | 671 |
| 664 std::unique_ptr<SoftwareImageDecodeCache::DecodedImage> | 672 std::unique_ptr<SoftwareImageDecodeCache::DecodedImage> |
| 665 SoftwareImageDecodeCache::GetScaledImageDecode(const ImageKey& key, | 673 SoftwareImageDecodeCache::GetScaledImageDecode(const ImageKey& key, |
| 666 sk_sp<const SkImage> image) { | 674 sk_sp<const SkImage> image) { |
| 667 // Construct a key to use in GetDecodedImageForDrawInternal(). | 675 // Construct a key to use in GetDecodedImageForDrawInternal(). |
| 668 // This allows us to reuse an image in any cache if available. | 676 // This allows us to reuse an image in any cache if available. |
| 669 gfx::Rect full_image_rect(image->width(), image->height()); | 677 gfx::Rect full_image_rect(image->width(), image->height()); |
| 670 DrawImage original_size_draw_image(std::move(image), | 678 DrawImage original_size_draw_image( |
| 671 gfx::RectToSkIRect(full_image_rect), | 679 std::move(image), gfx::RectToSkIRect(full_image_rect), |
| 672 kNone_SkFilterQuality, SkMatrix::I()); | 680 kNone_SkFilterQuality, SkMatrix::I(), key.target_color_space()); |
| 673 ImageKey original_size_key = | 681 ImageKey original_size_key = |
| 674 ImageKey::FromDrawImage(original_size_draw_image); | 682 ImageKey::FromDrawImage(original_size_draw_image); |
| 675 // Sanity checks. | 683 // Sanity checks. |
| 676 DCHECK(original_size_key.can_use_original_decode()) | 684 DCHECK(original_size_key.can_use_original_size_decode()) |
| 677 << original_size_key.ToString(); | 685 << original_size_key.ToString(); |
| 678 DCHECK(full_image_rect.size() == original_size_key.target_size()); | 686 DCHECK(full_image_rect.size() == original_size_key.target_size()); |
| 679 | 687 |
| 680 auto decoded_draw_image = GetDecodedImageForDrawInternal( | 688 auto decoded_draw_image = GetDecodedImageForDrawInternal( |
| 681 original_size_key, original_size_draw_image); | 689 original_size_key, original_size_draw_image); |
| 682 AutoDrawWithImageFinished auto_finish_draw(this, original_size_draw_image, | 690 AutoDrawWithImageFinished auto_finish_draw(this, original_size_draw_image, |
| 683 decoded_draw_image); | 691 decoded_draw_image); |
| 684 if (!decoded_draw_image.image()) | 692 if (!decoded_draw_image.image()) |
| 685 return nullptr; | 693 return nullptr; |
| 686 | 694 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 710 DCHECK(key.filter_quality() == kHigh_SkFilterQuality || | 718 DCHECK(key.filter_quality() == kHigh_SkFilterQuality || |
| 711 key.filter_quality() == kMedium_SkFilterQuality); | 719 key.filter_quality() == kMedium_SkFilterQuality); |
| 712 { | 720 { |
| 713 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), | 721 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), |
| 714 "SoftwareImageDecodeCache::ScaleImage - scale pixels"); | 722 "SoftwareImageDecodeCache::ScaleImage - scale pixels"); |
| 715 bool result = | 723 bool result = |
| 716 decoded_pixmap.scalePixels(scaled_pixmap, key.filter_quality()); | 724 decoded_pixmap.scalePixels(scaled_pixmap, key.filter_quality()); |
| 717 DCHECK(result) << key.ToString(); | 725 DCHECK(result) << key.ToString(); |
| 718 } | 726 } |
| 719 | 727 |
| 728 // TODO(ccameron,msarett): Convert image to target color space. |
| 729 // http://crbug.com/706613 |
| 730 |
| 720 return base::MakeUnique<DecodedImage>( | 731 return base::MakeUnique<DecodedImage>( |
| 721 scaled_info, std::move(scaled_pixels), | 732 scaled_info, std::move(scaled_pixels), |
| 722 SkSize::Make(-key.src_rect().x(), -key.src_rect().y()), | 733 SkSize::Make(-key.src_rect().x(), -key.src_rect().y()), |
| 723 next_tracing_id_.GetNext()); | 734 next_tracing_id_.GetNext()); |
| 724 } | 735 } |
| 725 | 736 |
| 726 void SoftwareImageDecodeCache::DrawWithImageFinished( | 737 void SoftwareImageDecodeCache::DrawWithImageFinished( |
| 727 const DrawImage& image, | 738 const DrawImage& image, |
| 728 const DecodedDrawImage& decoded_image) { | 739 const DecodedDrawImage& decoded_image) { |
| 729 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"), | 740 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"), |
| (...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 959 | 970 |
| 960 // Drop from medium to low if the matrix we applied wasn't decomposable or if | 971 // Drop from medium to low if the matrix we applied wasn't decomposable or if |
| 961 // we're enlarging the image in both dimensions. | 972 // we're enlarging the image in both dimensions. |
| 962 if (quality == kMedium_SkFilterQuality) { | 973 if (quality == kMedium_SkFilterQuality) { |
| 963 if (!image.matrix_is_decomposable() || | 974 if (!image.matrix_is_decomposable() || |
| 964 (scale.width() >= 1.f && scale.height() >= 1.f)) { | 975 (scale.width() >= 1.f && scale.height() >= 1.f)) { |
| 965 quality = kLow_SkFilterQuality; | 976 quality = kLow_SkFilterQuality; |
| 966 } | 977 } |
| 967 } | 978 } |
| 968 | 979 |
| 969 bool can_use_original_decode = | 980 bool can_use_original_size_decode = |
| 970 quality == kLow_SkFilterQuality || quality == kNone_SkFilterQuality; | 981 quality == kLow_SkFilterQuality || quality == kNone_SkFilterQuality; |
| 982 |
| 971 bool should_use_subrect = false; | 983 bool should_use_subrect = false; |
| 972 if (can_use_original_decode && | 984 if (can_use_original_size_decode && |
| 973 (image.image()->width() >= kMinDimensionToSubrect || | 985 (image.image()->width() >= kMinDimensionToSubrect || |
| 974 image.image()->height() >= kMinDimensionToSubrect)) { | 986 image.image()->height() >= kMinDimensionToSubrect)) { |
| 975 base::CheckedNumeric<size_t> checked_original_size = 4u; | 987 base::CheckedNumeric<size_t> checked_original_size = 4u; |
| 976 checked_original_size *= image.image()->width(); | 988 checked_original_size *= image.image()->width(); |
| 977 checked_original_size *= image.image()->height(); | 989 checked_original_size *= image.image()->height(); |
| 978 size_t original_size = checked_original_size.ValueOrDefault( | 990 size_t original_size = checked_original_size.ValueOrDefault( |
| 979 std::numeric_limits<size_t>::max()); | 991 std::numeric_limits<size_t>::max()); |
| 980 | 992 |
| 981 base::CheckedNumeric<size_t> checked_src_rect_size = 4u; | 993 base::CheckedNumeric<size_t> checked_src_rect_size = 4u; |
| 982 checked_src_rect_size *= src_rect.width(); | 994 checked_src_rect_size *= src_rect.width(); |
| 983 checked_src_rect_size *= src_rect.height(); | 995 checked_src_rect_size *= src_rect.height(); |
| 984 size_t src_rect_size = checked_src_rect_size.ValueOrDefault( | 996 size_t src_rect_size = checked_src_rect_size.ValueOrDefault( |
| 985 std::numeric_limits<size_t>::max()); | 997 std::numeric_limits<size_t>::max()); |
| 986 if (original_size > kMemoryThresholdToSubrect && | 998 if (original_size > kMemoryThresholdToSubrect && |
| 987 src_rect_size <= original_size * kMemoryRatioToSubrect) { | 999 src_rect_size <= original_size * kMemoryRatioToSubrect) { |
| 988 should_use_subrect = true; | 1000 should_use_subrect = true; |
| 989 can_use_original_decode = false; | 1001 can_use_original_size_decode = false; |
| 990 } | 1002 } |
| 991 } | 1003 } |
| 992 | 1004 |
| 993 // If we're going to use the original decode, then the target size should be | 1005 // If we're going to use the original decode, then the target size should be |
| 994 // the full image size, since that will allow for proper memory accounting. | 1006 // the full image size, since that will allow for proper memory accounting. |
| 995 // Note we skip the decode if the target size is empty altogether, so don't | 1007 // Note we skip the decode if the target size is empty altogether, so don't |
| 996 // update the target size in that case. | 1008 // update the target size in that case. |
| 997 if (!target_size.IsEmpty()) { | 1009 if (!target_size.IsEmpty()) { |
| 998 if (should_use_subrect) | 1010 if (should_use_subrect) |
| 999 target_size = src_rect.size(); | 1011 target_size = src_rect.size(); |
| 1000 else if (can_use_original_decode) | 1012 else if (can_use_original_size_decode) |
| 1001 target_size = gfx::Size(image.image()->width(), image.image()->height()); | 1013 target_size = gfx::Size(image.image()->width(), image.image()->height()); |
| 1002 } | 1014 } |
| 1003 | 1015 |
| 1004 if (quality == kMedium_SkFilterQuality && !target_size.IsEmpty()) { | 1016 if (quality == kMedium_SkFilterQuality && !target_size.IsEmpty()) { |
| 1005 SkSize mip_target_size = | 1017 SkSize mip_target_size = |
| 1006 MipMapUtil::GetScaleAdjustmentForSize(src_rect.size(), target_size); | 1018 MipMapUtil::GetScaleAdjustmentForSize(src_rect.size(), target_size); |
| 1007 target_size.set_width(src_rect.width() * mip_target_size.width()); | 1019 target_size.set_width(src_rect.width() * mip_target_size.width()); |
| 1008 target_size.set_height(src_rect.height() * mip_target_size.height()); | 1020 target_size.set_height(src_rect.height() * mip_target_size.height()); |
| 1009 } | 1021 } |
| 1010 | 1022 |
| 1011 return ImageDecodeCacheKey(image.image()->uniqueID(), src_rect, target_size, | 1023 return ImageDecodeCacheKey(image.image()->uniqueID(), src_rect, target_size, |
| 1012 quality, can_use_original_decode, | 1024 image.target_color_space(), quality, |
| 1013 should_use_subrect); | 1025 can_use_original_size_decode, should_use_subrect); |
| 1014 } | 1026 } |
| 1015 | 1027 |
| 1016 ImageDecodeCacheKey::ImageDecodeCacheKey(uint32_t image_id, | 1028 ImageDecodeCacheKey::ImageDecodeCacheKey( |
| 1017 const gfx::Rect& src_rect, | 1029 uint32_t image_id, |
| 1018 const gfx::Size& target_size, | 1030 const gfx::Rect& src_rect, |
| 1019 SkFilterQuality filter_quality, | 1031 const gfx::Size& target_size, |
| 1020 bool can_use_original_decode, | 1032 const gfx::ColorSpace& target_color_space, |
| 1021 bool should_use_subrect) | 1033 SkFilterQuality filter_quality, |
| 1034 bool can_use_original_size_decode, |
| 1035 bool should_use_subrect) |
| 1022 : image_id_(image_id), | 1036 : image_id_(image_id), |
| 1023 src_rect_(src_rect), | 1037 src_rect_(src_rect), |
| 1024 target_size_(target_size), | 1038 target_size_(target_size), |
| 1039 target_color_space_(target_color_space), |
| 1025 filter_quality_(filter_quality), | 1040 filter_quality_(filter_quality), |
| 1026 can_use_original_decode_(can_use_original_decode), | 1041 can_use_original_size_decode_(can_use_original_size_decode), |
| 1027 should_use_subrect_(should_use_subrect) { | 1042 should_use_subrect_(should_use_subrect) { |
| 1028 if (can_use_original_decode_) { | 1043 if (can_use_original_size_decode_) { |
| 1029 hash_ = std::hash<uint32_t>()(image_id_); | 1044 hash_ = std::hash<uint32_t>()(image_id_); |
| 1030 } else { | 1045 } else { |
| 1031 // TODO(vmpstr): This is a mess. Maybe it's faster to just search the vector | 1046 // TODO(vmpstr): This is a mess. Maybe it's faster to just search the vector |
| 1032 // always (forwards or backwards to account for LRU). | 1047 // always (forwards or backwards to account for LRU). |
| 1033 uint64_t src_rect_hash = base::HashInts( | 1048 uint64_t src_rect_hash = base::HashInts( |
| 1034 static_cast<uint64_t>(base::HashInts(src_rect_.x(), src_rect_.y())), | 1049 static_cast<uint64_t>(base::HashInts(src_rect_.x(), src_rect_.y())), |
| 1035 static_cast<uint64_t>( | 1050 static_cast<uint64_t>( |
| 1036 base::HashInts(src_rect_.width(), src_rect_.height()))); | 1051 base::HashInts(src_rect_.width(), src_rect_.height()))); |
| 1037 | 1052 |
| 1038 uint64_t target_size_hash = | 1053 uint64_t target_size_hash = |
| 1039 base::HashInts(target_size_.width(), target_size_.height()); | 1054 base::HashInts(target_size_.width(), target_size_.height()); |
| 1040 | 1055 |
| 1041 hash_ = base::HashInts(base::HashInts(src_rect_hash, target_size_hash), | 1056 hash_ = base::HashInts(base::HashInts(src_rect_hash, target_size_hash), |
| 1042 base::HashInts(image_id_, filter_quality_)); | 1057 base::HashInts(image_id_, filter_quality_)); |
| 1043 } | 1058 } |
| 1059 // Include the target color space in the hash regardless of scaling. |
| 1060 hash_ = base::HashInts(hash_, target_color_space.GetHash()); |
| 1044 } | 1061 } |
| 1045 | 1062 |
| 1046 ImageDecodeCacheKey::ImageDecodeCacheKey(const ImageDecodeCacheKey& other) = | 1063 ImageDecodeCacheKey::ImageDecodeCacheKey(const ImageDecodeCacheKey& other) = |
| 1047 default; | 1064 default; |
| 1048 | 1065 |
| 1049 std::string ImageDecodeCacheKey::ToString() const { | 1066 std::string ImageDecodeCacheKey::ToString() const { |
| 1050 std::ostringstream str; | 1067 std::ostringstream str; |
| 1051 str << "id[" << image_id_ << "] src_rect[" << src_rect_.x() << "," | 1068 str << "id[" << image_id_ << "] src_rect[" << src_rect_.x() << "," |
| 1052 << src_rect_.y() << " " << src_rect_.width() << "x" << src_rect_.height() | 1069 << src_rect_.y() << " " << src_rect_.width() << "x" << src_rect_.height() |
| 1053 << "] target_size[" << target_size_.width() << "x" | 1070 << "] target_size[" << target_size_.width() << "x" |
| 1054 << target_size_.height() << "] filter_quality[" << filter_quality_ | 1071 << target_size_.height() << "] target_color_space" |
| 1055 << "] can_use_original_decode [" << can_use_original_decode_ | 1072 << target_color_space_.ToString() << " filter_quality[" << filter_quality_ |
| 1073 << "] can_use_original_size_decode [" << can_use_original_size_decode_ |
| 1056 << "] should_use_subrect [" << should_use_subrect_ << "] hash [" << hash_ | 1074 << "] should_use_subrect [" << should_use_subrect_ << "] hash [" << hash_ |
| 1057 << "]"; | 1075 << "]"; |
| 1058 return str.str(); | 1076 return str.str(); |
| 1059 } | 1077 } |
| 1060 | 1078 |
| 1061 // DecodedImage | 1079 // DecodedImage |
| 1062 SoftwareImageDecodeCache::DecodedImage::DecodedImage( | 1080 SoftwareImageDecodeCache::DecodedImage::DecodedImage( |
| 1063 const SkImageInfo& info, | 1081 const SkImageInfo& info, |
| 1064 std::unique_ptr<base::DiscardableMemory> memory, | 1082 std::unique_ptr<base::DiscardableMemory> memory, |
| 1065 const SkSize& src_rect_offset, | 1083 const SkSize& src_rect_offset, |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1182 } | 1200 } |
| 1183 } | 1201 } |
| 1184 } | 1202 } |
| 1185 | 1203 |
| 1186 void SoftwareImageDecodeCache::OnPurgeMemory() { | 1204 void SoftwareImageDecodeCache::OnPurgeMemory() { |
| 1187 base::AutoLock lock(lock_); | 1205 base::AutoLock lock(lock_); |
| 1188 ReduceCacheUsageUntilWithinLimit(0); | 1206 ReduceCacheUsageUntilWithinLimit(0); |
| 1189 } | 1207 } |
| 1190 | 1208 |
| 1191 } // namespace cc | 1209 } // namespace cc |
| OLD | NEW |