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

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

Issue 2801413002: color: Enable color conversion in image decoder caches (Closed)
Patch Set: Rebase Created 3 years, 8 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
« no previous file with comments | « cc/tiles/software_image_decode_cache.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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_cache.h" 5 #include "cc/tiles/software_image_decode_cache.h"
6 6
7 #include <inttypes.h> 7 #include <inttypes.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include <algorithm> 10 #include <algorithm>
(...skipping 428 matching lines...) Expand 10 before | Expand all | Expand 10 after
439 key.ToString()); 439 key.ToString());
440 sk_sp<const SkImage> image = draw_image.image(); 440 sk_sp<const SkImage> image = draw_image.image();
441 if (!image) 441 if (!image)
442 return nullptr; 442 return nullptr;
443 443
444 switch (key.filter_quality()) { 444 switch (key.filter_quality()) {
445 case kNone_SkFilterQuality: 445 case kNone_SkFilterQuality:
446 case kLow_SkFilterQuality: 446 case kLow_SkFilterQuality:
447 if (key.should_use_subrect()) 447 if (key.should_use_subrect())
448 return GetSubrectImageDecode(key, std::move(image)); 448 return GetSubrectImageDecode(key, std::move(image));
449 return GetOriginalImageDecode(std::move(image)); 449 return GetOriginalSizeImageDecode(key, std::move(image));
450 case kMedium_SkFilterQuality: 450 case kMedium_SkFilterQuality:
451 case kHigh_SkFilterQuality: 451 case kHigh_SkFilterQuality:
452 return GetScaledImageDecode(key, std::move(image)); 452 return GetScaledImageDecode(key, std::move(image));
453 default: 453 default:
454 NOTREACHED(); 454 NOTREACHED();
455 return nullptr; 455 return nullptr;
456 } 456 }
457 } 457 }
458 458
459 DecodedDrawImage SoftwareImageDecodeCache::GetDecodedImageForDraw( 459 DecodedDrawImage SoftwareImageDecodeCache::GetDecodedImageForDraw(
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
556 RefAtRasterImage(key); 556 RefAtRasterImage(key);
557 decoded_image->mark_used(); 557 decoded_image->mark_used();
558 auto decoded_draw_image = 558 auto decoded_draw_image =
559 DecodedDrawImage(decoded_image->image(), decoded_image->src_rect_offset(), 559 DecodedDrawImage(decoded_image->image(), decoded_image->src_rect_offset(),
560 GetScaleAdjustment(key), GetDecodedFilterQuality(key)); 560 GetScaleAdjustment(key), GetDecodedFilterQuality(key));
561 decoded_draw_image.set_at_raster_decode(true); 561 decoded_draw_image.set_at_raster_decode(true);
562 return decoded_draw_image; 562 return decoded_draw_image;
563 } 563 }
564 564
565 std::unique_ptr<SoftwareImageDecodeCache::DecodedImage> 565 std::unique_ptr<SoftwareImageDecodeCache::DecodedImage>
566 SoftwareImageDecodeCache::GetOriginalImageDecode(sk_sp<const SkImage> image) { 566 SoftwareImageDecodeCache::GetOriginalSizeImageDecode(
567 const ImageKey& key,
568 sk_sp<const SkImage> image) {
567 SkImageInfo decoded_info = 569 SkImageInfo decoded_info =
568 CreateImageInfo(image->width(), image->height(), format_); 570 CreateImageInfo(image->width(), image->height(), format_);
571 sk_sp<SkColorSpace> target_color_space =
572 key.target_color_space().ToSkColorSpace();
573
569 std::unique_ptr<base::DiscardableMemory> decoded_pixels; 574 std::unique_ptr<base::DiscardableMemory> decoded_pixels;
570 { 575 {
571 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), 576 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
572 "SoftwareImageDecodeCache::GetOriginalImageDecode - " 577 "SoftwareImageDecodeCache::GetOriginalSizeImageDecode - "
573 "allocate decoded pixels"); 578 "allocate decoded pixels");
574 decoded_pixels = 579 decoded_pixels =
575 base::DiscardableMemoryAllocator::GetInstance() 580 base::DiscardableMemoryAllocator::GetInstance()
576 ->AllocateLockedDiscardableMemory(decoded_info.minRowBytes() * 581 ->AllocateLockedDiscardableMemory(decoded_info.minRowBytes() *
577 decoded_info.height()); 582 decoded_info.height());
578 } 583 }
584 if (target_color_space) {
vmpstr 2017/04/27 22:49:45 Is this the right spot to do this? From my unders
ccameron 2017/05/03 21:17:13 This understanding is correct. So, if (target_col
585 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
586 "SoftwareImageDecodeCache::GetOriginalSizeImageDecode - "
587 "color conversion");
588 image = image->makeColorSpace(target_color_space,
589 SkTransferFunctionBehavior::kIgnore);
590 DCHECK(image);
591 }
579 { 592 {
580 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), 593 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
581 "SoftwareImageDecodeCache::GetOriginalImageDecode - " 594 "SoftwareImageDecodeCache::GetOriginalSizeImageDecode - "
582 "read pixels"); 595 "read pixels");
583 bool result = image->readPixels(decoded_info, decoded_pixels->data(), 596 bool result = image->readPixels(decoded_info, decoded_pixels->data(),
584 decoded_info.minRowBytes(), 0, 0, 597 decoded_info.minRowBytes(), 0, 0,
585 SkImage::kDisallow_CachingHint); 598 SkImage::kDisallow_CachingHint);
586 599
587 if (!result) { 600 if (!result) {
588 decoded_pixels->Unlock(); 601 decoded_pixels->Unlock();
589 return nullptr; 602 return nullptr;
590 } 603 }
591 } 604 }
592 605
593 // TODO(ccameron,msarett): Convert image to target color space. 606 return base::MakeUnique<DecodedImage>(
594 // http://crbug.com/706613 607 decoded_info.makeColorSpace(target_color_space),
595 608 std::move(decoded_pixels), SkSize::Make(0, 0),
596 return base::MakeUnique<DecodedImage>(decoded_info, std::move(decoded_pixels), 609 next_tracing_id_.GetNext());
597 SkSize::Make(0, 0),
598 next_tracing_id_.GetNext());
599 } 610 }
600 611
601 std::unique_ptr<SoftwareImageDecodeCache::DecodedImage> 612 std::unique_ptr<SoftwareImageDecodeCache::DecodedImage>
602 SoftwareImageDecodeCache::GetSubrectImageDecode(const ImageKey& key, 613 SoftwareImageDecodeCache::GetSubrectImageDecode(const ImageKey& key,
603 sk_sp<const SkImage> image) { 614 sk_sp<const SkImage> image) {
604 // Construct a key to use in GetDecodedImageForDrawInternal(). 615 // Construct a key to use in GetDecodedImageForDrawInternal().
605 // This allows us to reuse an image in any cache if available. 616 // This allows us to reuse an image in any cache if available.
606 gfx::Rect full_image_rect(image->width(), image->height()); 617 gfx::Rect full_image_rect(image->width(), image->height());
607 DrawImage original_size_draw_image( 618 DrawImage original_size_draw_image(
608 std::move(image), gfx::RectToSkIRect(full_image_rect), 619 std::move(image), gfx::RectToSkIRect(full_image_rect),
609 kNone_SkFilterQuality, SkMatrix::I(), key.target_color_space()); 620 kNone_SkFilterQuality, SkMatrix::I(), key.target_color_space());
610 ImageKey original_size_key = 621 ImageKey original_size_key =
611 ImageKey::FromDrawImage(original_size_draw_image); 622 ImageKey::FromDrawImage(original_size_draw_image);
623 sk_sp<SkColorSpace> target_color_space =
624 key.target_color_space().ToSkColorSpace();
625
612 // Sanity checks. 626 // Sanity checks.
613 DCHECK(original_size_key.can_use_original_size_decode()) 627 DCHECK(original_size_key.can_use_original_size_decode())
614 << original_size_key.ToString(); 628 << original_size_key.ToString();
615 DCHECK(full_image_rect.size() == original_size_key.target_size()); 629 DCHECK(full_image_rect.size() == original_size_key.target_size());
616 630
617 auto decoded_draw_image = GetDecodedImageForDrawInternal( 631 auto decoded_draw_image = GetDecodedImageForDrawInternal(
618 original_size_key, original_size_draw_image); 632 original_size_key, original_size_draw_image);
619 AutoDrawWithImageFinished auto_finish_draw(this, original_size_draw_image, 633 AutoDrawWithImageFinished auto_finish_draw(this, original_size_draw_image,
620 decoded_draw_image); 634 decoded_draw_image);
621 if (!decoded_draw_image.image()) 635 if (!decoded_draw_image.image())
622 return nullptr; 636 return nullptr;
623 637
638 DCHECK(SkColorSpace::Equals(decoded_draw_image.image()->colorSpace(),
639 target_color_space.get()));
624 SkImageInfo subrect_info = CreateImageInfo( 640 SkImageInfo subrect_info = CreateImageInfo(
625 key.target_size().width(), key.target_size().height(), format_); 641 key.target_size().width(), key.target_size().height(), format_);
626 std::unique_ptr<base::DiscardableMemory> subrect_pixels; 642 std::unique_ptr<base::DiscardableMemory> subrect_pixels;
627 { 643 {
628 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), 644 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
629 "SoftwareImageDecodeCache::GetSubrectImageDecode - " 645 "SoftwareImageDecodeCache::GetSubrectImageDecode - "
630 "allocate subrect pixels"); 646 "allocate subrect pixels");
631 // TODO(vmpstr): This is using checked math to diagnose a problem reported 647 // TODO(vmpstr): This is using checked math to diagnose a problem reported
632 // in crbug.com/662217. If this is causing crashes, then it should be fixed 648 // in crbug.com/662217. If this is causing crashes, then it should be fixed
633 // elsewhere by skipping images that are too large. 649 // elsewhere by skipping images that are too large.
634 base::CheckedNumeric<size_t> byte_size = subrect_info.minRowBytes(); 650 base::CheckedNumeric<size_t> byte_size = subrect_info.minRowBytes();
635 byte_size *= subrect_info.height(); 651 byte_size *= subrect_info.height();
636 subrect_pixels = 652 subrect_pixels =
637 base::DiscardableMemoryAllocator::GetInstance() 653 base::DiscardableMemoryAllocator::GetInstance()
638 ->AllocateLockedDiscardableMemory(byte_size.ValueOrDie()); 654 ->AllocateLockedDiscardableMemory(byte_size.ValueOrDie());
639 } 655 }
640 { 656 {
641 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), 657 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
642 "SoftwareImageDecodeCache::GetSubrectImageDecode - " 658 "SoftwareImageDecodeCache::GetSubrectImageDecode - "
643 "read pixels"); 659 "read pixels");
644 bool result = decoded_draw_image.image()->readPixels( 660 bool result = decoded_draw_image.image()->readPixels(
645 subrect_info, subrect_pixels->data(), subrect_info.minRowBytes(), 661 subrect_info, subrect_pixels->data(), subrect_info.minRowBytes(),
646 key.src_rect().x(), key.src_rect().y(), SkImage::kDisallow_CachingHint); 662 key.src_rect().x(), key.src_rect().y(), SkImage::kDisallow_CachingHint);
647 // We have a decoded image, and we're reading into already allocated memory. 663 // We have a decoded image, and we're reading into already allocated memory.
648 // This should never fail. 664 // This should never fail.
649 DCHECK(result); 665 DCHECK(result);
650 } 666 }
651 667
652 // TODO(ccameron,msarett): Convert image to target color space.
653 // http://crbug.com/706613
654
655 return base::WrapUnique( 668 return base::WrapUnique(
656 new DecodedImage(subrect_info, std::move(subrect_pixels), 669 new DecodedImage(subrect_info.makeColorSpace(target_color_space),
670 std::move(subrect_pixels),
657 SkSize::Make(-key.src_rect().x(), -key.src_rect().y()), 671 SkSize::Make(-key.src_rect().x(), -key.src_rect().y()),
658 next_tracing_id_.GetNext())); 672 next_tracing_id_.GetNext()));
659 } 673 }
660 674
661 std::unique_ptr<SoftwareImageDecodeCache::DecodedImage> 675 std::unique_ptr<SoftwareImageDecodeCache::DecodedImage>
662 SoftwareImageDecodeCache::GetScaledImageDecode(const ImageKey& key, 676 SoftwareImageDecodeCache::GetScaledImageDecode(const ImageKey& key,
663 sk_sp<const SkImage> image) { 677 sk_sp<const SkImage> image) {
664 // Construct a key to use in GetDecodedImageForDrawInternal(). 678 // Construct a key to use in GetDecodedImageForDrawInternal().
665 // This allows us to reuse an image in any cache if available. 679 // This allows us to reuse an image in any cache if available.
666 gfx::Rect full_image_rect(image->width(), image->height()); 680 gfx::Rect full_image_rect(image->width(), image->height());
667 DrawImage original_size_draw_image( 681 DrawImage original_size_draw_image(
668 std::move(image), gfx::RectToSkIRect(full_image_rect), 682 std::move(image), gfx::RectToSkIRect(full_image_rect),
669 kNone_SkFilterQuality, SkMatrix::I(), key.target_color_space()); 683 kNone_SkFilterQuality, SkMatrix::I(), key.target_color_space());
670 ImageKey original_size_key = 684 ImageKey original_size_key =
671 ImageKey::FromDrawImage(original_size_draw_image); 685 ImageKey::FromDrawImage(original_size_draw_image);
686 sk_sp<SkColorSpace> target_color_space =
687 key.target_color_space().ToSkColorSpace();
688
672 // Sanity checks. 689 // Sanity checks.
673 DCHECK(original_size_key.can_use_original_size_decode()) 690 DCHECK(original_size_key.can_use_original_size_decode())
674 << original_size_key.ToString(); 691 << original_size_key.ToString();
675 DCHECK(full_image_rect.size() == original_size_key.target_size()); 692 DCHECK(full_image_rect.size() == original_size_key.target_size());
676 693
677 auto decoded_draw_image = GetDecodedImageForDrawInternal( 694 auto decoded_draw_image = GetDecodedImageForDrawInternal(
678 original_size_key, original_size_draw_image); 695 original_size_key, original_size_draw_image);
679 AutoDrawWithImageFinished auto_finish_draw(this, original_size_draw_image, 696 AutoDrawWithImageFinished auto_finish_draw(this, original_size_draw_image,
680 decoded_draw_image); 697 decoded_draw_image);
681 if (!decoded_draw_image.image()) 698 if (!decoded_draw_image.image())
682 return nullptr; 699 return nullptr;
683 700
684 SkPixmap decoded_pixmap; 701 SkPixmap decoded_pixmap;
685 bool result = decoded_draw_image.image()->peekPixels(&decoded_pixmap); 702 bool result = decoded_draw_image.image()->peekPixels(&decoded_pixmap);
686 DCHECK(result) << key.ToString(); 703 DCHECK(result) << key.ToString();
687 if (key.src_rect() != full_image_rect) { 704 if (key.src_rect() != full_image_rect) {
688 result = decoded_pixmap.extractSubset(&decoded_pixmap, 705 result = decoded_pixmap.extractSubset(&decoded_pixmap,
689 gfx::RectToSkIRect(key.src_rect())); 706 gfx::RectToSkIRect(key.src_rect()));
690 DCHECK(result) << key.ToString(); 707 DCHECK(result) << key.ToString();
691 } 708 }
692 709
693 DCHECK(!key.target_size().IsEmpty()); 710 DCHECK(!key.target_size().IsEmpty());
711 DCHECK(SkColorSpace::Equals(decoded_draw_image.image()->colorSpace(),
712 target_color_space.get()));
694 SkImageInfo scaled_info = CreateImageInfo( 713 SkImageInfo scaled_info = CreateImageInfo(
695 key.target_size().width(), key.target_size().height(), format_); 714 key.target_size().width(), key.target_size().height(), format_);
696 std::unique_ptr<base::DiscardableMemory> scaled_pixels; 715 std::unique_ptr<base::DiscardableMemory> scaled_pixels;
697 { 716 {
698 TRACE_EVENT0( 717 TRACE_EVENT0(
699 TRACE_DISABLED_BY_DEFAULT("cc.debug"), 718 TRACE_DISABLED_BY_DEFAULT("cc.debug"),
700 "SoftwareImageDecodeCache::ScaleImage - allocate scaled pixels"); 719 "SoftwareImageDecodeCache::ScaleImage - allocate scaled pixels");
701 scaled_pixels = base::DiscardableMemoryAllocator::GetInstance() 720 scaled_pixels = base::DiscardableMemoryAllocator::GetInstance()
702 ->AllocateLockedDiscardableMemory( 721 ->AllocateLockedDiscardableMemory(
703 scaled_info.minRowBytes() * scaled_info.height()); 722 scaled_info.minRowBytes() * scaled_info.height());
704 } 723 }
705 SkPixmap scaled_pixmap(scaled_info, scaled_pixels->data(), 724 SkPixmap scaled_pixmap(scaled_info, scaled_pixels->data(),
706 scaled_info.minRowBytes()); 725 scaled_info.minRowBytes());
707 DCHECK(key.filter_quality() == kHigh_SkFilterQuality || 726 DCHECK(key.filter_quality() == kHigh_SkFilterQuality ||
708 key.filter_quality() == kMedium_SkFilterQuality); 727 key.filter_quality() == kMedium_SkFilterQuality);
709 { 728 {
710 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), 729 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
711 "SoftwareImageDecodeCache::ScaleImage - scale pixels"); 730 "SoftwareImageDecodeCache::ScaleImage - scale pixels");
712 bool result = 731 bool result =
713 decoded_pixmap.scalePixels(scaled_pixmap, key.filter_quality()); 732 decoded_pixmap.scalePixels(scaled_pixmap, key.filter_quality());
714 DCHECK(result) << key.ToString(); 733 DCHECK(result) << key.ToString();
715 } 734 }
716 735
717 // TODO(ccameron,msarett): Convert image to target color space.
718 // http://crbug.com/706613
719
720 return base::MakeUnique<DecodedImage>( 736 return base::MakeUnique<DecodedImage>(
721 scaled_info, std::move(scaled_pixels), 737 scaled_info.makeColorSpace(decoded_draw_image.image()->refColorSpace()),
738 std::move(scaled_pixels),
722 SkSize::Make(-key.src_rect().x(), -key.src_rect().y()), 739 SkSize::Make(-key.src_rect().x(), -key.src_rect().y()),
723 next_tracing_id_.GetNext()); 740 next_tracing_id_.GetNext());
724 } 741 }
725 742
726 void SoftwareImageDecodeCache::DrawWithImageFinished( 743 void SoftwareImageDecodeCache::DrawWithImageFinished(
727 const DrawImage& image, 744 const DrawImage& image,
728 const DecodedDrawImage& decoded_image) { 745 const DecodedDrawImage& decoded_image) {
729 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"), 746 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
730 "SoftwareImageDecodeCache::DrawWithImageFinished", "key", 747 "SoftwareImageDecodeCache::DrawWithImageFinished", "key",
731 ImageKey::FromDrawImage(image).ToString()); 748 ImageKey::FromDrawImage(image).ToString());
(...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after
1156 } 1173 }
1157 } 1174 }
1158 } 1175 }
1159 1176
1160 void SoftwareImageDecodeCache::OnPurgeMemory() { 1177 void SoftwareImageDecodeCache::OnPurgeMemory() {
1161 base::AutoLock lock(lock_); 1178 base::AutoLock lock(lock_);
1162 ReduceCacheUsageUntilWithinLimit(0); 1179 ReduceCacheUsageUntilWithinLimit(0);
1163 } 1180 }
1164 1181
1165 } // namespace cc 1182 } // namespace cc
OLDNEW
« no previous file with comments | « cc/tiles/software_image_decode_cache.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698