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

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

Issue 2813063002: cc: Remove SanityCheckState from software image cache. (Closed)
Patch Set: update Created 3 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_cache.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_cache.h" 5 #include "cc/tiles/software_image_decode_cache.h"
6 6
7 #include <inttypes.h> 7 #include <inttypes.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include <algorithm> 10 #include <algorithm>
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after
267 // If we already have the image in cache, then we can return it. 267 // If we already have the image in cache, then we can return it.
268 auto decoded_it = decoded_images_.Get(key); 268 auto decoded_it = decoded_images_.Get(key);
269 bool new_image_fits_in_memory = 269 bool new_image_fits_in_memory =
270 locked_images_budget_.AvailableMemoryBytes() >= key.locked_bytes(); 270 locked_images_budget_.AvailableMemoryBytes() >= key.locked_bytes();
271 if (decoded_it != decoded_images_.end()) { 271 if (decoded_it != decoded_images_.end()) {
272 bool image_was_locked = decoded_it->second->is_locked(); 272 bool image_was_locked = decoded_it->second->is_locked();
273 if (image_was_locked || 273 if (image_was_locked ||
274 (new_image_fits_in_memory && decoded_it->second->Lock())) { 274 (new_image_fits_in_memory && decoded_it->second->Lock())) {
275 RefImage(key); 275 RefImage(key);
276 *task = nullptr; 276 *task = nullptr;
277 SanityCheckState(__LINE__, true);
278 277
279 // If the image wasn't locked, then we just succeeded in locking it. 278 // If the image wasn't locked, then we just succeeded in locking it.
280 if (!image_was_locked) { 279 if (!image_was_locked) {
281 RecordLockExistingCachedImageHistogram(tracing_info.requesting_tile_bin, 280 RecordLockExistingCachedImageHistogram(tracing_info.requesting_tile_bin,
282 true); 281 true);
283 } 282 }
284 return true; 283 return true;
285 } 284 }
286 285
287 // If the image fits in memory, then we at least tried to lock it and 286 // If the image fits in memory, then we at least tried to lock it and
(...skipping 10 matching lines...) Expand all
298 // If the task exists, return it. Note that if we always need to create a new 297 // If the task exists, return it. Note that if we always need to create a new
299 // task, then just set |existing_task| to reference the passed in task (which 298 // task, then just set |existing_task| to reference the passed in task (which
300 // is set to nullptr above). 299 // is set to nullptr above).
301 scoped_refptr<TileTask>& existing_task = 300 scoped_refptr<TileTask>& existing_task =
302 (task_type == DecodeTaskType::USE_IN_RASTER_TASKS) 301 (task_type == DecodeTaskType::USE_IN_RASTER_TASKS)
303 ? pending_in_raster_image_tasks_[key] 302 ? pending_in_raster_image_tasks_[key]
304 : pending_out_of_raster_image_tasks_[key]; 303 : pending_out_of_raster_image_tasks_[key];
305 if (existing_task) { 304 if (existing_task) {
306 RefImage(key); 305 RefImage(key);
307 *task = existing_task; 306 *task = existing_task;
308 SanityCheckState(__LINE__, true);
309 return true; 307 return true;
310 } 308 }
311 309
312 // At this point, we have to create a new image/task, so we need to abort if 310 // At this point, we have to create a new image/task, so we need to abort if
313 // it doesn't fit into memory and there are currently no raster tasks that 311 // it doesn't fit into memory and there are currently no raster tasks that
314 // would have already accounted for memory. The latter part is possible if 312 // would have already accounted for memory. The latter part is possible if
315 // there's a running raster task that could not be canceled, and still has a 313 // there's a running raster task that could not be canceled, and still has a
316 // ref to the image that is now being reffed for the new schedule. 314 // ref to the image that is now being reffed for the new schedule.
317 if (!new_image_fits_in_memory && (decoded_images_ref_counts_.find(key) == 315 if (!new_image_fits_in_memory && (decoded_images_ref_counts_.find(key) ==
318 decoded_images_ref_counts_.end())) { 316 decoded_images_ref_counts_.end())) {
319 *task = nullptr; 317 *task = nullptr;
320 SanityCheckState(__LINE__, true);
321 return false; 318 return false;
322 } 319 }
323 320
324 // Actually create the task. RefImage will account for memory on the first 321 // Actually create the task. RefImage will account for memory on the first
325 // ref. 322 // ref.
326 RefImage(key); 323 RefImage(key);
327 existing_task = make_scoped_refptr( 324 existing_task = make_scoped_refptr(
328 new ImageDecodeTaskImpl(this, key, image, task_type, tracing_info)); 325 new ImageDecodeTaskImpl(this, key, image, task_type, tracing_info));
329 *task = existing_task; 326 *task = existing_task;
330 SanityCheckState(__LINE__, true);
331 return true; 327 return true;
332 } 328 }
333 329
334 void SoftwareImageDecodeCache::RefImage(const ImageKey& key) { 330 void SoftwareImageDecodeCache::RefImage(const ImageKey& key) {
335 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"), 331 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
336 "SoftwareImageDecodeCache::RefImage", "key", key.ToString()); 332 "SoftwareImageDecodeCache::RefImage", "key", key.ToString());
337 lock_.AssertAcquired(); 333 lock_.AssertAcquired();
338 int ref = ++decoded_images_ref_counts_[key]; 334 int ref = ++decoded_images_ref_counts_[key];
339 if (ref == 1) { 335 if (ref == 1) {
340 DCHECK_GE(locked_images_budget_.AvailableMemoryBytes(), key.locked_bytes()); 336 DCHECK_GE(locked_images_budget_.AvailableMemoryBytes(), key.locked_bytes());
(...skipping 17 matching lines...) Expand all
358 DCHECK(ref_count_it != decoded_images_ref_counts_.end()); 354 DCHECK(ref_count_it != decoded_images_ref_counts_.end());
359 355
360 --ref_count_it->second; 356 --ref_count_it->second;
361 if (ref_count_it->second == 0) { 357 if (ref_count_it->second == 0) {
362 decoded_images_ref_counts_.erase(ref_count_it); 358 decoded_images_ref_counts_.erase(ref_count_it);
363 locked_images_budget_.SubtractUsage(key.locked_bytes()); 359 locked_images_budget_.SubtractUsage(key.locked_bytes());
364 360
365 auto decoded_image_it = decoded_images_.Peek(key); 361 auto decoded_image_it = decoded_images_.Peek(key);
366 // If we've never decoded the image before ref reached 0, then we wouldn't 362 // If we've never decoded the image before ref reached 0, then we wouldn't
367 // have it in our cache. This would happen if we canceled tasks. 363 // have it in our cache. This would happen if we canceled tasks.
368 if (decoded_image_it == decoded_images_.end()) { 364 if (decoded_image_it == decoded_images_.end())
369 SanityCheckState(__LINE__, true);
370 return; 365 return;
371 }
372 DCHECK(decoded_image_it->second->is_locked()); 366 DCHECK(decoded_image_it->second->is_locked());
373 decoded_image_it->second->Unlock(); 367 decoded_image_it->second->Unlock();
374 } 368 }
375 SanityCheckState(__LINE__, true);
376 } 369 }
377 370
378 void SoftwareImageDecodeCache::DecodeImage(const ImageKey& key, 371 void SoftwareImageDecodeCache::DecodeImage(const ImageKey& key,
379 const DrawImage& image, 372 const DrawImage& image,
380 DecodeTaskType task_type) { 373 DecodeTaskType task_type) {
381 TRACE_EVENT1("cc", "SoftwareImageDecodeCache::DecodeImage", "key", 374 TRACE_EVENT1("cc", "SoftwareImageDecodeCache::DecodeImage", "key",
382 key.ToString()); 375 key.ToString());
383 base::AutoLock lock(lock_); 376 base::AutoLock lock(lock_);
384 AutoRemoveKeyFromTaskMap remove_key_from_task_map( 377 AutoRemoveKeyFromTaskMap remove_key_from_task_map(
385 (task_type == DecodeTaskType::USE_IN_RASTER_TASKS) 378 (task_type == DecodeTaskType::USE_IN_RASTER_TASKS)
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
429 422
430 // We could have finished all of the raster tasks (cancelled) while this image 423 // We could have finished all of the raster tasks (cancelled) while this image
431 // decode task was running, which means that we now have a locked image but no 424 // decode task was running, which means that we now have a locked image but no
432 // ref counts. Unlock it immediately in this case. 425 // ref counts. Unlock it immediately in this case.
433 if (decoded_images_ref_counts_.find(key) == 426 if (decoded_images_ref_counts_.find(key) ==
434 decoded_images_ref_counts_.end()) { 427 decoded_images_ref_counts_.end()) {
435 decoded_image->Unlock(); 428 decoded_image->Unlock();
436 } 429 }
437 430
438 decoded_images_.Put(key, std::move(decoded_image)); 431 decoded_images_.Put(key, std::move(decoded_image));
439 SanityCheckState(__LINE__, true);
440 } 432 }
441 433
442 std::unique_ptr<SoftwareImageDecodeCache::DecodedImage> 434 std::unique_ptr<SoftwareImageDecodeCache::DecodedImage>
443 SoftwareImageDecodeCache::DecodeImageInternal(const ImageKey& key, 435 SoftwareImageDecodeCache::DecodeImageInternal(const ImageKey& key,
444 const DrawImage& draw_image) { 436 const DrawImage& draw_image) {
445 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"), 437 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
446 "SoftwareImageDecodeCache::DecodeImageInternal", "key", 438 "SoftwareImageDecodeCache::DecodeImageInternal", "key",
447 key.ToString()); 439 key.ToString());
448 sk_sp<const SkImage> image = draw_image.image(); 440 sk_sp<const SkImage> image = draw_image.image();
449 if (!image) 441 if (!image)
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
487 auto decoded_images_it = decoded_images_.Get(key); 479 auto decoded_images_it = decoded_images_.Get(key);
488 // If we found the image and it's locked, then return it. If it's not locked, 480 // If we found the image and it's locked, then return it. If it's not locked,
489 // erase it from the cache since it might be put into the at-raster cache. 481 // erase it from the cache since it might be put into the at-raster cache.
490 std::unique_ptr<DecodedImage> scoped_decoded_image; 482 std::unique_ptr<DecodedImage> scoped_decoded_image;
491 DecodedImage* decoded_image = nullptr; 483 DecodedImage* decoded_image = nullptr;
492 if (decoded_images_it != decoded_images_.end()) { 484 if (decoded_images_it != decoded_images_.end()) {
493 decoded_image = decoded_images_it->second.get(); 485 decoded_image = decoded_images_it->second.get();
494 if (decoded_image->is_locked()) { 486 if (decoded_image->is_locked()) {
495 RefImage(key); 487 RefImage(key);
496 decoded_image->mark_used(); 488 decoded_image->mark_used();
497 SanityCheckState(__LINE__, true);
498 return DecodedDrawImage( 489 return DecodedDrawImage(
499 decoded_image->image(), decoded_image->src_rect_offset(), 490 decoded_image->image(), decoded_image->src_rect_offset(),
500 GetScaleAdjustment(key), GetDecodedFilterQuality(key)); 491 GetScaleAdjustment(key), GetDecodedFilterQuality(key));
501 } else { 492 } else {
502 scoped_decoded_image = std::move(decoded_images_it->second); 493 scoped_decoded_image = std::move(decoded_images_it->second);
503 decoded_images_.Erase(decoded_images_it); 494 decoded_images_.Erase(decoded_images_it);
504 } 495 }
505 } 496 }
506 497
507 // See if another thread already decoded this image at raster time. If so, we 498 // See if another thread already decoded this image at raster time. If so, we
508 // can just use that result directly. 499 // can just use that result directly.
509 auto at_raster_images_it = at_raster_decoded_images_.Get(key); 500 auto at_raster_images_it = at_raster_decoded_images_.Get(key);
510 if (at_raster_images_it != at_raster_decoded_images_.end()) { 501 if (at_raster_images_it != at_raster_decoded_images_.end()) {
511 DCHECK(at_raster_images_it->second->is_locked()); 502 DCHECK(at_raster_images_it->second->is_locked());
512 RefAtRasterImage(key); 503 RefAtRasterImage(key);
513 SanityCheckState(__LINE__, true);
514 DecodedImage* at_raster_decoded_image = at_raster_images_it->second.get(); 504 DecodedImage* at_raster_decoded_image = at_raster_images_it->second.get();
515 at_raster_decoded_image->mark_used(); 505 at_raster_decoded_image->mark_used();
516 auto decoded_draw_image = 506 auto decoded_draw_image =
517 DecodedDrawImage(at_raster_decoded_image->image(), 507 DecodedDrawImage(at_raster_decoded_image->image(),
518 at_raster_decoded_image->src_rect_offset(), 508 at_raster_decoded_image->src_rect_offset(),
519 GetScaleAdjustment(key), GetDecodedFilterQuality(key)); 509 GetScaleAdjustment(key), GetDecodedFilterQuality(key));
520 decoded_draw_image.set_at_raster_decode(true); 510 decoded_draw_image.set_at_raster_decode(true);
521 return decoded_draw_image; 511 return decoded_draw_image;
522 } 512 }
523 513
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
557 } 547 }
558 548
559 // If we really are the first ones, or if the other thread already unlocked 549 // If we really are the first ones, or if the other thread already unlocked
560 // the image, then put our work into at-raster time cache. 550 // the image, then put our work into at-raster time cache.
561 if (scoped_decoded_image) 551 if (scoped_decoded_image)
562 at_raster_decoded_images_.Put(key, std::move(scoped_decoded_image)); 552 at_raster_decoded_images_.Put(key, std::move(scoped_decoded_image));
563 553
564 DCHECK(decoded_image); 554 DCHECK(decoded_image);
565 DCHECK(decoded_image->is_locked()); 555 DCHECK(decoded_image->is_locked());
566 RefAtRasterImage(key); 556 RefAtRasterImage(key);
567 SanityCheckState(__LINE__, true);
568 decoded_image->mark_used(); 557 decoded_image->mark_used();
569 auto decoded_draw_image = 558 auto decoded_draw_image =
570 DecodedDrawImage(decoded_image->image(), decoded_image->src_rect_offset(), 559 DecodedDrawImage(decoded_image->image(), decoded_image->src_rect_offset(),
571 GetScaleAdjustment(key), GetDecodedFilterQuality(key)); 560 GetScaleAdjustment(key), GetDecodedFilterQuality(key));
572 decoded_draw_image.set_at_raster_decode(true); 561 decoded_draw_image.set_at_raster_decode(true);
573 return decoded_draw_image; 562 return decoded_draw_image;
574 } 563 }
575 564
576 std::unique_ptr<SoftwareImageDecodeCache::DecodedImage> 565 std::unique_ptr<SoftwareImageDecodeCache::DecodedImage>
577 SoftwareImageDecodeCache::GetOriginalImageDecode(sk_sp<const SkImage> image) { 566 SoftwareImageDecodeCache::GetOriginalImageDecode(sk_sp<const SkImage> image) {
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
741 "SoftwareImageDecodeCache::DrawWithImageFinished", "key", 730 "SoftwareImageDecodeCache::DrawWithImageFinished", "key",
742 ImageKey::FromDrawImage(image).ToString()); 731 ImageKey::FromDrawImage(image).ToString());
743 ImageKey key = ImageKey::FromDrawImage(image); 732 ImageKey key = ImageKey::FromDrawImage(image);
744 if (!decoded_image.image()) 733 if (!decoded_image.image())
745 return; 734 return;
746 735
747 if (decoded_image.is_at_raster_decode()) 736 if (decoded_image.is_at_raster_decode())
748 UnrefAtRasterImage(key); 737 UnrefAtRasterImage(key);
749 else 738 else
750 UnrefImage(image); 739 UnrefImage(image);
751 SanityCheckState(__LINE__, false);
752 } 740 }
753 741
754 void SoftwareImageDecodeCache::RefAtRasterImage(const ImageKey& key) { 742 void SoftwareImageDecodeCache::RefAtRasterImage(const ImageKey& key) {
755 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"), 743 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
756 "SoftwareImageDecodeCache::RefAtRasterImage", "key", 744 "SoftwareImageDecodeCache::RefAtRasterImage", "key",
757 key.ToString()); 745 key.ToString());
758 DCHECK(at_raster_decoded_images_.Peek(key) != 746 DCHECK(at_raster_decoded_images_.Peek(key) !=
759 at_raster_decoded_images_.end()); 747 at_raster_decoded_images_.end());
760 ++at_raster_decoded_images_ref_counts_[key]; 748 ++at_raster_decoded_images_ref_counts_[key];
761 } 749 }
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
885 image_pair.second->memory()->CreateMemoryAllocatorDump( 873 image_pair.second->memory()->CreateMemoryAllocatorDump(
886 dump_name.c_str(), pmd); 874 dump_name.c_str(), pmd);
887 DCHECK(dump); 875 DCHECK(dump);
888 size_t locked_bytes = 876 size_t locked_bytes =
889 image_pair.second->is_locked() ? image_pair.first.locked_bytes() : 0u; 877 image_pair.second->is_locked() ? image_pair.first.locked_bytes() : 0u;
890 dump->AddScalar("locked_size", MemoryAllocatorDump::kUnitsBytes, 878 dump->AddScalar("locked_size", MemoryAllocatorDump::kUnitsBytes,
891 locked_bytes); 879 locked_bytes);
892 } 880 }
893 } 881 }
894 882
895 void SoftwareImageDecodeCache::SanityCheckState(int line, bool lock_acquired) {
896 #if DCHECK_IS_ON()
897 if (!lock_acquired) {
898 base::AutoLock lock(lock_);
899 SanityCheckState(line, true);
900 return;
901 }
902
903 MemoryBudget budget(locked_images_budget_.total_limit_bytes());
904 for (const auto& image_pair : decoded_images_) {
905 const auto& key = image_pair.first;
906 const auto& image = image_pair.second;
907
908 auto ref_it = decoded_images_ref_counts_.find(key);
909 if (image->is_locked()) {
910 budget.AddUsage(key.locked_bytes());
911 DCHECK(ref_it != decoded_images_ref_counts_.end()) << line;
912 } else {
913 DCHECK(ref_it == decoded_images_ref_counts_.end() ||
914 pending_in_raster_image_tasks_.find(key) !=
915 pending_in_raster_image_tasks_.end() ||
916 pending_out_of_raster_image_tasks_.find(key) !=
917 pending_out_of_raster_image_tasks_.end())
918 << line;
919 }
920 }
921 DCHECK_GE(budget.AvailableMemoryBytes(),
922 locked_images_budget_.AvailableMemoryBytes())
923 << line;
924 #endif // DCHECK_IS_ON()
925 }
926
927 // SoftwareImageDecodeCacheKey 883 // SoftwareImageDecodeCacheKey
928 ImageDecodeCacheKey ImageDecodeCacheKey::FromDrawImage(const DrawImage& image) { 884 ImageDecodeCacheKey ImageDecodeCacheKey::FromDrawImage(const DrawImage& image) {
929 const SkSize& scale = image.scale(); 885 const SkSize& scale = image.scale();
930 // If the src_rect falls outside of the image, we need to clip it since 886 // If the src_rect falls outside of the image, we need to clip it since
931 // otherwise we might end up with uninitialized memory in the decode process. 887 // otherwise we might end up with uninitialized memory in the decode process.
932 // Note that the scale is still unchanged and the target size is now a 888 // Note that the scale is still unchanged and the target size is now a
933 // function of the new src_rect. 889 // function of the new src_rect.
934 const gfx::Rect& src_rect = GetSrcRect(image); 890 const gfx::Rect& src_rect = GetSrcRect(image);
935 gfx::Size target_size( 891 gfx::Size target_size(
936 SkScalarRoundToInt(std::abs(src_rect.width() * scale.width())), 892 SkScalarRoundToInt(std::abs(src_rect.width() * scale.width())),
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
1200 } 1156 }
1201 } 1157 }
1202 } 1158 }
1203 1159
1204 void SoftwareImageDecodeCache::OnPurgeMemory() { 1160 void SoftwareImageDecodeCache::OnPurgeMemory() {
1205 base::AutoLock lock(lock_); 1161 base::AutoLock lock(lock_);
1206 ReduceCacheUsageUntilWithinLimit(0); 1162 ReduceCacheUsageUntilWithinLimit(0);
1207 } 1163 }
1208 1164
1209 } // namespace cc 1165 } // namespace cc
OLDNEW
« no previous file with comments | « cc/tiles/software_image_decode_cache.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698