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

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: Updating comment to reflect change in code. 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
« no previous file with comments | « cc/tiles/software_image_decode_controller.h ('k') | no next file » | 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/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 352 matching lines...) Expand 10 before | Expand all | Expand 10 after
363 } 363 }
364 364
365 std::unique_ptr<SoftwareImageDecodeController::DecodedImage> 365 std::unique_ptr<SoftwareImageDecodeController::DecodedImage>
366 SoftwareImageDecodeController::DecodeImageInternal( 366 SoftwareImageDecodeController::DecodeImageInternal(
367 const ImageKey& key, 367 const ImageKey& key,
368 const DrawImage& draw_image) { 368 const DrawImage& draw_image) {
369 TRACE_EVENT1("disabled-by-default-cc.debug", 369 TRACE_EVENT1("disabled-by-default-cc.debug",
370 "SoftwareImageDecodeController::DecodeImageInternal", "key", 370 "SoftwareImageDecodeController::DecodeImageInternal", "key",
371 key.ToString()); 371 key.ToString());
372 const SkImage* image = draw_image.image(); 372 const SkImage* image = draw_image.image();
373 if (!image)
374 return nullptr;
373 375
374 // If we can use the original decode, then we don't need to do scaling. We can 376 switch (key.filter_quality()) {
375 // just read pixels into the final memory. 377 case kNone_SkFilterQuality:
376 if (key.can_use_original_decode()) { 378 case kLow_SkFilterQuality:
377 SkImageInfo decoded_info = 379 return GetOriginalImageDecode(key, *image);
378 CreateImageInfo(image->width(), image->height(), format_); 380 case kMedium_SkFilterQuality:
379 std::unique_ptr<base::DiscardableMemory> decoded_pixels; 381 NOTIMPLEMENTED();
380 { 382 return nullptr;
381 TRACE_EVENT0( 383 case kHigh_SkFilterQuality:
382 "disabled-by-default-cc.debug", 384 return GetScaledImageDecode(key, *image);
383 "SoftwareImageDecodeController::DecodeImageInternal - allocate " 385 default:
384 "decoded pixels"); 386 NOTREACHED();
385 decoded_pixels = 387 return nullptr;
386 base::DiscardableMemoryAllocator::GetInstance()
387 ->AllocateLockedDiscardableMemory(decoded_info.minRowBytes() *
388 decoded_info.height());
389 }
390 {
391 TRACE_EVENT0(
392 "disabled-by-default-cc.debug",
393 "SoftwareImageDecodeController::DecodeImageInternal - read pixels");
394 bool result = image->readPixels(decoded_info, decoded_pixels->data(),
395 decoded_info.minRowBytes(), 0, 0,
396 SkImage::kDisallow_CachingHint);
397
398 if (!result) {
399 decoded_pixels->Unlock();
400 return nullptr;
401 }
402 }
403
404 return base::WrapUnique(
405 new DecodedImage(decoded_info, std::move(decoded_pixels),
406 SkSize::Make(0, 0), next_tracing_id_.GetNext()));
407 } 388 }
408
409 // If we get here, that means we couldn't use the original sized decode for
410 // whatever reason. However, in all cases we do need an original decode to
411 // either do a scale or to extract a subrect from the image. So, what we can
412 // do is construct a key that would require a full sized decode, then get that
413 // decode via GetDecodedImageForDrawInternal(), use it, and unref it. This
414 // ensures that if the original sized decode is already available in any of
415 // the caches, we reuse that. We also ensure that all the proper locking takes
416 // place. If, on the other hand, the decode was not available,
417 // GetDecodedImageForDrawInternal() would decode the image, and unreffing it
418 // later ensures that we will store the discardable memory unlocked in the
419 // cache to be used by future requests.
420 gfx::Rect full_image_rect(image->width(), image->height());
421 DrawImage original_size_draw_image(image, gfx::RectToSkIRect(full_image_rect),
422 kNone_SkFilterQuality, SkMatrix::I());
423 ImageKey original_size_key =
424 ImageKey::FromDrawImage(original_size_draw_image);
425 // Sanity checks.
426 DCHECK(original_size_key.can_use_original_decode())
427 << original_size_key.ToString();
428 DCHECK(full_image_rect.size() == original_size_key.target_size());
429
430 auto decoded_draw_image = GetDecodedImageForDrawInternal(
431 original_size_key, original_size_draw_image);
432 if (!decoded_draw_image.image()) {
433 DrawWithImageFinished(original_size_draw_image, decoded_draw_image);
434 return nullptr;
435 }
436
437 SkPixmap decoded_pixmap;
438 bool result = decoded_draw_image.image()->peekPixels(&decoded_pixmap);
439 DCHECK(result) << key.ToString();
440 if (key.src_rect() != full_image_rect) {
441 result = decoded_pixmap.extractSubset(&decoded_pixmap,
442 gfx::RectToSkIRect(key.src_rect()));
443 DCHECK(result) << key.ToString();
444 }
445
446 // Now we have a decoded_pixmap which represents the src_rect at the
447 // original scale. All we need to do is scale it.
448 DCHECK(!key.target_size().IsEmpty());
449 SkImageInfo scaled_info = CreateImageInfo(
450 key.target_size().width(), key.target_size().height(), format_);
451 std::unique_ptr<base::DiscardableMemory> scaled_pixels;
452 {
453 TRACE_EVENT0(
454 "disabled-by-default-cc.debug",
455 "SoftwareImageDecodeController::DecodeImageInternal - allocate "
456 "scaled pixels");
457 scaled_pixels = base::DiscardableMemoryAllocator::GetInstance()
458 ->AllocateLockedDiscardableMemory(
459 scaled_info.minRowBytes() * scaled_info.height());
460 }
461 SkPixmap scaled_pixmap(scaled_info, scaled_pixels->data(),
462 scaled_info.minRowBytes());
463 // TODO(vmpstr): Start handling more than just high filter quality.
464 DCHECK_EQ(kHigh_SkFilterQuality, key.filter_quality());
465 {
466 TRACE_EVENT0(
467 "disabled-by-default-cc.debug",
468 "SoftwareImageDecodeController::DecodeImageInternal - scale pixels");
469 bool result =
470 decoded_pixmap.scalePixels(scaled_pixmap, key.filter_quality());
471 DCHECK(result) << key.ToString();
472 }
473
474 // Release the original sized decode. Any other intermediate result to release
475 // would be the subrect memory. However, that's in a unique_ptr and will be
476 // deleted automatically when we return.
477 DrawWithImageFinished(original_size_draw_image, decoded_draw_image);
478
479 return base::WrapUnique(
480 new DecodedImage(scaled_info, std::move(scaled_pixels),
481 SkSize::Make(-key.src_rect().x(), -key.src_rect().y()),
482 next_tracing_id_.GetNext()));
483 } 389 }
484 390
485 DecodedDrawImage SoftwareImageDecodeController::GetDecodedImageForDraw( 391 DecodedDrawImage SoftwareImageDecodeController::GetDecodedImageForDraw(
486 const DrawImage& draw_image) { 392 const DrawImage& draw_image) {
487 ImageKey key = ImageKey::FromDrawImage(draw_image); 393 ImageKey key = ImageKey::FromDrawImage(draw_image);
488 TRACE_EVENT1("disabled-by-default-cc.debug", 394 TRACE_EVENT1("disabled-by-default-cc.debug",
489 "SoftwareImageDecodeController::GetDecodedImageForDraw", "key", 395 "SoftwareImageDecodeController::GetDecodedImageForDraw", "key",
490 key.ToString()); 396 key.ToString());
491 // If the target size is empty, we can skip this image draw. 397 // If the target size is empty, we can skip this image draw.
492 if (key.target_size().IsEmpty()) 398 if (key.target_size().IsEmpty())
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
584 DCHECK(decoded_image->is_locked()); 490 DCHECK(decoded_image->is_locked());
585 RefAtRasterImage(key); 491 RefAtRasterImage(key);
586 SanityCheckState(__LINE__, true); 492 SanityCheckState(__LINE__, true);
587 auto decoded_draw_image = 493 auto decoded_draw_image =
588 DecodedDrawImage(decoded_image->image(), decoded_image->src_rect_offset(), 494 DecodedDrawImage(decoded_image->image(), decoded_image->src_rect_offset(),
589 GetScaleAdjustment(key), GetDecodedFilterQuality(key)); 495 GetScaleAdjustment(key), GetDecodedFilterQuality(key));
590 decoded_draw_image.set_at_raster_decode(true); 496 decoded_draw_image.set_at_raster_decode(true);
591 return decoded_draw_image; 497 return decoded_draw_image;
592 } 498 }
593 499
500 std::unique_ptr<SoftwareImageDecodeController::DecodedImage>
501 SoftwareImageDecodeController::GetOriginalImageDecode(const ImageKey& key,
502 const SkImage& image) {
503 SkImageInfo decoded_info =
504 CreateImageInfo(image.width(), image.height(), format_);
505 std::unique_ptr<base::DiscardableMemory> decoded_pixels;
506 {
507 TRACE_EVENT0("disabled-by-default-cc.debug",
508 "SoftwareImageDecodeController::GetOriginalImageDecode - "
509 "allocate decoded pixels");
510 decoded_pixels =
511 base::DiscardableMemoryAllocator::GetInstance()
512 ->AllocateLockedDiscardableMemory(decoded_info.minRowBytes() *
513 decoded_info.height());
514 }
515 {
516 TRACE_EVENT0("disabled-by-default-cc.debug",
517 "SoftwareImageDecodeController::GetOriginalImageDecode - "
518 "read pixels");
519 bool result = image.readPixels(decoded_info, decoded_pixels->data(),
520 decoded_info.minRowBytes(), 0, 0,
521 SkImage::kDisallow_CachingHint);
522
523 if (!result) {
524 decoded_pixels->Unlock();
525 return nullptr;
526 }
527 }
528 return base::WrapUnique(
529 new DecodedImage(decoded_info, std::move(decoded_pixels),
530 SkSize::Make(0, 0), next_tracing_id_.GetNext()));
531 }
532
533 std::unique_ptr<SoftwareImageDecodeController::DecodedImage>
534 SoftwareImageDecodeController::GetScaledImageDecode(const ImageKey& key,
535 const SkImage& image) {
536 // Construct a key to use in GetDecodedImageForDrawInternal().
537 // This allows us to reuse an image in any cache if available.
538 gfx::Rect full_image_rect(image.width(), image.height());
539 DrawImage original_size_draw_image(&image,
540 gfx::RectToSkIRect(full_image_rect),
541 kNone_SkFilterQuality, SkMatrix::I());
542 ImageKey original_size_key =
543 ImageKey::FromDrawImage(original_size_draw_image);
544 // Sanity checks.
545 DCHECK(original_size_key.can_use_original_decode())
546 << original_size_key.ToString();
547 DCHECK(full_image_rect.size() == original_size_key.target_size());
548
549 auto decoded_draw_image = GetDecodedImageForDrawInternal(
550 original_size_key, original_size_draw_image);
551 if (!decoded_draw_image.image()) {
552 DrawWithImageFinished(original_size_draw_image, decoded_draw_image);
553 return nullptr;
554 }
555
556 SkPixmap decoded_pixmap;
557 bool result = decoded_draw_image.image()->peekPixels(&decoded_pixmap);
558 DCHECK(result) << key.ToString();
559 if (key.src_rect() != full_image_rect) {
560 result = decoded_pixmap.extractSubset(&decoded_pixmap,
561 gfx::RectToSkIRect(key.src_rect()));
562 DCHECK(result) << key.ToString();
563 }
564
565 DCHECK(!key.target_size().IsEmpty());
566 SkImageInfo scaled_info = CreateImageInfo(
567 key.target_size().width(), key.target_size().height(), format_);
568 std::unique_ptr<base::DiscardableMemory> scaled_pixels;
569 {
570 TRACE_EVENT0(
571 "disabled-by-default-cc.debug",
572 "SoftwareImageDecodeController::ScaleImage - allocate scaled pixels");
573 scaled_pixels = base::DiscardableMemoryAllocator::GetInstance()
574 ->AllocateLockedDiscardableMemory(
575 scaled_info.minRowBytes() * scaled_info.height());
576 }
577 SkPixmap scaled_pixmap(scaled_info, scaled_pixels->data(),
578 scaled_info.minRowBytes());
579 // TODO(vmpstr): Start handling more than just high filter quality.
580 DCHECK_EQ(kHigh_SkFilterQuality, key.filter_quality());
581 {
582 TRACE_EVENT0("disabled-by-default-cc.debug",
583 "SoftwareImageDecodeController::ScaleImage - scale pixels");
584 bool result =
585 decoded_pixmap.scalePixels(scaled_pixmap, key.filter_quality());
586 DCHECK(result) << key.ToString();
587 }
588
589 // Release the original sized decode. Any other intermediate result to release
590 // would be the subrect memory. However, that's in a scoped_ptr and will be
591 // deleted automatically when we return.
592 DrawWithImageFinished(original_size_draw_image, decoded_draw_image);
593
594 return base::WrapUnique(
595 new DecodedImage(scaled_info, std::move(scaled_pixels),
596 SkSize::Make(-key.src_rect().x(), -key.src_rect().y()),
597 next_tracing_id_.GetNext()));
598 }
599
594 void SoftwareImageDecodeController::DrawWithImageFinished( 600 void SoftwareImageDecodeController::DrawWithImageFinished(
595 const DrawImage& image, 601 const DrawImage& image,
596 const DecodedDrawImage& decoded_image) { 602 const DecodedDrawImage& decoded_image) {
597 TRACE_EVENT1("disabled-by-default-cc.debug", 603 TRACE_EVENT1("disabled-by-default-cc.debug",
598 "SoftwareImageDecodeController::DrawWithImageFinished", "key", 604 "SoftwareImageDecodeController::DrawWithImageFinished", "key",
599 ImageKey::FromDrawImage(image).ToString()); 605 ImageKey::FromDrawImage(image).ToString());
600 ImageKey key = ImageKey::FromDrawImage(image); 606 ImageKey key = ImageKey::FromDrawImage(image);
601 if (!decoded_image.image() || !CanHandleImage(key)) 607 if (!decoded_image.image() || !CanHandleImage(key))
602 return; 608 return;
603 609
(...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after
926 void SoftwareImageDecodeController::MemoryBudget::ResetUsage() { 932 void SoftwareImageDecodeController::MemoryBudget::ResetUsage() {
927 current_usage_bytes_ = 0; 933 current_usage_bytes_ = 0;
928 } 934 }
929 935
930 size_t SoftwareImageDecodeController::MemoryBudget::GetCurrentUsageSafe() 936 size_t SoftwareImageDecodeController::MemoryBudget::GetCurrentUsageSafe()
931 const { 937 const {
932 return current_usage_bytes_.ValueOrDie(); 938 return current_usage_bytes_.ValueOrDie();
933 } 939 }
934 940
935 } // namespace cc 941 } // namespace cc
OLDNEW
« no previous file with comments | « 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