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

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

Issue 1801933004: Refactor SoftwareImageDecodeController (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Bad return type. Created 4 years, 9 months 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 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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/software_image_decode_controller.h" 5 #include "cc/tiles/software_image_decode_controller.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 8
9 #include <functional> 9 #include <functional>
10 10
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after
361 if (decoded_images_ref_counts_.find(key) == 361 if (decoded_images_ref_counts_.find(key) ==
362 decoded_images_ref_counts_.end()) { 362 decoded_images_ref_counts_.end()) {
363 decoded_image->Unlock(); 363 decoded_image->Unlock();
364 } 364 }
365 365
366 decoded_images_.Put(key, std::move(decoded_image)); 366 decoded_images_.Put(key, std::move(decoded_image));
367 SanityCheckState(__LINE__, true); 367 SanityCheckState(__LINE__, true);
368 } 368 }
369 369
370 scoped_ptr<SoftwareImageDecodeController::DecodedImage> 370 scoped_ptr<SoftwareImageDecodeController::DecodedImage>
371 SoftwareImageDecodeController::DecodeImageMediumQuality(const ImageKey& key,
372 const SkImage& image) {
373 NOTIMPLEMENTED();
374 return nullptr;
375 }
376
377 scoped_ptr<SoftwareImageDecodeController::DecodedImage>
378 SoftwareImageDecodeController::DecodeImageHighQuality(const ImageKey& key,
379 const SkImage& image) {
380 // If we get here, that means we couldn't use the original sized decode for
381 // whatever reason. However, in all cases we do need an original decode to
382 // either do a scale or to extract a subrect from the image.
383 auto decoded_image_result = DecodeImageOrUseCache(key, image);
384 if (!decoded_image_result.decoded_pixmap_.addr())
385 return nullptr;
386
387 // Now we have a decoded_pixmap which represents the src_rect at the
388 // original scale. All we need to do is scale it.
389 return ScaleImage(key, decoded_image_result);
390 }
391
392 scoped_ptr<SoftwareImageDecodeController::DecodedImage>
371 SoftwareImageDecodeController::DecodeImageInternal( 393 SoftwareImageDecodeController::DecodeImageInternal(
372 const ImageKey& key, 394 const ImageKey& key,
373 const DrawImage& draw_image) { 395 const DrawImage& draw_image) {
374 TRACE_EVENT1("disabled-by-default-cc.debug", 396 TRACE_EVENT1("disabled-by-default-cc.debug",
375 "SoftwareImageDecodeController::DecodeImageInternal", "key", 397 "SoftwareImageDecodeController::DecodeImageInternal", "key",
376 key.ToString()); 398 key.ToString());
377 const SkImage* image = draw_image.image(); 399 const SkImage* image = draw_image.image();
378 400 if (!image) {
379 // If we can use the original decode, then we don't need to do scaling. We can
380 // just read pixels into the final memory.
381 if (key.can_use_original_decode()) {
382 SkImageInfo decoded_info =
383 CreateImageInfo(image->width(), image->height(), format_);
384 scoped_ptr<base::DiscardableMemory> decoded_pixels;
385 {
386 TRACE_EVENT0(
387 "disabled-by-default-cc.debug",
388 "SoftwareImageDecodeController::DecodeImageInternal - allocate "
389 "decoded pixels");
390 decoded_pixels =
391 base::DiscardableMemoryAllocator::GetInstance()
392 ->AllocateLockedDiscardableMemory(decoded_info.minRowBytes() *
393 decoded_info.height());
394 }
395 {
396 TRACE_EVENT0(
397 "disabled-by-default-cc.debug",
398 "SoftwareImageDecodeController::DecodeImageInternal - read pixels");
399 bool result = image->readPixels(decoded_info, decoded_pixels->data(),
400 decoded_info.minRowBytes(), 0, 0,
401 SkImage::kDisallow_CachingHint);
402
403 if (!result) {
404 decoded_pixels->Unlock();
405 return nullptr;
406 }
407 }
408
409 return make_scoped_ptr(new DecodedImage(
410 decoded_info, std::move(decoded_pixels), SkSize::Make(0, 0)));
411 }
412
413 // If we get here, that means we couldn't use the original sized decode for
414 // whatever reason. However, in all cases we do need an original decode to
415 // either do a scale or to extract a subrect from the image. So, what we can
416 // do is construct a key that would require a full sized decode, then get that
417 // decode via GetDecodedImageForDrawInternal(), use it, and unref it. This
418 // ensures that if the original sized decode is already available in any of
419 // the caches, we reuse that. We also ensure that all the proper locking takes
420 // place. If, on the other hand, the decode was not available,
421 // GetDecodedImageForDrawInternal() would decode the image, and unreffing it
422 // later ensures that we will store the discardable memory unlocked in the
423 // cache to be used by future requests.
424 gfx::Rect full_image_rect(image->width(), image->height());
425 DrawImage original_size_draw_image(image, gfx::RectToSkIRect(full_image_rect),
426 kNone_SkFilterQuality, SkMatrix::I());
427 ImageKey original_size_key =
428 ImageKey::FromDrawImage(original_size_draw_image);
429 // Sanity checks.
430 DCHECK(original_size_key.can_use_original_decode());
431 DCHECK(full_image_rect.size() == original_size_key.target_size());
432
433 auto decoded_draw_image = GetDecodedImageForDrawInternal(
434 original_size_key, original_size_draw_image);
435 if (!decoded_draw_image.image()) {
436 DrawWithImageFinished(original_size_draw_image, decoded_draw_image);
437 return nullptr; 401 return nullptr;
438 } 402 }
439 403
440 SkPixmap decoded_pixmap; 404 switch (key.filter_quality()) {
441 bool result = decoded_draw_image.image()->peekPixels(&decoded_pixmap); 405 case kNone_SkFilterQuality:
442 DCHECK(result); 406 // fall through
443 if (key.src_rect() != full_image_rect) { 407 case kLow_SkFilterQuality:
444 result = decoded_pixmap.extractSubset(&decoded_pixmap, 408 return GetOriginalImageDecode(key, *image);
445 gfx::RectToSkIRect(key.src_rect())); 409 case kMedium_SkFilterQuality:
446 DCHECK(result); 410 return DecodeImageMediumQuality(key, *image);
411 case kHigh_SkFilterQuality:
412 return DecodeImageHighQuality(key, *image);
413 default:
414 NOTREACHED();
415 return nullptr;
447 } 416 }
448
449 // Now we have a decoded_pixmap which represents the src_rect at the
450 // original scale. All we need to do is scale it.
451 DCHECK(!key.target_size().IsEmpty());
452 SkImageInfo scaled_info = CreateImageInfo(
453 key.target_size().width(), key.target_size().height(), format_);
454 scoped_ptr<base::DiscardableMemory> scaled_pixels;
455 {
456 TRACE_EVENT0(
457 "disabled-by-default-cc.debug",
458 "SoftwareImageDecodeController::DecodeImageInternal - allocate "
459 "scaled pixels");
460 scaled_pixels = base::DiscardableMemoryAllocator::GetInstance()
461 ->AllocateLockedDiscardableMemory(
462 scaled_info.minRowBytes() * scaled_info.height());
463 }
464 SkPixmap scaled_pixmap(scaled_info, scaled_pixels->data(),
465 scaled_info.minRowBytes());
466 // TODO(vmpstr): Start handling more than just high filter quality.
467 DCHECK_EQ(kHigh_SkFilterQuality, key.filter_quality());
468 {
469 TRACE_EVENT0(
470 "disabled-by-default-cc.debug",
471 "SoftwareImageDecodeController::DecodeImageInternal - scale pixels");
472 bool result =
473 decoded_pixmap.scalePixels(scaled_pixmap, key.filter_quality());
474 DCHECK(result);
475 }
476
477 // Release the original sized decode. Any other intermediate result to release
478 // would be the subrect memory. However, that's in a scoped_ptr and will be
479 // deleted automatically when we return.
480 DrawWithImageFinished(original_size_draw_image, decoded_draw_image);
481
482 return make_scoped_ptr(
483 new DecodedImage(scaled_info, std::move(scaled_pixels),
484 SkSize::Make(-key.src_rect().x(), -key.src_rect().y())));
485 } 417 }
486 418
487 DecodedDrawImage SoftwareImageDecodeController::GetDecodedImageForDraw( 419 DecodedDrawImage SoftwareImageDecodeController::GetDecodedImageForDraw(
488 const DrawImage& draw_image) { 420 const DrawImage& draw_image) {
489 ImageKey key = ImageKey::FromDrawImage(draw_image); 421 ImageKey key = ImageKey::FromDrawImage(draw_image);
490 TRACE_EVENT1("disabled-by-default-cc.debug", 422 TRACE_EVENT1("disabled-by-default-cc.debug",
491 "SoftwareImageDecodeController::GetDecodedImageForDraw", "key", 423 "SoftwareImageDecodeController::GetDecodedImageForDraw", "key",
492 key.ToString()); 424 key.ToString());
493 // If the target size is empty, we can skip this image draw. 425 // If the target size is empty, we can skip this image draw.
494 if (key.target_size().IsEmpty()) 426 if (key.target_size().IsEmpty())
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
545 // Now we know that we don't have a locked image, and we seem to be the first 477 // Now we know that we don't have a locked image, and we seem to be the first
546 // thread encountering this image (that might not be true, since other threads 478 // thread encountering this image (that might not be true, since other threads
547 // might be decoding it already). This means that we need to decode the image 479 // might be decoding it already). This means that we need to decode the image
548 // assuming we can't lock the one we found in the cache. 480 // assuming we can't lock the one we found in the cache.
549 bool check_at_raster_cache = false; 481 bool check_at_raster_cache = false;
550 if (!decoded_image || !decoded_image->Lock()) { 482 if (!decoded_image || !decoded_image->Lock()) {
551 // Note that we have to release the lock, since this lock is also accessed 483 // Note that we have to release the lock, since this lock is also accessed
552 // on the compositor thread. This means holding on to the lock might stall 484 // on the compositor thread. This means holding on to the lock might stall
553 // the compositor thread for the duration of the decode! 485 // the compositor thread for the duration of the decode!
554 base::AutoUnlock unlock(lock_); 486 base::AutoUnlock unlock(lock_);
555 scoped_decoded_image = DecodeImageInternal(key, draw_image); 487 const SkImage* image = draw_image.image();
488 if (key.can_use_original_decode()) {
ericrk 2016/03/24 16:06:59 If we unify the two by calling DecodeImageInternal
ericrk 2016/03/24 16:06:59 Can't we just call DecodeImageInternal here? Seems
cblume 2016/03/24 18:45:10 I began removing it and noticed GetScaleAdjustment
cblume 2016/03/24 18:45:10 Done.
cblume 2016/03/24 18:46:49 Running the tests, the low quality test and none q
489 scoped_decoded_image = GetOriginalImageDecode(key, *image);
490 } else {
491 auto decoded_image_result = DecodeImageOrUseCache(key, *image);
492 if (!decoded_image_result.decoded_pixmap_.addr()) {
493 scoped_decoded_image = nullptr;
494 } else {
495 scoped_decoded_image = ScaleImage(key, decoded_image_result);
496 }
497 }
498
556 decoded_image = scoped_decoded_image.get(); 499 decoded_image = scoped_decoded_image.get();
557 500
558 // Skip the image if we couldn't decode it. 501 // Skip the image if we couldn't decode it.
559 if (!decoded_image) 502 if (!decoded_image)
560 return DecodedDrawImage(nullptr, kNone_SkFilterQuality); 503 return DecodedDrawImage(nullptr, kNone_SkFilterQuality);
561 check_at_raster_cache = true; 504 check_at_raster_cache = true;
562 } 505 }
563 506
564 DCHECK(decoded_image == scoped_decoded_image.get()); 507 DCHECK(decoded_image == scoped_decoded_image.get());
565 508
(...skipping 20 matching lines...) Expand all
586 DCHECK(decoded_image->is_locked()); 529 DCHECK(decoded_image->is_locked());
587 RefAtRasterImage(key); 530 RefAtRasterImage(key);
588 SanityCheckState(__LINE__, true); 531 SanityCheckState(__LINE__, true);
589 auto decoded_draw_image = 532 auto decoded_draw_image =
590 DecodedDrawImage(decoded_image->image(), decoded_image->src_rect_offset(), 533 DecodedDrawImage(decoded_image->image(), decoded_image->src_rect_offset(),
591 GetScaleAdjustment(key), GetDecodedFilterQuality(key)); 534 GetScaleAdjustment(key), GetDecodedFilterQuality(key));
592 decoded_draw_image.set_at_raster_decode(true); 535 decoded_draw_image.set_at_raster_decode(true);
593 return decoded_draw_image; 536 return decoded_draw_image;
594 } 537 }
595 538
539 SoftwareImageDecodeController::DecodedImageResult::DecodedImageResult(
540 SkPixmap decoded_pixmap,
541 DrawImage original_size_draw_image,
542 DecodedDrawImage decoded_draw_image)
543 : decoded_pixmap_(decoded_pixmap),
544 original_size_draw_image_(original_size_draw_image),
545 decoded_draw_image_(decoded_draw_image) {}
546
547 scoped_ptr<SoftwareImageDecodeController::DecodedImage>
548 SoftwareImageDecodeController::GetOriginalImageDecode(const ImageKey& key,
549 const SkImage& image) {
550 TRACE_EVENT1("disabled-by-default-cc.debug",
551 "SoftwareImageDecodeController::GetOriginalImageDecode", "key",
552 key.ToString());
553 DCHECK(key.can_use_original_decode());
554 SkImageInfo decoded_info =
555 CreateImageInfo(image.width(), image.height(), format_);
556 scoped_ptr<base::DiscardableMemory> decoded_pixels;
557 {
558 TRACE_EVENT0("disabled-by-default-cc.debug",
559 "SoftwareImageDecodeController::GetOriginalImageDecode - "
560 "allocate decoded pixels");
561 decoded_pixels =
562 base::DiscardableMemoryAllocator::GetInstance()
563 ->AllocateLockedDiscardableMemory(decoded_info.minRowBytes() *
564 decoded_info.height());
565 }
566 {
567 TRACE_EVENT0("disabled-by-default-cc.debug",
568 "SoftwareImageDecodeController::GetOriginalImageDecode - "
569 "read pixels");
570 bool result = image.readPixels(decoded_info, decoded_pixels->data(),
571 decoded_info.minRowBytes(), 0, 0,
572 SkImage::kDisallow_CachingHint);
573
574 if (!result) {
575 decoded_pixels->Unlock();
576 return nullptr;
577 }
578 }
579
580 return make_scoped_ptr(new DecodedImage(
581 decoded_info, std::move(decoded_pixels), SkSize::Make(0, 0)));
582 }
583
584 SoftwareImageDecodeController::DecodedImageResult
585 SoftwareImageDecodeController::DecodeImageOrUseCache(const ImageKey& key,
586 const SkImage& image) {
587 // Construct a key to use in GetDecodedImageForDrawInternal().
588 // This allows us to reuse an image in any cache if available.
589 gfx::Rect full_image_rect(image.width(), image.height());
590 DrawImage original_size_draw_image(&image,
591 gfx::RectToSkIRect(full_image_rect),
592 kNone_SkFilterQuality, SkMatrix::I());
593 ImageKey original_size_key =
594 ImageKey::FromDrawImage(original_size_draw_image);
595 // Sanity checks.
596 DCHECK(original_size_key.can_use_original_decode());
597 DCHECK(full_image_rect.size() == original_size_key.target_size());
598
599 auto decoded_draw_image = GetDecodedImageForDrawInternal(
600 original_size_key, original_size_draw_image);
601 if (!decoded_draw_image.image()) {
602 DrawWithImageFinished(original_size_draw_image, decoded_draw_image);
603 return DecodedImageResult(SkPixmap(), DrawImage(),
604 DecodedDrawImage(nullptr, kNone_SkFilterQuality));
605 }
606
607 SkPixmap decoded_pixmap;
608 bool result = decoded_draw_image.image()->peekPixels(&decoded_pixmap);
609 DCHECK(result);
610 if (key.src_rect() != full_image_rect) {
611 result = decoded_pixmap.extractSubset(&decoded_pixmap,
612 gfx::RectToSkIRect(key.src_rect()));
613 DCHECK(result);
614 }
615
616 return DecodedImageResult(decoded_pixmap, original_size_draw_image,
617 decoded_draw_image);
618 }
619
620 scoped_ptr<SoftwareImageDecodeController::DecodedImage>
621 SoftwareImageDecodeController::ScaleImage(
622 const ImageKey& key,
623 const DecodedImageResult& decoded_image_result) {
624 DCHECK(!key.target_size().IsEmpty());
625 SkImageInfo scaled_info = CreateImageInfo(
626 key.target_size().width(), key.target_size().height(), format_);
627 scoped_ptr<base::DiscardableMemory> scaled_pixels;
628 {
629 TRACE_EVENT0(
630 "disabled-by-default-cc.debug",
631 "SoftwareImageDecodeController::ScaleImage - allocate scaled pixels");
632 scaled_pixels = base::DiscardableMemoryAllocator::GetInstance()
633 ->AllocateLockedDiscardableMemory(
634 scaled_info.minRowBytes() * scaled_info.height());
635 }
636 SkPixmap scaled_pixmap(scaled_info, scaled_pixels->data(),
637 scaled_info.minRowBytes());
638 // TODO(vmpstr): Start handling more than just high filter quality.
639 DCHECK_EQ(kHigh_SkFilterQuality, key.filter_quality());
640 {
641 TRACE_EVENT0("disabled-by-default-cc.debug",
642 "SoftwareImageDecodeController::ScaleImage - scale pixels");
643 bool result = decoded_image_result.decoded_pixmap_.scalePixels(
644 scaled_pixmap, key.filter_quality());
645 DCHECK(result);
646 }
647
648 // Release the original sized decode. Any other intermediate result to release
649 // would be the subrect memory. However, that's in a scoped_ptr and will be
650 // deleted automatically when we return.
651 DrawWithImageFinished(decoded_image_result.original_size_draw_image_,
652 decoded_image_result.decoded_draw_image_);
653
654 return make_scoped_ptr(
655 new DecodedImage(scaled_info, std::move(scaled_pixels),
656 SkSize::Make(-key.src_rect().x(), -key.src_rect().y())));
657 }
658
596 void SoftwareImageDecodeController::DrawWithImageFinished( 659 void SoftwareImageDecodeController::DrawWithImageFinished(
597 const DrawImage& image, 660 const DrawImage& image,
598 const DecodedDrawImage& decoded_image) { 661 const DecodedDrawImage& decoded_image) {
599 TRACE_EVENT1("disabled-by-default-cc.debug", 662 TRACE_EVENT1("disabled-by-default-cc.debug",
600 "SoftwareImageDecodeController::DrawWithImageFinished", "key", 663 "SoftwareImageDecodeController::DrawWithImageFinished", "key",
601 ImageKey::FromDrawImage(image).ToString()); 664 ImageKey::FromDrawImage(image).ToString());
602 ImageKey key = ImageKey::FromDrawImage(image); 665 ImageKey key = ImageKey::FromDrawImage(image);
603 if (!decoded_image.image() || !CanHandleImage(key)) 666 if (!decoded_image.image() || !CanHandleImage(key))
604 return; 667 return;
605 668
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after
887 void SoftwareImageDecodeController::MemoryBudget::ResetUsage() { 950 void SoftwareImageDecodeController::MemoryBudget::ResetUsage() {
888 current_usage_bytes_ = 0; 951 current_usage_bytes_ = 0;
889 } 952 }
890 953
891 size_t SoftwareImageDecodeController::MemoryBudget::GetCurrentUsageSafe() 954 size_t SoftwareImageDecodeController::MemoryBudget::GetCurrentUsageSafe()
892 const { 955 const {
893 return current_usage_bytes_.ValueOrDie(); 956 return current_usage_bytes_.ValueOrDie();
894 } 957 }
895 958
896 } // namespace cc 959 } // namespace cc
OLDNEW
« cc/tiles/software_image_decode_controller.h ('K') | « cc/tiles/software_image_decode_controller.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698