| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/gpu_image_decode_cache.h" | 5 #include "cc/tiles/gpu_image_decode_cache.h" |
| 6 | 6 |
| 7 #include <inttypes.h> | 7 #include <inttypes.h> |
| 8 | 8 |
| 9 #include "base/auto_reset.h" | 9 #include "base/auto_reset.h" |
| 10 #include "base/debug/alias.h" | 10 #include "base/debug/alias.h" |
| 11 #include "base/hash.h" |
| 11 #include "base/memory/discardable_memory_allocator.h" | 12 #include "base/memory/discardable_memory_allocator.h" |
| 12 #include "base/memory/memory_coordinator_client_registry.h" | 13 #include "base/memory/memory_coordinator_client_registry.h" |
| 13 #include "base/memory/ptr_util.h" | 14 #include "base/memory/ptr_util.h" |
| 14 #include "base/metrics/histogram_macros.h" | 15 #include "base/metrics/histogram_macros.h" |
| 15 #include "base/numerics/safe_math.h" | 16 #include "base/numerics/safe_math.h" |
| 16 #include "base/strings/stringprintf.h" | 17 #include "base/strings/stringprintf.h" |
| 17 #include "base/threading/thread_task_runner_handle.h" | 18 #include "base/threading/thread_task_runner_handle.h" |
| 18 #include "base/trace_event/memory_dump_manager.h" | 19 #include "base/trace_event/memory_dump_manager.h" |
| 19 #include "cc/base/devtools_instrumentation.h" | 20 #include "cc/base/devtools_instrumentation.h" |
| 20 #include "cc/output/context_provider.h" | 21 #include "cc/output/context_provider.h" |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 102 return MipMapUtil::GetScaleAdjustmentForLevel(base_size, mip_level); | 103 return MipMapUtil::GetScaleAdjustmentForLevel(base_size, mip_level); |
| 103 } | 104 } |
| 104 | 105 |
| 105 // Calculates the size of a given mip level. | 106 // Calculates the size of a given mip level. |
| 106 gfx::Size CalculateSizeForMipLevel(const DrawImage& draw_image, int mip_level) { | 107 gfx::Size CalculateSizeForMipLevel(const DrawImage& draw_image, int mip_level) { |
| 107 gfx::Size base_size(draw_image.image()->width(), | 108 gfx::Size base_size(draw_image.image()->width(), |
| 108 draw_image.image()->height()); | 109 draw_image.image()->height()); |
| 109 return MipMapUtil::GetSizeForLevel(base_size, mip_level); | 110 return MipMapUtil::GetSizeForLevel(base_size, mip_level); |
| 110 } | 111 } |
| 111 | 112 |
| 112 // Generates a uint64_t which uniquely identifies a DrawImage for the purposes | |
| 113 // of the |in_use_cache_|. The key is generated as follows: | |
| 114 // ╔══════════════════════╤═══════════╤═══════════╗ | |
| 115 // ║ image_id │ mip_level │ quality ║ | |
| 116 // ╚════════32═bits═══════╧══16═bits══╧══16═bits══╝ | |
| 117 uint64_t GenerateInUseCacheKey(const DrawImage& draw_image) { | |
| 118 static_assert( | |
| 119 kLast_SkFilterQuality <= std::numeric_limits<uint16_t>::max(), | |
| 120 "InUseCacheKey depends on SkFilterQuality fitting in a uint16_t."); | |
| 121 | |
| 122 SkFilterQuality filter_quality = | |
| 123 CalculateUploadScaleFilterQuality(draw_image); | |
| 124 DCHECK_LE(filter_quality, kLast_SkFilterQuality); | |
| 125 | |
| 126 // An image has at most log_2(max(width, height)) mip levels, so given our | |
| 127 // usage of 32-bit sizes for images, key.mip_level is at most 31. | |
| 128 int32_t mip_level = CalculateUploadScaleMipLevel(draw_image); | |
| 129 DCHECK_LT(mip_level, 32); | |
| 130 | |
| 131 return (static_cast<uint64_t>(draw_image.image()->uniqueID()) << 32) | | |
| 132 (mip_level << 16) | filter_quality; | |
| 133 } | |
| 134 | |
| 135 } // namespace | 113 } // namespace |
| 136 | 114 |
| 115 // static |
| 116 GpuImageDecodeCache::InUseCacheKey |
| 117 GpuImageDecodeCache::InUseCacheKey::FromDrawImage(const DrawImage& draw_image) { |
| 118 return InUseCacheKey(draw_image); |
| 119 } |
| 120 |
| 121 // Extract the information to uniquely identify a DrawImage for the purposes of |
| 122 // the |in_use_cache_|. |
| 123 GpuImageDecodeCache::InUseCacheKey::InUseCacheKey(const DrawImage& draw_image) |
| 124 : image_id(draw_image.image()->uniqueID()), |
| 125 mip_level(CalculateUploadScaleMipLevel(draw_image)), |
| 126 filter_quality(CalculateUploadScaleFilterQuality(draw_image)), |
| 127 target_color_space(draw_image.target_color_space()) {} |
| 128 |
| 129 bool GpuImageDecodeCache::InUseCacheKey::operator==( |
| 130 const InUseCacheKey& other) const { |
| 131 return image_id == other.image_id && mip_level == other.mip_level && |
| 132 filter_quality == other.filter_quality && |
| 133 target_color_space == other.target_color_space; |
| 134 } |
| 135 |
| 136 size_t GpuImageDecodeCache::InUseCacheKeyHash::operator()( |
| 137 const InUseCacheKey& cache_key) const { |
| 138 return base::HashInts( |
| 139 cache_key.target_color_space.GetHash(), |
| 140 base::HashInts( |
| 141 cache_key.image_id, |
| 142 base::HashInts(cache_key.mip_level, cache_key.filter_quality))); |
| 143 } |
| 144 |
| 137 GpuImageDecodeCache::InUseCacheEntry::InUseCacheEntry( | 145 GpuImageDecodeCache::InUseCacheEntry::InUseCacheEntry( |
| 138 scoped_refptr<ImageData> image_data) | 146 scoped_refptr<ImageData> image_data) |
| 139 : image_data(std::move(image_data)) {} | 147 : image_data(std::move(image_data)) {} |
| 140 GpuImageDecodeCache::InUseCacheEntry::InUseCacheEntry(const InUseCacheEntry&) = | 148 GpuImageDecodeCache::InUseCacheEntry::InUseCacheEntry(const InUseCacheEntry&) = |
| 141 default; | 149 default; |
| 142 GpuImageDecodeCache::InUseCacheEntry::InUseCacheEntry(InUseCacheEntry&&) = | 150 GpuImageDecodeCache::InUseCacheEntry::InUseCacheEntry(InUseCacheEntry&&) = |
| 143 default; | 151 default; |
| 144 GpuImageDecodeCache::InUseCacheEntry::~InUseCacheEntry() = default; | 152 GpuImageDecodeCache::InUseCacheEntry::~InUseCacheEntry() = default; |
| 145 | 153 |
| 146 // Task which decodes an image and stores the result in discardable memory. | 154 // Task which decodes an image and stores the result in discardable memory. |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 319 void GpuImageDecodeCache::UploadedImageData::ReportUsageStats() const { | 327 void GpuImageDecodeCache::UploadedImageData::ReportUsageStats() const { |
| 320 UMA_HISTOGRAM_BOOLEAN("Renderer4.GpuImageUploadState.Used", | 328 UMA_HISTOGRAM_BOOLEAN("Renderer4.GpuImageUploadState.Used", |
| 321 usage_stats_.used); | 329 usage_stats_.used); |
| 322 UMA_HISTOGRAM_BOOLEAN("Renderer4.GpuImageUploadState.FirstRefWasted", | 330 UMA_HISTOGRAM_BOOLEAN("Renderer4.GpuImageUploadState.FirstRefWasted", |
| 323 usage_stats_.first_ref_wasted); | 331 usage_stats_.first_ref_wasted); |
| 324 } | 332 } |
| 325 | 333 |
| 326 GpuImageDecodeCache::ImageData::ImageData( | 334 GpuImageDecodeCache::ImageData::ImageData( |
| 327 DecodedDataMode mode, | 335 DecodedDataMode mode, |
| 328 size_t size, | 336 size_t size, |
| 337 const gfx::ColorSpace& target_color_space, |
| 329 const SkImage::DeferredTextureImageUsageParams& upload_params) | 338 const SkImage::DeferredTextureImageUsageParams& upload_params) |
| 330 : mode(mode), size(size), upload_params(upload_params) {} | 339 : mode(mode), |
| 340 size(size), |
| 341 target_color_space(target_color_space), |
| 342 upload_params(upload_params) {} |
| 331 | 343 |
| 332 GpuImageDecodeCache::ImageData::~ImageData() { | 344 GpuImageDecodeCache::ImageData::~ImageData() { |
| 333 // We should never delete ImageData while it is in use or before it has been | 345 // We should never delete ImageData while it is in use or before it has been |
| 334 // cleaned up. | 346 // cleaned up. |
| 335 DCHECK_EQ(0u, upload.ref_count); | 347 DCHECK_EQ(0u, upload.ref_count); |
| 336 DCHECK_EQ(0u, decode.ref_count); | 348 DCHECK_EQ(0u, decode.ref_count); |
| 337 DCHECK_EQ(false, decode.is_locked()); | 349 DCHECK_EQ(false, decode.is_locked()); |
| 338 // This should always be cleaned up before deleting the image, as it needs to | 350 // This should always be cleaned up before deleting the image, as it needs to |
| 339 // be freed with the GL context lock held. | 351 // be freed with the GL context lock held. |
| 340 DCHECK(!upload.image()); | 352 DCHECK(!upload.image()); |
| (...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 759 existing_task = make_scoped_refptr( | 771 existing_task = make_scoped_refptr( |
| 760 new ImageDecodeTaskImpl(this, draw_image, tracing_info, task_type)); | 772 new ImageDecodeTaskImpl(this, draw_image, tracing_info, task_type)); |
| 761 } | 773 } |
| 762 return existing_task; | 774 return existing_task; |
| 763 } | 775 } |
| 764 | 776 |
| 765 void GpuImageDecodeCache::RefImageDecode(const DrawImage& draw_image) { | 777 void GpuImageDecodeCache::RefImageDecode(const DrawImage& draw_image) { |
| 766 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), | 778 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), |
| 767 "GpuImageDecodeCache::RefImageDecode"); | 779 "GpuImageDecodeCache::RefImageDecode"); |
| 768 lock_.AssertAcquired(); | 780 lock_.AssertAcquired(); |
| 769 auto found = in_use_cache_.find(GenerateInUseCacheKey(draw_image)); | 781 auto found = in_use_cache_.find(InUseCacheKey::FromDrawImage(draw_image)); |
| 770 DCHECK(found != in_use_cache_.end()); | 782 DCHECK(found != in_use_cache_.end()); |
| 771 ++found->second.ref_count; | 783 ++found->second.ref_count; |
| 772 ++found->second.image_data->decode.ref_count; | 784 ++found->second.image_data->decode.ref_count; |
| 773 OwnershipChanged(draw_image, found->second.image_data.get()); | 785 OwnershipChanged(draw_image, found->second.image_data.get()); |
| 774 } | 786 } |
| 775 | 787 |
| 776 void GpuImageDecodeCache::UnrefImageDecode(const DrawImage& draw_image) { | 788 void GpuImageDecodeCache::UnrefImageDecode(const DrawImage& draw_image) { |
| 777 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), | 789 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), |
| 778 "GpuImageDecodeCache::UnrefImageDecode"); | 790 "GpuImageDecodeCache::UnrefImageDecode"); |
| 779 lock_.AssertAcquired(); | 791 lock_.AssertAcquired(); |
| 780 auto found = in_use_cache_.find(GenerateInUseCacheKey(draw_image)); | 792 auto found = in_use_cache_.find(InUseCacheKey::FromDrawImage(draw_image)); |
| 781 DCHECK(found != in_use_cache_.end()); | 793 DCHECK(found != in_use_cache_.end()); |
| 782 DCHECK_GT(found->second.image_data->decode.ref_count, 0u); | 794 DCHECK_GT(found->second.image_data->decode.ref_count, 0u); |
| 783 DCHECK_GT(found->second.ref_count, 0u); | 795 DCHECK_GT(found->second.ref_count, 0u); |
| 784 --found->second.ref_count; | 796 --found->second.ref_count; |
| 785 --found->second.image_data->decode.ref_count; | 797 --found->second.image_data->decode.ref_count; |
| 786 OwnershipChanged(draw_image, found->second.image_data.get()); | 798 OwnershipChanged(draw_image, found->second.image_data.get()); |
| 787 if (found->second.ref_count == 0u) { | 799 if (found->second.ref_count == 0u) { |
| 788 in_use_cache_.erase(found); | 800 in_use_cache_.erase(found); |
| 789 } | 801 } |
| 790 } | 802 } |
| 791 | 803 |
| 792 void GpuImageDecodeCache::RefImage(const DrawImage& draw_image) { | 804 void GpuImageDecodeCache::RefImage(const DrawImage& draw_image) { |
| 793 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), | 805 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), |
| 794 "GpuImageDecodeCache::RefImage"); | 806 "GpuImageDecodeCache::RefImage"); |
| 795 lock_.AssertAcquired(); | 807 lock_.AssertAcquired(); |
| 796 InUseCacheKey key = GenerateInUseCacheKey(draw_image); | 808 InUseCacheKey key = InUseCacheKey::FromDrawImage(draw_image); |
| 797 auto found = in_use_cache_.find(key); | 809 auto found = in_use_cache_.find(key); |
| 798 | 810 |
| 799 // If no secondary cache entry was found for the given |draw_image|, then | 811 // If no secondary cache entry was found for the given |draw_image|, then |
| 800 // the draw_image only exists in the |persistent_cache_|. Create an in-use | 812 // the draw_image only exists in the |persistent_cache_|. Create an in-use |
| 801 // cache entry now. | 813 // cache entry now. |
| 802 if (found == in_use_cache_.end()) { | 814 if (found == in_use_cache_.end()) { |
| 803 auto found_image = persistent_cache_.Peek(draw_image.image()->uniqueID()); | 815 auto found_image = persistent_cache_.Peek(draw_image.image()->uniqueID()); |
| 804 DCHECK(found_image != persistent_cache_.end()); | 816 DCHECK(found_image != persistent_cache_.end()); |
| 805 DCHECK(found_image->second->upload_params.fPreScaleMipLevel <= | 817 DCHECK(IsCompatible(found_image->second.get(), draw_image)); |
| 806 CalculateUploadScaleMipLevel(draw_image)); | |
| 807 found = in_use_cache_ | 818 found = in_use_cache_ |
| 808 .insert(InUseCache::value_type( | 819 .insert(InUseCache::value_type( |
| 809 key, InUseCacheEntry(found_image->second))) | 820 key, InUseCacheEntry(found_image->second))) |
| 810 .first; | 821 .first; |
| 811 } | 822 } |
| 812 | 823 |
| 813 DCHECK(found != in_use_cache_.end()); | 824 DCHECK(found != in_use_cache_.end()); |
| 814 ++found->second.ref_count; | 825 ++found->second.ref_count; |
| 815 ++found->second.image_data->upload.ref_count; | 826 ++found->second.image_data->upload.ref_count; |
| 816 OwnershipChanged(draw_image, found->second.image_data.get()); | 827 OwnershipChanged(draw_image, found->second.image_data.get()); |
| 817 } | 828 } |
| 818 | 829 |
| 819 void GpuImageDecodeCache::UnrefImageInternal(const DrawImage& draw_image) { | 830 void GpuImageDecodeCache::UnrefImageInternal(const DrawImage& draw_image) { |
| 820 lock_.AssertAcquired(); | 831 lock_.AssertAcquired(); |
| 821 auto found = in_use_cache_.find(GenerateInUseCacheKey(draw_image)); | 832 auto found = in_use_cache_.find(InUseCacheKey::FromDrawImage(draw_image)); |
| 822 DCHECK(found != in_use_cache_.end()); | 833 DCHECK(found != in_use_cache_.end()); |
| 823 DCHECK_GT(found->second.image_data->upload.ref_count, 0u); | 834 DCHECK_GT(found->second.image_data->upload.ref_count, 0u); |
| 824 DCHECK_GT(found->second.ref_count, 0u); | 835 DCHECK_GT(found->second.ref_count, 0u); |
| 825 --found->second.ref_count; | 836 --found->second.ref_count; |
| 826 --found->second.image_data->upload.ref_count; | 837 --found->second.image_data->upload.ref_count; |
| 827 OwnershipChanged(draw_image, found->second.image_data.get()); | 838 OwnershipChanged(draw_image, found->second.image_data.get()); |
| 828 if (found->second.ref_count == 0u) { | 839 if (found->second.ref_count == 0u) { |
| 829 in_use_cache_.erase(found); | 840 in_use_cache_.erase(found); |
| 830 } | 841 } |
| 831 } | 842 } |
| (...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1069 // In order to match GPU scaling quality (which uses mip-maps at high | 1080 // In order to match GPU scaling quality (which uses mip-maps at high |
| 1070 // quality), we want to use at most medium filter quality for the | 1081 // quality), we want to use at most medium filter quality for the |
| 1071 // scale. | 1082 // scale. |
| 1072 SkPixmap image_pixmap(image_info, backing_memory->data(), | 1083 SkPixmap image_pixmap(image_info, backing_memory->data(), |
| 1073 image_info.minRowBytes()); | 1084 image_info.minRowBytes()); |
| 1074 // Note that scalePixels falls back to readPixels if the sale is 1x, so | 1085 // Note that scalePixels falls back to readPixels if the sale is 1x, so |
| 1075 // no need to special case that as an optimization. | 1086 // no need to special case that as an optimization. |
| 1076 if (!draw_image.image()->scalePixels( | 1087 if (!draw_image.image()->scalePixels( |
| 1077 image_pixmap, CalculateUploadScaleFilterQuality(draw_image), | 1088 image_pixmap, CalculateUploadScaleFilterQuality(draw_image), |
| 1078 SkImage::kDisallow_CachingHint)) { | 1089 SkImage::kDisallow_CachingHint)) { |
| 1090 DLOG(ERROR) << "scalePixels failed."; |
| 1079 backing_memory->Unlock(); | 1091 backing_memory->Unlock(); |
| 1080 backing_memory.reset(); | 1092 backing_memory.reset(); |
| 1081 } | 1093 } |
| 1082 break; | 1094 break; |
| 1083 } | 1095 } |
| 1084 case DecodedDataMode::GPU: { | 1096 case DecodedDataMode::GPU: { |
| 1085 // TODO(crbug.com/649167): Params should not have changed since initial | 1097 // TODO(crbug.com/649167): Params should not have changed since initial |
| 1086 // sizing. Somehow this still happens. We should investigate and re-add | 1098 // sizing. Somehow this still happens. We should investigate and re-add |
| 1087 // DCHECKs here to enforce this. | 1099 // DCHECKs here to enforce this. |
| 1088 | |
| 1089 if (!draw_image.image()->getDeferredTextureImageData( | 1100 if (!draw_image.image()->getDeferredTextureImageData( |
| 1090 *context_threadsafe_proxy_.get(), &image_data->upload_params, 1, | 1101 *context_threadsafe_proxy_.get(), &image_data->upload_params, 1, |
| 1091 backing_memory->data())) { | 1102 backing_memory->data(), |
| 1103 draw_image.target_color_space().ToSkColorSpace().get())) { |
| 1104 DLOG(ERROR) << "getDeferredTextureImageData failed despite params " |
| 1105 << "having validated."; |
| 1092 backing_memory->Unlock(); | 1106 backing_memory->Unlock(); |
| 1093 backing_memory.reset(); | 1107 backing_memory.reset(); |
| 1094 } | 1108 } |
| 1095 break; | 1109 break; |
| 1096 } | 1110 } |
| 1097 } | 1111 } |
| 1098 } | 1112 } |
| 1099 | 1113 |
| 1100 if (image_data->decode.data()) { | 1114 if (image_data->decode.data()) { |
| 1101 // An at-raster task decoded this before us. Ingore our decode. | 1115 // An at-raster task decoded this before us. Ingore our decode. |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1171 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), | 1185 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), |
| 1172 "GpuImageDecodeCache::CreateImageData"); | 1186 "GpuImageDecodeCache::CreateImageData"); |
| 1173 lock_.AssertAcquired(); | 1187 lock_.AssertAcquired(); |
| 1174 | 1188 |
| 1175 DecodedDataMode mode; | 1189 DecodedDataMode mode; |
| 1176 int upload_scale_mip_level = CalculateUploadScaleMipLevel(draw_image); | 1190 int upload_scale_mip_level = CalculateUploadScaleMipLevel(draw_image); |
| 1177 auto params = SkImage::DeferredTextureImageUsageParams( | 1191 auto params = SkImage::DeferredTextureImageUsageParams( |
| 1178 draw_image.matrix(), CalculateUploadScaleFilterQuality(draw_image), | 1192 draw_image.matrix(), CalculateUploadScaleFilterQuality(draw_image), |
| 1179 upload_scale_mip_level); | 1193 upload_scale_mip_level); |
| 1180 size_t data_size = draw_image.image()->getDeferredTextureImageData( | 1194 size_t data_size = draw_image.image()->getDeferredTextureImageData( |
| 1181 *context_threadsafe_proxy_.get(), ¶ms, 1, nullptr); | 1195 *context_threadsafe_proxy_.get(), ¶ms, 1, nullptr, |
| 1196 draw_image.target_color_space().ToSkColorSpace().get()); |
| 1182 | 1197 |
| 1183 if (data_size == 0) { | 1198 if (data_size == 0) { |
| 1184 // Can't upload image, too large or other failure. Try to use SW fallback. | 1199 // Can't upload image, too large or other failure. Try to use SW fallback. |
| 1185 SkImageInfo image_info = | 1200 SkImageInfo image_info = |
| 1186 CreateImageInfoForDrawImage(draw_image, upload_scale_mip_level); | 1201 CreateImageInfoForDrawImage(draw_image, upload_scale_mip_level); |
| 1187 data_size = image_info.getSafeSize(image_info.minRowBytes()); | 1202 data_size = image_info.getSafeSize(image_info.minRowBytes()); |
| 1188 mode = DecodedDataMode::CPU; | 1203 mode = DecodedDataMode::CPU; |
| 1189 } else { | 1204 } else { |
| 1190 mode = DecodedDataMode::GPU; | 1205 mode = DecodedDataMode::GPU; |
| 1191 } | 1206 } |
| 1192 | 1207 |
| 1193 return make_scoped_refptr(new ImageData(mode, data_size, params)); | 1208 return make_scoped_refptr( |
| 1209 new ImageData(mode, data_size, draw_image.target_color_space(), params)); |
| 1194 } | 1210 } |
| 1195 | 1211 |
| 1196 void GpuImageDecodeCache::DeletePendingImages() { | 1212 void GpuImageDecodeCache::DeletePendingImages() { |
| 1197 context_->GetLock()->AssertAcquired(); | 1213 context_->GetLock()->AssertAcquired(); |
| 1198 lock_.AssertAcquired(); | 1214 lock_.AssertAcquired(); |
| 1199 images_pending_deletion_.clear(); | 1215 images_pending_deletion_.clear(); |
| 1200 } | 1216 } |
| 1201 | 1217 |
| 1202 SkImageInfo GpuImageDecodeCache::CreateImageInfoForDrawImage( | 1218 SkImageInfo GpuImageDecodeCache::CreateImageInfoForDrawImage( |
| 1203 const DrawImage& draw_image, | 1219 const DrawImage& draw_image, |
| 1204 int upload_scale_mip_level) const { | 1220 int upload_scale_mip_level) const { |
| 1205 gfx::Size mip_size = | 1221 gfx::Size mip_size = |
| 1206 CalculateSizeForMipLevel(draw_image, upload_scale_mip_level); | 1222 CalculateSizeForMipLevel(draw_image, upload_scale_mip_level); |
| 1207 return SkImageInfo::Make(mip_size.width(), mip_size.height(), | 1223 return SkImageInfo::Make(mip_size.width(), mip_size.height(), |
| 1208 ResourceFormatToClosestSkColorType(format_), | 1224 ResourceFormatToClosestSkColorType(format_), |
| 1209 kPremul_SkAlphaType); | 1225 kPremul_SkAlphaType, |
| 1226 draw_image.target_color_space().ToSkColorSpace()); |
| 1210 } | 1227 } |
| 1211 | 1228 |
| 1212 // Tries to find an ImageData that can be used to draw the provided | 1229 // Tries to find an ImageData that can be used to draw the provided |
| 1213 // |draw_image|. First looks for an exact entry in our |in_use_cache_|. If one | 1230 // |draw_image|. First looks for an exact entry in our |in_use_cache_|. If one |
| 1214 // cannot be found, it looks for a compatible entry in our |persistent_cache_|. | 1231 // cannot be found, it looks for a compatible entry in our |persistent_cache_|. |
| 1215 GpuImageDecodeCache::ImageData* GpuImageDecodeCache::GetImageDataForDrawImage( | 1232 GpuImageDecodeCache::ImageData* GpuImageDecodeCache::GetImageDataForDrawImage( |
| 1216 const DrawImage& draw_image) { | 1233 const DrawImage& draw_image) { |
| 1217 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), | 1234 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), |
| 1218 "GpuImageDecodeCache::GetImageDataForDrawImage"); | 1235 "GpuImageDecodeCache::GetImageDataForDrawImage"); |
| 1219 lock_.AssertAcquired(); | 1236 lock_.AssertAcquired(); |
| 1220 auto found_in_use = in_use_cache_.find(GenerateInUseCacheKey(draw_image)); | 1237 auto found_in_use = |
| 1238 in_use_cache_.find(InUseCacheKey::FromDrawImage(draw_image)); |
| 1221 if (found_in_use != in_use_cache_.end()) | 1239 if (found_in_use != in_use_cache_.end()) |
| 1222 return found_in_use->second.image_data.get(); | 1240 return found_in_use->second.image_data.get(); |
| 1223 | 1241 |
| 1224 auto found_persistent = persistent_cache_.Get(draw_image.image()->uniqueID()); | 1242 auto found_persistent = persistent_cache_.Get(draw_image.image()->uniqueID()); |
| 1225 if (found_persistent != persistent_cache_.end()) { | 1243 if (found_persistent != persistent_cache_.end()) { |
| 1226 ImageData* image_data = found_persistent->second.get(); | 1244 ImageData* image_data = found_persistent->second.get(); |
| 1227 if (IsCompatible(image_data, draw_image)) { | 1245 if (IsCompatible(image_data, draw_image)) { |
| 1228 return image_data; | 1246 return image_data; |
| 1229 } else { | 1247 } else { |
| 1230 found_persistent->second->is_orphaned = true; | 1248 found_persistent->second->is_orphaned = true; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1243 // |image_data|. This is true if the |image_data| is not scaled, or if it | 1261 // |image_data|. This is true if the |image_data| is not scaled, or if it |
| 1244 // is scaled at an equal or larger scale and equal or larger quality to | 1262 // is scaled at an equal or larger scale and equal or larger quality to |
| 1245 // the provided |draw_image|. | 1263 // the provided |draw_image|. |
| 1246 bool GpuImageDecodeCache::IsCompatible(const ImageData* image_data, | 1264 bool GpuImageDecodeCache::IsCompatible(const ImageData* image_data, |
| 1247 const DrawImage& draw_image) const { | 1265 const DrawImage& draw_image) const { |
| 1248 bool is_scaled = image_data->upload_params.fPreScaleMipLevel != 0; | 1266 bool is_scaled = image_data->upload_params.fPreScaleMipLevel != 0; |
| 1249 bool scale_is_compatible = CalculateUploadScaleMipLevel(draw_image) >= | 1267 bool scale_is_compatible = CalculateUploadScaleMipLevel(draw_image) >= |
| 1250 image_data->upload_params.fPreScaleMipLevel; | 1268 image_data->upload_params.fPreScaleMipLevel; |
| 1251 bool quality_is_compatible = CalculateUploadScaleFilterQuality(draw_image) <= | 1269 bool quality_is_compatible = CalculateUploadScaleFilterQuality(draw_image) <= |
| 1252 image_data->upload_params.fQuality; | 1270 image_data->upload_params.fQuality; |
| 1253 return !is_scaled || (scale_is_compatible && quality_is_compatible); | 1271 bool color_is_compatible = |
| 1272 image_data->target_color_space == draw_image.target_color_space(); |
| 1273 if (!color_is_compatible) |
| 1274 return false; |
| 1275 if (is_scaled && (!scale_is_compatible || !quality_is_compatible)) |
| 1276 return false; |
| 1277 return true; |
| 1254 } | 1278 } |
| 1255 | 1279 |
| 1256 size_t GpuImageDecodeCache::GetDrawImageSizeForTesting(const DrawImage& image) { | 1280 size_t GpuImageDecodeCache::GetDrawImageSizeForTesting(const DrawImage& image) { |
| 1257 base::AutoLock lock(lock_); | 1281 base::AutoLock lock(lock_); |
| 1258 scoped_refptr<ImageData> data = CreateImageData(image); | 1282 scoped_refptr<ImageData> data = CreateImageData(image); |
| 1259 return data->size; | 1283 return data->size; |
| 1260 } | 1284 } |
| 1261 | 1285 |
| 1262 void GpuImageDecodeCache::SetImageDecodingFailedForTesting( | 1286 void GpuImageDecodeCache::SetImageDecodingFailedForTesting( |
| 1263 const DrawImage& image) { | 1287 const DrawImage& image) { |
| 1264 base::AutoLock lock(lock_); | 1288 base::AutoLock lock(lock_); |
| 1265 auto found = persistent_cache_.Peek(image.image()->uniqueID()); | 1289 auto found = persistent_cache_.Peek(image.image()->uniqueID()); |
| 1266 DCHECK(found != persistent_cache_.end()); | 1290 DCHECK(found != persistent_cache_.end()); |
| 1267 ImageData* image_data = found->second.get(); | 1291 ImageData* image_data = found->second.get(); |
| 1268 image_data->decode.decode_failure = true; | 1292 image_data->decode.decode_failure = true; |
| 1269 } | 1293 } |
| 1270 | 1294 |
| 1271 bool GpuImageDecodeCache::DiscardableIsLockedForTesting( | 1295 bool GpuImageDecodeCache::DiscardableIsLockedForTesting( |
| 1272 const DrawImage& image) { | 1296 const DrawImage& image) { |
| 1273 base::AutoLock lock(lock_); | 1297 base::AutoLock lock(lock_); |
| 1274 auto found = persistent_cache_.Peek(image.image()->uniqueID()); | 1298 auto found = persistent_cache_.Peek(image.image()->uniqueID()); |
| 1275 DCHECK(found != persistent_cache_.end()); | 1299 DCHECK(found != persistent_cache_.end()); |
| 1276 ImageData* image_data = found->second.get(); | 1300 ImageData* image_data = found->second.get(); |
| 1277 return image_data->decode.is_locked(); | 1301 return image_data->decode.is_locked(); |
| 1278 } | 1302 } |
| 1279 | 1303 |
| 1280 bool GpuImageDecodeCache::IsInInUseCacheForTesting( | 1304 bool GpuImageDecodeCache::IsInInUseCacheForTesting( |
| 1281 const DrawImage& image) const { | 1305 const DrawImage& image) const { |
| 1282 auto found = in_use_cache_.find(GenerateInUseCacheKey(image)); | 1306 auto found = in_use_cache_.find(InUseCacheKey::FromDrawImage(image)); |
| 1283 return found != in_use_cache_.end(); | 1307 return found != in_use_cache_.end(); |
| 1284 } | 1308 } |
| 1285 | 1309 |
| 1286 void GpuImageDecodeCache::OnMemoryStateChange(base::MemoryState state) { | 1310 void GpuImageDecodeCache::OnMemoryStateChange(base::MemoryState state) { |
| 1287 memory_state_ = state; | 1311 memory_state_ = state; |
| 1288 } | 1312 } |
| 1289 | 1313 |
| 1290 void GpuImageDecodeCache::OnPurgeMemory() { | 1314 void GpuImageDecodeCache::OnPurgeMemory() { |
| 1291 base::AutoLock lock(lock_); | 1315 base::AutoLock lock(lock_); |
| 1292 // Temporary changes |memory_state_| to free up cache as much as possible. | 1316 // Temporary changes |memory_state_| to free up cache as much as possible. |
| 1293 base::AutoReset<base::MemoryState> reset(&memory_state_, | 1317 base::AutoReset<base::MemoryState> reset(&memory_state_, |
| 1294 base::MemoryState::SUSPENDED); | 1318 base::MemoryState::SUSPENDED); |
| 1295 EnsureCapacity(0); | 1319 EnsureCapacity(0); |
| 1296 } | 1320 } |
| 1297 | 1321 |
| 1298 } // namespace cc | 1322 } // namespace cc |
| OLD | NEW |