| 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 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 260 } | 260 } |
| 261 | 261 |
| 262 void SoftwareImageDecodeController::UnrefImage(const DrawImage& image) { | 262 void SoftwareImageDecodeController::UnrefImage(const DrawImage& image) { |
| 263 // When we unref the image, there are several situations we need to consider: | 263 // When we unref the image, there are several situations we need to consider: |
| 264 // 1. The ref did not reach 0, which means we have to keep the image locked. | 264 // 1. The ref did not reach 0, which means we have to keep the image locked. |
| 265 // 2. The ref reached 0, we should unlock it. | 265 // 2. The ref reached 0, we should unlock it. |
| 266 // 2a. The image isn't in the locked cache because we didn't get to decode | 266 // 2a. The image isn't in the locked cache because we didn't get to decode |
| 267 // it yet (or failed to decode it). | 267 // it yet (or failed to decode it). |
| 268 // 2b. Unlock the image but keep it in list. | 268 // 2b. Unlock the image but keep it in list. |
| 269 const ImageKey& key = ImageKey::FromDrawImage(image); | 269 const ImageKey& key = ImageKey::FromDrawImage(image); |
| 270 DCHECK(CanHandleImage(key)); | 270 DCHECK(CanHandleImage(key)) << key.ToString(); |
| 271 TRACE_EVENT1("disabled-by-default-cc.debug", | 271 TRACE_EVENT1("disabled-by-default-cc.debug", |
| 272 "SoftwareImageDecodeController::UnrefImage", "key", | 272 "SoftwareImageDecodeController::UnrefImage", "key", |
| 273 key.ToString()); | 273 key.ToString()); |
| 274 | 274 |
| 275 base::AutoLock lock(lock_); | 275 base::AutoLock lock(lock_); |
| 276 auto ref_count_it = decoded_images_ref_counts_.find(key); | 276 auto ref_count_it = decoded_images_ref_counts_.find(key); |
| 277 DCHECK(ref_count_it != decoded_images_ref_counts_.end()); | 277 DCHECK(ref_count_it != decoded_images_ref_counts_.end()); |
| 278 | 278 |
| 279 --ref_count_it->second; | 279 --ref_count_it->second; |
| 280 if (ref_count_it->second == 0) { | 280 if (ref_count_it->second == 0) { |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 420 // place. If, on the other hand, the decode was not available, | 420 // place. If, on the other hand, the decode was not available, |
| 421 // GetDecodedImageForDrawInternal() would decode the image, and unreffing it | 421 // GetDecodedImageForDrawInternal() would decode the image, and unreffing it |
| 422 // later ensures that we will store the discardable memory unlocked in the | 422 // later ensures that we will store the discardable memory unlocked in the |
| 423 // cache to be used by future requests. | 423 // cache to be used by future requests. |
| 424 gfx::Rect full_image_rect(image->width(), image->height()); | 424 gfx::Rect full_image_rect(image->width(), image->height()); |
| 425 DrawImage original_size_draw_image(image, gfx::RectToSkIRect(full_image_rect), | 425 DrawImage original_size_draw_image(image, gfx::RectToSkIRect(full_image_rect), |
| 426 kNone_SkFilterQuality, SkMatrix::I()); | 426 kNone_SkFilterQuality, SkMatrix::I()); |
| 427 ImageKey original_size_key = | 427 ImageKey original_size_key = |
| 428 ImageKey::FromDrawImage(original_size_draw_image); | 428 ImageKey::FromDrawImage(original_size_draw_image); |
| 429 // Sanity checks. | 429 // Sanity checks. |
| 430 DCHECK(original_size_key.can_use_original_decode()); | 430 DCHECK(original_size_key.can_use_original_decode()) |
| 431 << original_size_key.ToString(); |
| 431 DCHECK(full_image_rect.size() == original_size_key.target_size()); | 432 DCHECK(full_image_rect.size() == original_size_key.target_size()); |
| 432 | 433 |
| 433 auto decoded_draw_image = GetDecodedImageForDrawInternal( | 434 auto decoded_draw_image = GetDecodedImageForDrawInternal( |
| 434 original_size_key, original_size_draw_image); | 435 original_size_key, original_size_draw_image); |
| 435 if (!decoded_draw_image.image()) { | 436 if (!decoded_draw_image.image()) { |
| 436 DrawWithImageFinished(original_size_draw_image, decoded_draw_image); | 437 DrawWithImageFinished(original_size_draw_image, decoded_draw_image); |
| 437 return nullptr; | 438 return nullptr; |
| 438 } | 439 } |
| 439 | 440 |
| 440 SkPixmap decoded_pixmap; | 441 SkPixmap decoded_pixmap; |
| 441 bool result = decoded_draw_image.image()->peekPixels(&decoded_pixmap); | 442 bool result = decoded_draw_image.image()->peekPixels(&decoded_pixmap); |
| 442 DCHECK(result); | 443 DCHECK(result) << key.ToString(); |
| 443 if (key.src_rect() != full_image_rect) { | 444 if (key.src_rect() != full_image_rect) { |
| 444 result = decoded_pixmap.extractSubset(&decoded_pixmap, | 445 result = decoded_pixmap.extractSubset(&decoded_pixmap, |
| 445 gfx::RectToSkIRect(key.src_rect())); | 446 gfx::RectToSkIRect(key.src_rect())); |
| 446 DCHECK(result); | 447 DCHECK(result) << key.ToString(); |
| 447 } | 448 } |
| 448 | 449 |
| 449 // Now we have a decoded_pixmap which represents the src_rect at the | 450 // 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 // original scale. All we need to do is scale it. |
| 451 DCHECK(!key.target_size().IsEmpty()); | 452 DCHECK(!key.target_size().IsEmpty()); |
| 452 SkImageInfo scaled_info = CreateImageInfo( | 453 SkImageInfo scaled_info = CreateImageInfo( |
| 453 key.target_size().width(), key.target_size().height(), format_); | 454 key.target_size().width(), key.target_size().height(), format_); |
| 454 scoped_ptr<base::DiscardableMemory> scaled_pixels; | 455 scoped_ptr<base::DiscardableMemory> scaled_pixels; |
| 455 { | 456 { |
| 456 TRACE_EVENT0( | 457 TRACE_EVENT0( |
| 457 "disabled-by-default-cc.debug", | 458 "disabled-by-default-cc.debug", |
| 458 "SoftwareImageDecodeController::DecodeImageInternal - allocate " | 459 "SoftwareImageDecodeController::DecodeImageInternal - allocate " |
| 459 "scaled pixels"); | 460 "scaled pixels"); |
| 460 scaled_pixels = base::DiscardableMemoryAllocator::GetInstance() | 461 scaled_pixels = base::DiscardableMemoryAllocator::GetInstance() |
| 461 ->AllocateLockedDiscardableMemory( | 462 ->AllocateLockedDiscardableMemory( |
| 462 scaled_info.minRowBytes() * scaled_info.height()); | 463 scaled_info.minRowBytes() * scaled_info.height()); |
| 463 } | 464 } |
| 464 SkPixmap scaled_pixmap(scaled_info, scaled_pixels->data(), | 465 SkPixmap scaled_pixmap(scaled_info, scaled_pixels->data(), |
| 465 scaled_info.minRowBytes()); | 466 scaled_info.minRowBytes()); |
| 466 // TODO(vmpstr): Start handling more than just high filter quality. | 467 // TODO(vmpstr): Start handling more than just high filter quality. |
| 467 DCHECK_EQ(kHigh_SkFilterQuality, key.filter_quality()); | 468 DCHECK_EQ(kHigh_SkFilterQuality, key.filter_quality()); |
| 468 { | 469 { |
| 469 TRACE_EVENT0( | 470 TRACE_EVENT0( |
| 470 "disabled-by-default-cc.debug", | 471 "disabled-by-default-cc.debug", |
| 471 "SoftwareImageDecodeController::DecodeImageInternal - scale pixels"); | 472 "SoftwareImageDecodeController::DecodeImageInternal - scale pixels"); |
| 472 bool result = | 473 bool result = |
| 473 decoded_pixmap.scalePixels(scaled_pixmap, key.filter_quality()); | 474 decoded_pixmap.scalePixels(scaled_pixmap, key.filter_quality()); |
| 474 DCHECK(result); | 475 DCHECK(result) << key.ToString(); |
| 475 } | 476 } |
| 476 | 477 |
| 477 // Release the original sized decode. Any other intermediate result to release | 478 // 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 // would be the subrect memory. However, that's in a scoped_ptr and will be |
| 479 // deleted automatically when we return. | 480 // deleted automatically when we return. |
| 480 DrawWithImageFinished(original_size_draw_image, decoded_draw_image); | 481 DrawWithImageFinished(original_size_draw_image, decoded_draw_image); |
| 481 | 482 |
| 482 return make_scoped_ptr( | 483 return make_scoped_ptr( |
| 483 new DecodedImage(scaled_info, std::move(scaled_pixels), | 484 new DecodedImage(scaled_info, std::move(scaled_pixels), |
| 484 SkSize::Make(-key.src_rect().x(), -key.src_rect().y()))); | 485 SkSize::Make(-key.src_rect().x(), -key.src_rect().y()))); |
| (...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 890 void SoftwareImageDecodeController::MemoryBudget::ResetUsage() { | 891 void SoftwareImageDecodeController::MemoryBudget::ResetUsage() { |
| 891 current_usage_bytes_ = 0; | 892 current_usage_bytes_ = 0; |
| 892 } | 893 } |
| 893 | 894 |
| 894 size_t SoftwareImageDecodeController::MemoryBudget::GetCurrentUsageSafe() | 895 size_t SoftwareImageDecodeController::MemoryBudget::GetCurrentUsageSafe() |
| 895 const { | 896 const { |
| 896 return current_usage_bytes_.ValueOrDie(); | 897 return current_usage_bytes_.ValueOrDie(); |
| 897 } | 898 } |
| 898 | 899 |
| 899 } // namespace cc | 900 } // namespace cc |
| OLD | NEW |