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/resources/tile_manager.h" | 5 #include "cc/resources/tile_manager.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <string> | 8 #include <string> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
11 #include "base/json/json_writer.h" | 11 #include "base/json/json_writer.h" |
12 #include "base/logging.h" | 12 #include "base/logging.h" |
13 #include "base/metrics/histogram.h" | 13 #include "base/metrics/histogram.h" |
14 #include "cc/debug/devtools_instrumentation.h" | 14 #include "cc/debug/devtools_instrumentation.h" |
15 #include "cc/debug/traced_value.h" | 15 #include "cc/debug/traced_value.h" |
16 #include "cc/resources/raster_worker_pool.h" | 16 #include "cc/resources/image_raster_worker_pool.h" |
17 #include "cc/resources/resource_pool.h" | 17 #include "cc/resources/pixel_buffer_raster_worker_pool.h" |
18 #include "cc/resources/tile.h" | 18 #include "cc/resources/tile.h" |
19 #include "third_party/skia/include/core/SkDevice.h" | 19 #include "third_party/skia/include/core/SkDevice.h" |
20 #include "ui/gfx/rect_conversions.h" | 20 #include "ui/gfx/rect_conversions.h" |
21 | 21 |
22 namespace cc { | 22 namespace cc { |
23 | 23 |
24 namespace { | 24 namespace { |
25 | 25 |
26 // If we raster too fast we become upload bound, and pending | |
27 // uploads consume memory. For maximum upload throughput, we would | |
28 // want to allow for upload_throughput * pipeline_time of pending | |
29 // uploads, after which we are just wasting memory. Since we don't | |
30 // know our upload throughput yet, this just caps our memory usage. | |
31 #if defined(OS_ANDROID) | |
32 // For reference, the Nexus10 can upload 1MB in about 2.5ms. | |
33 // Assuming a three frame deep pipeline this implies ~20MB. | |
34 const size_t kMaxPendingUploadBytes = 20 * 1024 * 1024; | |
35 // TODO(epenner): We should remove this upload limit (crbug.com/176197) | |
36 const size_t kMaxPendingUploads = 72; | |
37 #else | |
38 const size_t kMaxPendingUploadBytes = 100 * 1024 * 1024; | |
39 const size_t kMaxPendingUploads = 1000; | |
40 #endif | |
41 | |
42 #if defined(OS_ANDROID) | |
43 const int kMaxNumPendingTasksPerThread = 8; | |
44 #else | |
45 const int kMaxNumPendingTasksPerThread = 40; | |
46 #endif | |
47 | |
48 // Determine bin based on three categories of tiles: things we need now, | 26 // Determine bin based on three categories of tiles: things we need now, |
49 // things we need soon, and eventually. | 27 // things we need soon, and eventually. |
50 inline TileManagerBin BinFromTilePriority(const TilePriority& prio) { | 28 inline TileManagerBin BinFromTilePriority(const TilePriority& prio) { |
51 // The amount of time for which we want to have prepainting coverage. | 29 // The amount of time for which we want to have prepainting coverage. |
52 const float kPrepaintingWindowTimeSeconds = 1.0f; | 30 const float kPrepaintingWindowTimeSeconds = 1.0f; |
53 const float kBackflingGuardDistancePixels = 314.0f; | 31 const float kBackflingGuardDistancePixels = 314.0f; |
54 | 32 |
55 if (prio.time_to_visible_in_seconds == 0) | 33 if (prio.time_to_visible_in_seconds == 0) |
56 return NOW_BIN; | 34 return NOW_BIN; |
57 | 35 |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
105 } | 83 } |
106 | 84 |
107 // static | 85 // static |
108 scoped_ptr<TileManager> TileManager::Create( | 86 scoped_ptr<TileManager> TileManager::Create( |
109 TileManagerClient* client, | 87 TileManagerClient* client, |
110 ResourceProvider* resource_provider, | 88 ResourceProvider* resource_provider, |
111 size_t num_raster_threads, | 89 size_t num_raster_threads, |
112 bool use_color_estimator, | 90 bool use_color_estimator, |
113 RenderingStatsInstrumentation* rendering_stats_instrumentation, | 91 RenderingStatsInstrumentation* rendering_stats_instrumentation, |
114 bool use_map_image) { | 92 bool use_map_image) { |
115 scoped_ptr<RasterWorkerPool> raster_worker_pool = | 93 return make_scoped_ptr( |
116 RasterWorkerPool::Create(num_raster_threads); | 94 new TileManager(client, |
117 return make_scoped_ptr(new TileManager(client, | 95 resource_provider, |
118 resource_provider, | 96 use_map_image ? |
119 raster_worker_pool.Pass(), | 97 ImageRasterWorkerPool::Create( |
120 num_raster_threads, | 98 resource_provider, num_raster_threads) : |
121 use_color_estimator, | 99 PixelBufferRasterWorkerPool::Create( |
122 rendering_stats_instrumentation, | 100 resource_provider, num_raster_threads), |
123 use_map_image)); | 101 num_raster_threads, |
102 use_color_estimator, | |
103 rendering_stats_instrumentation, | |
104 use_map_image)); | |
kaanb
2013/05/30 02:02:06
You're not doing anything with |use_map_image| wit
reveman
2013/05/30 03:27:18
Done.
| |
124 } | 105 } |
125 | 106 |
126 TileManager::TileManager( | 107 TileManager::TileManager( |
127 TileManagerClient* client, | 108 TileManagerClient* client, |
128 ResourceProvider* resource_provider, | 109 ResourceProvider* resource_provider, |
129 scoped_ptr<RasterWorkerPool> raster_worker_pool, | 110 scoped_ptr<RasterWorkerPool> raster_worker_pool, |
130 size_t num_raster_threads, | 111 size_t num_raster_threads, |
131 bool use_color_estimator, | 112 bool use_color_estimator, |
132 RenderingStatsInstrumentation* rendering_stats_instrumentation, | 113 RenderingStatsInstrumentation* rendering_stats_instrumentation, |
133 bool use_map_image) | 114 bool use_map_image) |
134 : client_(client), | 115 : client_(client), |
135 resource_pool_(ResourcePool::Create(resource_provider)), | 116 resource_pool_(ResourcePool::Create(resource_provider)), |
136 raster_worker_pool_(raster_worker_pool.Pass()), | 117 raster_worker_pool_(raster_worker_pool.Pass()), |
137 manage_tiles_pending_(false), | 118 manage_tiles_pending_(false), |
138 bytes_pending_upload_(0), | |
139 has_performed_uploads_since_last_flush_(false), | |
140 ever_exceeded_memory_budget_(false), | 119 ever_exceeded_memory_budget_(false), |
141 rendering_stats_instrumentation_(rendering_stats_instrumentation), | 120 rendering_stats_instrumentation_(rendering_stats_instrumentation), |
142 use_color_estimator_(use_color_estimator), | 121 use_color_estimator_(use_color_estimator), |
143 did_initialize_visible_tile_(false), | 122 did_initialize_visible_tile_(false) { |
144 max_pending_tasks_(kMaxNumPendingTasksPerThread * num_raster_threads) { | |
145 raster_worker_pool_->SetClient(this); | |
146 } | 123 } |
147 | 124 |
148 TileManager::~TileManager() { | 125 TileManager::~TileManager() { |
149 // Reset global state and manage. This should cause | 126 // Reset global state and manage. This should cause |
150 // our memory usage to drop to zero. | 127 // our memory usage to drop to zero. |
151 global_state_ = GlobalStateThatImpactsTilePriority(); | 128 global_state_ = GlobalStateThatImpactsTilePriority(); |
152 AssignGpuMemoryToTiles(); | 129 AssignGpuMemoryToTiles(); |
153 // This should finish all pending tasks and release any uninitialized | 130 // This should finish all pending tasks and release any uninitialized |
154 // resources. | 131 // resources. |
155 raster_worker_pool_->Shutdown(); | 132 raster_worker_pool_->Shutdown(); |
156 AbortPendingTileUploads(); | |
157 DCHECK_EQ(0u, tiles_with_pending_upload_.size()); | |
158 DCHECK_EQ(0u, tiles_.size()); | 133 DCHECK_EQ(0u, tiles_.size()); |
159 } | 134 } |
160 | 135 |
161 void TileManager::SetGlobalState( | 136 void TileManager::SetGlobalState( |
162 const GlobalStateThatImpactsTilePriority& global_state) { | 137 const GlobalStateThatImpactsTilePriority& global_state) { |
163 global_state_ = global_state; | 138 global_state_ = global_state; |
164 resource_pool_->SetMaxMemoryUsageBytes( | 139 resource_pool_->SetMaxMemoryUsageBytes( |
165 global_state_.memory_limit_in_bytes, | 140 global_state_.memory_limit_in_bytes, |
166 global_state_.unused_memory_limit_in_bytes); | 141 global_state_.unused_memory_limit_in_bytes); |
167 ScheduleManageTiles(); | 142 ScheduleManageTiles(); |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
314 | 289 |
315 TRACE_EVENT_INSTANT1( | 290 TRACE_EVENT_INSTANT1( |
316 "cc", "DidManage", TRACE_EVENT_SCOPE_THREAD, | 291 "cc", "DidManage", TRACE_EVENT_SCOPE_THREAD, |
317 "state", TracedValue::FromValue(BasicStateAsValue().release())); | 292 "state", TracedValue::FromValue(BasicStateAsValue().release())); |
318 | 293 |
319 // Finally, schedule rasterizer tasks. | 294 // Finally, schedule rasterizer tasks. |
320 ScheduleTasks(); | 295 ScheduleTasks(); |
321 } | 296 } |
322 | 297 |
323 void TileManager::CheckForCompletedTileUploads() { | 298 void TileManager::CheckForCompletedTileUploads() { |
324 while (!tiles_with_pending_upload_.empty()) { | 299 raster_worker_pool_->CheckForCompletedTasks(); |
325 Tile* tile = tiles_with_pending_upload_.front(); | |
326 DCHECK(tile->tile_version().resource_); | |
327 | 300 |
328 // Set pixel tasks complete in the order they are posted. | 301 if (client_->ShouldForceTileUploadsRequiredForActivationToComplete()) { |
329 if (!resource_pool_->resource_provider()->DidSetPixelsComplete( | 302 TileSet initialized_tiles; |
330 tile->tile_version().resource_->id())) { | 303 for (TileSet::iterator it = |
331 break; | 304 tiles_that_need_to_be_initialized_for_activation_.begin(); |
305 it != tiles_that_need_to_be_initialized_for_activation_.end(); | |
306 ++it) { | |
307 Tile* tile = *it; | |
308 if (!tile->managed_state().raster_task.is_null() && | |
309 tile->tile_version().memory_state_ == USING_UNRELEASABLE_MEMORY && | |
310 !tile->tile_version().forced_upload_) { | |
311 if (!raster_worker_pool_->ForceUploadToComplete( | |
312 tile->managed_state().raster_task)) | |
313 continue; | |
314 | |
315 // Setting |forced_upload_| to true makes this tile ready to draw. | |
316 tile->tile_version().forced_upload_ = true; | |
317 initialized_tiles.insert(tile); | |
318 } | |
332 } | 319 } |
333 | 320 |
334 // It's now safe to release the pixel buffer. | 321 for (TileSet::iterator it = initialized_tiles.begin(); |
335 resource_pool_->resource_provider()->ReleasePixelBuffer( | 322 it != initialized_tiles.end(); |
336 tile->tile_version().resource_->id()); | 323 ++it) { |
337 | 324 Tile* tile = *it; |
338 bytes_pending_upload_ -= tile->bytes_consumed_if_allocated(); | |
339 bool was_forced = tile->tile_version().forced_upload_; | |
340 // Reset forced_upload_ since we now got the upload completed notification. | |
341 tile->tile_version().forced_upload_ = false; | |
342 tile->tile_version().memory_state_ = USING_RELEASABLE_MEMORY; | |
343 if (!was_forced) | |
344 DidFinishTileInitialization(tile); | 325 DidFinishTileInitialization(tile); |
345 | 326 DCHECK(tile->tile_version().IsReadyToDraw()); |
346 tiles_with_pending_upload_.pop(); | 327 } |
347 } | |
348 | |
349 ScheduleTasks(); | |
350 } | |
351 | |
352 void TileManager::AbortPendingTileUploads() { | |
353 while (!tiles_with_pending_upload_.empty()) { | |
354 Tile* tile = tiles_with_pending_upload_.front(); | |
355 DCHECK(tile->tile_version().resource_); | |
356 | |
357 resource_pool_->resource_provider()->AbortSetPixels( | |
358 tile->tile_version().resource_->id()); | |
359 resource_pool_->resource_provider()->ReleasePixelBuffer( | |
360 tile->tile_version().resource_->id()); | |
361 tile->tile_version().memory_state_ = USING_RELEASABLE_MEMORY; | |
362 | |
363 FreeResourcesForTile(tile); | |
364 | |
365 bytes_pending_upload_ -= tile->bytes_consumed_if_allocated(); | |
366 tiles_with_pending_upload_.pop(); | |
367 } | |
368 } | |
369 | |
370 void TileManager::ForceTileUploadToComplete(Tile* tile) { | |
371 DCHECK(tile); | |
372 if (tile->tile_version().resource_ && | |
373 tile->tile_version().memory_state_ == USING_UNRELEASABLE_MEMORY && | |
374 !tile->tile_version().forced_upload_) { | |
375 resource_pool_->resource_provider()-> | |
376 ForceSetPixelsToComplete(tile->tile_version().resource_->id()); | |
377 | |
378 // We have to set the memory state to be unreleasable, to ensure | |
379 // that the tile will not be freed until we get the upload finished | |
380 // notification. However, setting |forced_upload_| to true makes | |
381 // this tile ready to draw. | |
382 tile->tile_version().memory_state_ = USING_UNRELEASABLE_MEMORY; | |
383 tile->tile_version().forced_upload_ = true; | |
384 DidFinishTileInitialization(tile); | |
385 DCHECK(tile->tile_version().IsReadyToDraw()); | |
386 } | 328 } |
387 | 329 |
388 if (did_initialize_visible_tile_) { | 330 if (did_initialize_visible_tile_) { |
389 did_initialize_visible_tile_ = false; | 331 did_initialize_visible_tile_ = false; |
390 client_->DidInitializeVisibleTile(); | 332 client_->DidInitializeVisibleTile(); |
391 } | 333 } |
392 } | 334 } |
393 | 335 |
394 void TileManager::GetMemoryStats( | 336 void TileManager::GetMemoryStats( |
395 size_t* memory_required_bytes, | 337 size_t* memory_required_bytes, |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
452 } | 394 } |
453 | 395 |
454 void TileManager::AddRequiredTileForActivation(Tile* tile) { | 396 void TileManager::AddRequiredTileForActivation(Tile* tile) { |
455 DCHECK(std::find(tiles_that_need_to_be_initialized_for_activation_.begin(), | 397 DCHECK(std::find(tiles_that_need_to_be_initialized_for_activation_.begin(), |
456 tiles_that_need_to_be_initialized_for_activation_.end(), | 398 tiles_that_need_to_be_initialized_for_activation_.end(), |
457 tile) == | 399 tile) == |
458 tiles_that_need_to_be_initialized_for_activation_.end()); | 400 tiles_that_need_to_be_initialized_for_activation_.end()); |
459 tiles_that_need_to_be_initialized_for_activation_.insert(tile); | 401 tiles_that_need_to_be_initialized_for_activation_.insert(tile); |
460 } | 402 } |
461 | 403 |
462 void TileManager::DidFinishDispatchingWorkerPoolCompletionCallbacks() { | |
463 // If a flush is needed, do it now before starting to dispatch more tasks. | |
464 if (has_performed_uploads_since_last_flush_) { | |
465 resource_pool_->resource_provider()->ShallowFlushIfSupported(); | |
466 has_performed_uploads_since_last_flush_ = false; | |
467 } | |
468 | |
469 ScheduleTasks(); | |
470 } | |
471 | |
472 void TileManager::AssignGpuMemoryToTiles() { | 404 void TileManager::AssignGpuMemoryToTiles() { |
473 TRACE_EVENT0("cc", "TileManager::AssignGpuMemoryToTiles"); | 405 TRACE_EVENT0("cc", "TileManager::AssignGpuMemoryToTiles"); |
474 size_t unreleasable_bytes = 0; | 406 size_t unreleasable_bytes = 0; |
475 | 407 |
476 // Now give memory out to the tiles until we're out, and build | 408 // Now give memory out to the tiles until we're out, and build |
477 // the needs-to-be-rasterized queue. | 409 // the needs-to-be-rasterized queue. |
478 tiles_that_need_to_be_rasterized_.clear(); | 410 tiles_that_need_to_be_rasterized_.clear(); |
479 tiles_that_need_to_be_initialized_for_activation_.clear(); | 411 tiles_that_need_to_be_initialized_for_activation_.clear(); |
480 | 412 |
481 // By clearing the tiles_that_need_to_be_rasterized_ vector list | 413 // By clearing the tiles_that_need_to_be_rasterized_ vector list |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
550 // 2. Tile with unreleasable memory could otherwise incorrectly | 482 // 2. Tile with unreleasable memory could otherwise incorrectly |
551 // be added as it's not affected by |bytes_allocatable|. | 483 // be added as it's not affected by |bytes_allocatable|. |
552 if (higher_priority_tile_oomed) | 484 if (higher_priority_tile_oomed) |
553 continue; | 485 continue; |
554 | 486 |
555 if (!tile_version.resource_) | 487 if (!tile_version.resource_) |
556 tiles_that_need_to_be_rasterized_.push_back(tile); | 488 tiles_that_need_to_be_rasterized_.push_back(tile); |
557 | 489 |
558 if (!tile_version.resource_ && tile->required_for_activation()) | 490 if (!tile_version.resource_ && tile->required_for_activation()) |
559 AddRequiredTileForActivation(tile); | 491 AddRequiredTileForActivation(tile); |
560 | |
561 if (tile_version.memory_state_ == USING_UNRELEASABLE_MEMORY && | |
562 tile->required_for_activation()) { | |
563 // If after rasterizing, this tile has become required or the client has | |
564 // changed its mind about forcing tiles, do that now. | |
565 if (!tile->tile_version().forced_upload_ && | |
566 client_->ShouldForceTileUploadsRequiredForActivationToComplete()) { | |
567 ForceTileUploadToComplete(tile); | |
568 } | |
569 } | |
570 } | 492 } |
571 | 493 |
572 // In OOM situation, we iterate tiles_, remove the memory for active tree | 494 // In OOM situation, we iterate tiles_, remove the memory for active tree |
573 // and not the now bin. And give them to bytes_oom_in_now_bin_on_pending_tree | 495 // and not the now bin. And give them to bytes_oom_in_now_bin_on_pending_tree |
574 if (!tiles_requiring_memory_but_oomed.empty()) { | 496 if (!tiles_requiring_memory_but_oomed.empty()) { |
575 size_t bytes_freed = 0; | 497 size_t bytes_freed = 0; |
576 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { | 498 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { |
577 Tile* tile = *it; | 499 Tile* tile = *it; |
578 ManagedTileState& mts = tile->managed_state(); | 500 ManagedTileState& mts = tile->managed_state(); |
579 ManagedTileState::TileVersion& tile_version = tile->tile_version(); | 501 ManagedTileState::TileVersion& tile_version = tile->tile_version(); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
631 DCHECK_NE(USING_UNRELEASABLE_MEMORY, tile->tile_version().memory_state_); | 553 DCHECK_NE(USING_UNRELEASABLE_MEMORY, tile->tile_version().memory_state_); |
632 if (tile->tile_version().resource_) { | 554 if (tile->tile_version().resource_) { |
633 resource_pool_->ReleaseResource( | 555 resource_pool_->ReleaseResource( |
634 tile->tile_version().resource_.Pass()); | 556 tile->tile_version().resource_.Pass()); |
635 } | 557 } |
636 tile->tile_version().memory_state_ = NOT_ALLOWED_TO_USE_MEMORY; | 558 tile->tile_version().memory_state_ = NOT_ALLOWED_TO_USE_MEMORY; |
637 } | 559 } |
638 | 560 |
639 void TileManager::ScheduleTasks() { | 561 void TileManager::ScheduleTasks() { |
640 TRACE_EVENT0("cc", "TileManager::ScheduleTasks"); | 562 TRACE_EVENT0("cc", "TileManager::ScheduleTasks"); |
641 RasterWorkerPool::Task::Queue tasks; | 563 RasterWorkerPool::RasterTask::Queue tasks; |
642 | |
643 size_t bytes_pending_upload = bytes_pending_upload_; | |
644 unsigned pending_tasks = 0; | |
645 | 564 |
646 // Build a new task queue containing all task currently needed. Tasks | 565 // Build a new task queue containing all task currently needed. Tasks |
647 // are added in order of priority, highest priority task first. | 566 // are added in order of priority, highest priority task first. |
648 for (TileVector::iterator it = tiles_that_need_to_be_rasterized_.begin(); | 567 for (TileVector::iterator it = tiles_that_need_to_be_rasterized_.begin(); |
649 it != tiles_that_need_to_be_rasterized_.end(); | 568 it != tiles_that_need_to_be_rasterized_.end(); |
650 ++it) { | 569 ++it) { |
651 Tile* tile = *it; | 570 Tile* tile = *it; |
652 ManagedTileState& mts = tile->managed_state(); | 571 ManagedTileState& mts = tile->managed_state(); |
653 | 572 |
654 // Skip tile if determined to not require resource. | 573 DCHECK(tile->tile_version().requires_resource()); |
655 if (!tile->tile_version().requires_resource()) | 574 DCHECK(!tile->tile_version().resource_); |
656 continue; | |
657 | |
658 // Skip tile if already rasterized. | |
659 if (tile->tile_version().resource_) | |
660 continue; | |
661 | |
662 // TODO(reveman): Remove throttling based on max pending tasks. | |
663 if (pending_tasks >= max_pending_tasks_) | |
664 break; | |
665 | |
666 // TODO(reveman): Remove throttling based on max pending uploads. | |
667 if (tiles_with_pending_upload_.size() >= kMaxPendingUploads) | |
668 break; | |
669 | |
670 // TODO(reveman): Throttle based on shared memory usage rather | |
671 // than bytes pending upload. | |
672 size_t new_bytes_pending = bytes_pending_upload; | |
673 new_bytes_pending += tile->bytes_consumed_if_allocated(); | |
674 if (new_bytes_pending > kMaxPendingUploadBytes) | |
675 break; | |
676 bytes_pending_upload = new_bytes_pending; | |
677 | 575 |
678 // Create raster task for this tile if necessary. | 576 // Create raster task for this tile if necessary. |
679 if (mts.raster_task.is_null()) | 577 if (mts.raster_task.is_null()) |
680 mts.raster_task = CreateRasterTask(tile); | 578 mts.raster_task = CreateRasterTask(tile); |
681 | 579 |
682 // Finally append raster task. | 580 // Finally append raster task. |
683 tasks.Append(mts.raster_task); | 581 tasks.Append(mts.raster_task); |
684 pending_tasks++; | |
685 } | 582 } |
686 | 583 |
687 if (!tasks.empty()) { | 584 // Schedule running of |tasks|. This replaces any previously |
688 RasterWorkerPool::Task root(&tasks); | 585 // scheduled tasks and effectively cancels all tasks not present |
689 | 586 // in |tasks|. |
690 // Schedule running of |tasks|. This replaces any previously | 587 raster_worker_pool_->ScheduleTasks(&tasks); |
691 // scheduled tasks and effectively cancels all tasks not present | |
692 // in |tasks|. | |
693 raster_worker_pool_->ScheduleTasks(&root); | |
694 } else { | |
695 raster_worker_pool_->ScheduleTasks(NULL); | |
696 } | |
697 | |
698 if (did_initialize_visible_tile_) { | |
699 did_initialize_visible_tile_ = false; | |
700 client_->DidInitializeVisibleTile(); | |
701 } | |
702 } | 588 } |
703 | 589 |
704 RasterWorkerPool::Task TileManager::CreateImageDecodeTask( | 590 RasterWorkerPool::Task TileManager::CreateImageDecodeTask( |
705 Tile* tile, skia::LazyPixelRef* pixel_ref) { | 591 Tile* tile, skia::LazyPixelRef* pixel_ref) { |
706 TRACE_EVENT0("cc", "TileManager::CreateImageDecodeTask"); | 592 TRACE_EVENT0("cc", "TileManager::CreateImageDecodeTask"); |
707 | 593 |
708 return RasterWorkerPool::Task( | 594 return RasterWorkerPool::Task( |
709 base::Bind(&TileManager::RunImageDecodeTask, | 595 base::Bind(&TileManager::RunImageDecodeTask, |
710 pixel_ref, | 596 pixel_ref, |
711 tile->layer_id(), | 597 tile->layer_id(), |
712 rendering_stats_instrumentation_), | 598 rendering_stats_instrumentation_), |
713 base::Bind(&TileManager::OnImageDecodeTaskCompleted, | 599 base::Bind(&TileManager::OnImageDecodeTaskCompleted, |
714 base::Unretained(this), | 600 base::Unretained(this), |
715 make_scoped_refptr(tile), | 601 make_scoped_refptr(tile), |
716 pixel_ref->getGenerationID())); | 602 pixel_ref->getGenerationID())); |
717 } | 603 } |
718 | 604 |
719 void TileManager::OnImageDecodeTaskCompleted(scoped_refptr<Tile> tile, | 605 void TileManager::OnImageDecodeTaskCompleted(scoped_refptr<Tile> tile, |
720 uint32_t pixel_ref_id, | 606 uint32_t pixel_ref_id) { |
721 bool was_canceled) { | |
722 TRACE_EVENT0("cc", "TileManager::OnImageDecodeTaskCompleted"); | 607 TRACE_EVENT0("cc", "TileManager::OnImageDecodeTaskCompleted"); |
723 DCHECK(pending_decode_tasks_.find(pixel_ref_id) != | 608 DCHECK(pending_decode_tasks_.find(pixel_ref_id) != |
724 pending_decode_tasks_.end()); | 609 pending_decode_tasks_.end()); |
725 pending_decode_tasks_.erase(pixel_ref_id); | 610 pending_decode_tasks_.erase(pixel_ref_id); |
726 } | 611 } |
727 | 612 |
728 TileManager::RasterTaskMetadata TileManager::GetRasterTaskMetadata( | 613 TileManager::RasterTaskMetadata TileManager::GetRasterTaskMetadata( |
729 const Tile& tile) const { | 614 const Tile& tile) const { |
730 RasterTaskMetadata metadata; | 615 RasterTaskMetadata metadata; |
731 const ManagedTileState& mts = tile.managed_state(); | 616 const ManagedTileState& mts = tile.managed_state(); |
732 metadata.is_tile_in_pending_tree_now_bin = | 617 metadata.is_tile_in_pending_tree_now_bin = |
733 mts.tree_bin[PENDING_TREE] == NOW_BIN; | 618 mts.tree_bin[PENDING_TREE] == NOW_BIN; |
734 metadata.tile_resolution = mts.resolution; | 619 metadata.tile_resolution = mts.resolution; |
735 metadata.layer_id = tile.layer_id(); | 620 metadata.layer_id = tile.layer_id(); |
736 metadata.tile_id = &tile; | 621 metadata.tile_id = &tile; |
737 metadata.source_frame_number = tile.source_frame_number(); | 622 metadata.source_frame_number = tile.source_frame_number(); |
738 return metadata; | 623 return metadata; |
739 } | 624 } |
740 | 625 |
741 RasterWorkerPool::Task TileManager::CreateRasterTask(Tile* tile) { | 626 RasterWorkerPool::RasterTask TileManager::CreateRasterTask(Tile* tile) { |
742 TRACE_EVENT0("cc", "TileManager::CreateRasterTask"); | 627 TRACE_EVENT0("cc", "TileManager::CreateRasterTask"); |
743 | 628 |
744 scoped_ptr<ResourcePool::Resource> resource = | 629 scoped_ptr<ResourcePool::Resource> resource = |
745 resource_pool_->AcquireResource( | 630 resource_pool_->AcquireResource( |
746 tile->tile_size_.size(), | 631 tile->tile_size_.size(), |
747 tile->tile_version().resource_format_); | 632 tile->tile_version().resource_format_); |
748 resource_pool_->resource_provider()->AcquirePixelBuffer(resource->id()); | 633 const Resource* const_resource = resource.get(); |
749 | 634 |
750 DCHECK_EQ(CAN_USE_MEMORY, tile->tile_version().memory_state_); | 635 DCHECK_EQ(CAN_USE_MEMORY, tile->tile_version().memory_state_); |
751 tile->tile_version().memory_state_ = USING_UNRELEASABLE_MEMORY; | 636 tile->tile_version().memory_state_ = USING_UNRELEASABLE_MEMORY; |
637 tile->tile_version().resource_id_ = resource->id(); | |
752 | 638 |
753 PicturePileImpl::Analysis* analysis = new PicturePileImpl::Analysis; | 639 PicturePileImpl::Analysis* analysis = new PicturePileImpl::Analysis; |
754 | 640 |
755 // MapPixelBuffer() returns NULL if context was lost at the time | |
756 // AcquirePixelBuffer() was called. For simplicity we still create | |
757 // a raster task that is essentially a noop in these situations. | |
758 uint8* buffer = resource_pool_->resource_provider()->MapPixelBuffer( | |
759 resource->id()); | |
760 | |
761 // Create and queue all image decode tasks that this tile depends on. | 641 // Create and queue all image decode tasks that this tile depends on. |
762 RasterWorkerPool::Task::Queue decode_tasks; | 642 RasterWorkerPool::Task::Set decode_tasks; |
763 for (PicturePileImpl::PixelRefIterator iter(tile->content_rect(), | 643 for (PicturePileImpl::PixelRefIterator iter(tile->content_rect(), |
764 tile->contents_scale(), | 644 tile->contents_scale(), |
765 tile->picture_pile()); | 645 tile->picture_pile()); |
766 iter; ++iter) { | 646 iter; ++iter) { |
767 skia::LazyPixelRef* pixel_ref = *iter; | 647 skia::LazyPixelRef* pixel_ref = *iter; |
768 uint32_t id = pixel_ref->getGenerationID(); | 648 uint32_t id = pixel_ref->getGenerationID(); |
769 | 649 |
770 // Append existing image decode task if available. | 650 // Append existing image decode task if available. |
771 PixelRefMap::iterator decode_task_it = pending_decode_tasks_.find(id); | 651 PixelRefMap::iterator decode_task_it = pending_decode_tasks_.find(id); |
772 if (decode_task_it != pending_decode_tasks_.end()) { | 652 if (decode_task_it != pending_decode_tasks_.end()) { |
773 decode_tasks.Append(decode_task_it->second); | 653 decode_tasks.Insert(decode_task_it->second); |
774 continue; | 654 continue; |
775 } | 655 } |
776 | 656 |
777 // TODO(qinmin): passing correct image size to PrepareToDecode(). | 657 // TODO(qinmin): passing correct image size to PrepareToDecode(). |
778 if (pixel_ref->PrepareToDecode(skia::LazyPixelRef::PrepareParams())) { | 658 if (pixel_ref->PrepareToDecode(skia::LazyPixelRef::PrepareParams())) { |
779 rendering_stats_instrumentation_->IncrementDeferredImageCacheHitCount(); | 659 rendering_stats_instrumentation_->IncrementDeferredImageCacheHitCount(); |
780 continue; | 660 continue; |
781 } | 661 } |
782 | 662 |
783 // Create and append new image decode task for this pixel ref. | 663 // Create and append new image decode task for this pixel ref. |
784 RasterWorkerPool::Task decode_task = CreateImageDecodeTask( | 664 RasterWorkerPool::Task decode_task = CreateImageDecodeTask( |
785 tile, pixel_ref); | 665 tile, pixel_ref); |
786 decode_tasks.Append(decode_task); | 666 decode_tasks.Insert(decode_task); |
787 pending_decode_tasks_[id] = decode_task; | 667 pending_decode_tasks_[id] = decode_task; |
788 } | 668 } |
789 | 669 |
790 return RasterWorkerPool::PictureTask( | 670 return RasterWorkerPool::RasterTask( |
791 tile->picture_pile(), | 671 tile->picture_pile(), |
672 const_resource, | |
792 base::Bind(&TileManager::RunAnalyzeAndRasterTask, | 673 base::Bind(&TileManager::RunAnalyzeAndRasterTask, |
793 base::Bind(&TileManager::RunAnalyzeTask, | 674 base::Bind(&TileManager::RunAnalyzeTask, |
794 analysis, | 675 analysis, |
795 tile->content_rect(), | 676 tile->content_rect(), |
796 tile->contents_scale(), | 677 tile->contents_scale(), |
797 use_color_estimator_, | 678 use_color_estimator_, |
798 GetRasterTaskMetadata(*tile), | 679 GetRasterTaskMetadata(*tile), |
799 rendering_stats_instrumentation_), | 680 rendering_stats_instrumentation_), |
800 base::Bind(&TileManager::RunRasterTask, | 681 base::Bind(&TileManager::RunRasterTask, |
801 buffer, | |
802 analysis, | 682 analysis, |
803 tile->content_rect(), | 683 tile->content_rect(), |
804 tile->contents_scale(), | 684 tile->contents_scale(), |
805 GetRasterTaskMetadata(*tile), | 685 GetRasterTaskMetadata(*tile), |
806 rendering_stats_instrumentation_)), | 686 rendering_stats_instrumentation_)), |
807 base::Bind(&TileManager::OnRasterTaskCompleted, | 687 base::Bind(&TileManager::OnRasterTaskCompleted, |
808 base::Unretained(this), | 688 base::Unretained(this), |
809 make_scoped_refptr(tile), | 689 make_scoped_refptr(tile), |
810 base::Passed(&resource), | 690 base::Passed(&resource), |
811 base::Owned(analysis)), | 691 base::Owned(analysis)), |
812 &decode_tasks); | 692 &decode_tasks); |
813 } | 693 } |
814 | 694 |
815 void TileManager::OnRasterTaskCompleted( | 695 void TileManager::OnRasterTaskCompleted( |
816 scoped_refptr<Tile> tile, | 696 scoped_refptr<Tile> tile, |
817 scoped_ptr<ResourcePool::Resource> resource, | 697 scoped_ptr<ResourcePool::Resource> resource, |
818 PicturePileImpl::Analysis* analysis, | 698 PicturePileImpl::Analysis* analysis, |
819 bool was_canceled) { | 699 bool was_canceled) { |
820 TRACE_EVENT0("cc", "TileManager::OnRasterTaskCompleted"); | 700 TRACE_EVENT0("cc", "TileManager::OnRasterTaskCompleted"); |
821 | 701 |
822 ManagedTileState& mts = tile->managed_state(); | 702 ManagedTileState& mts = tile->managed_state(); |
823 DCHECK(!mts.raster_task.is_null()); | 703 DCHECK(!mts.raster_task.is_null()); |
824 mts.raster_task.Reset(); | 704 mts.raster_task.Reset(); |
825 | 705 |
826 // Tile resources can't be freed until upload has completed. | 706 // Tile resources can't be freed until task has completed. |
827 DCHECK_EQ(USING_UNRELEASABLE_MEMORY, tile->tile_version().memory_state_); | 707 DCHECK_EQ(USING_UNRELEASABLE_MEMORY, tile->tile_version().memory_state_); |
828 | 708 |
829 // Release raster resources. | |
830 resource_pool_->resource_provider()->UnmapPixelBuffer(resource->id()); | |
831 | |
832 if (was_canceled) { | 709 if (was_canceled) { |
833 tile->tile_version().memory_state_ = CAN_USE_MEMORY; | 710 tile->tile_version().memory_state_ = CAN_USE_MEMORY; |
834 resource_pool_->resource_provider()->ReleasePixelBuffer(resource->id()); | |
835 resource_pool_->ReleaseResource(resource.Pass()); | 711 resource_pool_->ReleaseResource(resource.Pass()); |
836 return; | 712 return; |
837 } | 713 } |
838 | 714 |
839 mts.picture_pile_analysis = *analysis; | 715 mts.picture_pile_analysis = *analysis; |
840 mts.picture_pile_analyzed = true; | 716 mts.picture_pile_analyzed = true; |
841 | 717 |
842 if (analysis->is_solid_color) { | 718 if (analysis->is_solid_color) { |
843 tile->tile_version().set_solid_color(analysis->solid_color); | 719 tile->tile_version().set_solid_color(analysis->solid_color); |
844 resource_pool_->resource_provider()->ReleasePixelBuffer(resource->id()); | |
845 resource_pool_->ReleaseResource(resource.Pass()); | 720 resource_pool_->ReleaseResource(resource.Pass()); |
846 DidFinishTileInitialization(tile); | 721 } else { |
847 return; | 722 tile->tile_version().memory_state_ = USING_RELEASABLE_MEMORY; |
723 tile->tile_version().resource_ = resource.Pass(); | |
848 } | 724 } |
849 | 725 |
850 resource_pool_->resource_provider()->BeginSetPixels(resource->id()); | 726 DidFinishTileInitialization(tile); |
851 has_performed_uploads_since_last_flush_ = true; | |
852 | |
853 tile->tile_version().resource_ = resource.Pass(); | |
854 | |
855 bytes_pending_upload_ += tile->bytes_consumed_if_allocated(); | |
856 tiles_with_pending_upload_.push(tile); | |
857 | |
858 if (tile->required_for_activation() && | |
859 client_->ShouldForceTileUploadsRequiredForActivationToComplete()) | |
860 ForceTileUploadToComplete(tile); | |
861 } | 727 } |
862 | 728 |
863 void TileManager::DidFinishTileInitialization(Tile* tile) { | 729 void TileManager::DidFinishTileInitialization(Tile* tile) { |
864 if (tile->priority(ACTIVE_TREE).distance_to_visible_in_pixels == 0) | 730 if (tile->priority(ACTIVE_TREE).distance_to_visible_in_pixels == 0) |
865 did_initialize_visible_tile_ = true; | 731 did_initialize_visible_tile_ = true; |
866 if (tile->required_for_activation()) { | 732 if (tile->required_for_activation()) { |
867 // It's possible that a tile required for activation is not in this list | 733 // It's possible that a tile required for activation is not in this list |
868 // if it was marked as being required after being dispatched for | 734 // if it was marked as being required after being dispatched for |
869 // rasterization but before AssignGPUMemory was called again. | 735 // rasterization but before AssignGPUMemory was called again. |
870 tiles_that_need_to_be_initialized_for_activation_.erase(tile); | 736 tiles_that_need_to_be_initialized_for_activation_.erase(tile); |
(...skipping 15 matching lines...) Expand all Loading... | |
886 TRACE_EVENT0("cc", "TileManager::RunImageDecodeTask"); | 752 TRACE_EVENT0("cc", "TileManager::RunImageDecodeTask"); |
887 devtools_instrumentation::ScopedLayerTask image_decode_task( | 753 devtools_instrumentation::ScopedLayerTask image_decode_task( |
888 devtools_instrumentation::kImageDecodeTask, layer_id); | 754 devtools_instrumentation::kImageDecodeTask, layer_id); |
889 base::TimeTicks start_time = stats_instrumentation->StartRecording(); | 755 base::TimeTicks start_time = stats_instrumentation->StartRecording(); |
890 pixel_ref->Decode(); | 756 pixel_ref->Decode(); |
891 base::TimeDelta duration = stats_instrumentation->EndRecording(start_time); | 757 base::TimeDelta duration = stats_instrumentation->EndRecording(start_time); |
892 stats_instrumentation->AddDeferredImageDecode(duration); | 758 stats_instrumentation->AddDeferredImageDecode(duration); |
893 } | 759 } |
894 | 760 |
895 // static | 761 // static |
896 void TileManager::RunAnalyzeAndRasterTask( | 762 bool TileManager::RunAnalyzeAndRasterTask( |
897 const RasterWorkerPool::PictureTask::Callback& analyze_task, | 763 const base::Callback<void(PicturePileImpl*)>& analyze_task, |
898 const RasterWorkerPool::PictureTask::Callback& raster_task, | 764 const RasterWorkerPool::RasterTask::Callback& raster_task, |
765 uint8* buffer, | |
899 PicturePileImpl* picture_pile) { | 766 PicturePileImpl* picture_pile) { |
900 analyze_task.Run(picture_pile); | 767 analyze_task.Run(picture_pile); |
901 raster_task.Run(picture_pile); | 768 return raster_task.Run(buffer, picture_pile); |
902 } | 769 } |
903 | 770 |
904 // static | 771 // static |
905 void TileManager::RunAnalyzeTask( | 772 void TileManager::RunAnalyzeTask( |
906 PicturePileImpl::Analysis* analysis, | 773 PicturePileImpl::Analysis* analysis, |
907 gfx::Rect rect, | 774 gfx::Rect rect, |
908 float contents_scale, | 775 float contents_scale, |
909 bool use_color_estimator, | 776 bool use_color_estimator, |
910 const RasterTaskMetadata& metadata, | 777 const RasterTaskMetadata& metadata, |
911 RenderingStatsInstrumentation* stats_instrumentation, | 778 RenderingStatsInstrumentation* stats_instrumentation, |
(...skipping 22 matching lines...) Expand all Loading... | |
934 scoped_ptr<base::DictionaryValue> res(new base::DictionaryValue()); | 801 scoped_ptr<base::DictionaryValue> res(new base::DictionaryValue()); |
935 res->Set("tile_id", TracedValue::CreateIDRef(tile_id).release()); | 802 res->Set("tile_id", TracedValue::CreateIDRef(tile_id).release()); |
936 res->SetBoolean("is_tile_in_pending_tree_now_bin", | 803 res->SetBoolean("is_tile_in_pending_tree_now_bin", |
937 is_tile_in_pending_tree_now_bin); | 804 is_tile_in_pending_tree_now_bin); |
938 res->Set("resolution", TileResolutionAsValue(tile_resolution).release()); | 805 res->Set("resolution", TileResolutionAsValue(tile_resolution).release()); |
939 res->SetInteger("source_frame_number", source_frame_number); | 806 res->SetInteger("source_frame_number", source_frame_number); |
940 return res.PassAs<base::Value>(); | 807 return res.PassAs<base::Value>(); |
941 } | 808 } |
942 | 809 |
943 // static | 810 // static |
944 void TileManager::RunRasterTask( | 811 bool TileManager::RunRasterTask( |
945 uint8* buffer, | |
946 PicturePileImpl::Analysis* analysis, | 812 PicturePileImpl::Analysis* analysis, |
947 gfx::Rect rect, | 813 gfx::Rect rect, |
948 float contents_scale, | 814 float contents_scale, |
949 const RasterTaskMetadata& metadata, | 815 const RasterTaskMetadata& metadata, |
950 RenderingStatsInstrumentation* stats_instrumentation, | 816 RenderingStatsInstrumentation* stats_instrumentation, |
817 uint8* buffer, | |
951 PicturePileImpl* picture_pile) { | 818 PicturePileImpl* picture_pile) { |
952 TRACE_EVENT1( | 819 TRACE_EVENT1( |
953 "cc", "TileManager::RunRasterTask", | 820 "cc", "TileManager::RunRasterTask", |
954 "metadata", TracedValue::FromValue(metadata.AsValue().release())); | 821 "metadata", TracedValue::FromValue(metadata.AsValue().release())); |
955 devtools_instrumentation::ScopedLayerTask raster_task( | 822 devtools_instrumentation::ScopedLayerTask raster_task( |
956 devtools_instrumentation::kRasterTask, metadata.layer_id); | 823 devtools_instrumentation::kRasterTask, metadata.layer_id); |
957 | 824 |
958 DCHECK(picture_pile); | 825 DCHECK(picture_pile); |
959 DCHECK(analysis); | 826 DCHECK(analysis); |
960 | 827 |
961 // |buffer| can be NULL in lost context situations. | 828 // |buffer| can be NULL in lost context situations. |
962 if (!buffer) | 829 if (!buffer) |
963 return; | 830 return false; |
964 | 831 |
965 if (analysis->is_solid_color) | 832 if (analysis->is_solid_color) |
966 return; | 833 return false; |
967 | 834 |
968 SkBitmap bitmap; | 835 SkBitmap bitmap; |
969 bitmap.setConfig(SkBitmap::kARGB_8888_Config, rect.width(), rect.height()); | 836 bitmap.setConfig(SkBitmap::kARGB_8888_Config, rect.width(), rect.height()); |
kaanb
2013/05/30 02:02:06
While you're touching this file can you also plumb
reveman
2013/05/30 03:27:18
Done.
| |
970 bitmap.setPixels(buffer); | 837 bitmap.setPixels(buffer); |
971 SkDevice device(bitmap); | 838 SkDevice device(bitmap); |
972 SkCanvas canvas(&device); | 839 SkCanvas canvas(&device); |
973 | 840 |
974 if (stats_instrumentation->record_rendering_stats()) { | 841 if (stats_instrumentation->record_rendering_stats()) { |
975 PicturePileImpl::RasterStats raster_stats; | 842 PicturePileImpl::RasterStats raster_stats; |
976 picture_pile->RasterToBitmap(&canvas, rect, contents_scale, &raster_stats); | 843 picture_pile->RasterToBitmap(&canvas, rect, contents_scale, &raster_stats); |
977 stats_instrumentation->AddRaster( | 844 stats_instrumentation->AddRaster( |
978 raster_stats.total_rasterize_time, | 845 raster_stats.total_rasterize_time, |
979 raster_stats.best_rasterize_time, | 846 raster_stats.best_rasterize_time, |
980 raster_stats.total_pixels_rasterized, | 847 raster_stats.total_pixels_rasterized, |
981 metadata.is_tile_in_pending_tree_now_bin); | 848 metadata.is_tile_in_pending_tree_now_bin); |
982 | 849 |
983 HISTOGRAM_CUSTOM_COUNTS( | 850 HISTOGRAM_CUSTOM_COUNTS( |
984 "Renderer4.PictureRasterTimeUS", | 851 "Renderer4.PictureRasterTimeUS", |
985 raster_stats.total_rasterize_time.InMicroseconds(), | 852 raster_stats.total_rasterize_time.InMicroseconds(), |
986 0, | 853 0, |
987 100000, | 854 100000, |
988 100); | 855 100); |
989 } else { | 856 } else { |
990 picture_pile->RasterToBitmap(&canvas, rect, contents_scale, NULL); | 857 picture_pile->RasterToBitmap(&canvas, rect, contents_scale, NULL); |
991 } | 858 } |
859 | |
860 return true; | |
992 } | 861 } |
993 | 862 |
994 } // namespace cc | 863 } // namespace cc |
OLD | NEW |