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

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

Issue 1801933004: Refactor SoftwareImageDecodeController (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixing typo in variable name in constructor declaration. Created 4 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
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_controller.h" 5 #include "cc/tiles/software_image_decode_controller.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 8
9 #include <functional> 9 #include <functional>
10 10
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after
361 if (decoded_images_ref_counts_.find(key) == 361 if (decoded_images_ref_counts_.find(key) ==
362 decoded_images_ref_counts_.end()) { 362 decoded_images_ref_counts_.end()) {
363 decoded_image->Unlock(); 363 decoded_image->Unlock();
364 } 364 }
365 365
366 decoded_images_.Put(key, std::move(decoded_image)); 366 decoded_images_.Put(key, std::move(decoded_image));
367 SanityCheckState(__LINE__, true); 367 SanityCheckState(__LINE__, true);
368 } 368 }
369 369
370 scoped_ptr<SoftwareImageDecodeController::DecodedImage> 370 scoped_ptr<SoftwareImageDecodeController::DecodedImage>
371 SoftwareImageDecodeController::DecodeImageMediumQuality(const ImageKey& key,
372 const SkImage& image) {
373 NOTIMPLEMENTED();
374 return nullptr;
375 }
376
377 scoped_ptr<SoftwareImageDecodeController::DecodedImage>
378 SoftwareImageDecodeController::DecodeImageHighQuality(const ImageKey& key,
379 const SkImage& image) {
380 // If we get here, that means we couldn't use the original sized decode for
381 // whatever reason. However, in all cases we do need an original decode to
382 // either do a scale or to extract a subrect from the image.
383 auto decoded_image_result = DecodeImageOrUseCache(key, image);
384 if (!decoded_image_result.decoded_pixmap_.addr())
385 return nullptr;
386
387 // Now we have a decoded_pixmap which represents the src_rect at the
388 // original scale. All we need to do is scale it.
389 return ScaleImage(key, decoded_image_result);
390 }
391
392 scoped_ptr<SoftwareImageDecodeController::DecodedImage>
371 SoftwareImageDecodeController::DecodeImageInternal( 393 SoftwareImageDecodeController::DecodeImageInternal(
372 const ImageKey& key, 394 const ImageKey& key,
373 const DrawImage& draw_image) { 395 const DrawImage& draw_image) {
374 TRACE_EVENT1("disabled-by-default-cc.debug", 396 TRACE_EVENT1("disabled-by-default-cc.debug",
375 "SoftwareImageDecodeController::DecodeImageInternal", "key", 397 "SoftwareImageDecodeController::DecodeImageInternal", "key",
376 key.ToString()); 398 key.ToString());
377 const SkImage* image = draw_image.image(); 399 const SkImage* image = draw_image.image();
378 400 if (!image) {
379 // If we can use the original decode, then we don't need to do scaling. We can
380 // just read pixels into the final memory.
381 if (key.can_use_original_decode()) {
382 SkImageInfo decoded_info =
383 CreateImageInfo(image->width(), image->height(), format_);
384 scoped_ptr<base::DiscardableMemory> decoded_pixels;
385 {
386 TRACE_EVENT0(
387 "disabled-by-default-cc.debug",
388 "SoftwareImageDecodeController::DecodeImageInternal - allocate "
389 "decoded pixels");
390 decoded_pixels =
391 base::DiscardableMemoryAllocator::GetInstance()
392 ->AllocateLockedDiscardableMemory(decoded_info.minRowBytes() *
393 decoded_info.height());
394 }
395 {
396 TRACE_EVENT0(
397 "disabled-by-default-cc.debug",
398 "SoftwareImageDecodeController::DecodeImageInternal - read pixels");
399 bool result = image->readPixels(decoded_info, decoded_pixels->data(),
400 decoded_info.minRowBytes(), 0, 0,
401 SkImage::kDisallow_CachingHint);
402
403 if (!result) {
404 decoded_pixels->Unlock();
405 return nullptr;
406 }
407 }
408
409 return make_scoped_ptr(new DecodedImage(
410 decoded_info, std::move(decoded_pixels), SkSize::Make(0, 0)));
411 }
412
413 // If we get here, that means we couldn't use the original sized decode for
414 // whatever reason. However, in all cases we do need an original decode to
415 // either do a scale or to extract a subrect from the image. So, what we can
416 // do is construct a key that would require a full sized decode, then get that
417 // decode via GetDecodedImageForDrawInternal(), use it, and unref it. This
418 // ensures that if the original sized decode is already available in any of
419 // the caches, we reuse that. We also ensure that all the proper locking takes
420 // place. If, on the other hand, the decode was not available,
421 // GetDecodedImageForDrawInternal() would decode the image, and unreffing it
422 // later ensures that we will store the discardable memory unlocked in the
423 // cache to be used by future requests.
424 gfx::Rect full_image_rect(image->width(), image->height());
425 DrawImage original_size_draw_image(image, gfx::RectToSkIRect(full_image_rect),
426 kNone_SkFilterQuality, SkMatrix::I());
427 ImageKey original_size_key =
428 ImageKey::FromDrawImage(original_size_draw_image);
429 // Sanity checks.
430 DCHECK(original_size_key.can_use_original_decode());
431 DCHECK(full_image_rect.size() == original_size_key.target_size());
432
433 auto decoded_draw_image = GetDecodedImageForDrawInternal(
434 original_size_key, original_size_draw_image);
435 if (!decoded_draw_image.image()) {
436 DrawWithImageFinished(original_size_draw_image, decoded_draw_image);
437 return nullptr; 401 return nullptr;
438 } 402 }
439 403
440 SkPixmap decoded_pixmap; 404 switch (key.filter_quality()) {
441 bool result = decoded_draw_image.image()->peekPixels(&decoded_pixmap); 405 case kNone_SkFilterQuality:
442 DCHECK(result); 406 // fall through
vmpstr 2016/03/31 19:54:32 I don't think you really need this comment. That i
cblume 2016/04/09 06:48:54 Done.
443 if (key.src_rect() != full_image_rect) { 407 case kLow_SkFilterQuality:
444 result = decoded_pixmap.extractSubset(&decoded_pixmap, 408 return GetOriginalImageDecode(key, *image);
445 gfx::RectToSkIRect(key.src_rect())); 409 case kMedium_SkFilterQuality:
446 DCHECK(result); 410 return DecodeImageMediumQuality(key, *image);
411 case kHigh_SkFilterQuality:
412 return DecodeImageHighQuality(key, *image);
413 default:
414 NOTREACHED();
415 return nullptr;
447 } 416 }
448
449 // Now we have a decoded_pixmap which represents the src_rect at the
450 // original scale. All we need to do is scale it.
451 DCHECK(!key.target_size().IsEmpty());
452 SkImageInfo scaled_info = CreateImageInfo(
453 key.target_size().width(), key.target_size().height(), format_);
454 scoped_ptr<base::DiscardableMemory> scaled_pixels;
455 {
456 TRACE_EVENT0(
457 "disabled-by-default-cc.debug",
458 "SoftwareImageDecodeController::DecodeImageInternal - allocate "
459 "scaled pixels");
460 scaled_pixels = base::DiscardableMemoryAllocator::GetInstance()
461 ->AllocateLockedDiscardableMemory(
462 scaled_info.minRowBytes() * scaled_info.height());
463 }
464 SkPixmap scaled_pixmap(scaled_info, scaled_pixels->data(),
465 scaled_info.minRowBytes());
466 // TODO(vmpstr): Start handling more than just high filter quality.
467 DCHECK_EQ(kHigh_SkFilterQuality, key.filter_quality());
468 {
469 TRACE_EVENT0(
470 "disabled-by-default-cc.debug",
471 "SoftwareImageDecodeController::DecodeImageInternal - scale pixels");
472 bool result =
473 decoded_pixmap.scalePixels(scaled_pixmap, key.filter_quality());
474 DCHECK(result);
475 }
476
477 // Release the original sized decode. Any other intermediate result to release
478 // would be the subrect memory. However, that's in a scoped_ptr and will be
479 // deleted automatically when we return.
480 DrawWithImageFinished(original_size_draw_image, decoded_draw_image);
481
482 return make_scoped_ptr(
483 new DecodedImage(scaled_info, std::move(scaled_pixels),
484 SkSize::Make(-key.src_rect().x(), -key.src_rect().y())));
485 } 417 }
486 418
487 DecodedDrawImage SoftwareImageDecodeController::GetDecodedImageForDraw( 419 DecodedDrawImage SoftwareImageDecodeController::GetDecodedImageForDraw(
488 const DrawImage& draw_image) { 420 const DrawImage& draw_image) {
489 ImageKey key = ImageKey::FromDrawImage(draw_image); 421 ImageKey key = ImageKey::FromDrawImage(draw_image);
490 TRACE_EVENT1("disabled-by-default-cc.debug", 422 TRACE_EVENT1("disabled-by-default-cc.debug",
491 "SoftwareImageDecodeController::GetDecodedImageForDraw", "key", 423 "SoftwareImageDecodeController::GetDecodedImageForDraw", "key",
492 key.ToString()); 424 key.ToString());
493 // If the target size is empty, we can skip this image draw. 425 // If the target size is empty, we can skip this image draw.
494 if (key.target_size().IsEmpty()) 426 if (key.target_size().IsEmpty())
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
546 // thread encountering this image (that might not be true, since other threads 478 // thread encountering this image (that might not be true, since other threads
547 // might be decoding it already). This means that we need to decode the image 479 // might be decoding it already). This means that we need to decode the image
548 // assuming we can't lock the one we found in the cache. 480 // assuming we can't lock the one we found in the cache.
549 bool check_at_raster_cache = false; 481 bool check_at_raster_cache = false;
550 if (!decoded_image || !decoded_image->Lock()) { 482 if (!decoded_image || !decoded_image->Lock()) {
551 // Note that we have to release the lock, since this lock is also accessed 483 // Note that we have to release the lock, since this lock is also accessed
552 // on the compositor thread. This means holding on to the lock might stall 484 // on the compositor thread. This means holding on to the lock might stall
553 // the compositor thread for the duration of the decode! 485 // the compositor thread for the duration of the decode!
554 base::AutoUnlock unlock(lock_); 486 base::AutoUnlock unlock(lock_);
555 scoped_decoded_image = DecodeImageInternal(key, draw_image); 487 scoped_decoded_image = DecodeImageInternal(key, draw_image);
488
vmpstr 2016/03/31 19:54:32 unnecessary change
cblume 2016/04/09 06:48:54 Done.
556 decoded_image = scoped_decoded_image.get(); 489 decoded_image = scoped_decoded_image.get();
557 490
558 // Skip the image if we couldn't decode it. 491 // Skip the image if we couldn't decode it.
559 if (!decoded_image) 492 if (!decoded_image)
560 return DecodedDrawImage(nullptr, kNone_SkFilterQuality); 493 return DecodedDrawImage(nullptr, kNone_SkFilterQuality);
561 check_at_raster_cache = true; 494 check_at_raster_cache = true;
562 } 495 }
563 496
564 DCHECK(decoded_image == scoped_decoded_image.get()); 497 DCHECK(decoded_image == scoped_decoded_image.get());
565 498
(...skipping 20 matching lines...) Expand all
586 DCHECK(decoded_image->is_locked()); 519 DCHECK(decoded_image->is_locked());
587 RefAtRasterImage(key); 520 RefAtRasterImage(key);
588 SanityCheckState(__LINE__, true); 521 SanityCheckState(__LINE__, true);
589 auto decoded_draw_image = 522 auto decoded_draw_image =
590 DecodedDrawImage(decoded_image->image(), decoded_image->src_rect_offset(), 523 DecodedDrawImage(decoded_image->image(), decoded_image->src_rect_offset(),
591 GetScaleAdjustment(key), GetDecodedFilterQuality(key)); 524 GetScaleAdjustment(key), GetDecodedFilterQuality(key));
592 decoded_draw_image.set_at_raster_decode(true); 525 decoded_draw_image.set_at_raster_decode(true);
593 return decoded_draw_image; 526 return decoded_draw_image;
594 } 527 }
595 528
529 SoftwareImageDecodeController::DecodedImageResult::DecodedImageResult(
vmpstr 2016/03/31 19:54:32 Move this function to be after all other SoftwareI
cblume 2016/04/09 06:48:54 Done.
530 SkPixmap decoded_pixmap,
531 DrawImage original_size_draw_image,
532 DecodedDrawImage decoded_draw_image)
533 : decoded_pixmap_(decoded_pixmap),
534 original_size_draw_image_(original_size_draw_image),
535 decoded_draw_image_(decoded_draw_image) {}
536
537 scoped_ptr<SoftwareImageDecodeController::DecodedImage>
538 SoftwareImageDecodeController::GetOriginalImageDecode(const ImageKey& key,
539 const SkImage& image) {
540 TRACE_EVENT1("disabled-by-default-cc.debug",
541 "SoftwareImageDecodeController::GetOriginalImageDecode", "key",
542 key.ToString());
543 DCHECK(key.can_use_original_decode());
544 SkImageInfo decoded_info =
545 CreateImageInfo(image.width(), image.height(), format_);
546 scoped_ptr<base::DiscardableMemory> decoded_pixels;
547 {
548 TRACE_EVENT0("disabled-by-default-cc.debug",
549 "SoftwareImageDecodeController::GetOriginalImageDecode - "
550 "allocate decoded pixels");
551 decoded_pixels =
552 base::DiscardableMemoryAllocator::GetInstance()
553 ->AllocateLockedDiscardableMemory(decoded_info.minRowBytes() *
554 decoded_info.height());
555 }
556 {
557 TRACE_EVENT0("disabled-by-default-cc.debug",
558 "SoftwareImageDecodeController::GetOriginalImageDecode - "
559 "read pixels");
560 bool result = image.readPixels(decoded_info, decoded_pixels->data(),
561 decoded_info.minRowBytes(), 0, 0,
562 SkImage::kDisallow_CachingHint);
563
564 if (!result) {
565 decoded_pixels->Unlock();
566 return nullptr;
567 }
568 }
569
570 return make_scoped_ptr(new DecodedImage(
571 decoded_info, std::move(decoded_pixels), SkSize::Make(0, 0)));
572 }
573
574 SoftwareImageDecodeController::DecodedImageResult
575 SoftwareImageDecodeController::DecodeImageOrUseCache(const ImageKey& key,
vmpstr 2016/03/31 19:54:32 I'm still a bit confused about DecodeImageOrUseCac
cblume 2016/04/09 06:48:54 DecodeImageInternal's old body was split into 3 fu
576 const SkImage& image) {
577 // Construct a key to use in GetDecodedImageForDrawInternal().
578 // This allows us to reuse an image in any cache if available.
579 gfx::Rect full_image_rect(image.width(), image.height());
580 DrawImage original_size_draw_image(&image,
581 gfx::RectToSkIRect(full_image_rect),
582 kNone_SkFilterQuality, SkMatrix::I());
583 ImageKey original_size_key =
584 ImageKey::FromDrawImage(original_size_draw_image);
585 // Sanity checks.
586 DCHECK(original_size_key.can_use_original_decode());
587 DCHECK(full_image_rect.size() == original_size_key.target_size());
588
589 auto decoded_draw_image = GetDecodedImageForDrawInternal(
590 original_size_key, original_size_draw_image);
591 if (!decoded_draw_image.image()) {
592 DrawWithImageFinished(original_size_draw_image, decoded_draw_image);
593 return DecodedImageResult(SkPixmap(), DrawImage(),
594 DecodedDrawImage(nullptr, kNone_SkFilterQuality));
595 }
596
597 SkPixmap decoded_pixmap;
598 bool result = decoded_draw_image.image()->peekPixels(&decoded_pixmap);
599 DCHECK(result);
600 if (key.src_rect() != full_image_rect) {
601 result = decoded_pixmap.extractSubset(&decoded_pixmap,
602 gfx::RectToSkIRect(key.src_rect()));
603 DCHECK(result);
604 }
605
606 return DecodedImageResult(decoded_pixmap, original_size_draw_image,
607 decoded_draw_image);
608 }
609
610 scoped_ptr<SoftwareImageDecodeController::DecodedImage>
611 SoftwareImageDecodeController::ScaleImage(
612 const ImageKey& key,
613 const DecodedImageResult& decoded_image_result) {
614 DCHECK(!key.target_size().IsEmpty());
615 SkImageInfo scaled_info = CreateImageInfo(
616 key.target_size().width(), key.target_size().height(), format_);
617 scoped_ptr<base::DiscardableMemory> scaled_pixels;
618 {
619 TRACE_EVENT0(
620 "disabled-by-default-cc.debug",
621 "SoftwareImageDecodeController::ScaleImage - allocate scaled pixels");
622 scaled_pixels = base::DiscardableMemoryAllocator::GetInstance()
623 ->AllocateLockedDiscardableMemory(
624 scaled_info.minRowBytes() * scaled_info.height());
625 }
626 SkPixmap scaled_pixmap(scaled_info, scaled_pixels->data(),
627 scaled_info.minRowBytes());
628 // TODO(vmpstr): Start handling more than just high filter quality.
629 DCHECK_EQ(kHigh_SkFilterQuality, key.filter_quality());
630 {
631 TRACE_EVENT0("disabled-by-default-cc.debug",
632 "SoftwareImageDecodeController::ScaleImage - scale pixels");
633 bool result = decoded_image_result.decoded_pixmap_.scalePixels(
634 scaled_pixmap, key.filter_quality());
635 DCHECK(result);
636 }
637
638 // Release the original sized decode. Any other intermediate result to release
639 // would be the subrect memory. However, that's in a scoped_ptr and will be
640 // deleted automatically when we return.
641 DrawWithImageFinished(decoded_image_result.original_size_draw_image_,
642 decoded_image_result.decoded_draw_image_);
643
644 return make_scoped_ptr(
645 new DecodedImage(scaled_info, std::move(scaled_pixels),
646 SkSize::Make(-key.src_rect().x(), -key.src_rect().y())));
647 }
648
596 void SoftwareImageDecodeController::DrawWithImageFinished( 649 void SoftwareImageDecodeController::DrawWithImageFinished(
597 const DrawImage& image, 650 const DrawImage& image,
598 const DecodedDrawImage& decoded_image) { 651 const DecodedDrawImage& decoded_image) {
599 TRACE_EVENT1("disabled-by-default-cc.debug", 652 TRACE_EVENT1("disabled-by-default-cc.debug",
600 "SoftwareImageDecodeController::DrawWithImageFinished", "key", 653 "SoftwareImageDecodeController::DrawWithImageFinished", "key",
601 ImageKey::FromDrawImage(image).ToString()); 654 ImageKey::FromDrawImage(image).ToString());
602 ImageKey key = ImageKey::FromDrawImage(image); 655 ImageKey key = ImageKey::FromDrawImage(image);
603 if (!decoded_image.image() || !CanHandleImage(key)) 656 if (!decoded_image.image() || !CanHandleImage(key))
604 return; 657 return;
605 658
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after
890 void SoftwareImageDecodeController::MemoryBudget::ResetUsage() { 943 void SoftwareImageDecodeController::MemoryBudget::ResetUsage() {
891 current_usage_bytes_ = 0; 944 current_usage_bytes_ = 0;
892 } 945 }
893 946
894 size_t SoftwareImageDecodeController::MemoryBudget::GetCurrentUsageSafe() 947 size_t SoftwareImageDecodeController::MemoryBudget::GetCurrentUsageSafe()
895 const { 948 const {
896 return current_usage_bytes_.ValueOrDie(); 949 return current_usage_bytes_.ValueOrDie();
897 } 950 }
898 951
899 } // namespace cc 952 } // namespace cc
OLDNEW
« cc/tiles/software_image_decode_controller.h ('K') | « cc/tiles/software_image_decode_controller.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698