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_controller.h" | 5 #include "cc/tiles/gpu_image_decode_controller.h" |
6 | 6 |
7 #include "base/memory/discardable_memory_allocator.h" | 7 #include "base/memory/discardable_memory_allocator.h" |
8 #include "base/memory/ptr_util.h" | 8 #include "base/memory/ptr_util.h" |
| 9 #include "base/metrics/histogram_macros.h" |
9 #include "base/numerics/safe_math.h" | 10 #include "base/numerics/safe_math.h" |
10 #include "base/strings/stringprintf.h" | 11 #include "base/strings/stringprintf.h" |
11 #include "base/threading/thread_task_runner_handle.h" | 12 #include "base/threading/thread_task_runner_handle.h" |
12 #include "cc/debug/devtools_instrumentation.h" | 13 #include "cc/debug/devtools_instrumentation.h" |
13 #include "cc/output/context_provider.h" | 14 #include "cc/output/context_provider.h" |
14 #include "cc/raster/tile_task.h" | 15 #include "cc/raster/tile_task.h" |
15 #include "cc/resources/resource_format_utils.h" | 16 #include "cc/resources/resource_format_utils.h" |
16 #include "gpu/command_buffer/client/context_support.h" | 17 #include "gpu/command_buffer/client/context_support.h" |
17 #include "gpu/command_buffer/client/gles2_interface.h" | 18 #include "gpu/command_buffer/client/gles2_interface.h" |
18 #include "gpu_image_decode_controller.h" | 19 #include "gpu_image_decode_controller.h" |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
129 | 130 |
130 private: | 131 private: |
131 GpuImageDecodeController* controller_; | 132 GpuImageDecodeController* controller_; |
132 DrawImage image_; | 133 DrawImage image_; |
133 const ImageDecodeController::TracingInfo tracing_info_; | 134 const ImageDecodeController::TracingInfo tracing_info_; |
134 | 135 |
135 DISALLOW_COPY_AND_ASSIGN(ImageUploadTaskImpl); | 136 DISALLOW_COPY_AND_ASSIGN(ImageUploadTaskImpl); |
136 }; | 137 }; |
137 | 138 |
138 GpuImageDecodeController::DecodedImageData::DecodedImageData() = default; | 139 GpuImageDecodeController::DecodedImageData::DecodedImageData() = default; |
139 GpuImageDecodeController::DecodedImageData::~DecodedImageData() = default; | 140 GpuImageDecodeController::DecodedImageData::~DecodedImageData() { |
| 141 ResetData(); |
| 142 } |
140 | 143 |
141 bool GpuImageDecodeController::DecodedImageData::Lock() { | 144 bool GpuImageDecodeController::DecodedImageData::Lock() { |
142 DCHECK(!is_locked_); | 145 DCHECK(!is_locked_); |
143 is_locked_ = data_->Lock(); | 146 is_locked_ = data_->Lock(); |
| 147 if (is_locked_) |
| 148 ++usage_stats_.lock_count; |
144 return is_locked_; | 149 return is_locked_; |
145 } | 150 } |
146 | 151 |
147 void GpuImageDecodeController::DecodedImageData::Unlock() { | 152 void GpuImageDecodeController::DecodedImageData::Unlock() { |
148 DCHECK(is_locked_); | 153 DCHECK(is_locked_); |
149 data_->Unlock(); | 154 data_->Unlock(); |
| 155 if (usage_stats_.lock_count == 1) |
| 156 usage_stats_.first_lock_wasted = !usage_stats_.used; |
150 is_locked_ = false; | 157 is_locked_ = false; |
151 } | 158 } |
152 | 159 |
153 void GpuImageDecodeController::DecodedImageData::SetLockedData( | 160 void GpuImageDecodeController::DecodedImageData::SetLockedData( |
154 std::unique_ptr<base::DiscardableMemory> data) { | 161 std::unique_ptr<base::DiscardableMemory> data) { |
155 DCHECK(!is_locked_); | 162 DCHECK(!is_locked_); |
| 163 DCHECK(data); |
| 164 DCHECK(!data_); |
156 data_ = std::move(data); | 165 data_ = std::move(data); |
157 is_locked_ = true; | 166 is_locked_ = true; |
158 } | 167 } |
159 | 168 |
160 void GpuImageDecodeController::DecodedImageData::ResetData() { | 169 void GpuImageDecodeController::DecodedImageData::ResetData() { |
161 DCHECK(!is_locked_); | 170 DCHECK(!is_locked_); |
| 171 if (data_) |
| 172 ReportUsageStats(); |
162 data_ = nullptr; | 173 data_ = nullptr; |
| 174 usage_stats_ = UsageStats(); |
| 175 } |
| 176 |
| 177 void GpuImageDecodeController::DecodedImageData::ReportUsageStats() const { |
| 178 // lock_count | used | result state |
| 179 // ===========+=======+================== |
| 180 // 1 | false | WASTED_ONCE |
| 181 // 1 | true | USED_ONCE |
| 182 // >1 | false | WASTED_RELOCKED |
| 183 // >1 | true | USED_RELOCKED |
| 184 // Note that it's important not to reorder the following enums, since the |
| 185 // numerical values are used in the histogram code. |
| 186 enum State : int { |
| 187 DECODED_IMAGE_STATE_WASTED_ONCE, |
| 188 DECODED_IMAGE_STATE_USED_ONCE, |
| 189 DECODED_IMAGE_STATE_WASTED_RELOCKED, |
| 190 DECODED_IMAGE_STATE_USED_RELOCKED, |
| 191 DECODED_IMAGE_STATE_COUNT |
| 192 } state = DECODED_IMAGE_STATE_WASTED_ONCE; |
| 193 |
| 194 if (usage_stats_.lock_count == 1) { |
| 195 if (usage_stats_.used) |
| 196 state = DECODED_IMAGE_STATE_USED_ONCE; |
| 197 else |
| 198 state = DECODED_IMAGE_STATE_WASTED_ONCE; |
| 199 } else { |
| 200 if (usage_stats_.used) |
| 201 state = DECODED_IMAGE_STATE_USED_RELOCKED; |
| 202 else |
| 203 state = DECODED_IMAGE_STATE_WASTED_RELOCKED; |
| 204 } |
| 205 |
| 206 UMA_HISTOGRAM_ENUMERATION("Renderer4.GpuImageDecodeState", state, |
| 207 DECODED_IMAGE_STATE_COUNT); |
| 208 UMA_HISTOGRAM_BOOLEAN("Renderer4.GpuImageDecodeState.FirstLockWasted", |
| 209 usage_stats_.first_lock_wasted); |
163 } | 210 } |
164 | 211 |
165 GpuImageDecodeController::UploadedImageData::UploadedImageData() = default; | 212 GpuImageDecodeController::UploadedImageData::UploadedImageData() = default; |
166 GpuImageDecodeController::UploadedImageData::~UploadedImageData() = default; | 213 GpuImageDecodeController::UploadedImageData::~UploadedImageData() { |
| 214 SetImage(nullptr); |
| 215 } |
167 | 216 |
168 void GpuImageDecodeController::UploadedImageData::SetImage( | 217 void GpuImageDecodeController::UploadedImageData::SetImage( |
169 sk_sp<SkImage> image) { | 218 sk_sp<SkImage> image) { |
| 219 DCHECK(!image_ || !image); |
| 220 if (image_) { |
| 221 ReportUsageStats(); |
| 222 usage_stats_ = UsageStats(); |
| 223 } |
170 image_ = std::move(image); | 224 image_ = std::move(image); |
171 } | 225 } |
172 | 226 |
| 227 void GpuImageDecodeController::UploadedImageData::ReportUsageStats() const { |
| 228 UMA_HISTOGRAM_BOOLEAN("Renderer4.GpuImageUploadState.Used", |
| 229 usage_stats_.used); |
| 230 UMA_HISTOGRAM_BOOLEAN("Renderer4.GpuImageUploadState.FirstRefWasted", |
| 231 usage_stats_.first_ref_wasted); |
| 232 } |
| 233 |
173 GpuImageDecodeController::ImageData::ImageData(DecodedDataMode mode, | 234 GpuImageDecodeController::ImageData::ImageData(DecodedDataMode mode, |
174 size_t size) | 235 size_t size) |
175 : mode(mode), size(size) {} | 236 : mode(mode), size(size) {} |
176 | 237 |
177 GpuImageDecodeController::ImageData::~ImageData() = default; | 238 GpuImageDecodeController::ImageData::~ImageData() = default; |
178 | 239 |
179 GpuImageDecodeController::GpuImageDecodeController(ContextProvider* context, | 240 GpuImageDecodeController::GpuImageDecodeController(ContextProvider* context, |
180 ResourceFormat decode_format, | 241 ResourceFormat decode_format, |
181 size_t max_gpu_image_bytes) | 242 size_t max_gpu_image_bytes) |
182 : format_(decode_format), | 243 : format_(decode_format), |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
335 | 396 |
336 // We may or may not need to decode and upload the image we've found, the | 397 // We may or may not need to decode and upload the image we've found, the |
337 // following functions early-out to if we already decoded. | 398 // following functions early-out to if we already decoded. |
338 DecodeImageIfNecessary(draw_image, image_data); | 399 DecodeImageIfNecessary(draw_image, image_data); |
339 UploadImageIfNecessary(draw_image, image_data); | 400 UploadImageIfNecessary(draw_image, image_data); |
340 // Unref the image decode, but not the image. The image ref will be released | 401 // Unref the image decode, but not the image. The image ref will be released |
341 // in DrawWithImageFinished. | 402 // in DrawWithImageFinished. |
342 UnrefImageDecode(draw_image); | 403 UnrefImageDecode(draw_image); |
343 | 404 |
344 sk_sp<SkImage> image = image_data->upload.image(); | 405 sk_sp<SkImage> image = image_data->upload.image(); |
| 406 image_data->upload.mark_used(); |
345 DCHECK(image || image_data->decode.decode_failure); | 407 DCHECK(image || image_data->decode.decode_failure); |
346 | 408 |
347 DecodedDrawImage decoded_draw_image(std::move(image), | 409 DecodedDrawImage decoded_draw_image(std::move(image), |
348 draw_image.filter_quality()); | 410 draw_image.filter_quality()); |
349 decoded_draw_image.set_at_raster_decode(image_data->is_at_raster); | 411 decoded_draw_image.set_at_raster_decode(image_data->is_at_raster); |
350 return decoded_draw_image; | 412 return decoded_draw_image; |
351 } | 413 } |
352 | 414 |
353 void GpuImageDecodeController::DrawWithImageFinished( | 415 void GpuImageDecodeController::DrawWithImageFinished( |
354 const DrawImage& draw_image, | 416 const DrawImage& draw_image, |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
552 ++found->second->upload.ref_count; | 614 ++found->second->upload.ref_count; |
553 RefCountChanged(found->second.get()); | 615 RefCountChanged(found->second.get()); |
554 } | 616 } |
555 | 617 |
556 void GpuImageDecodeController::UnrefImageInternal(const DrawImage& draw_image) { | 618 void GpuImageDecodeController::UnrefImageInternal(const DrawImage& draw_image) { |
557 lock_.AssertAcquired(); | 619 lock_.AssertAcquired(); |
558 auto found = image_data_.Peek(draw_image.image()->uniqueID()); | 620 auto found = image_data_.Peek(draw_image.image()->uniqueID()); |
559 DCHECK(found != image_data_.end()); | 621 DCHECK(found != image_data_.end()); |
560 DCHECK_GT(found->second->upload.ref_count, 0u); | 622 DCHECK_GT(found->second->upload.ref_count, 0u); |
561 --found->second->upload.ref_count; | 623 --found->second->upload.ref_count; |
| 624 if (found->second->upload.ref_count == 0) |
| 625 found->second->upload.notify_ref_reached_zero(); |
562 RefCountChanged(found->second.get()); | 626 RefCountChanged(found->second.get()); |
563 } | 627 } |
564 | 628 |
565 // Called any time an image or decode ref count changes. Takes care of any | 629 // Called any time an image or decode ref count changes. Takes care of any |
566 // necessary memory budget book-keeping and cleanup. | 630 // necessary memory budget book-keeping and cleanup. |
567 void GpuImageDecodeController::RefCountChanged(ImageData* image_data) { | 631 void GpuImageDecodeController::RefCountChanged(ImageData* image_data) { |
568 lock_.AssertAcquired(); | 632 lock_.AssertAcquired(); |
569 | 633 |
570 bool has_any_refs = | 634 bool has_any_refs = |
571 image_data->upload.ref_count > 0 || image_data->decode.ref_count > 0; | 635 image_data->upload.ref_count > 0 || image_data->decode.ref_count > 0; |
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
819 break; | 883 break; |
820 } | 884 } |
821 case DecodedDataMode::GPU: { | 885 case DecodedDataMode::GPU: { |
822 uploaded_image = SkImage::MakeFromDeferredTextureImageData( | 886 uploaded_image = SkImage::MakeFromDeferredTextureImageData( |
823 context_->GrContext(), image_data->decode.data()->data(), | 887 context_->GrContext(), image_data->decode.data()->data(), |
824 SkBudgeted::kNo); | 888 SkBudgeted::kNo); |
825 break; | 889 break; |
826 } | 890 } |
827 } | 891 } |
828 } | 892 } |
| 893 image_data->decode.mark_used(); |
829 DCHECK(uploaded_image); | 894 DCHECK(uploaded_image); |
830 | 895 |
831 // At-raster may have decoded this while we were unlocked. If so, ignore our | 896 // At-raster may have decoded this while we were unlocked. If so, ignore our |
832 // result. | 897 // result. |
833 if (!image_data->upload.image()) | 898 if (!image_data->upload.image()) |
834 image_data->upload.SetImage(std::move(uploaded_image)); | 899 image_data->upload.SetImage(std::move(uploaded_image)); |
835 } | 900 } |
836 | 901 |
837 std::unique_ptr<GpuImageDecodeController::ImageData> | 902 std::unique_ptr<GpuImageDecodeController::ImageData> |
838 GpuImageDecodeController::CreateImageData(const DrawImage& draw_image) { | 903 GpuImageDecodeController::CreateImageData(const DrawImage& draw_image) { |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
881 bool GpuImageDecodeController::DiscardableIsLockedForTesting( | 946 bool GpuImageDecodeController::DiscardableIsLockedForTesting( |
882 const DrawImage& image) { | 947 const DrawImage& image) { |
883 base::AutoLock lock(lock_); | 948 base::AutoLock lock(lock_); |
884 auto found = image_data_.Peek(image.image()->uniqueID()); | 949 auto found = image_data_.Peek(image.image()->uniqueID()); |
885 DCHECK(found != image_data_.end()); | 950 DCHECK(found != image_data_.end()); |
886 ImageData* image_data = found->second.get(); | 951 ImageData* image_data = found->second.get(); |
887 return image_data->decode.is_locked(); | 952 return image_data->decode.is_locked(); |
888 } | 953 } |
889 | 954 |
890 } // namespace cc | 955 } // namespace cc |
OLD | NEW |