Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |