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/numerics/safe_math.h" | 9 #include "base/numerics/safe_math.h" |
10 #include "base/strings/stringprintf.h" | 10 #include "base/strings/stringprintf.h" |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
55 | 55 |
56 } // namespace | 56 } // namespace |
57 | 57 |
58 // Task which decodes an image and stores the result in discardable memory. | 58 // Task which decodes an image and stores the result in discardable memory. |
59 // This task does not use GPU resources and can be run on any thread. | 59 // This task does not use GPU resources and can be run on any thread. |
60 class ImageDecodeTaskImpl : public TileTask { | 60 class ImageDecodeTaskImpl : public TileTask { |
61 public: | 61 public: |
62 ImageDecodeTaskImpl(GpuImageDecodeController* controller, | 62 ImageDecodeTaskImpl(GpuImageDecodeController* controller, |
63 const DrawImage& draw_image, | 63 const DrawImage& draw_image, |
64 const ImageDecodeController::TracingInfo& tracing_info) | 64 const ImageDecodeController::TracingInfo& tracing_info) |
65 : TileTask(true), | 65 : TileTask(TileTask::Type::IMAGE_DECODE, true), |
66 controller_(controller), | 66 controller_(controller), |
67 image_(draw_image), | 67 image_(draw_image), |
68 tracing_info_(tracing_info) { | 68 tracing_info_(tracing_info) { |
69 DCHECK(!SkipImage(draw_image)); | 69 DCHECK(!SkipImage(draw_image)); |
70 } | 70 } |
71 | 71 |
72 // Overridden from Task: | 72 // Overridden from Task: |
73 void RunOnWorkerThread() override { | 73 void RunOnWorkerThread() override { |
74 TRACE_EVENT2("cc", "ImageDecodeTaskImpl::RunOnWorkerThread", "mode", "gpu", | 74 TRACE_EVENT2("cc", "ImageDecodeTaskImpl::RunOnWorkerThread", "mode", "gpu", |
75 "source_prepare_tiles_id", tracing_info_.prepare_tiles_id); | 75 "source_prepare_tiles_id", tracing_info_.prepare_tiles_id); |
76 controller_->DecodeImage(image_); | 76 controller_->DecodeImage(image_); |
77 } | 77 } |
78 | 78 |
79 // Overridden from TileTask: | |
80 void ScheduleOnOriginThread(RasterBufferProvider* provider) override {} | |
81 void CompleteOnOriginThread(RasterBufferProvider* provider) override { | |
82 controller_->DecodeTaskCompleted(image_); | |
83 } | |
84 | |
85 protected: | 79 protected: |
86 ~ImageDecodeTaskImpl() override {} | 80 ~ImageDecodeTaskImpl() override {} |
87 | 81 |
88 private: | 82 private: |
| 83 friend class GpuImageDecodeController; |
| 84 |
89 GpuImageDecodeController* controller_; | 85 GpuImageDecodeController* controller_; |
90 DrawImage image_; | 86 DrawImage image_; |
91 const ImageDecodeController::TracingInfo tracing_info_; | 87 const ImageDecodeController::TracingInfo tracing_info_; |
92 | 88 |
93 DISALLOW_COPY_AND_ASSIGN(ImageDecodeTaskImpl); | 89 DISALLOW_COPY_AND_ASSIGN(ImageDecodeTaskImpl); |
94 }; | 90 }; |
95 | 91 |
96 // Task which creates an image from decoded data. Typically this involves | 92 // Task which creates an image from decoded data. Typically this involves |
97 // uploading data to the GPU, which requires this task be run on the non- | 93 // uploading data to the GPU, which requires this task be run on the non- |
98 // concurrent thread. | 94 // concurrent thread. |
99 class ImageUploadTaskImpl : public TileTask { | 95 class ImageUploadTaskImpl : public TileTask { |
100 public: | 96 public: |
101 ImageUploadTaskImpl(GpuImageDecodeController* controller, | 97 ImageUploadTaskImpl(GpuImageDecodeController* controller, |
102 const DrawImage& draw_image, | 98 const DrawImage& draw_image, |
103 scoped_refptr<TileTask> decode_dependency, | 99 scoped_refptr<TileTask> decode_dependency, |
104 const ImageDecodeController::TracingInfo& tracing_info) | 100 const ImageDecodeController::TracingInfo& tracing_info) |
105 : TileTask(false), | 101 : TileTask(TileTask::Type::IMAGE_UPLOAD, false), |
106 controller_(controller), | 102 controller_(controller), |
107 image_(draw_image), | 103 image_(draw_image), |
108 tracing_info_(tracing_info) { | 104 tracing_info_(tracing_info) { |
109 DCHECK(!SkipImage(draw_image)); | 105 DCHECK(!SkipImage(draw_image)); |
110 // If an image is already decoded and locked, we will not generate a | 106 // If an image is already decoded and locked, we will not generate a |
111 // decode task. | 107 // decode task. |
112 if (decode_dependency) | 108 if (decode_dependency) |
113 dependencies_.push_back(std::move(decode_dependency)); | 109 dependencies_.push_back(std::move(decode_dependency)); |
114 } | 110 } |
115 | 111 |
116 // Override from Task: | 112 // Override from Task: |
117 void RunOnWorkerThread() override { | 113 void RunOnWorkerThread() override { |
118 TRACE_EVENT2("cc", "ImageUploadTaskImpl::RunOnWorkerThread", "mode", "gpu", | 114 TRACE_EVENT2("cc", "ImageUploadTaskImpl::RunOnWorkerThread", "mode", "gpu", |
119 "source_prepare_tiles_id", tracing_info_.prepare_tiles_id); | 115 "source_prepare_tiles_id", tracing_info_.prepare_tiles_id); |
120 controller_->UploadImage(image_); | 116 controller_->UploadImage(image_); |
121 } | 117 } |
122 | 118 |
123 void ScheduleOnOriginThread(RasterBufferProvider* provider) override {} | |
124 void CompleteOnOriginThread(RasterBufferProvider* provider) override { | |
125 controller_->UploadTaskCompleted(image_); | |
126 } | |
127 | |
128 protected: | 119 protected: |
129 ~ImageUploadTaskImpl() override {} | 120 ~ImageUploadTaskImpl() override {} |
130 | 121 |
131 private: | 122 private: |
| 123 friend class GpuImageDecodeController; |
| 124 |
132 GpuImageDecodeController* controller_; | 125 GpuImageDecodeController* controller_; |
133 DrawImage image_; | 126 DrawImage image_; |
134 const ImageDecodeController::TracingInfo tracing_info_; | 127 const ImageDecodeController::TracingInfo tracing_info_; |
135 | 128 |
136 DISALLOW_COPY_AND_ASSIGN(ImageUploadTaskImpl); | 129 DISALLOW_COPY_AND_ASSIGN(ImageUploadTaskImpl); |
137 }; | 130 }; |
138 | 131 |
139 GpuImageDecodeController::DecodedImageData::DecodedImageData() | 132 GpuImageDecodeController::DecodedImageData::DecodedImageData() |
140 : ref_count(0), is_locked(false), decode_failure(false) {} | 133 : ref_count(0), is_locked(false), decode_failure(false) {} |
141 | 134 |
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
360 | 353 |
361 // We are holding the context lock, so finish cleaning up deleted images | 354 // We are holding the context lock, so finish cleaning up deleted images |
362 // now. | 355 // now. |
363 DeletePendingImages(); | 356 DeletePendingImages(); |
364 } else { | 357 } else { |
365 base::AutoLock lock(lock_); | 358 base::AutoLock lock(lock_); |
366 cached_bytes_limit_ = kMaxGpuImageBytes; | 359 cached_bytes_limit_ = kMaxGpuImageBytes; |
367 } | 360 } |
368 } | 361 } |
369 | 362 |
| 363 void GpuImageDecodeController::OnImageDecodeTaskCompleted(TileTask* task) { |
| 364 base::AutoLock lock(lock_); |
| 365 ImageDecodeTaskImpl* decode_task = static_cast<ImageDecodeTaskImpl*>(task); |
| 366 DCHECK(decode_task); |
| 367 // Decode task is complete, remove it from our list of pending tasks. |
| 368 pending_image_decode_tasks_.erase(decode_task->image_.image()->uniqueID()); |
| 369 |
| 370 // While the decode task is active, we keep a ref on the decoded data. |
| 371 // Release that ref now. |
| 372 UnrefImageDecode(decode_task->image_); |
| 373 } |
| 374 |
| 375 void GpuImageDecodeController::OnImageUploadTaskCompleted(TileTask* task) { |
| 376 base::AutoLock lock(lock_); |
| 377 ImageUploadTaskImpl* upload_task = static_cast<ImageUploadTaskImpl*>(task); |
| 378 DCHECK(upload_task); |
| 379 // Upload task is complete, remove it from our list of pending tasks. |
| 380 pending_image_upload_tasks_.erase(upload_task->image_.image()->uniqueID()); |
| 381 |
| 382 // While the upload task is active, we keep a ref on both the image it will be |
| 383 // populating, as well as the decode it needs to populate it. Release these |
| 384 // refs now. |
| 385 UnrefImageDecode(upload_task->image_); |
| 386 UnrefImageInternal(upload_task->image_); |
| 387 } |
| 388 |
370 bool GpuImageDecodeController::OnMemoryDump( | 389 bool GpuImageDecodeController::OnMemoryDump( |
371 const base::trace_event::MemoryDumpArgs& args, | 390 const base::trace_event::MemoryDumpArgs& args, |
372 base::trace_event::ProcessMemoryDump* pmd) { | 391 base::trace_event::ProcessMemoryDump* pmd) { |
373 for (const auto& image_pair : image_data_) { | 392 for (const auto& image_pair : image_data_) { |
374 const ImageData* image_data = image_pair.second.get(); | 393 const ImageData* image_data = image_pair.second.get(); |
375 const uint32_t image_id = image_pair.first; | 394 const uint32_t image_id = image_pair.first; |
376 | 395 |
377 // If we have discardable decoded data, dump this here. | 396 // If we have discardable decoded data, dump this here. |
378 if (image_data->decode.data) { | 397 if (image_data->decode.data) { |
379 std::string discardable_dump_name = base::StringPrintf( | 398 std::string discardable_dump_name = base::StringPrintf( |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
435 | 454 |
436 void GpuImageDecodeController::UploadImage(const DrawImage& draw_image) { | 455 void GpuImageDecodeController::UploadImage(const DrawImage& draw_image) { |
437 ContextProvider::ScopedContextLock context_lock(context_); | 456 ContextProvider::ScopedContextLock context_lock(context_); |
438 base::AutoLock lock(lock_); | 457 base::AutoLock lock(lock_); |
439 auto found = image_data_.Peek(draw_image.image()->uniqueID()); | 458 auto found = image_data_.Peek(draw_image.image()->uniqueID()); |
440 DCHECK(found != image_data_.end()); | 459 DCHECK(found != image_data_.end()); |
441 DCHECK(!found->second->is_at_raster); | 460 DCHECK(!found->second->is_at_raster); |
442 UploadImageIfNecessary(draw_image, found->second.get()); | 461 UploadImageIfNecessary(draw_image, found->second.get()); |
443 } | 462 } |
444 | 463 |
445 void GpuImageDecodeController::DecodeTaskCompleted( | |
446 const DrawImage& draw_image) { | |
447 base::AutoLock lock(lock_); | |
448 // Decode task is complete, remove it from our list of pending tasks. | |
449 pending_image_decode_tasks_.erase(draw_image.image()->uniqueID()); | |
450 | |
451 // While the decode task is active, we keep a ref on the decoded data. | |
452 // Release that ref now. | |
453 UnrefImageDecode(draw_image); | |
454 } | |
455 | |
456 void GpuImageDecodeController::UploadTaskCompleted( | |
457 const DrawImage& draw_image) { | |
458 base::AutoLock lock(lock_); | |
459 // Upload task is complete, remove it from our list of pending tasks. | |
460 pending_image_upload_tasks_.erase(draw_image.image()->uniqueID()); | |
461 | |
462 // While the upload task is active, we keep a ref on both the image it will be | |
463 // populating, as well as the decode it needs to populate it. Release these | |
464 // refs now. | |
465 UnrefImageDecode(draw_image); | |
466 UnrefImageInternal(draw_image); | |
467 } | |
468 | |
469 // Checks if an existing image decode exists. If not, returns a task to produce | 464 // Checks if an existing image decode exists. If not, returns a task to produce |
470 // the requested decode. | 465 // the requested decode. |
471 scoped_refptr<TileTask> GpuImageDecodeController::GetImageDecodeTaskAndRef( | 466 scoped_refptr<TileTask> GpuImageDecodeController::GetImageDecodeTaskAndRef( |
472 const DrawImage& draw_image, | 467 const DrawImage& draw_image, |
473 const TracingInfo& tracing_info) { | 468 const TracingInfo& tracing_info) { |
474 lock_.AssertAcquired(); | 469 lock_.AssertAcquired(); |
475 | 470 |
476 const uint32_t image_id = draw_image.image()->uniqueID(); | 471 const uint32_t image_id = draw_image.image()->uniqueID(); |
477 | 472 |
478 // This ref is kept alive while an upload task may need this decode. We | 473 // This ref is kept alive while an upload task may need this decode. We |
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
824 void GpuImageDecodeController::SetImageDecodingFailedForTesting( | 819 void GpuImageDecodeController::SetImageDecodingFailedForTesting( |
825 const DrawImage& image) { | 820 const DrawImage& image) { |
826 base::AutoLock lock(lock_); | 821 base::AutoLock lock(lock_); |
827 auto found = image_data_.Peek(image.image()->uniqueID()); | 822 auto found = image_data_.Peek(image.image()->uniqueID()); |
828 DCHECK(found != image_data_.end()); | 823 DCHECK(found != image_data_.end()); |
829 ImageData* image_data = found->second.get(); | 824 ImageData* image_data = found->second.get(); |
830 image_data->decode.decode_failure = true; | 825 image_data->decode.decode_failure = true; |
831 } | 826 } |
832 | 827 |
833 } // namespace cc | 828 } // namespace cc |
OLD | NEW |