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 438 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
779 existing_task = make_scoped_refptr( | 791 existing_task = make_scoped_refptr( |
780 new ImageDecodeTaskImpl(this, draw_image, tracing_info, task_type)); | 792 new ImageDecodeTaskImpl(this, draw_image, tracing_info, task_type)); |
781 } | 793 } |
782 return existing_task; | 794 return existing_task; |
783 } | 795 } |
784 | 796 |
785 void GpuImageDecodeCache::RefImageDecode(const DrawImage& draw_image) { | 797 void GpuImageDecodeCache::RefImageDecode(const DrawImage& draw_image) { |
786 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), | 798 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), |
787 "GpuImageDecodeCache::RefImageDecode"); | 799 "GpuImageDecodeCache::RefImageDecode"); |
788 lock_.AssertAcquired(); | 800 lock_.AssertAcquired(); |
789 auto found = in_use_cache_.find(GenerateInUseCacheKey(draw_image)); | 801 auto found = in_use_cache_.find(InUseCacheKey::FromDrawImage(draw_image)); |
790 DCHECK(found != in_use_cache_.end()); | 802 DCHECK(found != in_use_cache_.end()); |
791 ++found->second.ref_count; | 803 ++found->second.ref_count; |
792 ++found->second.image_data->decode.ref_count; | 804 ++found->second.image_data->decode.ref_count; |
793 OwnershipChanged(draw_image, found->second.image_data.get()); | 805 OwnershipChanged(draw_image, found->second.image_data.get()); |
794 } | 806 } |
795 | 807 |
796 void GpuImageDecodeCache::UnrefImageDecode(const DrawImage& draw_image) { | 808 void GpuImageDecodeCache::UnrefImageDecode(const DrawImage& draw_image) { |
797 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), | 809 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), |
798 "GpuImageDecodeCache::UnrefImageDecode"); | 810 "GpuImageDecodeCache::UnrefImageDecode"); |
799 lock_.AssertAcquired(); | 811 lock_.AssertAcquired(); |
800 auto found = in_use_cache_.find(GenerateInUseCacheKey(draw_image)); | 812 auto found = in_use_cache_.find(InUseCacheKey::FromDrawImage(draw_image)); |
801 DCHECK(found != in_use_cache_.end()); | 813 DCHECK(found != in_use_cache_.end()); |
802 DCHECK_GT(found->second.image_data->decode.ref_count, 0u); | 814 DCHECK_GT(found->second.image_data->decode.ref_count, 0u); |
803 DCHECK_GT(found->second.ref_count, 0u); | 815 DCHECK_GT(found->second.ref_count, 0u); |
804 --found->second.ref_count; | 816 --found->second.ref_count; |
805 --found->second.image_data->decode.ref_count; | 817 --found->second.image_data->decode.ref_count; |
806 OwnershipChanged(draw_image, found->second.image_data.get()); | 818 OwnershipChanged(draw_image, found->second.image_data.get()); |
807 if (found->second.ref_count == 0u) { | 819 if (found->second.ref_count == 0u) { |
808 in_use_cache_.erase(found); | 820 in_use_cache_.erase(found); |
809 } | 821 } |
810 } | 822 } |
811 | 823 |
812 void GpuImageDecodeCache::RefImage(const DrawImage& draw_image) { | 824 void GpuImageDecodeCache::RefImage(const DrawImage& draw_image) { |
813 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), | 825 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), |
814 "GpuImageDecodeCache::RefImage"); | 826 "GpuImageDecodeCache::RefImage"); |
815 lock_.AssertAcquired(); | 827 lock_.AssertAcquired(); |
816 InUseCacheKey key = GenerateInUseCacheKey(draw_image); | 828 InUseCacheKey key = InUseCacheKey::FromDrawImage(draw_image); |
817 auto found = in_use_cache_.find(key); | 829 auto found = in_use_cache_.find(key); |
818 | 830 |
819 // If no secondary cache entry was found for the given |draw_image|, then | 831 // If no secondary cache entry was found for the given |draw_image|, then |
820 // the draw_image only exists in the |persistent_cache_|. Create an in-use | 832 // the draw_image only exists in the |persistent_cache_|. Create an in-use |
821 // cache entry now. | 833 // cache entry now. |
822 if (found == in_use_cache_.end()) { | 834 if (found == in_use_cache_.end()) { |
823 auto found_image = persistent_cache_.Peek(draw_image.image()->uniqueID()); | 835 auto found_image = persistent_cache_.Peek(draw_image.image()->uniqueID()); |
824 DCHECK(found_image != persistent_cache_.end()); | 836 DCHECK(found_image != persistent_cache_.end()); |
825 DCHECK(found_image->second->upload_params.fPreScaleMipLevel <= | 837 DCHECK(IsCompatible(found_image->second.get(), draw_image)); |
826 CalculateUploadScaleMipLevel(draw_image)); | |
827 found = in_use_cache_ | 838 found = in_use_cache_ |
828 .insert(InUseCache::value_type( | 839 .insert(InUseCache::value_type( |
829 key, InUseCacheEntry(found_image->second))) | 840 key, InUseCacheEntry(found_image->second))) |
830 .first; | 841 .first; |
831 } | 842 } |
832 | 843 |
833 DCHECK(found != in_use_cache_.end()); | 844 DCHECK(found != in_use_cache_.end()); |
834 ++found->second.ref_count; | 845 ++found->second.ref_count; |
835 ++found->second.image_data->upload.ref_count; | 846 ++found->second.image_data->upload.ref_count; |
836 OwnershipChanged(draw_image, found->second.image_data.get()); | 847 OwnershipChanged(draw_image, found->second.image_data.get()); |
837 } | 848 } |
838 | 849 |
839 void GpuImageDecodeCache::UnrefImageInternal(const DrawImage& draw_image) { | 850 void GpuImageDecodeCache::UnrefImageInternal(const DrawImage& draw_image) { |
840 lock_.AssertAcquired(); | 851 lock_.AssertAcquired(); |
841 auto found = in_use_cache_.find(GenerateInUseCacheKey(draw_image)); | 852 auto found = in_use_cache_.find(InUseCacheKey::FromDrawImage(draw_image)); |
842 DCHECK(found != in_use_cache_.end()); | 853 DCHECK(found != in_use_cache_.end()); |
843 DCHECK_GT(found->second.image_data->upload.ref_count, 0u); | 854 DCHECK_GT(found->second.image_data->upload.ref_count, 0u); |
844 DCHECK_GT(found->second.ref_count, 0u); | 855 DCHECK_GT(found->second.ref_count, 0u); |
845 --found->second.ref_count; | 856 --found->second.ref_count; |
846 --found->second.image_data->upload.ref_count; | 857 --found->second.image_data->upload.ref_count; |
847 OwnershipChanged(draw_image, found->second.image_data.get()); | 858 OwnershipChanged(draw_image, found->second.image_data.get()); |
848 if (found->second.ref_count == 0u) { | 859 if (found->second.ref_count == 0u) { |
849 in_use_cache_.erase(found); | 860 in_use_cache_.erase(found); |
850 } | 861 } |
851 } | 862 } |
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1089 // In order to match GPU scaling quality (which uses mip-maps at high | 1100 // In order to match GPU scaling quality (which uses mip-maps at high |
1090 // quality), we want to use at most medium filter quality for the | 1101 // quality), we want to use at most medium filter quality for the |
1091 // scale. | 1102 // scale. |
1092 SkPixmap image_pixmap(image_info, backing_memory->data(), | 1103 SkPixmap image_pixmap(image_info, backing_memory->data(), |
1093 image_info.minRowBytes()); | 1104 image_info.minRowBytes()); |
1094 // Note that scalePixels falls back to readPixels if the sale is 1x, so | 1105 // Note that scalePixels falls back to readPixels if the sale is 1x, so |
1095 // no need to special case that as an optimization. | 1106 // no need to special case that as an optimization. |
1096 if (!draw_image.image()->scalePixels( | 1107 if (!draw_image.image()->scalePixels( |
1097 image_pixmap, CalculateUploadScaleFilterQuality(draw_image), | 1108 image_pixmap, CalculateUploadScaleFilterQuality(draw_image), |
1098 SkImage::kDisallow_CachingHint)) { | 1109 SkImage::kDisallow_CachingHint)) { |
| 1110 DLOG(ERROR) << "scalePixels failed."; |
1099 backing_memory->Unlock(); | 1111 backing_memory->Unlock(); |
1100 backing_memory.reset(); | 1112 backing_memory.reset(); |
1101 } | 1113 } |
1102 break; | 1114 break; |
1103 } | 1115 } |
1104 case DecodedDataMode::GPU: { | 1116 case DecodedDataMode::GPU: { |
1105 // TODO(crbug.com/649167): Params should not have changed since initial | 1117 // TODO(crbug.com/649167): Params should not have changed since initial |
1106 // sizing. Somehow this still happens. We should investigate and re-add | 1118 // sizing. Somehow this still happens. We should investigate and re-add |
1107 // DCHECKs here to enforce this. | 1119 // DCHECKs here to enforce this. |
1108 | |
1109 if (!draw_image.image()->getDeferredTextureImageData( | 1120 if (!draw_image.image()->getDeferredTextureImageData( |
1110 *context_threadsafe_proxy_.get(), &image_data->upload_params, 1, | 1121 *context_threadsafe_proxy_.get(), &image_data->upload_params, 1, |
1111 backing_memory->data())) { | 1122 backing_memory->data(), nullptr)) { |
| 1123 DLOG(ERROR) << "getDeferredTextureImageData failed despite params " |
| 1124 << "having validated."; |
1112 backing_memory->Unlock(); | 1125 backing_memory->Unlock(); |
1113 backing_memory.reset(); | 1126 backing_memory.reset(); |
1114 } | 1127 } |
1115 break; | 1128 break; |
1116 } | 1129 } |
1117 } | 1130 } |
1118 } | 1131 } |
1119 | 1132 |
| 1133 // TODO(ccameron,msarett): Convert image to target color space. |
| 1134 // http://crbug.com/706613 |
| 1135 |
1120 if (image_data->decode.data()) { | 1136 if (image_data->decode.data()) { |
1121 // An at-raster task decoded this before us. Ingore our decode. | 1137 // An at-raster task decoded this before us. Ingore our decode. |
1122 return; | 1138 return; |
1123 } | 1139 } |
1124 | 1140 |
1125 if (!backing_memory) { | 1141 if (!backing_memory) { |
1126 // If |backing_memory| was not populated, we had a non-decodable image. | 1142 // If |backing_memory| was not populated, we had a non-decodable image. |
1127 image_data->decode.decode_failure = true; | 1143 image_data->decode.decode_failure = true; |
1128 return; | 1144 return; |
1129 } | 1145 } |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1191 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), | 1207 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), |
1192 "GpuImageDecodeCache::CreateImageData"); | 1208 "GpuImageDecodeCache::CreateImageData"); |
1193 lock_.AssertAcquired(); | 1209 lock_.AssertAcquired(); |
1194 | 1210 |
1195 DecodedDataMode mode; | 1211 DecodedDataMode mode; |
1196 int upload_scale_mip_level = CalculateUploadScaleMipLevel(draw_image); | 1212 int upload_scale_mip_level = CalculateUploadScaleMipLevel(draw_image); |
1197 auto params = SkImage::DeferredTextureImageUsageParams( | 1213 auto params = SkImage::DeferredTextureImageUsageParams( |
1198 draw_image.matrix(), CalculateUploadScaleFilterQuality(draw_image), | 1214 draw_image.matrix(), CalculateUploadScaleFilterQuality(draw_image), |
1199 upload_scale_mip_level); | 1215 upload_scale_mip_level); |
1200 size_t data_size = draw_image.image()->getDeferredTextureImageData( | 1216 size_t data_size = draw_image.image()->getDeferredTextureImageData( |
1201 *context_threadsafe_proxy_.get(), ¶ms, 1, nullptr); | 1217 *context_threadsafe_proxy_.get(), ¶ms, 1, nullptr, |
| 1218 draw_image.target_color_space().ToSkColorSpace().get()); |
1202 | 1219 |
1203 if (data_size == 0) { | 1220 if (data_size == 0) { |
1204 // Can't upload image, too large or other failure. Try to use SW fallback. | 1221 // Can't upload image, too large or other failure. Try to use SW fallback. |
1205 SkImageInfo image_info = | 1222 SkImageInfo image_info = |
1206 CreateImageInfoForDrawImage(draw_image, upload_scale_mip_level); | 1223 CreateImageInfoForDrawImage(draw_image, upload_scale_mip_level); |
1207 data_size = image_info.getSafeSize(image_info.minRowBytes()); | 1224 data_size = image_info.getSafeSize(image_info.minRowBytes()); |
1208 mode = DecodedDataMode::CPU; | 1225 mode = DecodedDataMode::CPU; |
1209 } else { | 1226 } else { |
1210 mode = DecodedDataMode::GPU; | 1227 mode = DecodedDataMode::GPU; |
1211 } | 1228 } |
1212 | 1229 |
1213 return make_scoped_refptr(new ImageData(mode, data_size, params)); | 1230 return make_scoped_refptr( |
| 1231 new ImageData(mode, data_size, draw_image.target_color_space(), params)); |
1214 } | 1232 } |
1215 | 1233 |
1216 void GpuImageDecodeCache::DeletePendingImages() { | 1234 void GpuImageDecodeCache::DeletePendingImages() { |
1217 context_->GetLock()->AssertAcquired(); | 1235 context_->GetLock()->AssertAcquired(); |
1218 lock_.AssertAcquired(); | 1236 lock_.AssertAcquired(); |
1219 images_pending_deletion_.clear(); | 1237 images_pending_deletion_.clear(); |
1220 } | 1238 } |
1221 | 1239 |
1222 SkImageInfo GpuImageDecodeCache::CreateImageInfoForDrawImage( | 1240 SkImageInfo GpuImageDecodeCache::CreateImageInfoForDrawImage( |
1223 const DrawImage& draw_image, | 1241 const DrawImage& draw_image, |
1224 int upload_scale_mip_level) const { | 1242 int upload_scale_mip_level) const { |
1225 gfx::Size mip_size = | 1243 gfx::Size mip_size = |
1226 CalculateSizeForMipLevel(draw_image, upload_scale_mip_level); | 1244 CalculateSizeForMipLevel(draw_image, upload_scale_mip_level); |
1227 return SkImageInfo::Make(mip_size.width(), mip_size.height(), | 1245 return SkImageInfo::Make(mip_size.width(), mip_size.height(), |
1228 ResourceFormatToClosestSkColorType(format_), | 1246 ResourceFormatToClosestSkColorType(format_), |
1229 kPremul_SkAlphaType); | 1247 kPremul_SkAlphaType, |
| 1248 draw_image.target_color_space().ToSkColorSpace()); |
1230 } | 1249 } |
1231 | 1250 |
1232 // Tries to find an ImageData that can be used to draw the provided | 1251 // Tries to find an ImageData that can be used to draw the provided |
1233 // |draw_image|. First looks for an exact entry in our |in_use_cache_|. If one | 1252 // |draw_image|. First looks for an exact entry in our |in_use_cache_|. If one |
1234 // cannot be found, it looks for a compatible entry in our |persistent_cache_|. | 1253 // cannot be found, it looks for a compatible entry in our |persistent_cache_|. |
1235 GpuImageDecodeCache::ImageData* GpuImageDecodeCache::GetImageDataForDrawImage( | 1254 GpuImageDecodeCache::ImageData* GpuImageDecodeCache::GetImageDataForDrawImage( |
1236 const DrawImage& draw_image) { | 1255 const DrawImage& draw_image) { |
1237 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), | 1256 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), |
1238 "GpuImageDecodeCache::GetImageDataForDrawImage"); | 1257 "GpuImageDecodeCache::GetImageDataForDrawImage"); |
1239 lock_.AssertAcquired(); | 1258 lock_.AssertAcquired(); |
1240 auto found_in_use = in_use_cache_.find(GenerateInUseCacheKey(draw_image)); | 1259 auto found_in_use = |
| 1260 in_use_cache_.find(InUseCacheKey::FromDrawImage(draw_image)); |
1241 if (found_in_use != in_use_cache_.end()) | 1261 if (found_in_use != in_use_cache_.end()) |
1242 return found_in_use->second.image_data.get(); | 1262 return found_in_use->second.image_data.get(); |
1243 | 1263 |
1244 auto found_persistent = persistent_cache_.Get(draw_image.image()->uniqueID()); | 1264 auto found_persistent = persistent_cache_.Get(draw_image.image()->uniqueID()); |
1245 if (found_persistent != persistent_cache_.end()) { | 1265 if (found_persistent != persistent_cache_.end()) { |
1246 ImageData* image_data = found_persistent->second.get(); | 1266 ImageData* image_data = found_persistent->second.get(); |
1247 if (IsCompatible(image_data, draw_image)) { | 1267 if (IsCompatible(image_data, draw_image)) { |
1248 return image_data; | 1268 return image_data; |
1249 } else { | 1269 } else { |
1250 found_persistent->second->is_orphaned = true; | 1270 found_persistent->second->is_orphaned = true; |
(...skipping 12 matching lines...) Expand all Loading... |
1263 // |image_data|. This is true if the |image_data| is not scaled, or if it | 1283 // |image_data|. This is true if the |image_data| is not scaled, or if it |
1264 // is scaled at an equal or larger scale and equal or larger quality to | 1284 // is scaled at an equal or larger scale and equal or larger quality to |
1265 // the provided |draw_image|. | 1285 // the provided |draw_image|. |
1266 bool GpuImageDecodeCache::IsCompatible(const ImageData* image_data, | 1286 bool GpuImageDecodeCache::IsCompatible(const ImageData* image_data, |
1267 const DrawImage& draw_image) const { | 1287 const DrawImage& draw_image) const { |
1268 bool is_scaled = image_data->upload_params.fPreScaleMipLevel != 0; | 1288 bool is_scaled = image_data->upload_params.fPreScaleMipLevel != 0; |
1269 bool scale_is_compatible = CalculateUploadScaleMipLevel(draw_image) >= | 1289 bool scale_is_compatible = CalculateUploadScaleMipLevel(draw_image) >= |
1270 image_data->upload_params.fPreScaleMipLevel; | 1290 image_data->upload_params.fPreScaleMipLevel; |
1271 bool quality_is_compatible = CalculateUploadScaleFilterQuality(draw_image) <= | 1291 bool quality_is_compatible = CalculateUploadScaleFilterQuality(draw_image) <= |
1272 image_data->upload_params.fQuality; | 1292 image_data->upload_params.fQuality; |
1273 return !is_scaled || (scale_is_compatible && quality_is_compatible); | 1293 bool color_is_compatible = |
| 1294 image_data->target_color_space == draw_image.target_color_space(); |
| 1295 if (!color_is_compatible) |
| 1296 return false; |
| 1297 if (is_scaled && (!scale_is_compatible || !quality_is_compatible)) |
| 1298 return false; |
| 1299 return true; |
1274 } | 1300 } |
1275 | 1301 |
1276 size_t GpuImageDecodeCache::GetDrawImageSizeForTesting(const DrawImage& image) { | 1302 size_t GpuImageDecodeCache::GetDrawImageSizeForTesting(const DrawImage& image) { |
1277 base::AutoLock lock(lock_); | 1303 base::AutoLock lock(lock_); |
1278 scoped_refptr<ImageData> data = CreateImageData(image); | 1304 scoped_refptr<ImageData> data = CreateImageData(image); |
1279 return data->size; | 1305 return data->size; |
1280 } | 1306 } |
1281 | 1307 |
1282 void GpuImageDecodeCache::SetImageDecodingFailedForTesting( | 1308 void GpuImageDecodeCache::SetImageDecodingFailedForTesting( |
1283 const DrawImage& image) { | 1309 const DrawImage& image) { |
1284 base::AutoLock lock(lock_); | 1310 base::AutoLock lock(lock_); |
1285 auto found = persistent_cache_.Peek(image.image()->uniqueID()); | 1311 auto found = persistent_cache_.Peek(image.image()->uniqueID()); |
1286 DCHECK(found != persistent_cache_.end()); | 1312 DCHECK(found != persistent_cache_.end()); |
1287 ImageData* image_data = found->second.get(); | 1313 ImageData* image_data = found->second.get(); |
1288 image_data->decode.decode_failure = true; | 1314 image_data->decode.decode_failure = true; |
1289 } | 1315 } |
1290 | 1316 |
1291 bool GpuImageDecodeCache::DiscardableIsLockedForTesting( | 1317 bool GpuImageDecodeCache::DiscardableIsLockedForTesting( |
1292 const DrawImage& image) { | 1318 const DrawImage& image) { |
1293 base::AutoLock lock(lock_); | 1319 base::AutoLock lock(lock_); |
1294 auto found = persistent_cache_.Peek(image.image()->uniqueID()); | 1320 auto found = persistent_cache_.Peek(image.image()->uniqueID()); |
1295 DCHECK(found != persistent_cache_.end()); | 1321 DCHECK(found != persistent_cache_.end()); |
1296 ImageData* image_data = found->second.get(); | 1322 ImageData* image_data = found->second.get(); |
1297 return image_data->decode.is_locked(); | 1323 return image_data->decode.is_locked(); |
1298 } | 1324 } |
1299 | 1325 |
1300 bool GpuImageDecodeCache::IsInInUseCacheForTesting( | 1326 bool GpuImageDecodeCache::IsInInUseCacheForTesting( |
1301 const DrawImage& image) const { | 1327 const DrawImage& image) const { |
1302 auto found = in_use_cache_.find(GenerateInUseCacheKey(image)); | 1328 auto found = in_use_cache_.find(InUseCacheKey::FromDrawImage(image)); |
1303 return found != in_use_cache_.end(); | 1329 return found != in_use_cache_.end(); |
1304 } | 1330 } |
1305 | 1331 |
1306 void GpuImageDecodeCache::OnMemoryStateChange(base::MemoryState state) { | 1332 void GpuImageDecodeCache::OnMemoryStateChange(base::MemoryState state) { |
1307 memory_state_ = state; | 1333 memory_state_ = state; |
1308 } | 1334 } |
1309 | 1335 |
1310 void GpuImageDecodeCache::OnPurgeMemory() { | 1336 void GpuImageDecodeCache::OnPurgeMemory() { |
1311 base::AutoLock lock(lock_); | 1337 base::AutoLock lock(lock_); |
1312 // Temporary changes |memory_state_| to free up cache as much as possible. | 1338 // Temporary changes |memory_state_| to free up cache as much as possible. |
1313 base::AutoReset<base::MemoryState> reset(&memory_state_, | 1339 base::AutoReset<base::MemoryState> reset(&memory_state_, |
1314 base::MemoryState::SUSPENDED); | 1340 base::MemoryState::SUSPENDED); |
1315 EnsureCapacity(0); | 1341 EnsureCapacity(0); |
1316 } | 1342 } |
1317 | 1343 |
1318 } // namespace cc | 1344 } // namespace cc |
OLD | NEW |