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 |
11 #include "base/format_macros.h" | 11 #include "base/format_macros.h" |
12 #include "base/macros.h" | 12 #include "base/macros.h" |
13 #include "base/memory/discardable_memory.h" | 13 #include "base/memory/discardable_memory.h" |
| 14 #include "base/memory/ptr_util.h" |
14 #include "base/strings/stringprintf.h" | 15 #include "base/strings/stringprintf.h" |
15 #include "base/thread_task_runner_handle.h" | 16 #include "base/thread_task_runner_handle.h" |
16 #include "base/trace_event/memory_dump_manager.h" | 17 #include "base/trace_event/memory_dump_manager.h" |
17 #include "cc/debug/devtools_instrumentation.h" | 18 #include "cc/debug/devtools_instrumentation.h" |
18 #include "cc/raster/tile_task_runner.h" | 19 #include "cc/raster/tile_task_runner.h" |
19 #include "third_party/skia/include/core/SkCanvas.h" | 20 #include "third_party/skia/include/core/SkCanvas.h" |
20 #include "third_party/skia/include/core/SkImage.h" | 21 #include "third_party/skia/include/core/SkImage.h" |
21 #include "ui/gfx/skia_util.h" | 22 #include "ui/gfx/skia_util.h" |
22 | 23 |
23 namespace cc { | 24 namespace cc { |
(...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
340 return; | 341 return; |
341 } | 342 } |
342 | 343 |
343 auto image_it = decoded_images_.Peek(key); | 344 auto image_it = decoded_images_.Peek(key); |
344 if (image_it != decoded_images_.end()) { | 345 if (image_it != decoded_images_.end()) { |
345 if (image_it->second->is_locked() || image_it->second->Lock()) | 346 if (image_it->second->is_locked() || image_it->second->Lock()) |
346 return; | 347 return; |
347 decoded_images_.Erase(image_it); | 348 decoded_images_.Erase(image_it); |
348 } | 349 } |
349 | 350 |
350 scoped_ptr<DecodedImage> decoded_image; | 351 std::unique_ptr<DecodedImage> decoded_image; |
351 { | 352 { |
352 base::AutoUnlock unlock(lock_); | 353 base::AutoUnlock unlock(lock_); |
353 decoded_image = DecodeImageInternal(key, image); | 354 decoded_image = DecodeImageInternal(key, image); |
354 } | 355 } |
355 | 356 |
356 // Abort if we failed to decode the image. | 357 // Abort if we failed to decode the image. |
357 if (!decoded_image) | 358 if (!decoded_image) |
358 return; | 359 return; |
359 | 360 |
360 // At this point, it could have been the case that this image was decoded in | 361 // At this point, it could have been the case that this image was decoded in |
(...skipping 15 matching lines...) Expand all Loading... |
376 // ref counts. Unlock it immediately in this case. | 377 // ref counts. Unlock it immediately in this case. |
377 if (decoded_images_ref_counts_.find(key) == | 378 if (decoded_images_ref_counts_.find(key) == |
378 decoded_images_ref_counts_.end()) { | 379 decoded_images_ref_counts_.end()) { |
379 decoded_image->Unlock(); | 380 decoded_image->Unlock(); |
380 } | 381 } |
381 | 382 |
382 decoded_images_.Put(key, std::move(decoded_image)); | 383 decoded_images_.Put(key, std::move(decoded_image)); |
383 SanityCheckState(__LINE__, true); | 384 SanityCheckState(__LINE__, true); |
384 } | 385 } |
385 | 386 |
386 scoped_ptr<SoftwareImageDecodeController::DecodedImage> | 387 std::unique_ptr<SoftwareImageDecodeController::DecodedImage> |
387 SoftwareImageDecodeController::DecodeImageInternal( | 388 SoftwareImageDecodeController::DecodeImageInternal( |
388 const ImageKey& key, | 389 const ImageKey& key, |
389 const DrawImage& draw_image) { | 390 const DrawImage& draw_image) { |
390 TRACE_EVENT1("disabled-by-default-cc.debug", | 391 TRACE_EVENT1("disabled-by-default-cc.debug", |
391 "SoftwareImageDecodeController::DecodeImageInternal", "key", | 392 "SoftwareImageDecodeController::DecodeImageInternal", "key", |
392 key.ToString()); | 393 key.ToString()); |
393 const SkImage* image = draw_image.image(); | 394 const SkImage* image = draw_image.image(); |
394 | 395 |
395 // If we can use the original decode, then we don't need to do scaling. We can | 396 // If we can use the original decode, then we don't need to do scaling. We can |
396 // just read pixels into the final memory. | 397 // just read pixels into the final memory. |
397 if (key.can_use_original_decode()) { | 398 if (key.can_use_original_decode()) { |
398 SkImageInfo decoded_info = | 399 SkImageInfo decoded_info = |
399 CreateImageInfo(image->width(), image->height(), format_); | 400 CreateImageInfo(image->width(), image->height(), format_); |
400 scoped_ptr<base::DiscardableMemory> decoded_pixels; | 401 std::unique_ptr<base::DiscardableMemory> decoded_pixels; |
401 { | 402 { |
402 TRACE_EVENT0( | 403 TRACE_EVENT0( |
403 "disabled-by-default-cc.debug", | 404 "disabled-by-default-cc.debug", |
404 "SoftwareImageDecodeController::DecodeImageInternal - allocate " | 405 "SoftwareImageDecodeController::DecodeImageInternal - allocate " |
405 "decoded pixels"); | 406 "decoded pixels"); |
406 decoded_pixels = | 407 decoded_pixels = |
407 base::DiscardableMemoryAllocator::GetInstance() | 408 base::DiscardableMemoryAllocator::GetInstance() |
408 ->AllocateLockedDiscardableMemory(decoded_info.minRowBytes() * | 409 ->AllocateLockedDiscardableMemory(decoded_info.minRowBytes() * |
409 decoded_info.height()); | 410 decoded_info.height()); |
410 } | 411 } |
411 { | 412 { |
412 TRACE_EVENT0( | 413 TRACE_EVENT0( |
413 "disabled-by-default-cc.debug", | 414 "disabled-by-default-cc.debug", |
414 "SoftwareImageDecodeController::DecodeImageInternal - read pixels"); | 415 "SoftwareImageDecodeController::DecodeImageInternal - read pixels"); |
415 bool result = image->readPixels(decoded_info, decoded_pixels->data(), | 416 bool result = image->readPixels(decoded_info, decoded_pixels->data(), |
416 decoded_info.minRowBytes(), 0, 0, | 417 decoded_info.minRowBytes(), 0, 0, |
417 SkImage::kDisallow_CachingHint); | 418 SkImage::kDisallow_CachingHint); |
418 | 419 |
419 if (!result) { | 420 if (!result) { |
420 decoded_pixels->Unlock(); | 421 decoded_pixels->Unlock(); |
421 return nullptr; | 422 return nullptr; |
422 } | 423 } |
423 } | 424 } |
424 | 425 |
425 return make_scoped_ptr( | 426 return base::WrapUnique( |
426 new DecodedImage(decoded_info, std::move(decoded_pixels), | 427 new DecodedImage(decoded_info, std::move(decoded_pixels), |
427 SkSize::Make(0, 0), next_tracing_id_.GetNext())); | 428 SkSize::Make(0, 0), next_tracing_id_.GetNext())); |
428 } | 429 } |
429 | 430 |
430 // If we get here, that means we couldn't use the original sized decode for | 431 // If we get here, that means we couldn't use the original sized decode for |
431 // whatever reason. However, in all cases we do need an original decode to | 432 // whatever reason. However, in all cases we do need an original decode to |
432 // either do a scale or to extract a subrect from the image. So, what we can | 433 // either do a scale or to extract a subrect from the image. So, what we can |
433 // do is construct a key that would require a full sized decode, then get that | 434 // do is construct a key that would require a full sized decode, then get that |
434 // decode via GetDecodedImageForDrawInternal(), use it, and unref it. This | 435 // decode via GetDecodedImageForDrawInternal(), use it, and unref it. This |
435 // ensures that if the original sized decode is already available in any of | 436 // ensures that if the original sized decode is already available in any of |
(...skipping 26 matching lines...) Expand all Loading... |
462 result = decoded_pixmap.extractSubset(&decoded_pixmap, | 463 result = decoded_pixmap.extractSubset(&decoded_pixmap, |
463 gfx::RectToSkIRect(key.src_rect())); | 464 gfx::RectToSkIRect(key.src_rect())); |
464 DCHECK(result) << key.ToString(); | 465 DCHECK(result) << key.ToString(); |
465 } | 466 } |
466 | 467 |
467 // Now we have a decoded_pixmap which represents the src_rect at the | 468 // Now we have a decoded_pixmap which represents the src_rect at the |
468 // original scale. All we need to do is scale it. | 469 // original scale. All we need to do is scale it. |
469 DCHECK(!key.target_size().IsEmpty()); | 470 DCHECK(!key.target_size().IsEmpty()); |
470 SkImageInfo scaled_info = CreateImageInfo( | 471 SkImageInfo scaled_info = CreateImageInfo( |
471 key.target_size().width(), key.target_size().height(), format_); | 472 key.target_size().width(), key.target_size().height(), format_); |
472 scoped_ptr<base::DiscardableMemory> scaled_pixels; | 473 std::unique_ptr<base::DiscardableMemory> scaled_pixels; |
473 { | 474 { |
474 TRACE_EVENT0( | 475 TRACE_EVENT0( |
475 "disabled-by-default-cc.debug", | 476 "disabled-by-default-cc.debug", |
476 "SoftwareImageDecodeController::DecodeImageInternal - allocate " | 477 "SoftwareImageDecodeController::DecodeImageInternal - allocate " |
477 "scaled pixels"); | 478 "scaled pixels"); |
478 scaled_pixels = base::DiscardableMemoryAllocator::GetInstance() | 479 scaled_pixels = base::DiscardableMemoryAllocator::GetInstance() |
479 ->AllocateLockedDiscardableMemory( | 480 ->AllocateLockedDiscardableMemory( |
480 scaled_info.minRowBytes() * scaled_info.height()); | 481 scaled_info.minRowBytes() * scaled_info.height()); |
481 } | 482 } |
482 SkPixmap scaled_pixmap(scaled_info, scaled_pixels->data(), | 483 SkPixmap scaled_pixmap(scaled_info, scaled_pixels->data(), |
483 scaled_info.minRowBytes()); | 484 scaled_info.minRowBytes()); |
484 // TODO(vmpstr): Start handling more than just high filter quality. | 485 // TODO(vmpstr): Start handling more than just high filter quality. |
485 DCHECK_EQ(kHigh_SkFilterQuality, key.filter_quality()); | 486 DCHECK_EQ(kHigh_SkFilterQuality, key.filter_quality()); |
486 { | 487 { |
487 TRACE_EVENT0( | 488 TRACE_EVENT0( |
488 "disabled-by-default-cc.debug", | 489 "disabled-by-default-cc.debug", |
489 "SoftwareImageDecodeController::DecodeImageInternal - scale pixels"); | 490 "SoftwareImageDecodeController::DecodeImageInternal - scale pixels"); |
490 bool result = | 491 bool result = |
491 decoded_pixmap.scalePixels(scaled_pixmap, key.filter_quality()); | 492 decoded_pixmap.scalePixels(scaled_pixmap, key.filter_quality()); |
492 DCHECK(result) << key.ToString(); | 493 DCHECK(result) << key.ToString(); |
493 } | 494 } |
494 | 495 |
495 // Release the original sized decode. Any other intermediate result to release | 496 // Release the original sized decode. Any other intermediate result to release |
496 // would be the subrect memory. However, that's in a scoped_ptr and will be | 497 // would be the subrect memory. However, that's in a unique_ptr and will be |
497 // deleted automatically when we return. | 498 // deleted automatically when we return. |
498 DrawWithImageFinished(original_size_draw_image, decoded_draw_image); | 499 DrawWithImageFinished(original_size_draw_image, decoded_draw_image); |
499 | 500 |
500 return make_scoped_ptr( | 501 return base::WrapUnique( |
501 new DecodedImage(scaled_info, std::move(scaled_pixels), | 502 new DecodedImage(scaled_info, std::move(scaled_pixels), |
502 SkSize::Make(-key.src_rect().x(), -key.src_rect().y()), | 503 SkSize::Make(-key.src_rect().x(), -key.src_rect().y()), |
503 next_tracing_id_.GetNext())); | 504 next_tracing_id_.GetNext())); |
504 } | 505 } |
505 | 506 |
506 DecodedDrawImage SoftwareImageDecodeController::GetDecodedImageForDraw( | 507 DecodedDrawImage SoftwareImageDecodeController::GetDecodedImageForDraw( |
507 const DrawImage& draw_image) { | 508 const DrawImage& draw_image) { |
508 ImageKey key = ImageKey::FromDrawImage(draw_image); | 509 ImageKey key = ImageKey::FromDrawImage(draw_image); |
509 TRACE_EVENT1("disabled-by-default-cc.debug", | 510 TRACE_EVENT1("disabled-by-default-cc.debug", |
510 "SoftwareImageDecodeController::GetDecodedImageForDraw", "key", | 511 "SoftwareImageDecodeController::GetDecodedImageForDraw", "key", |
(...skipping 11 matching lines...) Expand all Loading... |
522 DecodedDrawImage SoftwareImageDecodeController::GetDecodedImageForDrawInternal( | 523 DecodedDrawImage SoftwareImageDecodeController::GetDecodedImageForDrawInternal( |
523 const ImageKey& key, | 524 const ImageKey& key, |
524 const DrawImage& draw_image) { | 525 const DrawImage& draw_image) { |
525 TRACE_EVENT1("disabled-by-default-cc.debug", | 526 TRACE_EVENT1("disabled-by-default-cc.debug", |
526 "SoftwareImageDecodeController::GetDecodedImageForDrawInternal", | 527 "SoftwareImageDecodeController::GetDecodedImageForDrawInternal", |
527 "key", key.ToString()); | 528 "key", key.ToString()); |
528 base::AutoLock lock(lock_); | 529 base::AutoLock lock(lock_); |
529 auto decoded_images_it = decoded_images_.Get(key); | 530 auto decoded_images_it = decoded_images_.Get(key); |
530 // If we found the image and it's locked, then return it. If it's not locked, | 531 // If we found the image and it's locked, then return it. If it's not locked, |
531 // erase it from the cache since it might be put into the at-raster cache. | 532 // erase it from the cache since it might be put into the at-raster cache. |
532 scoped_ptr<DecodedImage> scoped_decoded_image; | 533 std::unique_ptr<DecodedImage> scoped_decoded_image; |
533 DecodedImage* decoded_image = nullptr; | 534 DecodedImage* decoded_image = nullptr; |
534 if (decoded_images_it != decoded_images_.end()) { | 535 if (decoded_images_it != decoded_images_.end()) { |
535 decoded_image = decoded_images_it->second.get(); | 536 decoded_image = decoded_images_it->second.get(); |
536 if (decoded_image->is_locked()) { | 537 if (decoded_image->is_locked()) { |
537 RefImage(key); | 538 RefImage(key); |
538 SanityCheckState(__LINE__, true); | 539 SanityCheckState(__LINE__, true); |
539 return DecodedDrawImage( | 540 return DecodedDrawImage( |
540 decoded_image->image(), decoded_image->src_rect_offset(), | 541 decoded_image->image(), decoded_image->src_rect_offset(), |
541 GetScaleAdjustment(key), GetDecodedFilterQuality(key)); | 542 GetScaleAdjustment(key), GetDecodedFilterQuality(key)); |
542 } else { | 543 } else { |
(...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
886 << "] target_size[" << target_size_.width() << "x" | 887 << "] target_size[" << target_size_.width() << "x" |
887 << target_size_.height() << "] filter_quality[" << filter_quality_ | 888 << target_size_.height() << "] filter_quality[" << filter_quality_ |
888 << "] can_use_original_decode [" << can_use_original_decode_ << "] hash [" | 889 << "] can_use_original_decode [" << can_use_original_decode_ << "] hash [" |
889 << hash_ << "]"; | 890 << hash_ << "]"; |
890 return str.str(); | 891 return str.str(); |
891 } | 892 } |
892 | 893 |
893 // DecodedImage | 894 // DecodedImage |
894 SoftwareImageDecodeController::DecodedImage::DecodedImage( | 895 SoftwareImageDecodeController::DecodedImage::DecodedImage( |
895 const SkImageInfo& info, | 896 const SkImageInfo& info, |
896 scoped_ptr<base::DiscardableMemory> memory, | 897 std::unique_ptr<base::DiscardableMemory> memory, |
897 const SkSize& src_rect_offset, | 898 const SkSize& src_rect_offset, |
898 uint64_t tracing_id) | 899 uint64_t tracing_id) |
899 : locked_(true), | 900 : locked_(true), |
900 image_info_(info), | 901 image_info_(info), |
901 memory_(std::move(memory)), | 902 memory_(std::move(memory)), |
902 src_rect_offset_(src_rect_offset), | 903 src_rect_offset_(src_rect_offset), |
903 tracing_id_(tracing_id) { | 904 tracing_id_(tracing_id) { |
904 image_ = skia::AdoptRef(SkImage::NewFromRaster( | 905 image_ = skia::AdoptRef(SkImage::NewFromRaster( |
905 image_info_, memory_->data(), image_info_.minRowBytes(), | 906 image_info_, memory_->data(), image_info_.minRowBytes(), |
906 [](const void* pixels, void* context) {}, nullptr)); | 907 [](const void* pixels, void* context) {}, nullptr)); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
947 void SoftwareImageDecodeController::MemoryBudget::ResetUsage() { | 948 void SoftwareImageDecodeController::MemoryBudget::ResetUsage() { |
948 current_usage_bytes_ = 0; | 949 current_usage_bytes_ = 0; |
949 } | 950 } |
950 | 951 |
951 size_t SoftwareImageDecodeController::MemoryBudget::GetCurrentUsageSafe() | 952 size_t SoftwareImageDecodeController::MemoryBudget::GetCurrentUsageSafe() |
952 const { | 953 const { |
953 return current_usage_bytes_.ValueOrDie(); | 954 return current_usage_bytes_.ValueOrDie(); |
954 } | 955 } |
955 | 956 |
956 } // namespace cc | 957 } // namespace cc |
OLD | NEW |