OLD | NEW |
1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 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/tile_manager.h" | 5 #include "cc/tile_manager.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/debug/trace_event.h" | 10 #include "base/debug/trace_event.h" |
(...skipping 12 matching lines...) Expand all Loading... |
23 | 23 |
24 // If we raster too fast we become upload bound, and pending | 24 // If we raster too fast we become upload bound, and pending |
25 // uploads consume memory. For maximum upload throughput, we would | 25 // uploads consume memory. For maximum upload throughput, we would |
26 // want to allow for upload_throughput * pipeline_time of pending | 26 // want to allow for upload_throughput * pipeline_time of pending |
27 // uploads, after which we are just wasting memory. Since we don't | 27 // uploads, after which we are just wasting memory. Since we don't |
28 // know our upload throughput yet, this just caps our memory usage. | 28 // know our upload throughput yet, this just caps our memory usage. |
29 #if defined(OS_ANDROID) | 29 #if defined(OS_ANDROID) |
30 // For reference, the Nexus10 can upload 1MB in about 2.5ms. | 30 // For reference, the Nexus10 can upload 1MB in about 2.5ms. |
31 // Assuming a three frame deep pipeline this implies ~20MB. | 31 // Assuming a three frame deep pipeline this implies ~20MB. |
32 const int kMaxPendingUploadBytes = 20 * 1024 * 1024; | 32 const int kMaxPendingUploadBytes = 20 * 1024 * 1024; |
| 33 const int kMaxPendingRasterBytes = 2 * 1024 * 1024; |
33 #else | 34 #else |
34 const int kMaxPendingUploadBytes = 100 * 1024 * 1024; | 35 const int kMaxPendingUploadBytes = 100 * 1024 * 1024; |
| 36 const int kMaxPendingRasterBytes = 10 * 1024 * 1024; |
35 #endif | 37 #endif |
36 | 38 |
37 // Determine bin based on three categories of tiles: things we need now, | 39 // Determine bin based on three categories of tiles: things we need now, |
38 // things we need soon, and eventually. | 40 // things we need soon, and eventually. |
39 inline TileManagerBin BinFromTilePriority(const TilePriority& prio) { | 41 inline TileManagerBin BinFromTilePriority(const TilePriority& prio) { |
40 if (!prio.is_live) | 42 if (!prio.is_live) |
41 return NEVER_BIN; | 43 return NEVER_BIN; |
42 | 44 |
43 // The amount of time for which we want to have prepainting coverage. | 45 // The amount of time for which we want to have prepainting coverage. |
44 const double prepainting_window_time_seconds = 1.0; | 46 const double prepainting_window_time_seconds = 1.0; |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
162 return state.PassAs<base::Value>(); | 164 return state.PassAs<base::Value>(); |
163 } | 165 } |
164 | 166 |
165 TileManager::TileManager( | 167 TileManager::TileManager( |
166 TileManagerClient* client, | 168 TileManagerClient* client, |
167 ResourceProvider* resource_provider, | 169 ResourceProvider* resource_provider, |
168 size_t num_raster_threads, | 170 size_t num_raster_threads, |
169 bool use_cheapness_estimator) | 171 bool use_cheapness_estimator) |
170 : client_(client), | 172 : client_(client), |
171 resource_pool_(ResourcePool::Create(resource_provider)), | 173 resource_pool_(ResourcePool::Create(resource_provider)), |
172 raster_worker_pool_(RasterWorkerPool::Create(num_raster_threads)), | 174 raster_worker_pool_(RasterWorkerPool::Create(this, num_raster_threads)), |
173 manage_tiles_pending_(false), | 175 manage_tiles_pending_(false), |
174 manage_tiles_call_count_(0), | 176 manage_tiles_call_count_(0), |
| 177 ever_exceeded_memory_budget_(false), |
| 178 bytes_pending_raster_(0), |
175 bytes_pending_set_pixels_(0), | 179 bytes_pending_set_pixels_(0), |
176 ever_exceeded_memory_budget_(false), | |
177 record_rendering_stats_(false), | 180 record_rendering_stats_(false), |
178 use_cheapness_estimator_(use_cheapness_estimator) { | 181 use_cheapness_estimator_(use_cheapness_estimator) { |
179 for (int i = 0; i < NUM_STATES; ++i) { | 182 for (int i = 0; i < NUM_STATES; ++i) { |
180 for (int j = 0; j < NUM_TREES; ++j) { | 183 for (int j = 0; j < NUM_TREES; ++j) { |
181 for (int k = 0; k < NUM_BINS; ++k) | 184 for (int k = 0; k < NUM_BINS; ++k) |
182 raster_state_count_[i][j][k] = 0; | 185 raster_state_count_[i][j][k] = 0; |
183 } | 186 } |
184 } | 187 } |
185 } | 188 } |
186 | 189 |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
388 // Assign gpu memory and determine what tiles need to be rasterized. | 391 // Assign gpu memory and determine what tiles need to be rasterized. |
389 AssignGpuMemoryToTiles(); | 392 AssignGpuMemoryToTiles(); |
390 | 393 |
391 TRACE_EVENT_INSTANT1("cc", "DidManage", "state", | 394 TRACE_EVENT_INSTANT1("cc", "DidManage", "state", |
392 ValueToString(BasicStateAsValue())); | 395 ValueToString(BasicStateAsValue())); |
393 | 396 |
394 // Finally, kick the rasterizer. | 397 // Finally, kick the rasterizer. |
395 DispatchMoreTasks(); | 398 DispatchMoreTasks(); |
396 } | 399 } |
397 | 400 |
| 401 void TileManager::CheckForCompletedRasterTasks() { |
| 402 int pending_upload_count = tiles_with_pending_set_pixels_.size(); |
| 403 |
| 404 // Check for completed tasks and dispatch replies. |
| 405 raster_worker_pool_->CheckForCompletedTasks(); |
| 406 |
| 407 // Flush if we began new uploads. |
| 408 if (tiles_with_pending_set_pixels_.size() != pending_upload_count) |
| 409 resource_pool_->resource_provider()->shallowFlushIfSupported(); |
| 410 |
| 411 DispatchMoreTasks(); |
| 412 |
| 413 // Schedule another check if we still have pending raster tasks. |
| 414 if (bytes_pending_raster_) |
| 415 client_->ScheduleCheckForCompletedRasterTasks(); |
| 416 } |
| 417 |
398 void TileManager::CheckForCompletedTileUploads() { | 418 void TileManager::CheckForCompletedTileUploads() { |
399 while (!tiles_with_pending_set_pixels_.empty()) { | 419 while (!tiles_with_pending_set_pixels_.empty()) { |
400 Tile* tile = tiles_with_pending_set_pixels_.front(); | 420 Tile* tile = tiles_with_pending_set_pixels_.front(); |
401 DCHECK(tile->managed_state().resource); | 421 DCHECK(tile->managed_state().resource); |
402 | 422 |
403 // Set pixel tasks complete in the order they are posted. | 423 // Set pixel tasks complete in the order they are posted. |
404 if (!resource_pool_->resource_provider()->didSetPixelsComplete( | 424 if (!resource_pool_->resource_provider()->didSetPixelsComplete( |
405 tile->managed_state().resource->id())) { | 425 tile->managed_state().resource->id())) { |
406 break; | 426 break; |
407 } | 427 } |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
534 case IDLE_STATE: | 554 case IDLE_STATE: |
535 break; | 555 break; |
536 default: | 556 default: |
537 NOTREACHED(); | 557 NOTREACHED(); |
538 } | 558 } |
539 } | 559 } |
540 | 560 |
541 return false; | 561 return false; |
542 } | 562 } |
543 | 563 |
| 564 void TileManager::OnIdle() { |
| 565 client_->DidDetectIdleRaster(); |
| 566 } |
| 567 |
544 void TileManager::AssignGpuMemoryToTiles() { | 568 void TileManager::AssignGpuMemoryToTiles() { |
545 TRACE_EVENT0("cc", "TileManager::AssignGpuMemoryToTiles"); | 569 TRACE_EVENT0("cc", "TileManager::AssignGpuMemoryToTiles"); |
546 // Some memory cannot be released. Figure out which. | 570 // Some memory cannot be released. Figure out which. |
547 size_t unreleasable_bytes = 0; | 571 size_t unreleasable_bytes = 0; |
548 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { | 572 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { |
549 Tile* tile = *it; | 573 Tile* tile = *it; |
550 if (!tile->managed_state().can_be_freed) | 574 if (!tile->managed_state().can_be_freed) |
551 unreleasable_bytes += tile->bytes_consumed_if_allocated(); | 575 unreleasable_bytes += tile->bytes_consumed_if_allocated(); |
552 } | 576 } |
553 | 577 |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
625 } | 649 } |
626 | 650 |
627 void TileManager::FreeResourcesForTile(Tile* tile) { | 651 void TileManager::FreeResourcesForTile(Tile* tile) { |
628 ManagedTileState& managed_tile_state = tile->managed_state(); | 652 ManagedTileState& managed_tile_state = tile->managed_state(); |
629 DCHECK(managed_tile_state.can_be_freed); | 653 DCHECK(managed_tile_state.can_be_freed); |
630 if (managed_tile_state.resource) | 654 if (managed_tile_state.resource) |
631 resource_pool_->ReleaseResource(managed_tile_state.resource.Pass()); | 655 resource_pool_->ReleaseResource(managed_tile_state.resource.Pass()); |
632 } | 656 } |
633 | 657 |
634 bool TileManager::CanDispatchRasterTask(Tile* tile) { | 658 bool TileManager::CanDispatchRasterTask(Tile* tile) { |
635 if (raster_worker_pool_->IsBusy()) | 659 size_t new_raster_bytes_pending = bytes_pending_raster_; |
| 660 new_raster_bytes_pending += tile->bytes_consumed_if_allocated(); |
| 661 if (new_raster_bytes_pending > kMaxPendingRasterBytes) |
636 return false; | 662 return false; |
637 size_t new_bytes_pending = bytes_pending_set_pixels_; | 663 |
638 new_bytes_pending += tile->bytes_consumed_if_allocated(); | 664 size_t new_upload_bytes_pending = bytes_pending_raster_ + |
639 return new_bytes_pending <= kMaxPendingUploadBytes; | 665 bytes_pending_set_pixels_; |
| 666 new_upload_bytes_pending += tile->bytes_consumed_if_allocated(); |
| 667 if (new_upload_bytes_pending > kMaxPendingUploadBytes) |
| 668 return false; |
| 669 |
| 670 return true; |
640 } | 671 } |
641 | 672 |
642 void TileManager::DispatchMoreTasks() { | 673 void TileManager::DispatchMoreTasks() { |
643 // Because tiles in the image decoding list have higher priorities, we | 674 // Because tiles in the image decoding list have higher priorities, we |
644 // need to process those tiles first before we start to handle the tiles | 675 // need to process those tiles first before we start to handle the tiles |
645 // in the need_to_be_rasterized queue. | 676 // in the need_to_be_rasterized queue. |
646 for(TileList::iterator it = tiles_with_image_decoding_tasks_.begin(); | 677 for(TileList::iterator it = tiles_with_image_decoding_tasks_.begin(); |
647 it != tiles_with_image_decoding_tasks_.end(); ) { | 678 it != tiles_with_image_decoding_tasks_.end(); ) { |
648 DispatchImageDecodeTasksForTile(*it); | 679 DispatchImageDecodeTasksForTile(*it); |
649 ManagedTileState& managed_state = (*it)->managed_state(); | 680 ManagedTileState& managed_state = (*it)->managed_state(); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
703 if (pending_decode_tasks_.end() != pending_decode_tasks_.find( | 734 if (pending_decode_tasks_.end() != pending_decode_tasks_.find( |
704 (*it)->getGenerationID())) { | 735 (*it)->getGenerationID())) { |
705 ++it; | 736 ++it; |
706 continue; | 737 continue; |
707 } | 738 } |
708 // TODO(qinmin): passing correct image size to PrepareToDecode(). | 739 // TODO(qinmin): passing correct image size to PrepareToDecode(). |
709 if ((*it)->PrepareToDecode(skia::LazyPixelRef::PrepareParams())) { | 740 if ((*it)->PrepareToDecode(skia::LazyPixelRef::PrepareParams())) { |
710 rendering_stats_.totalDeferredImageCacheHitCount++; | 741 rendering_stats_.totalDeferredImageCacheHitCount++; |
711 pending_pixel_refs.erase(it++); | 742 pending_pixel_refs.erase(it++); |
712 } else { | 743 } else { |
713 if (raster_worker_pool_->IsBusy()) | 744 if (!CanDispatchRasterTask(tile)) |
714 return; | 745 return; |
715 DispatchOneImageDecodeTask(tile, *it); | 746 DispatchOneImageDecodeTask(tile, *it); |
716 ++it; | 747 ++it; |
717 } | 748 } |
718 } | 749 } |
719 } | 750 } |
720 | 751 |
721 void TileManager::DispatchOneImageDecodeTask( | 752 void TileManager::DispatchOneImageDecodeTask( |
722 scoped_refptr<Tile> tile, skia::LazyPixelRef* pixel_ref) { | 753 scoped_refptr<Tile> tile, skia::LazyPixelRef* pixel_ref) { |
723 TRACE_EVENT0("cc", "TileManager::DispatchOneImageDecodeTask"); | 754 TRACE_EVENT0("cc", "TileManager::DispatchOneImageDecodeTask"); |
724 uint32_t pixel_ref_id = pixel_ref->getGenerationID(); | 755 uint32_t pixel_ref_id = pixel_ref->getGenerationID(); |
725 DCHECK(pending_decode_tasks_.end() == | 756 DCHECK(pending_decode_tasks_.end() == |
726 pending_decode_tasks_.find(pixel_ref_id)); | 757 pending_decode_tasks_.find(pixel_ref_id)); |
727 pending_decode_tasks_[pixel_ref_id] = pixel_ref; | 758 pending_decode_tasks_[pixel_ref_id] = pixel_ref; |
728 | 759 |
729 raster_worker_pool_->PostTaskAndReply( | 760 raster_worker_pool_->PostTaskAndReply( |
730 base::Bind(&TileManager::RunImageDecodeTask, pixel_ref), | 761 base::Bind(&TileManager::RunImageDecodeTask, pixel_ref), |
731 base::Bind(&TileManager::OnImageDecodeTaskCompleted, | 762 base::Bind(&TileManager::OnImageDecodeTaskCompleted, |
732 base::Unretained(this), | 763 base::Unretained(this), |
733 tile, | 764 tile, |
734 pixel_ref_id)); | 765 pixel_ref_id)); |
| 766 |
| 767 client_->ScheduleCheckForCompletedRasterTasks(); |
735 } | 768 } |
736 | 769 |
737 void TileManager::OnImageDecodeTaskCompleted( | 770 void TileManager::OnImageDecodeTaskCompleted( |
738 scoped_refptr<Tile> tile, uint32_t pixel_ref_id) { | 771 scoped_refptr<Tile> tile, uint32_t pixel_ref_id) { |
739 TRACE_EVENT0("cc", "TileManager::OnImageDecodeTaskCompleted"); | 772 TRACE_EVENT0("cc", "TileManager::OnImageDecodeTaskCompleted"); |
740 pending_decode_tasks_.erase(pixel_ref_id); | 773 pending_decode_tasks_.erase(pixel_ref_id); |
741 | 774 |
742 for (TileList::iterator it = tiles_with_image_decoding_tasks_.begin(); | 775 for (TileList::iterator it = tiles_with_image_decoding_tasks_.begin(); |
743 it != tiles_with_image_decoding_tasks_.end(); ++it) { | 776 it != tiles_with_image_decoding_tasks_.end(); ++it) { |
744 std::list<skia::LazyPixelRef*>& pixel_refs = | 777 std::list<skia::LazyPixelRef*>& pixel_refs = |
745 (*it)->managed_state().pending_pixel_refs; | 778 (*it)->managed_state().pending_pixel_refs; |
746 for (std::list<skia::LazyPixelRef*>::iterator pixel_it = | 779 for (std::list<skia::LazyPixelRef*>::iterator pixel_it = |
747 pixel_refs.begin(); pixel_it != pixel_refs.end(); ++pixel_it) { | 780 pixel_refs.begin(); pixel_it != pixel_refs.end(); ++pixel_it) { |
748 if (pixel_ref_id == (*pixel_it)->getGenerationID()) { | 781 if (pixel_ref_id == (*pixel_it)->getGenerationID()) { |
749 pixel_refs.erase(pixel_it); | 782 pixel_refs.erase(pixel_it); |
750 break; | 783 break; |
751 } | 784 } |
752 } | 785 } |
753 } | 786 } |
754 | |
755 DispatchMoreTasks(); | |
756 } | 787 } |
757 | 788 |
758 scoped_ptr<ResourcePool::Resource> TileManager::PrepareTileForRaster( | 789 scoped_ptr<ResourcePool::Resource> TileManager::PrepareTileForRaster( |
759 Tile* tile) { | 790 Tile* tile) { |
760 ManagedTileState& managed_tile_state = tile->managed_state(); | 791 ManagedTileState& managed_tile_state = tile->managed_state(); |
761 DCHECK(managed_tile_state.can_use_gpu_memory); | 792 DCHECK(managed_tile_state.can_use_gpu_memory); |
762 scoped_ptr<ResourcePool::Resource> resource = | 793 scoped_ptr<ResourcePool::Resource> resource = |
763 resource_pool_->AcquireResource(tile->tile_size_.size(), tile->format_); | 794 resource_pool_->AcquireResource(tile->tile_size_.size(), tile->format_); |
764 resource_pool_->resource_provider()->acquirePixelBuffer(resource->id()); | 795 resource_pool_->resource_provider()->acquirePixelBuffer(resource->id()); |
765 | 796 |
(...skipping 15 matching lines...) Expand all Loading... |
781 resource_pool_->resource_provider()->mapPixelBuffer( | 812 resource_pool_->resource_provider()->mapPixelBuffer( |
782 resource_id), | 813 resource_id), |
783 tile->content_rect_, | 814 tile->content_rect_, |
784 tile->contents_scale(), | 815 tile->contents_scale(), |
785 use_cheapness_estimator_), | 816 use_cheapness_estimator_), |
786 base::Bind(&TileManager::OnRasterTaskCompleted, | 817 base::Bind(&TileManager::OnRasterTaskCompleted, |
787 base::Unretained(this), | 818 base::Unretained(this), |
788 tile, | 819 tile, |
789 base::Passed(&resource), | 820 base::Passed(&resource), |
790 manage_tiles_call_count_)); | 821 manage_tiles_call_count_)); |
| 822 |
| 823 bytes_pending_raster_ += tile->bytes_consumed_if_allocated(); |
| 824 client_->ScheduleCheckForCompletedRasterTasks(); |
791 } | 825 } |
792 | 826 |
793 void TileManager::PerformOneRaster(Tile* tile) { | 827 void TileManager::PerformOneRaster(Tile* tile) { |
794 scoped_ptr<ResourcePool::Resource> resource = PrepareTileForRaster(tile); | 828 scoped_ptr<ResourcePool::Resource> resource = PrepareTileForRaster(tile); |
795 ResourceProvider::ResourceId resource_id = resource->id(); | 829 ResourceProvider::ResourceId resource_id = resource->id(); |
796 | 830 |
797 PerformRaster(resource_pool_->resource_provider()->mapPixelBuffer( | 831 PerformRaster(resource_pool_->resource_provider()->mapPixelBuffer( |
798 resource_id), | 832 resource_id), |
799 tile->content_rect_, | 833 tile->content_rect_, |
800 tile->contents_scale(), | 834 tile->contents_scale(), |
(...skipping 30 matching lines...) Expand all Loading... |
831 // The component order may be bgra if we're uploading bgra pixels to rgba | 865 // The component order may be bgra if we're uploading bgra pixels to rgba |
832 // texture. Mark contents as swizzled if image component order is | 866 // texture. Mark contents as swizzled if image component order is |
833 // different than texture format. | 867 // different than texture format. |
834 managed_tile_state.contents_swizzled = | 868 managed_tile_state.contents_swizzled = |
835 !PlatformColor::sameComponentOrder(tile->format_); | 869 !PlatformColor::sameComponentOrder(tile->format_); |
836 | 870 |
837 // Tile resources can't be freed until upload has completed. | 871 // Tile resources can't be freed until upload has completed. |
838 managed_tile_state.can_be_freed = false; | 872 managed_tile_state.can_be_freed = false; |
839 | 873 |
840 resource_pool_->resource_provider()->beginSetPixels(resource->id()); | 874 resource_pool_->resource_provider()->beginSetPixels(resource->id()); |
841 resource_pool_->resource_provider()->shallowFlushIfSupported(); | |
842 managed_tile_state.resource = resource.Pass(); | 875 managed_tile_state.resource = resource.Pass(); |
843 | 876 |
844 bytes_pending_set_pixels_ += tile->bytes_consumed_if_allocated(); | 877 bytes_pending_set_pixels_ += tile->bytes_consumed_if_allocated(); |
845 DidTileRasterStateChange(tile, SET_PIXELS_STATE); | 878 DidTileRasterStateChange(tile, SET_PIXELS_STATE); |
846 tiles_with_pending_set_pixels_.push(tile); | 879 tiles_with_pending_set_pixels_.push(tile); |
847 } else { | 880 } else { |
848 resource_pool_->resource_provider()->releasePixelBuffer(resource->id()); | 881 resource_pool_->resource_provider()->releasePixelBuffer(resource->id()); |
849 resource_pool_->ReleaseResource(resource.Pass()); | 882 resource_pool_->ReleaseResource(resource.Pass()); |
850 managed_tile_state.resource_is_being_initialized = false; | 883 managed_tile_state.resource_is_being_initialized = false; |
851 DidTileRasterStateChange(tile, IDLE_STATE); | 884 DidTileRasterStateChange(tile, IDLE_STATE); |
852 } | 885 } |
853 } | 886 } |
854 | 887 |
855 void TileManager::OnRasterTaskCompleted( | 888 void TileManager::OnRasterTaskCompleted( |
856 scoped_refptr<Tile> tile, | 889 scoped_refptr<Tile> tile, |
857 scoped_ptr<ResourcePool::Resource> resource, | 890 scoped_ptr<ResourcePool::Resource> resource, |
858 int manage_tiles_call_count_when_dispatched) { | 891 int manage_tiles_call_count_when_dispatched) { |
| 892 bytes_pending_raster_ -= tile->bytes_consumed_if_allocated(); |
859 OnRasterCompleted(tile, resource.Pass(), | 893 OnRasterCompleted(tile, resource.Pass(), |
860 manage_tiles_call_count_when_dispatched); | 894 manage_tiles_call_count_when_dispatched); |
861 DispatchMoreTasks(); | |
862 } | 895 } |
863 | 896 |
864 void TileManager::DidFinishTileInitialization(Tile* tile) { | 897 void TileManager::DidFinishTileInitialization(Tile* tile) { |
865 ManagedTileState& managed_tile_state = tile->managed_state(); | 898 ManagedTileState& managed_tile_state = tile->managed_state(); |
866 DCHECK(managed_tile_state.resource); | 899 DCHECK(managed_tile_state.resource); |
867 managed_tile_state.resource_is_being_initialized = false; | 900 managed_tile_state.resource_is_being_initialized = false; |
868 managed_tile_state.can_be_freed = true; | 901 managed_tile_state.can_be_freed = true; |
869 } | 902 } |
870 | 903 |
871 void TileManager::DidTileRasterStateChange(Tile* tile, TileRasterState state) { | 904 void TileManager::DidTileRasterStateChange(Tile* tile, TileRasterState state) { |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
964 decode_begin_time = base::TimeTicks::Now(); | 997 decode_begin_time = base::TimeTicks::Now(); |
965 pixel_ref->Decode(); | 998 pixel_ref->Decode(); |
966 if (stats) { | 999 if (stats) { |
967 stats->totalDeferredImageDecodeCount++; | 1000 stats->totalDeferredImageDecodeCount++; |
968 stats->totalDeferredImageDecodeTime += | 1001 stats->totalDeferredImageDecodeTime += |
969 base::TimeTicks::Now() - decode_begin_time; | 1002 base::TimeTicks::Now() - decode_begin_time; |
970 } | 1003 } |
971 } | 1004 } |
972 | 1005 |
973 } // namespace cc | 1006 } // namespace cc |
OLD | NEW |