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/image_decode_controller.h" | 5 #include "cc/tiles/image_decode_controller.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 | 8 |
9 #include "base/macros.h" | 9 #include "base/macros.h" |
10 #include "base/memory/discardable_memory.h" | 10 #include "base/memory/discardable_memory.h" |
(...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
364 new DecodedImage(scaled_info, std::move(scaled_pixels), | 364 new DecodedImage(scaled_info, std::move(scaled_pixels), |
365 SkSize::Make(-key.src_rect().x(), -key.src_rect().y()))); | 365 SkSize::Make(-key.src_rect().x(), -key.src_rect().y()))); |
366 } | 366 } |
367 | 367 |
368 DecodedDrawImage ImageDecodeController::GetDecodedImageForDraw( | 368 DecodedDrawImage ImageDecodeController::GetDecodedImageForDraw( |
369 const DrawImage& draw_image) { | 369 const DrawImage& draw_image) { |
370 ImageKey key = ImageKey::FromDrawImage(draw_image); | 370 ImageKey key = ImageKey::FromDrawImage(draw_image); |
371 TRACE_EVENT1("disabled-by-default-cc.debug", | 371 TRACE_EVENT1("disabled-by-default-cc.debug", |
372 "ImageDecodeController::GetDecodedImageAndRef", "key", | 372 "ImageDecodeController::GetDecodedImageAndRef", "key", |
373 key.ToString()); | 373 key.ToString()); |
| 374 if (!CanHandleImage(key, draw_image)) |
| 375 return DecodedDrawImage(draw_image.image(), draw_image.filter_quality()); |
| 376 |
374 // If the target size is empty, we can skip this image draw. | 377 // If the target size is empty, we can skip this image draw. |
375 if (key.target_size().IsEmpty()) | 378 if (key.target_size().IsEmpty()) |
376 return DecodedDrawImage(nullptr, kNone_SkFilterQuality); | 379 return DecodedDrawImage(nullptr, kNone_SkFilterQuality); |
377 | 380 |
378 if (!CanHandleImage(key, draw_image)) | |
379 return DecodedDrawImage(draw_image.image(), draw_image.filter_quality()); | |
380 | |
381 base::AutoLock lock(lock_); | 381 base::AutoLock lock(lock_); |
382 auto decoded_images_it = FindImage(&decoded_images_, key); | 382 auto decoded_images_it = FindImage(&decoded_images_, key); |
383 // If we found the image and it's locked, then return it. If it's not locked, | 383 // If we found the image and it's locked, then return it. If it's not locked, |
384 // erase it from the cache since it might be put into the at-raster cache. | 384 // erase it from the cache since it might be put into the at-raster cache. |
385 scoped_refptr<DecodedImage> decoded_image; | 385 scoped_refptr<DecodedImage> decoded_image; |
386 if (decoded_images_it != decoded_images_.end()) { | 386 if (decoded_images_it != decoded_images_.end()) { |
387 decoded_image = decoded_images_it->second; | 387 decoded_image = decoded_images_it->second; |
388 if (decoded_image->is_locked()) { | 388 if (decoded_image->is_locked()) { |
389 RefImage(key); | 389 RefImage(key); |
390 SanityCheckState(__LINE__, true); | 390 SanityCheckState(__LINE__, true); |
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
632 DCHECK_GE(budget.AvailableMemoryBytes(), | 632 DCHECK_GE(budget.AvailableMemoryBytes(), |
633 locked_images_budget_.AvailableMemoryBytes()) | 633 locked_images_budget_.AvailableMemoryBytes()) |
634 << line; | 634 << line; |
635 #endif // DCHECK_IS_ON() | 635 #endif // DCHECK_IS_ON() |
636 } | 636 } |
637 | 637 |
638 // ImageDecodeControllerKey | 638 // ImageDecodeControllerKey |
639 ImageDecodeControllerKey ImageDecodeControllerKey::FromDrawImage( | 639 ImageDecodeControllerKey ImageDecodeControllerKey::FromDrawImage( |
640 const DrawImage& image) { | 640 const DrawImage& image) { |
641 const SkSize& scale = image.scale(); | 641 const SkSize& scale = image.scale(); |
642 // If the src_rect falls outside of the image, we need to clip it since | |
643 // otherwise we might end up with uninitialized memory in the decode process. | |
644 // Note that the scale is still unchanged and the target size is now a | |
645 // function of the new src_rect. | |
646 gfx::Rect src_rect = gfx::IntersectRects( | |
647 gfx::SkIRectToRect(image.src_rect()), | |
648 gfx::Rect(image.image()->width(), image.image()->height())); | |
649 | |
650 gfx::Size target_size( | 642 gfx::Size target_size( |
651 SkScalarRoundToInt(std::abs(src_rect.width() * scale.width())), | 643 SkScalarRoundToInt(std::abs(image.src_rect().width() * scale.width())), |
652 SkScalarRoundToInt(std::abs(src_rect.height() * scale.height()))); | 644 SkScalarRoundToInt(std::abs(image.src_rect().height() * scale.height()))); |
653 | 645 |
654 // Start with the quality that was requested. | 646 // Start with the quality that was requested. |
655 SkFilterQuality quality = image.filter_quality(); | 647 SkFilterQuality quality = image.filter_quality(); |
656 | 648 |
657 // If we're not going to do a scale, we can use low filter quality. Note that | 649 // If we're not going to do a scale, we can use low filter quality. Note that |
658 // checking if the sizes are the same is better than checking if scale is 1.f, | 650 // checking if the sizes are the same is better than checking if scale is 1.f, |
659 // because even non-1 scale can result in the same (rounded) width/height. | 651 // because even non-1 scale can result in the same (rounded) width/height. |
660 if (target_size.width() == src_rect.width() && | 652 if (target_size.width() == image.src_rect().width() && |
661 target_size.height() == src_rect.height()) { | 653 target_size.height() == image.src_rect().height()) { |
662 quality = std::min(quality, kLow_SkFilterQuality); | 654 quality = std::min(quality, kLow_SkFilterQuality); |
663 } | 655 } |
664 | 656 |
665 // Drop from high to medium if the image has perspective applied, the matrix | 657 // Drop from high to medium if the image has perspective applied, the matrix |
666 // we applied wasn't decomposable, or if the scaled image will be too large. | 658 // we applied wasn't decomposable, or if the scaled image will be too large. |
667 if (quality == kHigh_SkFilterQuality) { | 659 if (quality == kHigh_SkFilterQuality) { |
668 if (image.matrix_has_perspective() || !image.matrix_is_decomposable()) { | 660 if (image.matrix_has_perspective() || !image.matrix_is_decomposable()) { |
669 quality = kMedium_SkFilterQuality; | 661 quality = kMedium_SkFilterQuality; |
670 } else { | 662 } else { |
671 base::CheckedNumeric<size_t> size = 4u; | 663 base::CheckedNumeric<size_t> size = 4u; |
672 size *= target_size.width(); | 664 size *= target_size.width(); |
673 size *= target_size.height(); | 665 size *= target_size.height(); |
674 if (size.ValueOrDefault(std::numeric_limits<size_t>::max()) > | 666 if (size.ValueOrDefault(std::numeric_limits<size_t>::max()) > |
675 kMaxHighQualityImageSizeBytes) { | 667 kMaxHighQualityImageSizeBytes) { |
676 quality = kMedium_SkFilterQuality; | 668 quality = kMedium_SkFilterQuality; |
677 } | 669 } |
678 } | 670 } |
679 } | 671 } |
680 | 672 |
681 // Drop from medium to low if the matrix we applied wasn't decomposable or if | 673 // Drop from medium to low if the matrix we applied wasn't decomposable or if |
682 // we're enlarging the image in both dimensions. | 674 // we're enlarging the image in both dimensions. |
683 if (quality == kMedium_SkFilterQuality) { | 675 if (quality == kMedium_SkFilterQuality) { |
684 if (!image.matrix_is_decomposable() || | 676 if (!image.matrix_is_decomposable() || |
685 (scale.width() >= 1.f && scale.height() >= 1.f)) { | 677 (scale.width() >= 1.f && scale.height() >= 1.f)) { |
686 quality = kLow_SkFilterQuality; | 678 quality = kLow_SkFilterQuality; |
687 } | 679 } |
688 } | 680 } |
689 | 681 |
690 return ImageDecodeControllerKey(image.image()->uniqueID(), src_rect, | 682 return ImageDecodeControllerKey(image.image()->uniqueID(), |
| 683 gfx::SkIRectToRect(image.src_rect()), |
691 target_size, quality); | 684 target_size, quality); |
692 } | 685 } |
693 | 686 |
694 ImageDecodeControllerKey::ImageDecodeControllerKey( | 687 ImageDecodeControllerKey::ImageDecodeControllerKey( |
695 uint32_t image_id, | 688 uint32_t image_id, |
696 const gfx::Rect& src_rect, | 689 const gfx::Rect& src_rect, |
697 const gfx::Size& target_size, | 690 const gfx::Size& target_size, |
698 SkFilterQuality filter_quality) | 691 SkFilterQuality filter_quality) |
699 : image_id_(image_id), | 692 : image_id_(image_id), |
700 src_rect_(src_rect), | 693 src_rect_(src_rect), |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
763 | 756 |
764 void ImageDecodeController::MemoryBudget::ResetUsage() { | 757 void ImageDecodeController::MemoryBudget::ResetUsage() { |
765 current_usage_bytes_ = 0; | 758 current_usage_bytes_ = 0; |
766 } | 759 } |
767 | 760 |
768 size_t ImageDecodeController::MemoryBudget::GetCurrentUsageSafe() const { | 761 size_t ImageDecodeController::MemoryBudget::GetCurrentUsageSafe() const { |
769 return current_usage_bytes_.ValueOrDie(); | 762 return current_usage_bytes_.ValueOrDie(); |
770 } | 763 } |
771 | 764 |
772 } // namespace cc | 765 } // namespace cc |
OLD | NEW |