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

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

Issue 1778673005: cc: ImageDecodes: Remove ref counting from SIDC::DecodedImage. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 9 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 253 matching lines...) Expand 10 before | Expand all | Expand 10 after
264 264
265 auto image_it = decoded_images_.Peek(key); 265 auto image_it = decoded_images_.Peek(key);
266 if (image_it != decoded_images_.end()) { 266 if (image_it != decoded_images_.end()) {
267 if (image_it->second->is_locked() || image_it->second->Lock()) { 267 if (image_it->second->is_locked() || image_it->second->Lock()) {
268 pending_image_tasks_.erase(key); 268 pending_image_tasks_.erase(key);
269 return; 269 return;
270 } 270 }
271 decoded_images_.Erase(image_it); 271 decoded_images_.Erase(image_it);
272 } 272 }
273 273
274 scoped_refptr<DecodedImage> decoded_image; 274 scoped_ptr<DecodedImage> decoded_image;
275 { 275 {
276 base::AutoUnlock unlock(lock_); 276 base::AutoUnlock unlock(lock_);
277 decoded_image = DecodeImageInternal(key, image); 277 decoded_image = DecodeImageInternal(key, image);
278 } 278 }
279 279
280 // Erase the pending task from the queue, since the task won't be doing 280 // Erase the pending task from the queue, since the task won't be doing
281 // anything useful after this function terminates. That is, if this image 281 // anything useful after this function terminates. That is, if this image
282 // needs to be decoded again, we have to create a new task. 282 // needs to be decoded again, we have to create a new task.
283 pending_image_tasks_.erase(key); 283 pending_image_tasks_.erase(key);
284 284
(...skipping 20 matching lines...) Expand all
305 // ref counts. Unlock it immediately in this case. 305 // ref counts. Unlock it immediately in this case.
306 if (decoded_images_ref_counts_.find(key) == 306 if (decoded_images_ref_counts_.find(key) ==
307 decoded_images_ref_counts_.end()) { 307 decoded_images_ref_counts_.end()) {
308 decoded_image->Unlock(); 308 decoded_image->Unlock();
309 } 309 }
310 310
311 decoded_images_.Put(key, std::move(decoded_image)); 311 decoded_images_.Put(key, std::move(decoded_image));
312 SanityCheckState(__LINE__, true); 312 SanityCheckState(__LINE__, true);
313 } 313 }
314 314
315 scoped_refptr<SoftwareImageDecodeController::DecodedImage> 315 scoped_ptr<SoftwareImageDecodeController::DecodedImage>
316 SoftwareImageDecodeController::DecodeImageInternal( 316 SoftwareImageDecodeController::DecodeImageInternal(
317 const ImageKey& key, 317 const ImageKey& key,
318 const DrawImage& draw_image) { 318 const DrawImage& draw_image) {
319 TRACE_EVENT1("disabled-by-default-cc.debug", 319 TRACE_EVENT1("disabled-by-default-cc.debug",
320 "SoftwareImageDecodeController::DecodeImageInternal", "key", 320 "SoftwareImageDecodeController::DecodeImageInternal", "key",
321 key.ToString()); 321 key.ToString());
322 const SkImage* image = draw_image.image(); 322 const SkImage* image = draw_image.image();
323 323
324 // If we can use the original decode, then we don't need to do scaling. We can 324 // If we can use the original decode, then we don't need to do scaling. We can
325 // just read pixels into the final memory. 325 // just read pixels into the final memory.
(...skipping 18 matching lines...) Expand all
344 bool result = image->readPixels(decoded_info, decoded_pixels->data(), 344 bool result = image->readPixels(decoded_info, decoded_pixels->data(),
345 decoded_info.minRowBytes(), 0, 0, 345 decoded_info.minRowBytes(), 0, 0,
346 SkImage::kDisallow_CachingHint); 346 SkImage::kDisallow_CachingHint);
347 347
348 if (!result) { 348 if (!result) {
349 decoded_pixels->Unlock(); 349 decoded_pixels->Unlock();
350 return nullptr; 350 return nullptr;
351 } 351 }
352 } 352 }
353 353
354 return make_scoped_refptr(new DecodedImage( 354 return make_scoped_ptr(new DecodedImage(
355 decoded_info, std::move(decoded_pixels), SkSize::Make(0, 0))); 355 decoded_info, std::move(decoded_pixels), SkSize::Make(0, 0)));
356 } 356 }
357 357
358 // If we get here, that means we couldn't use the original sized decode for 358 // If we get here, that means we couldn't use the original sized decode for
359 // whatever reason. However, in all cases we do need an original decode to 359 // whatever reason. However, in all cases we do need an original decode to
360 // either do a scale or to extract a subrect from the image. So, what we can 360 // either do a scale or to extract a subrect from the image. So, what we can
361 // do is construct a key that would require a full sized decode, then get that 361 // do is construct a key that would require a full sized decode, then get that
362 // decode via GetDecodedImageForDrawInternal(), use it, and unref it. This 362 // decode via GetDecodedImageForDrawInternal(), use it, and unref it. This
363 // ensures that if the original sized decode is already available in any of 363 // ensures that if the original sized decode is already available in any of
364 // the caches, we reuse that. We also ensure that all the proper locking takes 364 // the caches, we reuse that. We also ensure that all the proper locking takes
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
417 bool result = 417 bool result =
418 decoded_pixmap.scalePixels(scaled_pixmap, key.filter_quality()); 418 decoded_pixmap.scalePixels(scaled_pixmap, key.filter_quality());
419 DCHECK(result); 419 DCHECK(result);
420 } 420 }
421 421
422 // Release the original sized decode. Any other intermediate result to release 422 // Release the original sized decode. Any other intermediate result to release
423 // would be the subrect memory. However, that's in a scoped_ptr and will be 423 // would be the subrect memory. However, that's in a scoped_ptr and will be
424 // deleted automatically when we return. 424 // deleted automatically when we return.
425 DrawWithImageFinished(original_size_draw_image, decoded_draw_image); 425 DrawWithImageFinished(original_size_draw_image, decoded_draw_image);
426 426
427 return make_scoped_refptr( 427 return make_scoped_ptr(
428 new DecodedImage(scaled_info, std::move(scaled_pixels), 428 new DecodedImage(scaled_info, std::move(scaled_pixels),
429 SkSize::Make(-key.src_rect().x(), -key.src_rect().y()))); 429 SkSize::Make(-key.src_rect().x(), -key.src_rect().y())));
430 } 430 }
431 431
432 DecodedDrawImage SoftwareImageDecodeController::GetDecodedImageForDraw( 432 DecodedDrawImage SoftwareImageDecodeController::GetDecodedImageForDraw(
433 const DrawImage& draw_image) { 433 const DrawImage& draw_image) {
434 ImageKey key = ImageKey::FromDrawImage(draw_image); 434 ImageKey key = ImageKey::FromDrawImage(draw_image);
435 TRACE_EVENT1("disabled-by-default-cc.debug", 435 TRACE_EVENT1("disabled-by-default-cc.debug",
436 "SoftwareImageDecodeController::GetDecodedImageForDraw", "key", 436 "SoftwareImageDecodeController::GetDecodedImageForDraw", "key",
437 key.ToString()); 437 key.ToString());
(...skipping 10 matching lines...) Expand all
448 DecodedDrawImage SoftwareImageDecodeController::GetDecodedImageForDrawInternal( 448 DecodedDrawImage SoftwareImageDecodeController::GetDecodedImageForDrawInternal(
449 const ImageKey& key, 449 const ImageKey& key,
450 const DrawImage& draw_image) { 450 const DrawImage& draw_image) {
451 TRACE_EVENT1("disabled-by-default-cc.debug", 451 TRACE_EVENT1("disabled-by-default-cc.debug",
452 "SoftwareImageDecodeController::GetDecodedImageForDrawInternal", 452 "SoftwareImageDecodeController::GetDecodedImageForDrawInternal",
453 "key", key.ToString()); 453 "key", key.ToString());
454 base::AutoLock lock(lock_); 454 base::AutoLock lock(lock_);
455 auto decoded_images_it = decoded_images_.Get(key); 455 auto decoded_images_it = decoded_images_.Get(key);
456 // If we found the image and it's locked, then return it. If it's not locked, 456 // If we found the image and it's locked, then return it. If it's not locked,
457 // erase it from the cache since it might be put into the at-raster cache. 457 // erase it from the cache since it might be put into the at-raster cache.
458 scoped_refptr<DecodedImage> decoded_image; 458 scoped_ptr<DecodedImage> scoped_decoded_image;
459 DecodedImage* decoded_image = nullptr;
459 if (decoded_images_it != decoded_images_.end()) { 460 if (decoded_images_it != decoded_images_.end()) {
460 decoded_image = decoded_images_it->second; 461 decoded_image = decoded_images_it->second.get();
461 if (decoded_image->is_locked()) { 462 if (decoded_image->is_locked()) {
462 RefImage(key); 463 RefImage(key);
463 SanityCheckState(__LINE__, true); 464 SanityCheckState(__LINE__, true);
464 return DecodedDrawImage( 465 return DecodedDrawImage(
465 decoded_image->image(), decoded_image->src_rect_offset(), 466 decoded_image->image(), decoded_image->src_rect_offset(),
466 GetScaleAdjustment(key), GetDecodedFilterQuality(key)); 467 GetScaleAdjustment(key), GetDecodedFilterQuality(key));
467 } else { 468 } else {
469 scoped_decoded_image = std::move(decoded_images_it->second);
468 decoded_images_.Erase(decoded_images_it); 470 decoded_images_.Erase(decoded_images_it);
469 } 471 }
470 } 472 }
471 473
472 // See if another thread already decoded this image at raster time. If so, we 474 // See if another thread already decoded this image at raster time. If so, we
473 // can just use that result directly. 475 // can just use that result directly.
474 auto at_raster_images_it = at_raster_decoded_images_.Get(key); 476 auto at_raster_images_it = at_raster_decoded_images_.Get(key);
475 if (at_raster_images_it != at_raster_decoded_images_.end()) { 477 if (at_raster_images_it != at_raster_decoded_images_.end()) {
476 DCHECK(at_raster_images_it->second->is_locked()); 478 DCHECK(at_raster_images_it->second->is_locked());
477 RefAtRasterImage(key); 479 RefAtRasterImage(key);
478 SanityCheckState(__LINE__, true); 480 SanityCheckState(__LINE__, true);
479 const scoped_refptr<DecodedImage>& at_raster_decoded_image = 481 DecodedImage* at_raster_decoded_image = at_raster_images_it->second.get();
480 at_raster_images_it->second;
481 auto decoded_draw_image = 482 auto decoded_draw_image =
482 DecodedDrawImage(at_raster_decoded_image->image(), 483 DecodedDrawImage(at_raster_decoded_image->image(),
483 at_raster_decoded_image->src_rect_offset(), 484 at_raster_decoded_image->src_rect_offset(),
484 GetScaleAdjustment(key), GetDecodedFilterQuality(key)); 485 GetScaleAdjustment(key), GetDecodedFilterQuality(key));
485 decoded_draw_image.set_at_raster_decode(true); 486 decoded_draw_image.set_at_raster_decode(true);
486 return decoded_draw_image; 487 return decoded_draw_image;
487 } 488 }
488 489
489 // Now we know that we don't have a locked image, and we seem to be the first 490 // Now we know that we don't have a locked image, and we seem to be the first
490 // thread encountering this image (that might not be true, since other threads 491 // thread encountering this image (that might not be true, since other threads
491 // might be decoding it already). This means that we need to decode the image 492 // might be decoding it already). This means that we need to decode the image
492 // assuming we can't lock the one we found in the cache. 493 // assuming we can't lock the one we found in the cache.
493 bool check_at_raster_cache = false; 494 bool check_at_raster_cache = false;
494 if (!decoded_image || !decoded_image->Lock()) { 495 if (!decoded_image || !decoded_image->Lock()) {
495 // Note that we have to release the lock, since this lock is also accessed 496 // Note that we have to release the lock, since this lock is also accessed
496 // on the compositor thread. This means holding on to the lock might stall 497 // on the compositor thread. This means holding on to the lock might stall
497 // the compositor thread for the duration of the decode! 498 // the compositor thread for the duration of the decode!
498 base::AutoUnlock unlock(lock_); 499 base::AutoUnlock unlock(lock_);
499 decoded_image = DecodeImageInternal(key, draw_image); 500 scoped_decoded_image = DecodeImageInternal(key, draw_image);
501 decoded_image = scoped_decoded_image.get();
500 502
501 // Skip the image if we couldn't decode it. 503 // Skip the image if we couldn't decode it.
502 if (!decoded_image) 504 if (!decoded_image)
503 return DecodedDrawImage(nullptr, kNone_SkFilterQuality); 505 return DecodedDrawImage(nullptr, kNone_SkFilterQuality);
504 check_at_raster_cache = true; 506 check_at_raster_cache = true;
505 } 507 }
506 508
509 DCHECK(decoded_image == scoped_decoded_image.get());
510
507 // While we unlocked the lock, it could be the case that another thread 511 // While we unlocked the lock, it could be the case that another thread
508 // already decoded this already and put it in the at-raster cache. Look it up 512 // already decoded this already and put it in the at-raster cache. Look it up
509 // first. 513 // first.
510 bool need_to_add_image_to_cache = true;
511 if (check_at_raster_cache) { 514 if (check_at_raster_cache) {
512 at_raster_images_it = at_raster_decoded_images_.Get(key); 515 at_raster_images_it = at_raster_decoded_images_.Get(key);
513 if (at_raster_images_it != at_raster_decoded_images_.end()) { 516 if (at_raster_images_it != at_raster_decoded_images_.end()) {
514 // We have to drop our decode, since the one in the cache is being used by 517 // We have to drop our decode, since the one in the cache is being used by
515 // another thread. 518 // another thread.
516 decoded_image->Unlock(); 519 decoded_image->Unlock();
517 decoded_image = at_raster_images_it->second; 520 decoded_image = at_raster_images_it->second.get();
518 need_to_add_image_to_cache = false; 521 scoped_decoded_image = nullptr;
519 } 522 }
520 } 523 }
521 524
522 // If we really are the first ones, or if the other thread already unlocked 525 // If we really are the first ones, or if the other thread already unlocked
523 // the image, then put our work into at-raster time cache. 526 // the image, then put our work into at-raster time cache.
524 if (need_to_add_image_to_cache) 527 if (scoped_decoded_image)
525 at_raster_decoded_images_.Put(key, decoded_image); 528 at_raster_decoded_images_.Put(key, std::move(scoped_decoded_image));
526 529
527 DCHECK(decoded_image); 530 DCHECK(decoded_image);
528 DCHECK(decoded_image->is_locked()); 531 DCHECK(decoded_image->is_locked());
529 RefAtRasterImage(key); 532 RefAtRasterImage(key);
530 SanityCheckState(__LINE__, true); 533 SanityCheckState(__LINE__, true);
531 auto decoded_draw_image = 534 auto decoded_draw_image =
532 DecodedDrawImage(decoded_image->image(), decoded_image->src_rect_offset(), 535 DecodedDrawImage(decoded_image->image(), decoded_image->src_rect_offset(),
533 GetScaleAdjustment(key), GetDecodedFilterQuality(key)); 536 GetScaleAdjustment(key), GetDecodedFilterQuality(key));
534 decoded_draw_image.set_at_raster_decode(true); 537 decoded_draw_image.set_at_raster_decode(true);
535 return decoded_draw_image; 538 return decoded_draw_image;
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
588 // 2b. ... and is unlocked and... 591 // 2b. ... and is unlocked and...
589 // 2b1. ... its ref count is 0: unlock our image and replace the 592 // 2b1. ... its ref count is 0: unlock our image and replace the
590 // existing one with ours. 593 // existing one with ours.
591 // 2b2. ... its ref count is not 0: this shouldn't be possible. 594 // 2b2. ... its ref count is not 0: this shouldn't be possible.
592 auto image_it = decoded_images_.Peek(key); 595 auto image_it = decoded_images_.Peek(key);
593 if (image_it == decoded_images_.end()) { 596 if (image_it == decoded_images_.end()) {
594 if (decoded_images_ref_counts_.find(key) == 597 if (decoded_images_ref_counts_.find(key) ==
595 decoded_images_ref_counts_.end()) { 598 decoded_images_ref_counts_.end()) {
596 at_raster_image_it->second->Unlock(); 599 at_raster_image_it->second->Unlock();
597 } 600 }
598 decoded_images_.Put(key, at_raster_image_it->second); 601 decoded_images_.Put(key, std::move(at_raster_image_it->second));
599 } else if (image_it->second->is_locked()) { 602 } else if (image_it->second->is_locked()) {
600 at_raster_image_it->second->Unlock(); 603 at_raster_image_it->second->Unlock();
601 } else { 604 } else {
602 DCHECK(decoded_images_ref_counts_.find(key) == 605 DCHECK(decoded_images_ref_counts_.find(key) ==
603 decoded_images_ref_counts_.end()); 606 decoded_images_ref_counts_.end());
604 at_raster_image_it->second->Unlock(); 607 at_raster_image_it->second->Unlock();
605 decoded_images_.Erase(image_it); 608 decoded_images_.Erase(image_it);
606 decoded_images_.Put(key, at_raster_image_it->second); 609 decoded_images_.Put(key, std::move(at_raster_image_it->second));
607 } 610 }
608 at_raster_decoded_images_.Erase(at_raster_image_it); 611 at_raster_decoded_images_.Erase(at_raster_image_it);
609 } 612 }
610 } 613 }
611 614
612 bool SoftwareImageDecodeController::CanHandleImage(const ImageKey& key) { 615 bool SoftwareImageDecodeController::CanHandleImage(const ImageKey& key) {
613 // TODO(vmpstr): Start handling medium filter quality as well. 616 // TODO(vmpstr): Start handling medium filter quality as well.
614 return key.filter_quality() != kMedium_SkFilterQuality; 617 return key.filter_quality() != kMedium_SkFilterQuality;
615 } 618 }
616 619
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after
829 void SoftwareImageDecodeController::MemoryBudget::ResetUsage() { 832 void SoftwareImageDecodeController::MemoryBudget::ResetUsage() {
830 current_usage_bytes_ = 0; 833 current_usage_bytes_ = 0;
831 } 834 }
832 835
833 size_t SoftwareImageDecodeController::MemoryBudget::GetCurrentUsageSafe() 836 size_t SoftwareImageDecodeController::MemoryBudget::GetCurrentUsageSafe()
834 const { 837 const {
835 return current_usage_bytes_.ValueOrDie(); 838 return current_usage_bytes_.ValueOrDie();
836 } 839 }
837 840
838 } // namespace cc 841 } // 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