Chromium Code Reviews| 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/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 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 100 key.target_size().width() / static_cast<float>(key.src_rect().width()); | 100 key.target_size().width() / static_cast<float>(key.src_rect().width()); |
| 101 float y_scale = | 101 float y_scale = |
| 102 key.target_size().height() / static_cast<float>(key.src_rect().height()); | 102 key.target_size().height() / static_cast<float>(key.src_rect().height()); |
| 103 return SkSize::Make(x_scale, y_scale); | 103 return SkSize::Make(x_scale, y_scale); |
| 104 } | 104 } |
| 105 | 105 |
| 106 SkFilterQuality GetDecodedFilterQuality(const ImageDecodeControllerKey& key) { | 106 SkFilterQuality GetDecodedFilterQuality(const ImageDecodeControllerKey& key) { |
| 107 return std::min(key.filter_quality(), kLow_SkFilterQuality); | 107 return std::min(key.filter_quality(), kLow_SkFilterQuality); |
| 108 } | 108 } |
| 109 | 109 |
| 110 SkColorType SkColorTypeForDecoding(ResourceFormat format) { | |
|
vmpstr
2016/03/21 20:53:40
I think you kind of lost this patch in the merge?
cblume
2016/03/21 23:01:03
Whoops. Fixed.
| |
| 111 // Use kN32_SkColorType if there is no corresponding SkColorType. | |
| 112 switch (format) { | |
| 113 case RGBA_4444: | |
| 114 return kARGB_4444_SkColorType; | |
| 115 case RGBA_8888: | |
| 116 case BGRA_8888: | |
| 117 return kN32_SkColorType; | |
| 118 case ALPHA_8: | |
| 119 return kAlpha_8_SkColorType; | |
| 120 case RGB_565: | |
| 121 return kRGB_565_SkColorType; | |
| 122 case LUMINANCE_8: | |
| 123 return kGray_8_SkColorType; | |
| 124 case ETC1: | |
| 125 case RED_8: | |
| 126 case LUMINANCE_F16: | |
| 127 return kN32_SkColorType; | |
| 128 } | |
| 129 NOTREACHED(); | |
| 130 return kN32_SkColorType; | |
| 131 } | |
| 132 | |
| 133 SkImageInfo CreateImageInfo(size_t width, | |
| 134 size_t height, | |
| 135 ResourceFormat format) { | |
| 136 return SkImageInfo::Make(width, height, SkColorTypeForDecoding(format), | |
| 137 kPremul_SkAlphaType); | |
| 138 } | |
| 139 | |
| 140 } // namespace | 110 } // namespace |
| 141 | 111 |
| 142 SoftwareImageDecodeController::SoftwareImageDecodeController( | 112 SoftwareImageDecodeController::SoftwareImageDecodeController( |
| 143 ResourceFormat format) | 113 ResourceFormat format) |
| 144 : decoded_images_(ImageMRUCache::NO_AUTO_EVICT), | 114 : decoded_images_(ImageMRUCache::NO_AUTO_EVICT), |
| 145 at_raster_decoded_images_(ImageMRUCache::NO_AUTO_EVICT), | 115 at_raster_decoded_images_(ImageMRUCache::NO_AUTO_EVICT), |
| 146 locked_images_budget_(kLockedMemoryLimitBytes), | 116 locked_images_budget_(kLockedMemoryLimitBytes), |
| 147 format_(format) {} | 117 format_(format) {} |
| 148 | 118 |
| 149 SoftwareImageDecodeController::~SoftwareImageDecodeController() { | 119 SoftwareImageDecodeController::~SoftwareImageDecodeController() { |
| (...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 358 if (decoded_images_ref_counts_.find(key) == | 328 if (decoded_images_ref_counts_.find(key) == |
| 359 decoded_images_ref_counts_.end()) { | 329 decoded_images_ref_counts_.end()) { |
| 360 decoded_image->Unlock(); | 330 decoded_image->Unlock(); |
| 361 } | 331 } |
| 362 | 332 |
| 363 decoded_images_.Put(key, std::move(decoded_image)); | 333 decoded_images_.Put(key, std::move(decoded_image)); |
| 364 SanityCheckState(__LINE__, true); | 334 SanityCheckState(__LINE__, true); |
| 365 } | 335 } |
| 366 | 336 |
| 367 scoped_ptr<SoftwareImageDecodeController::DecodedImage> | 337 scoped_ptr<SoftwareImageDecodeController::DecodedImage> |
| 338 SoftwareImageDecodeController::DecodeImageNoneLowQuality(const ImageKey& key, | |
|
vmpstr
2016/03/21 20:53:40
Maybe we can just skip this function and use GetOr
cblume
2016/03/21 23:01:04
Done.
| |
| 339 const SkImage& image) { | |
| 340 DCHECK(key.can_use_original_decode()); | |
| 341 | |
| 342 return AttemptToUseOriginalImage(key, image); | |
| 343 } | |
| 344 | |
| 345 scoped_ptr<SoftwareImageDecodeController::DecodedImage> | |
| 346 SoftwareImageDecodeController::DecodeImageMediumQuality(const ImageKey& key, | |
| 347 const SkImage& image) { | |
| 348 NOTIMPLEMENTED(); | |
| 349 return nullptr; | |
| 350 } | |
| 351 | |
| 352 scoped_ptr<SoftwareImageDecodeController::DecodedImage> | |
| 353 SoftwareImageDecodeController::DecodeImageHighQuality(const ImageKey& key, | |
| 354 const SkImage& image) { | |
| 355 // If we get here, that means we couldn't use the original sized decode for | |
| 356 // whatever reason. However, in all cases we do need an original decode to | |
| 357 // either do a scale or to extract a subrect from the image. | |
| 358 auto decoded_image_result = DecodeImageOrUseCache(key, image); | |
| 359 if (!decoded_image_result.decoded_pixmap_.addr()) { | |
|
vmpstr
2016/03/21 20:53:40
nit: Usually for single line if and a single line
cblume
2016/03/21 23:01:04
Done.
| |
| 360 return nullptr; | |
| 361 } | |
| 362 | |
| 363 | |
| 364 // Now we have a decoded_pixmap which represents the src_rect at the | |
| 365 // original scale. All we need to do is scale it. | |
| 366 return ScaleImage(key, decoded_image_result); | |
| 367 } | |
| 368 | |
| 369 scoped_ptr<SoftwareImageDecodeController::DecodedImage> | |
| 368 SoftwareImageDecodeController::DecodeImageInternal( | 370 SoftwareImageDecodeController::DecodeImageInternal( |
| 369 const ImageKey& key, | 371 const ImageKey& key, |
| 370 const DrawImage& draw_image) { | 372 const DrawImage& draw_image) { |
| 371 TRACE_EVENT1("disabled-by-default-cc.debug", | 373 TRACE_EVENT1("disabled-by-default-cc.debug", |
| 372 "SoftwareImageDecodeController::DecodeImageInternal", "key", | 374 "SoftwareImageDecodeController::DecodeImageInternal", "key", |
| 373 key.ToString()); | 375 key.ToString()); |
| 374 const SkImage* image = draw_image.image(); | 376 const SkImage* image = draw_image.image(); |
| 375 | 377 if (!image) { |
| 376 // If we can use the original decode, then we don't need to do scaling. We can | |
| 377 // just read pixels into the final memory. | |
| 378 if (key.can_use_original_decode()) { | |
| 379 SkImageInfo decoded_info = | |
| 380 CreateImageInfo(image->width(), image->height(), format_); | |
| 381 scoped_ptr<base::DiscardableMemory> decoded_pixels; | |
| 382 { | |
| 383 TRACE_EVENT0( | |
| 384 "disabled-by-default-cc.debug", | |
| 385 "SoftwareImageDecodeController::DecodeImageInternal - allocate " | |
| 386 "decoded pixels"); | |
| 387 decoded_pixels = | |
| 388 base::DiscardableMemoryAllocator::GetInstance() | |
| 389 ->AllocateLockedDiscardableMemory(decoded_info.minRowBytes() * | |
| 390 decoded_info.height()); | |
| 391 } | |
| 392 { | |
| 393 TRACE_EVENT0( | |
| 394 "disabled-by-default-cc.debug", | |
| 395 "SoftwareImageDecodeController::DecodeImageInternal - read pixels"); | |
| 396 bool result = image->readPixels(decoded_info, decoded_pixels->data(), | |
| 397 decoded_info.minRowBytes(), 0, 0, | |
| 398 SkImage::kDisallow_CachingHint); | |
| 399 | |
| 400 if (!result) { | |
| 401 decoded_pixels->Unlock(); | |
| 402 return nullptr; | |
| 403 } | |
| 404 } | |
| 405 | |
| 406 return make_scoped_ptr(new DecodedImage( | |
| 407 decoded_info, std::move(decoded_pixels), SkSize::Make(0, 0))); | |
| 408 } | |
| 409 | |
| 410 // If we get here, that means we couldn't use the original sized decode for | |
| 411 // whatever reason. However, in all cases we do need an original decode to | |
| 412 // either do a scale or to extract a subrect from the image. So, what we can | |
| 413 // do is construct a key that would require a full sized decode, then get that | |
| 414 // decode via GetDecodedImageForDrawInternal(), use it, and unref it. This | |
| 415 // ensures that if the original sized decode is already available in any of | |
| 416 // the caches, we reuse that. We also ensure that all the proper locking takes | |
| 417 // place. If, on the other hand, the decode was not available, | |
| 418 // GetDecodedImageForDrawInternal() would decode the image, and unreffing it | |
| 419 // later ensures that we will store the discardable memory unlocked in the | |
| 420 // cache to be used by future requests. | |
| 421 gfx::Rect full_image_rect(image->width(), image->height()); | |
| 422 DrawImage original_size_draw_image(image, gfx::RectToSkIRect(full_image_rect), | |
| 423 kNone_SkFilterQuality, SkMatrix::I()); | |
| 424 ImageKey original_size_key = | |
| 425 ImageKey::FromDrawImage(original_size_draw_image); | |
| 426 // Sanity checks. | |
| 427 DCHECK(original_size_key.can_use_original_decode()); | |
| 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; | 378 return nullptr; |
| 435 } | 379 } |
| 436 | 380 |
| 437 SkPixmap decoded_pixmap; | 381 switch (key.filter_quality()) { |
| 438 bool result = decoded_draw_image.image()->peekPixels(&decoded_pixmap); | 382 case kNone_SkFilterQuality: |
| 439 DCHECK(result); | 383 // fall through |
| 440 if (key.src_rect() != full_image_rect) { | 384 case kLow_SkFilterQuality: |
| 441 result = decoded_pixmap.extractSubset(&decoded_pixmap, | 385 return DecodeImageNoneLowQuality(key, *image); |
| 442 gfx::RectToSkIRect(key.src_rect())); | 386 case kMedium_SkFilterQuality: |
| 443 DCHECK(result); | 387 return DecodeImageMediumQuality(key, *image); |
| 388 case kHigh_SkFilterQuality: | |
| 389 return DecodeImageHighQuality(key, *image); | |
| 390 default: | |
| 391 NOTREACHED(); | |
| 392 return nullptr; | |
| 444 } | 393 } |
| 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 scoped_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); | |
| 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 scoped_ptr and will be | |
| 476 // deleted automatically when we return. | |
| 477 DrawWithImageFinished(original_size_draw_image, decoded_draw_image); | |
| 478 | |
| 479 return make_scoped_ptr( | |
| 480 new DecodedImage(scaled_info, std::move(scaled_pixels), | |
| 481 SkSize::Make(-key.src_rect().x(), -key.src_rect().y()))); | |
| 482 } | 394 } |
| 483 | 395 |
| 484 DecodedDrawImage SoftwareImageDecodeController::GetDecodedImageForDraw( | 396 DecodedDrawImage SoftwareImageDecodeController::GetDecodedImageForDraw( |
| 485 const DrawImage& draw_image) { | 397 const DrawImage& draw_image) { |
| 486 ImageKey key = ImageKey::FromDrawImage(draw_image); | 398 ImageKey key = ImageKey::FromDrawImage(draw_image); |
| 487 TRACE_EVENT1("disabled-by-default-cc.debug", | 399 TRACE_EVENT1("disabled-by-default-cc.debug", |
| 488 "SoftwareImageDecodeController::GetDecodedImageForDraw", "key", | 400 "SoftwareImageDecodeController::GetDecodedImageForDraw", "key", |
| 489 key.ToString()); | 401 key.ToString()); |
| 490 // If the target size is empty, we can skip this image draw. | 402 // If the target size is empty, we can skip this image draw. |
| 491 if (key.target_size().IsEmpty()) | 403 if (key.target_size().IsEmpty()) |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 542 // Now we know that we don't have a locked image, and we seem to be the first | 454 // Now we know that we don't have a locked image, and we seem to be the first |
| 543 // thread encountering this image (that might not be true, since other threads | 455 // thread encountering this image (that might not be true, since other threads |
| 544 // might be decoding it already). This means that we need to decode the image | 456 // might be decoding it already). This means that we need to decode the image |
| 545 // assuming we can't lock the one we found in the cache. | 457 // assuming we can't lock the one we found in the cache. |
| 546 bool check_at_raster_cache = false; | 458 bool check_at_raster_cache = false; |
| 547 if (!decoded_image || !decoded_image->Lock()) { | 459 if (!decoded_image || !decoded_image->Lock()) { |
| 548 // Note that we have to release the lock, since this lock is also accessed | 460 // Note that we have to release the lock, since this lock is also accessed |
| 549 // on the compositor thread. This means holding on to the lock might stall | 461 // on the compositor thread. This means holding on to the lock might stall |
| 550 // the compositor thread for the duration of the decode! | 462 // the compositor thread for the duration of the decode! |
| 551 base::AutoUnlock unlock(lock_); | 463 base::AutoUnlock unlock(lock_); |
| 552 scoped_decoded_image = DecodeImageInternal(key, draw_image); | 464 const SkImage* image = draw_image.image(); |
| 465 if (!image) { | |
|
vmpstr
2016/03/21 20:53:40
When would this be the case?
| |
| 466 return DecodedDrawImage(nullptr, kNone_SkFilterQuality); | |
|
vmpstr
2016/03/21 20:53:40
If this is a case that we need to handle, then it
cblume
2016/03/21 23:01:03
I think you are right, this won't ever be the case
| |
| 467 } | |
| 468 scoped_decoded_image = AttemptToUseOriginalImage(key, *image); | |
| 553 decoded_image = scoped_decoded_image.get(); | 469 decoded_image = scoped_decoded_image.get(); |
| 554 | 470 |
| 555 // Skip the image if we couldn't decode it. | 471 // Skip the image if we couldn't decode it. |
| 556 if (!decoded_image) | 472 if (!decoded_image) |
| 557 return DecodedDrawImage(nullptr, kNone_SkFilterQuality); | 473 return DecodedDrawImage(nullptr, kNone_SkFilterQuality); |
| 558 check_at_raster_cache = true; | 474 check_at_raster_cache = true; |
| 559 } | 475 } |
| 560 | 476 |
| 561 DCHECK(decoded_image == scoped_decoded_image.get()); | 477 DCHECK(decoded_image == scoped_decoded_image.get()); |
| 562 | 478 |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 583 DCHECK(decoded_image->is_locked()); | 499 DCHECK(decoded_image->is_locked()); |
| 584 RefAtRasterImage(key); | 500 RefAtRasterImage(key); |
| 585 SanityCheckState(__LINE__, true); | 501 SanityCheckState(__LINE__, true); |
| 586 auto decoded_draw_image = | 502 auto decoded_draw_image = |
| 587 DecodedDrawImage(decoded_image->image(), decoded_image->src_rect_offset(), | 503 DecodedDrawImage(decoded_image->image(), decoded_image->src_rect_offset(), |
| 588 GetScaleAdjustment(key), GetDecodedFilterQuality(key)); | 504 GetScaleAdjustment(key), GetDecodedFilterQuality(key)); |
| 589 decoded_draw_image.set_at_raster_decode(true); | 505 decoded_draw_image.set_at_raster_decode(true); |
| 590 return decoded_draw_image; | 506 return decoded_draw_image; |
| 591 } | 507 } |
| 592 | 508 |
| 509 SoftwareImageDecodeController::DecodedImageResult::DecodedImageResult( | |
| 510 SkPixmap decoded_pixmap, | |
| 511 DrawImage original_size_draw_image, | |
| 512 DecodedDrawImage decoded_draw_image) | |
| 513 : decoded_pixmap_(decoded_pixmap), | |
| 514 original_size_draw_image_(original_size_draw_image), | |
| 515 decoded_draw_image_(decoded_draw_image) {} | |
| 516 | |
| 517 scoped_ptr<SoftwareImageDecodeController::DecodedImage> | |
| 518 SoftwareImageDecodeController::AttemptToUseOriginalImage(const ImageKey& key, | |
|
vmpstr
2016/03/21 20:53:40
nit: Can we call this "GetOriginalImageDecode" or
cblume
2016/03/21 23:01:03
Done.
| |
| 519 const SkImage& image) { | |
| 520 TRACE_EVENT1("disabled-by-default-cc.debug", | |
| 521 "SoftwareImageDecodeController::AttemptToUseOriginalImage", | |
| 522 "key", key.ToString()); | |
| 523 if (!key.can_use_original_decode()) { | |
|
vmpstr
2016/03/21 20:53:40
Can we make this a DCHECK? Whatever code is callin
cblume
2016/03/21 23:01:04
Done.
| |
| 524 return nullptr; | |
| 525 } else { | |
| 526 SkImageInfo decoded_info = | |
| 527 SkImageInfo::MakeN32Premul(image.width(), image.height()); | |
| 528 scoped_ptr<base::DiscardableMemory> decoded_pixels; | |
| 529 { | |
| 530 TRACE_EVENT0("disabled-by-default-cc.debug", | |
| 531 "SoftwareImageDecodeController::AttemptToUseOriginalImage - " | |
| 532 "allocate decoded pixels"); | |
| 533 decoded_pixels = | |
| 534 base::DiscardableMemoryAllocator::GetInstance() | |
| 535 ->AllocateLockedDiscardableMemory(decoded_info.minRowBytes() * | |
| 536 decoded_info.height()); | |
| 537 } | |
| 538 { | |
| 539 TRACE_EVENT0("disabled-by-default-cc.debug", | |
| 540 "SoftwareImageDecodeController::AttemptToUseOriginalImage - " | |
| 541 "read pixels"); | |
| 542 bool result = image.readPixels(decoded_info, decoded_pixels->data(), | |
| 543 decoded_info.minRowBytes(), 0, 0, | |
| 544 SkImage::kDisallow_CachingHint); | |
| 545 | |
| 546 if (!result) { | |
| 547 decoded_pixels->Unlock(); | |
| 548 return nullptr; | |
| 549 } | |
| 550 } | |
| 551 | |
| 552 return make_scoped_ptr(new DecodedImage( | |
| 553 decoded_info, std::move(decoded_pixels), SkSize::Make(0, 0))); | |
| 554 } | |
| 555 } | |
| 556 | |
| 557 SoftwareImageDecodeController::DecodedImageResult | |
| 558 SoftwareImageDecodeController::DecodeImageOrUseCache(const ImageKey& key, | |
| 559 const SkImage& image) { | |
| 560 // Construct a key to use in GetDecodedImageForDrawInternal(). | |
| 561 // This allows us to reuse an image in any cache if available. | |
| 562 gfx::Rect full_image_rect(image.width(), image.height()); | |
| 563 DrawImage original_size_draw_image(&image, | |
| 564 gfx::RectToSkIRect(full_image_rect), | |
| 565 kNone_SkFilterQuality, SkMatrix::I()); | |
| 566 ImageKey original_size_key = | |
| 567 ImageKey::FromDrawImage(original_size_draw_image); | |
| 568 // Sanity checks. | |
| 569 DCHECK(original_size_key.can_use_original_decode()); | |
| 570 DCHECK(full_image_rect.size() == original_size_key.target_size()); | |
| 571 | |
| 572 auto decoded_draw_image = GetDecodedImageForDrawInternal( | |
| 573 original_size_key, original_size_draw_image); | |
| 574 | |
| 575 if (!decoded_draw_image.image()) { | |
| 576 DrawWithImageFinished(original_size_draw_image, decoded_draw_image); | |
| 577 return DecodedImageResult(SkPixmap(), DrawImage(), | |
| 578 DecodedDrawImage(nullptr, kNone_SkFilterQuality)); | |
| 579 } | |
| 580 | |
| 581 SkPixmap decoded_pixmap; | |
| 582 bool result = decoded_draw_image.image()->peekPixels(&decoded_pixmap); | |
| 583 DCHECK(result); | |
| 584 if (key.src_rect() != full_image_rect) { | |
| 585 result = decoded_pixmap.extractSubset(&decoded_pixmap, | |
| 586 gfx::RectToSkIRect(key.src_rect())); | |
| 587 DCHECK(result); | |
| 588 } | |
| 589 | |
| 590 return DecodedImageResult(decoded_pixmap, original_size_draw_image, | |
| 591 decoded_draw_image); | |
| 592 } | |
| 593 | |
| 594 scoped_ptr<SoftwareImageDecodeController::DecodedImage> | |
| 595 SoftwareImageDecodeController::ScaleImage( | |
| 596 const ImageKey& key, | |
| 597 const DecodedImageResult& decoded_image_result) { | |
| 598 DCHECK(!key.target_size().IsEmpty()); | |
| 599 SkImageInfo scaled_info = SkImageInfo::MakeN32Premul( | |
| 600 key.target_size().width(), key.target_size().height()); | |
| 601 scoped_ptr<base::DiscardableMemory> scaled_pixels; | |
| 602 { | |
| 603 TRACE_EVENT0( | |
| 604 "disabled-by-default-cc.debug", | |
| 605 "SoftwareImageDecodeController::ScaleImage - allocate scaled pixels"); | |
| 606 scaled_pixels = base::DiscardableMemoryAllocator::GetInstance() | |
| 607 ->AllocateLockedDiscardableMemory( | |
| 608 scaled_info.minRowBytes() * scaled_info.height()); | |
| 609 } | |
| 610 SkPixmap scaled_pixmap(scaled_info, scaled_pixels->data(), | |
| 611 scaled_info.minRowBytes()); | |
| 612 // TODO(vmpstr): Start handling more than just high filter quality. | |
| 613 DCHECK_EQ(kHigh_SkFilterQuality, key.filter_quality()); | |
| 614 { | |
| 615 TRACE_EVENT0("disabled-by-default-cc.debug", | |
| 616 "SoftwareImageDecodeController::ScaleImage - scale pixels"); | |
| 617 bool result = decoded_image_result.decoded_pixmap_.scalePixels( | |
| 618 scaled_pixmap, key.filter_quality()); | |
| 619 DCHECK(result); | |
| 620 } | |
| 621 | |
| 622 // Release the original sized decode. Any other intermediate result to release | |
| 623 // would be the subrect memory. However, that's in a scoped_ptr and will be | |
| 624 // deleted automatically when we return. | |
| 625 DrawWithImageFinished(decoded_image_result.original_size_draw_image_, | |
| 626 decoded_image_result.decoded_draw_image_); | |
| 627 | |
| 628 return make_scoped_ptr(new SoftwareImageDecodeController::DecodedImage( | |
| 629 scaled_info, std::move(scaled_pixels), | |
| 630 SkSize::Make(-key.src_rect().x(), -key.src_rect().y()))); | |
| 631 } | |
| 632 | |
| 593 void SoftwareImageDecodeController::DrawWithImageFinished( | 633 void SoftwareImageDecodeController::DrawWithImageFinished( |
| 594 const DrawImage& image, | 634 const DrawImage& image, |
| 595 const DecodedDrawImage& decoded_image) { | 635 const DecodedDrawImage& decoded_image) { |
| 596 TRACE_EVENT1("disabled-by-default-cc.debug", | 636 TRACE_EVENT1("disabled-by-default-cc.debug", |
| 597 "SoftwareImageDecodeController::DrawWithImageFinished", "key", | 637 "SoftwareImageDecodeController::DrawWithImageFinished", "key", |
| 598 ImageKey::FromDrawImage(image).ToString()); | 638 ImageKey::FromDrawImage(image).ToString()); |
| 599 ImageKey key = ImageKey::FromDrawImage(image); | 639 ImageKey key = ImageKey::FromDrawImage(image); |
| 600 if (!decoded_image.image() || !CanHandleImage(key)) | 640 if (!decoded_image.image() || !CanHandleImage(key)) |
| 601 return; | 641 return; |
| 602 | 642 |
| (...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 884 void SoftwareImageDecodeController::MemoryBudget::ResetUsage() { | 924 void SoftwareImageDecodeController::MemoryBudget::ResetUsage() { |
| 885 current_usage_bytes_ = 0; | 925 current_usage_bytes_ = 0; |
| 886 } | 926 } |
| 887 | 927 |
| 888 size_t SoftwareImageDecodeController::MemoryBudget::GetCurrentUsageSafe() | 928 size_t SoftwareImageDecodeController::MemoryBudget::GetCurrentUsageSafe() |
| 889 const { | 929 const { |
| 890 return current_usage_bytes_.ValueOrDie(); | 930 return current_usage_bytes_.ValueOrDie(); |
| 891 } | 931 } |
| 892 | 932 |
| 893 } // namespace cc | 933 } // namespace cc |
| OLD | NEW |