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 | |
377 // If the target size is empty, we can skip this image draw. | 374 // If the target size is empty, we can skip this image draw. |
378 if (key.target_size().IsEmpty()) | 375 if (key.target_size().IsEmpty()) |
379 return DecodedDrawImage(nullptr, kNone_SkFilterQuality); | 376 return DecodedDrawImage(nullptr, kNone_SkFilterQuality); |
380 | 377 |
| 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 |
642 gfx::Size target_size( | 650 gfx::Size target_size( |
643 SkScalarRoundToInt(std::abs(image.src_rect().width() * scale.width())), | 651 SkScalarRoundToInt(std::abs(src_rect.width() * scale.width())), |
644 SkScalarRoundToInt(std::abs(image.src_rect().height() * scale.height()))); | 652 SkScalarRoundToInt(std::abs(src_rect.height() * scale.height()))); |
645 | 653 |
646 // Start with the quality that was requested. | 654 // Start with the quality that was requested. |
647 SkFilterQuality quality = image.filter_quality(); | 655 SkFilterQuality quality = image.filter_quality(); |
648 | 656 |
649 // If we're not going to do a scale, we can use low filter quality. Note that | 657 // If we're not going to do a scale, we can use low filter quality. Note that |
650 // checking if the sizes are the same is better than checking if scale is 1.f, | 658 // checking if the sizes are the same is better than checking if scale is 1.f, |
651 // because even non-1 scale can result in the same (rounded) width/height. | 659 // because even non-1 scale can result in the same (rounded) width/height. |
652 if (target_size.width() == image.src_rect().width() && | 660 if (target_size.width() == src_rect.width() && |
653 target_size.height() == image.src_rect().height()) { | 661 target_size.height() == src_rect.height()) { |
654 quality = std::min(quality, kLow_SkFilterQuality); | 662 quality = std::min(quality, kLow_SkFilterQuality); |
655 } | 663 } |
656 | 664 |
657 // Drop from high to medium if the image has perspective applied, the matrix | 665 // Drop from high to medium if the image has perspective applied, the matrix |
658 // we applied wasn't decomposable, or if the scaled image will be too large. | 666 // we applied wasn't decomposable, or if the scaled image will be too large. |
659 if (quality == kHigh_SkFilterQuality) { | 667 if (quality == kHigh_SkFilterQuality) { |
660 if (image.matrix_has_perspective() || !image.matrix_is_decomposable()) { | 668 if (image.matrix_has_perspective() || !image.matrix_is_decomposable()) { |
661 quality = kMedium_SkFilterQuality; | 669 quality = kMedium_SkFilterQuality; |
662 } else { | 670 } else { |
663 base::CheckedNumeric<size_t> size = 4u; | 671 base::CheckedNumeric<size_t> size = 4u; |
664 size *= target_size.width(); | 672 size *= target_size.width(); |
665 size *= target_size.height(); | 673 size *= target_size.height(); |
666 if (size.ValueOrDefault(std::numeric_limits<size_t>::max()) > | 674 if (size.ValueOrDefault(std::numeric_limits<size_t>::max()) > |
667 kMaxHighQualityImageSizeBytes) { | 675 kMaxHighQualityImageSizeBytes) { |
668 quality = kMedium_SkFilterQuality; | 676 quality = kMedium_SkFilterQuality; |
669 } | 677 } |
670 } | 678 } |
671 } | 679 } |
672 | 680 |
673 // Drop from medium to low if the matrix we applied wasn't decomposable or if | 681 // Drop from medium to low if the matrix we applied wasn't decomposable or if |
674 // we're enlarging the image in both dimensions. | 682 // we're enlarging the image in both dimensions. |
675 if (quality == kMedium_SkFilterQuality) { | 683 if (quality == kMedium_SkFilterQuality) { |
676 if (!image.matrix_is_decomposable() || | 684 if (!image.matrix_is_decomposable() || |
677 (scale.width() >= 1.f && scale.height() >= 1.f)) { | 685 (scale.width() >= 1.f && scale.height() >= 1.f)) { |
678 quality = kLow_SkFilterQuality; | 686 quality = kLow_SkFilterQuality; |
679 } | 687 } |
680 } | 688 } |
681 | 689 |
682 return ImageDecodeControllerKey(image.image()->uniqueID(), | 690 return ImageDecodeControllerKey(image.image()->uniqueID(), src_rect, |
683 gfx::SkIRectToRect(image.src_rect()), | |
684 target_size, quality); | 691 target_size, quality); |
685 } | 692 } |
686 | 693 |
687 ImageDecodeControllerKey::ImageDecodeControllerKey( | 694 ImageDecodeControllerKey::ImageDecodeControllerKey( |
688 uint32_t image_id, | 695 uint32_t image_id, |
689 const gfx::Rect& src_rect, | 696 const gfx::Rect& src_rect, |
690 const gfx::Size& target_size, | 697 const gfx::Size& target_size, |
691 SkFilterQuality filter_quality) | 698 SkFilterQuality filter_quality) |
692 : image_id_(image_id), | 699 : image_id_(image_id), |
693 src_rect_(src_rect), | 700 src_rect_(src_rect), |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
756 | 763 |
757 void ImageDecodeController::MemoryBudget::ResetUsage() { | 764 void ImageDecodeController::MemoryBudget::ResetUsage() { |
758 current_usage_bytes_ = 0; | 765 current_usage_bytes_ = 0; |
759 } | 766 } |
760 | 767 |
761 size_t ImageDecodeController::MemoryBudget::GetCurrentUsageSafe() const { | 768 size_t ImageDecodeController::MemoryBudget::GetCurrentUsageSafe() const { |
762 return current_usage_bytes_.ValueOrDie(); | 769 return current_usage_bytes_.ValueOrDie(); |
763 } | 770 } |
764 | 771 |
765 } // namespace cc | 772 } // namespace cc |
OLD | NEW |