Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(507)

Side by Side Diff: cc/tiles/gpu_image_decode_cache.cc

Issue 2537683002: cc: Add image decode queue functionality to image manager. (Closed)
Patch Set: image-queue: update Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/debug/alias.h" 9 #include "base/debug/alias.h"
10 #include "base/memory/discardable_memory_allocator.h" 10 #include "base/memory/discardable_memory_allocator.h"
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
142 GpuImageDecodeCache::InUseCacheEntry::InUseCacheEntry(InUseCacheEntry&&) = 142 GpuImageDecodeCache::InUseCacheEntry::InUseCacheEntry(InUseCacheEntry&&) =
143 default; 143 default;
144 GpuImageDecodeCache::InUseCacheEntry::~InUseCacheEntry() = default; 144 GpuImageDecodeCache::InUseCacheEntry::~InUseCacheEntry() = default;
145 145
146 // Task which decodes an image and stores the result in discardable memory. 146 // Task which decodes an image and stores the result in discardable memory.
147 // This task does not use GPU resources and can be run on any thread. 147 // This task does not use GPU resources and can be run on any thread.
148 class ImageDecodeTaskImpl : public TileTask { 148 class ImageDecodeTaskImpl : public TileTask {
149 public: 149 public:
150 ImageDecodeTaskImpl(GpuImageDecodeCache* cache, 150 ImageDecodeTaskImpl(GpuImageDecodeCache* cache,
151 const DrawImage& draw_image, 151 const DrawImage& draw_image,
152 const ImageDecodeCache::TracingInfo& tracing_info) 152 const ImageDecodeCache::TracingInfo& tracing_info,
153 GpuImageDecodeCache::DecodeTaskType task_type)
153 : TileTask(true), 154 : TileTask(true),
154 cache_(cache), 155 cache_(cache),
155 image_(draw_image), 156 image_(draw_image),
156 tracing_info_(tracing_info) { 157 tracing_info_(tracing_info),
158 task_type_(task_type) {
157 DCHECK(!SkipImage(draw_image)); 159 DCHECK(!SkipImage(draw_image));
158 } 160 }
159 161
160 // Overridden from Task: 162 // Overridden from Task:
161 void RunOnWorkerThread() override { 163 void RunOnWorkerThread() override {
162 TRACE_EVENT2("cc", "ImageDecodeTaskImpl::RunOnWorkerThread", "mode", "gpu", 164 TRACE_EVENT2("cc", "ImageDecodeTaskImpl::RunOnWorkerThread", "mode", "gpu",
163 "source_prepare_tiles_id", tracing_info_.prepare_tiles_id); 165 "source_prepare_tiles_id", tracing_info_.prepare_tiles_id);
164 devtools_instrumentation::ScopedImageDecodeTask image_decode_task( 166 devtools_instrumentation::ScopedImageDecodeTask image_decode_task(
165 image_.image().get(), 167 image_.image().get(),
166 devtools_instrumentation::ScopedImageDecodeTask::GPU); 168 devtools_instrumentation::ScopedImageDecodeTask::GPU);
167 cache_->DecodeImage(image_); 169 cache_->DecodeImage(image_);
168 } 170 }
169 171
170 // Overridden from TileTask: 172 // Overridden from TileTask:
171 void OnTaskCompleted() override { 173 void OnTaskCompleted() override {
172 cache_->OnImageDecodeTaskCompleted(image_); 174 cache_->OnImageDecodeTaskCompleted(image_, task_type_);
173 } 175 }
174 176
175 protected: 177 protected:
176 ~ImageDecodeTaskImpl() override {} 178 ~ImageDecodeTaskImpl() override {}
177 179
178 private: 180 private:
179 GpuImageDecodeCache* cache_; 181 GpuImageDecodeCache* cache_;
180 DrawImage image_; 182 DrawImage image_;
181 const ImageDecodeCache::TracingInfo tracing_info_; 183 const ImageDecodeCache::TracingInfo tracing_info_;
184 GpuImageDecodeCache::DecodeTaskType task_type_;
ericrk 2016/12/06 23:22:52 nit: const
182 185
183 DISALLOW_COPY_AND_ASSIGN(ImageDecodeTaskImpl); 186 DISALLOW_COPY_AND_ASSIGN(ImageDecodeTaskImpl);
184 }; 187 };
185 188
186 // Task which creates an image from decoded data. Typically this involves 189 // Task which creates an image from decoded data. Typically this involves
187 // uploading data to the GPU, which requires this task be run on the non- 190 // uploading data to the GPU, which requires this task be run on the non-
188 // concurrent thread. 191 // concurrent thread.
189 class ImageUploadTaskImpl : public TileTask { 192 class ImageUploadTaskImpl : public TileTask {
190 public: 193 public:
191 ImageUploadTaskImpl(GpuImageDecodeCache* cache, 194 ImageUploadTaskImpl(GpuImageDecodeCache* cache,
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
370 // It is safe to unregister, even if we didn't register in the constructor. 373 // It is safe to unregister, even if we didn't register in the constructor.
371 base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider( 374 base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider(
372 this); 375 this);
373 // Unregister this component with memory_coordinator::ClientRegistry. 376 // Unregister this component with memory_coordinator::ClientRegistry.
374 base::MemoryCoordinatorClientRegistry::GetInstance()->Unregister(this); 377 base::MemoryCoordinatorClientRegistry::GetInstance()->Unregister(this);
375 } 378 }
376 379
377 bool GpuImageDecodeCache::GetTaskForImageAndRef(const DrawImage& draw_image, 380 bool GpuImageDecodeCache::GetTaskForImageAndRef(const DrawImage& draw_image,
378 const TracingInfo& tracing_info, 381 const TracingInfo& tracing_info,
379 scoped_refptr<TileTask>* task) { 382 scoped_refptr<TileTask>* task) {
383 return GetTaskForImageAndRefInternal(draw_image, tracing_info,
384 PART_OF_UPLOAD_TASK, task);
385 }
386
387 bool GpuImageDecodeCache::GetOutOfRasterDecodeTaskForImageAndRef(
388 const DrawImage& draw_image,
389 scoped_refptr<TileTask>* task) {
390 return GetTaskForImageAndRefInternal(draw_image, TracingInfo(),
391 STAND_ALONE_DECODE_TASK, task);
392 }
393
394 bool GpuImageDecodeCache::GetTaskForImageAndRefInternal(
395 const DrawImage& draw_image,
396 const TracingInfo& tracing_info,
397 DecodeTaskType task_type,
398 scoped_refptr<TileTask>* task) {
380 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), 399 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
381 "GpuImageDecodeCache::GetTaskForImageAndRef"); 400 "GpuImageDecodeCache::GetTaskForImageAndRef");
382 if (SkipImage(draw_image)) { 401 if (SkipImage(draw_image)) {
383 *task = nullptr; 402 *task = nullptr;
384 return false; 403 return false;
385 } 404 }
386 405
387 base::AutoLock lock(lock_); 406 base::AutoLock lock(lock_);
388 const auto image_id = draw_image.image()->uniqueID(); 407 const auto image_id = draw_image.image()->uniqueID();
389 ImageData* image_data = GetImageDataForDrawImage(draw_image); 408 ImageData* image_data = GetImageDataForDrawImage(draw_image);
390 scoped_refptr<ImageData> new_data; 409 scoped_refptr<ImageData> new_data;
391 if (!image_data) { 410 if (!image_data) {
392 // We need an ImageData, create one now. 411 // We need an ImageData, create one now.
393 new_data = CreateImageData(draw_image); 412 new_data = CreateImageData(draw_image);
394 image_data = new_data.get(); 413 image_data = new_data.get();
395 } else if (image_data->is_at_raster) { 414 } else if (image_data->is_at_raster) {
396 // Image is at-raster, just return, this usage will be at-raster as well. 415 // Image is at-raster, just return, this usage will be at-raster as well.
397 *task = nullptr; 416 *task = nullptr;
398 return false; 417 return false;
399 } else if (image_data->decode.decode_failure) { 418 } else if (image_data->decode.decode_failure) {
400 // We have already tried and failed to decode this image, so just return. 419 // We have already tried and failed to decode this image, so just return.
401 *task = nullptr; 420 *task = nullptr;
402 return false; 421 return false;
403 } else if (image_data->upload.image()) { 422 } else if (image_data->upload.image()) {
404 // The image is already uploaded, ref and return. 423 // The image is already uploaded, ref and return.
405 RefImage(draw_image); 424 RefImage(draw_image);
406 *task = nullptr; 425 *task = nullptr;
407 return true; 426 return true;
408 } else if (image_data->upload.task) { 427 } else if (task_type == PART_OF_UPLOAD_TASK && image_data->upload.task) {
409 // We had an existing upload task, ref the image and return the task. 428 // We had an existing upload task, ref the image and return the task.
410 RefImage(draw_image); 429 RefImage(draw_image);
411 *task = image_data->upload.task; 430 *task = image_data->upload.task;
412 return true; 431 return true;
432 } else if (task_type == STAND_ALONE_DECODE_TASK &&
433 image_data->decode.stand_alone_task) {
434 // We had an existing out of raster task, ref the image and return the task.
435 RefImage(draw_image);
436 *task = image_data->decode.stand_alone_task;
437 return true;
413 } 438 }
414 439
415 // Ensure that the image we're about to decode/upload will fit in memory. 440 // Ensure that the image we're about to decode/upload will fit in memory.
416 if (!EnsureCapacity(image_data->size)) { 441 if (!EnsureCapacity(image_data->size)) {
417 // Image will not fit, do an at-raster decode. 442 // Image will not fit, do an at-raster decode.
418 *task = nullptr; 443 *task = nullptr;
419 return false; 444 return false;
420 } 445 }
421 446
422 // If we had to create new image data, add it to our map now that we know it 447 // If we had to create new image data, add it to our map now that we know it
423 // will fit. 448 // will fit.
424 if (new_data) 449 if (new_data)
425 persistent_cache_.Put(image_id, std::move(new_data)); 450 persistent_cache_.Put(image_id, std::move(new_data));
426 451
427 // Ref image and create a upload and decode tasks. We will release this ref 452 if (task_type == PART_OF_UPLOAD_TASK) {
428 // in UploadTaskCompleted. 453 // Ref image and create a upload and decode tasks. We will release this ref
429 RefImage(draw_image); 454 // in UploadTaskCompleted.
430 *task = make_scoped_refptr(new ImageUploadTaskImpl( 455 RefImage(draw_image);
431 this, draw_image, GetImageDecodeTaskAndRef(draw_image, tracing_info), 456 *task = make_scoped_refptr(new ImageUploadTaskImpl(
432 tracing_info)); 457 this, draw_image,
433 image_data->upload.task = *task; 458 GetImageDecodeTaskAndRef(draw_image, tracing_info, task_type),
459 tracing_info));
460 image_data->upload.task = *task;
461 } else {
462 *task = GetImageDecodeTaskAndRef(draw_image, tracing_info, task_type);
463 }
434 464
435 // Ref the image again - this ref is owned by the caller, and it is their 465 // Ref the image again - this ref is owned by the caller, and it is their
436 // responsibility to release it by calling UnrefImage. 466 // responsibility to release it by calling UnrefImage.
437 RefImage(draw_image); 467 RefImage(draw_image);
438 return true; 468 return true;
439 } 469 }
440 470
441 void GpuImageDecodeCache::UnrefImage(const DrawImage& draw_image) { 471 void GpuImageDecodeCache::UnrefImage(const DrawImage& draw_image) {
442 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), 472 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
443 "GpuImageDecodeCache::UnrefImage"); 473 "GpuImageDecodeCache::UnrefImage");
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
637 "GpuImageDecodeCache::UploadImage"); 667 "GpuImageDecodeCache::UploadImage");
638 ContextProvider::ScopedContextLock context_lock(context_); 668 ContextProvider::ScopedContextLock context_lock(context_);
639 base::AutoLock lock(lock_); 669 base::AutoLock lock(lock_);
640 ImageData* image_data = GetImageDataForDrawImage(draw_image); 670 ImageData* image_data = GetImageDataForDrawImage(draw_image);
641 DCHECK(image_data); 671 DCHECK(image_data);
642 DCHECK(!image_data->is_at_raster); 672 DCHECK(!image_data->is_at_raster);
643 UploadImageIfNecessary(draw_image, image_data); 673 UploadImageIfNecessary(draw_image, image_data);
644 } 674 }
645 675
646 void GpuImageDecodeCache::OnImageDecodeTaskCompleted( 676 void GpuImageDecodeCache::OnImageDecodeTaskCompleted(
647 const DrawImage& draw_image) { 677 const DrawImage& draw_image,
678 DecodeTaskType task_type) {
648 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), 679 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
649 "GpuImageDecodeCache::OnImageDecodeTaskCompleted"); 680 "GpuImageDecodeCache::OnImageDecodeTaskCompleted");
650 base::AutoLock lock(lock_); 681 base::AutoLock lock(lock_);
651 // Decode task is complete, remove our reference to it. 682 // Decode task is complete, remove our reference to it.
652 ImageData* image_data = GetImageDataForDrawImage(draw_image); 683 ImageData* image_data = GetImageDataForDrawImage(draw_image);
653 DCHECK(image_data); 684 DCHECK(image_data);
654 DCHECK(image_data->decode.task); 685 if (task_type == PART_OF_UPLOAD_TASK) {
655 image_data->decode.task = nullptr; 686 DCHECK(image_data->decode.task);
687 image_data->decode.task = nullptr;
688 } else {
689 DCHECK(task_type == STAND_ALONE_DECODE_TASK);
690 DCHECK(image_data->decode.stand_alone_task);
691 image_data->decode.stand_alone_task = nullptr;
692 }
656 693
657 // While the decode task is active, we keep a ref on the decoded data. 694 // While the decode task is active, we keep a ref on the decoded data.
658 // Release that ref now. 695 // Release that ref now.
659 UnrefImageDecode(draw_image); 696 UnrefImageDecode(draw_image);
660 } 697 }
661 698
662 void GpuImageDecodeCache::OnImageUploadTaskCompleted( 699 void GpuImageDecodeCache::OnImageUploadTaskCompleted(
663 const DrawImage& draw_image) { 700 const DrawImage& draw_image) {
664 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), 701 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
665 "GpuImageDecodeCache::OnImageUploadTaskCompleted"); 702 "GpuImageDecodeCache::OnImageUploadTaskCompleted");
666 base::AutoLock lock(lock_); 703 base::AutoLock lock(lock_);
667 // Upload task is complete, remove our reference to it. 704 // Upload task is complete, remove our reference to it.
668 ImageData* image_data = GetImageDataForDrawImage(draw_image); 705 ImageData* image_data = GetImageDataForDrawImage(draw_image);
669 DCHECK(image_data); 706 DCHECK(image_data);
670 DCHECK(image_data->upload.task); 707 DCHECK(image_data->upload.task);
671 image_data->upload.task = nullptr; 708 image_data->upload.task = nullptr;
672 709
673 // While the upload task is active, we keep a ref on both the image it will be 710 // While the upload task is active, we keep a ref on both the image it will be
674 // populating, as well as the decode it needs to populate it. Release these 711 // populating, as well as the decode it needs to populate it. Release these
675 // refs now. 712 // refs now.
676 UnrefImageDecode(draw_image); 713 UnrefImageDecode(draw_image);
677 UnrefImageInternal(draw_image); 714 UnrefImageInternal(draw_image);
678 } 715 }
679 716
680 // Checks if an existing image decode exists. If not, returns a task to produce 717 // Checks if an existing image decode exists. If not, returns a task to produce
681 // the requested decode. 718 // the requested decode.
682 scoped_refptr<TileTask> GpuImageDecodeCache::GetImageDecodeTaskAndRef( 719 scoped_refptr<TileTask> GpuImageDecodeCache::GetImageDecodeTaskAndRef(
683 const DrawImage& draw_image, 720 const DrawImage& draw_image,
684 const TracingInfo& tracing_info) { 721 const TracingInfo& tracing_info,
722 DecodeTaskType task_type) {
685 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), 723 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
686 "GpuImageDecodeCache::GetImageDecodeTaskAndRef"); 724 "GpuImageDecodeCache::GetImageDecodeTaskAndRef");
687 lock_.AssertAcquired(); 725 lock_.AssertAcquired();
688 726
689 // This ref is kept alive while an upload task may need this decode. We 727 // This ref is kept alive while an upload task may need this decode. We
690 // release this ref in UploadTaskCompleted. 728 // release this ref in UploadTaskCompleted.
691 RefImageDecode(draw_image); 729 if (task_type == PART_OF_UPLOAD_TASK)
730 RefImageDecode(draw_image);
ericrk 2016/12/06 23:22:52 Should we just move this out of this function, to
692 731
693 ImageData* image_data = GetImageDataForDrawImage(draw_image); 732 ImageData* image_data = GetImageDataForDrawImage(draw_image);
694 DCHECK(image_data); 733 DCHECK(image_data);
695 if (image_data->decode.is_locked()) { 734 if (image_data->decode.is_locked()) {
696 // We should never be creating a decode task for an at raster image. 735 // We should never be creating a decode task for an at raster image.
697 DCHECK(!image_data->is_at_raster); 736 DCHECK(!image_data->is_at_raster);
698 // We should never be creating a decode for an already-uploaded image. 737 // We should never be creating a decode for an already-uploaded image.
699 DCHECK(!image_data->upload.image()); 738 DCHECK(!image_data->upload.image());
700 return nullptr; 739 return nullptr;
701 } 740 }
702 741
703 // We didn't have an existing locked image, create a task to lock or decode. 742 // We didn't have an existing locked image, create a task to lock or decode.
704 scoped_refptr<TileTask>& existing_task = image_data->decode.task; 743 scoped_refptr<TileTask>& existing_task =
744 (task_type == PART_OF_UPLOAD_TASK) ? image_data->decode.task
745 : image_data->decode.stand_alone_task;
705 if (!existing_task) { 746 if (!existing_task) {
706 // Ref image decode and create a decode task. This ref will be released in 747 // Ref image decode and create a decode task. This ref will be released in
707 // DecodeTaskCompleted. 748 // DecodeTaskCompleted.
708 RefImageDecode(draw_image); 749 RefImageDecode(draw_image);
709 existing_task = make_scoped_refptr( 750 existing_task = make_scoped_refptr(
710 new ImageDecodeTaskImpl(this, draw_image, tracing_info)); 751 new ImageDecodeTaskImpl(this, draw_image, tracing_info, task_type));
711 } 752 }
712 return existing_task; 753 return existing_task;
713 } 754 }
714 755
715 void GpuImageDecodeCache::RefImageDecode(const DrawImage& draw_image) { 756 void GpuImageDecodeCache::RefImageDecode(const DrawImage& draw_image) {
716 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), 757 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
717 "GpuImageDecodeCache::RefImageDecode"); 758 "GpuImageDecodeCache::RefImageDecode");
718 lock_.AssertAcquired(); 759 lock_.AssertAcquired();
719 auto found = in_use_cache_.find(GenerateInUseCacheKey(draw_image)); 760 auto found = in_use_cache_.find(GenerateInUseCacheKey(draw_image));
720 DCHECK(found != in_use_cache_.end()); 761 DCHECK(found != in_use_cache_.end());
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
847 if (image_data->upload.ref_count == 0 && image_data->upload.budgeted && 888 if (image_data->upload.ref_count == 0 && image_data->upload.budgeted &&
848 !image_data->upload.image()) { 889 !image_data->upload.image()) {
849 DCHECK_GE(bytes_used_, image_data->size); 890 DCHECK_GE(bytes_used_, image_data->size);
850 bytes_used_ -= image_data->size; 891 bytes_used_ -= image_data->size;
851 image_data->upload.budgeted = false; 892 image_data->upload.budgeted = false;
852 } 893 }
853 894
854 // We should unlock the discardable memory for the image in two cases: 895 // We should unlock the discardable memory for the image in two cases:
855 // 1) The image is no longer being used (no decode or upload refs). 896 // 1) The image is no longer being used (no decode or upload refs).
856 // 2) This is a GPU backed image that has already been uploaded (no decode 897 // 2) This is a GPU backed image that has already been uploaded (no decode
857 // refs). 898 // refs, and we actually already have an image).
858 bool should_unlock_discardable = 899 bool should_unlock_discardable =
859 !has_any_refs || (image_data->mode == DecodedDataMode::GPU && 900 !has_any_refs ||
860 !image_data->decode.ref_count); 901 (image_data->mode == DecodedDataMode::GPU &&
902 !image_data->decode.ref_count && image_data->upload.image());
861 903
862 if (should_unlock_discardable && image_data->decode.is_locked()) { 904 if (should_unlock_discardable && image_data->decode.is_locked()) {
863 DCHECK(image_data->decode.data()); 905 DCHECK(image_data->decode.data());
864 image_data->decode.Unlock(); 906 image_data->decode.Unlock();
865 } 907 }
866 908
867 #if DCHECK_IS_ON() 909 #if DCHECK_IS_ON()
868 // Sanity check the above logic. 910 // Sanity check the above logic.
869 if (image_data->upload.image()) { 911 if (image_data->upload.image()) {
870 DCHECK(image_data->is_at_raster || image_data->upload.budgeted); 912 DCHECK(image_data->is_at_raster || image_data->upload.budgeted);
(...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after
1228 EnsureCapacity(0); 1270 EnsureCapacity(0);
1229 break; 1271 break;
1230 } 1272 }
1231 case base::MemoryState::UNKNOWN: 1273 case base::MemoryState::UNKNOWN:
1232 // NOT_REACHED. 1274 // NOT_REACHED.
1233 break; 1275 break;
1234 } 1276 }
1235 } 1277 }
1236 1278
1237 } // namespace cc 1279 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698