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

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

Issue 1691623002: Reland: cc: Imagedecodes: Clip the src_rect to the image rect. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase Created 4 years, 10 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 | « no previous file | cc/tiles/image_decode_controller_unittest.cc » ('j') | 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/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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | cc/tiles/image_decode_controller_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698