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

Side by Side Diff: cc/resources/tile_manager.cc

Issue 16190002: cc: Add new RasterWorkerPool interface. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: image_tasks_[task] = image_task; Created 7 years, 6 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
OLDNEW
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/SkCanvas.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
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));
124 } 104 }
125 105
126 TileManager::TileManager( 106 TileManager::TileManager(
127 TileManagerClient* client, 107 TileManagerClient* client,
128 ResourceProvider* resource_provider, 108 ResourceProvider* resource_provider,
129 scoped_ptr<RasterWorkerPool> raster_worker_pool, 109 scoped_ptr<RasterWorkerPool> raster_worker_pool,
130 size_t num_raster_threads, 110 size_t num_raster_threads,
131 bool use_color_estimator, 111 bool use_color_estimator,
132 RenderingStatsInstrumentation* rendering_stats_instrumentation, 112 RenderingStatsInstrumentation* rendering_stats_instrumentation)
133 bool use_map_image)
134 : client_(client), 113 : client_(client),
135 resource_pool_(ResourcePool::Create(resource_provider)), 114 resource_pool_(ResourcePool::Create(resource_provider)),
136 raster_worker_pool_(raster_worker_pool.Pass()), 115 raster_worker_pool_(raster_worker_pool.Pass()),
137 manage_tiles_pending_(false), 116 manage_tiles_pending_(false),
138 bytes_pending_upload_(0),
139 has_performed_uploads_since_last_flush_(false),
140 ever_exceeded_memory_budget_(false), 117 ever_exceeded_memory_budget_(false),
141 rendering_stats_instrumentation_(rendering_stats_instrumentation), 118 rendering_stats_instrumentation_(rendering_stats_instrumentation),
142 use_color_estimator_(use_color_estimator), 119 use_color_estimator_(use_color_estimator),
143 did_initialize_visible_tile_(false), 120 did_initialize_visible_tile_(false) {
144 max_pending_tasks_(kMaxNumPendingTasksPerThread * num_raster_threads) {
145 raster_worker_pool_->SetClient(this);
146 } 121 }
147 122
148 TileManager::~TileManager() { 123 TileManager::~TileManager() {
149 // Reset global state and manage. This should cause 124 // Reset global state and manage. This should cause
150 // our memory usage to drop to zero. 125 // our memory usage to drop to zero.
151 global_state_ = GlobalStateThatImpactsTilePriority(); 126 global_state_ = GlobalStateThatImpactsTilePriority();
152 AssignGpuMemoryToTiles(); 127 AssignGpuMemoryToTiles();
153 // This should finish all pending tasks and release any uninitialized 128 // This should finish all pending tasks and release any uninitialized
154 // resources. 129 // resources.
155 raster_worker_pool_->Shutdown(); 130 raster_worker_pool_->Shutdown();
156 AbortPendingTileUploads();
157 DCHECK_EQ(0u, tiles_with_pending_upload_.size());
158 DCHECK_EQ(0u, tiles_.size()); 131 DCHECK_EQ(0u, tiles_.size());
159 } 132 }
160 133
161 void TileManager::SetGlobalState( 134 void TileManager::SetGlobalState(
162 const GlobalStateThatImpactsTilePriority& global_state) { 135 const GlobalStateThatImpactsTilePriority& global_state) {
163 global_state_ = global_state; 136 global_state_ = global_state;
164 resource_pool_->SetMaxMemoryUsageBytes( 137 resource_pool_->SetMaxMemoryUsageBytes(
165 global_state_.memory_limit_in_bytes, 138 global_state_.memory_limit_in_bytes,
166 global_state_.unused_memory_limit_in_bytes); 139 global_state_.unused_memory_limit_in_bytes);
167 ScheduleManageTiles(); 140 ScheduleManageTiles();
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
314 287
315 TRACE_EVENT_INSTANT1( 288 TRACE_EVENT_INSTANT1(
316 "cc", "DidManage", TRACE_EVENT_SCOPE_THREAD, 289 "cc", "DidManage", TRACE_EVENT_SCOPE_THREAD,
317 "state", TracedValue::FromValue(BasicStateAsValue().release())); 290 "state", TracedValue::FromValue(BasicStateAsValue().release()));
318 291
319 // Finally, schedule rasterizer tasks. 292 // Finally, schedule rasterizer tasks.
320 ScheduleTasks(); 293 ScheduleTasks();
321 } 294 }
322 295
323 void TileManager::CheckForCompletedTileUploads() { 296 void TileManager::CheckForCompletedTileUploads() {
324 while (!tiles_with_pending_upload_.empty()) { 297 raster_worker_pool_->CheckForCompletedTasks();
325 Tile* tile = tiles_with_pending_upload_.front();
326 DCHECK(tile->tile_version().resource_);
327 298
328 // Set pixel tasks complete in the order they are posted. 299 if (client_->ShouldForceTileUploadsRequiredForActivationToComplete()) {
enne (OOO) 2013/05/30 19:38:31 style nit: early out here instead?
reveman 2013/05/30 23:25:18 Done.
329 if (!resource_pool_->resource_provider()->DidSetPixelsComplete( 300 TileSet initialized_tiles;
330 tile->tile_version().resource_->id())) { 301 for (TileSet::iterator it =
331 break; 302 tiles_that_need_to_be_initialized_for_activation_.begin();
303 it != tiles_that_need_to_be_initialized_for_activation_.end();
304 ++it) {
305 Tile* tile = *it;
306 if (!tile->managed_state().raster_task.is_null() &&
307 tile->tile_version().memory_state_ == USING_UNRELEASABLE_MEMORY &&
308 !tile->tile_version().forced_upload_) {
309 if (!raster_worker_pool_->ForceUploadToComplete(
310 tile->managed_state().raster_task))
311 continue;
312
313 // Setting |forced_upload_| to true makes this tile ready to draw.
314 tile->tile_version().forced_upload_ = true;
315 initialized_tiles.insert(tile);
316 }
332 } 317 }
333 318
334 // It's now safe to release the pixel buffer. 319 for (TileSet::iterator it = initialized_tiles.begin();
335 resource_pool_->resource_provider()->ReleasePixelBuffer( 320 it != initialized_tiles.end();
336 tile->tile_version().resource_->id()); 321 ++it) {
337 322 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); 323 DidFinishTileInitialization(tile);
345 324 DCHECK(tile->tile_version().IsReadyToDraw());
346 tiles_with_pending_upload_.pop(); 325 }
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 } 326 }
368 } 327 }
369 328
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 }
387 }
388
389 void TileManager::GetMemoryStats( 329 void TileManager::GetMemoryStats(
390 size_t* memory_required_bytes, 330 size_t* memory_required_bytes,
391 size_t* memory_nice_to_have_bytes, 331 size_t* memory_nice_to_have_bytes,
392 size_t* memory_used_bytes) const { 332 size_t* memory_used_bytes) const {
393 *memory_required_bytes = 0; 333 *memory_required_bytes = 0;
394 *memory_nice_to_have_bytes = 0; 334 *memory_nice_to_have_bytes = 0;
395 *memory_used_bytes = 0; 335 *memory_used_bytes = 0;
396 for (TileVector::const_iterator it = tiles_.begin(); 336 for (TileVector::const_iterator it = tiles_.begin();
397 it != tiles_.end(); 337 it != tiles_.end();
398 ++it) { 338 ++it) {
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
447 } 387 }
448 388
449 void TileManager::AddRequiredTileForActivation(Tile* tile) { 389 void TileManager::AddRequiredTileForActivation(Tile* tile) {
450 DCHECK(std::find(tiles_that_need_to_be_initialized_for_activation_.begin(), 390 DCHECK(std::find(tiles_that_need_to_be_initialized_for_activation_.begin(),
451 tiles_that_need_to_be_initialized_for_activation_.end(), 391 tiles_that_need_to_be_initialized_for_activation_.end(),
452 tile) == 392 tile) ==
453 tiles_that_need_to_be_initialized_for_activation_.end()); 393 tiles_that_need_to_be_initialized_for_activation_.end());
454 tiles_that_need_to_be_initialized_for_activation_.insert(tile); 394 tiles_that_need_to_be_initialized_for_activation_.insert(tile);
455 } 395 }
456 396
457 void TileManager::DidFinishDispatchingWorkerPoolCompletionCallbacks() {
458 // If a flush is needed, do it now before starting to dispatch more tasks.
459 if (has_performed_uploads_since_last_flush_) {
460 resource_pool_->resource_provider()->ShallowFlushIfSupported();
461 has_performed_uploads_since_last_flush_ = false;
462 }
463
464 ScheduleTasks();
465 }
466
467 void TileManager::AssignGpuMemoryToTiles() { 397 void TileManager::AssignGpuMemoryToTiles() {
468 TRACE_EVENT0("cc", "TileManager::AssignGpuMemoryToTiles"); 398 TRACE_EVENT0("cc", "TileManager::AssignGpuMemoryToTiles");
469 size_t unreleasable_bytes = 0; 399 size_t unreleasable_bytes = 0;
470 400
471 // Now give memory out to the tiles until we're out, and build 401 // Now give memory out to the tiles until we're out, and build
472 // the needs-to-be-rasterized queue. 402 // the needs-to-be-rasterized queue.
473 tiles_that_need_to_be_rasterized_.clear(); 403 tiles_that_need_to_be_rasterized_.clear();
474 tiles_that_need_to_be_initialized_for_activation_.clear(); 404 tiles_that_need_to_be_initialized_for_activation_.clear();
475 405
476 // By clearing the tiles_that_need_to_be_rasterized_ vector list 406 // By clearing the tiles_that_need_to_be_rasterized_ vector list
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
545 // 2. Tile with unreleasable memory could otherwise incorrectly 475 // 2. Tile with unreleasable memory could otherwise incorrectly
546 // be added as it's not affected by |bytes_allocatable|. 476 // be added as it's not affected by |bytes_allocatable|.
547 if (higher_priority_tile_oomed) 477 if (higher_priority_tile_oomed)
548 continue; 478 continue;
549 479
550 if (!tile_version.resource_) 480 if (!tile_version.resource_)
551 tiles_that_need_to_be_rasterized_.push_back(tile); 481 tiles_that_need_to_be_rasterized_.push_back(tile);
552 482
553 if (!tile_version.resource_ && tile->required_for_activation()) 483 if (!tile_version.resource_ && tile->required_for_activation())
554 AddRequiredTileForActivation(tile); 484 AddRequiredTileForActivation(tile);
555
556 if (tile_version.memory_state_ == USING_UNRELEASABLE_MEMORY &&
557 tile->required_for_activation()) {
558 // If after rasterizing, this tile has become required or the client has
559 // changed its mind about forcing tiles, do that now.
560 if (!tile->tile_version().forced_upload_ &&
561 client_->ShouldForceTileUploadsRequiredForActivationToComplete()) {
562 ForceTileUploadToComplete(tile);
563 }
564 }
565 } 485 }
566 486
567 // In OOM situation, we iterate tiles_, remove the memory for active tree 487 // In OOM situation, we iterate tiles_, remove the memory for active tree
568 // and not the now bin. And give them to bytes_oom_in_now_bin_on_pending_tree 488 // and not the now bin. And give them to bytes_oom_in_now_bin_on_pending_tree
569 if (!tiles_requiring_memory_but_oomed.empty()) { 489 if (!tiles_requiring_memory_but_oomed.empty()) {
570 size_t bytes_freed = 0; 490 size_t bytes_freed = 0;
571 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { 491 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) {
572 Tile* tile = *it; 492 Tile* tile = *it;
573 ManagedTileState& mts = tile->managed_state(); 493 ManagedTileState& mts = tile->managed_state();
574 ManagedTileState::TileVersion& tile_version = tile->tile_version(); 494 ManagedTileState::TileVersion& tile_version = tile->tile_version();
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
626 DCHECK_NE(USING_UNRELEASABLE_MEMORY, tile->tile_version().memory_state_); 546 DCHECK_NE(USING_UNRELEASABLE_MEMORY, tile->tile_version().memory_state_);
627 if (tile->tile_version().resource_) { 547 if (tile->tile_version().resource_) {
628 resource_pool_->ReleaseResource( 548 resource_pool_->ReleaseResource(
629 tile->tile_version().resource_.Pass()); 549 tile->tile_version().resource_.Pass());
630 } 550 }
631 tile->tile_version().memory_state_ = NOT_ALLOWED_TO_USE_MEMORY; 551 tile->tile_version().memory_state_ = NOT_ALLOWED_TO_USE_MEMORY;
632 } 552 }
633 553
634 void TileManager::ScheduleTasks() { 554 void TileManager::ScheduleTasks() {
635 TRACE_EVENT0("cc", "TileManager::ScheduleTasks"); 555 TRACE_EVENT0("cc", "TileManager::ScheduleTasks");
636 RasterWorkerPool::Task::Queue tasks; 556 RasterWorkerPool::RasterTask::Queue tasks;
637
638 size_t bytes_pending_upload = bytes_pending_upload_;
639 unsigned pending_tasks = 0;
640 557
641 // Build a new task queue containing all task currently needed. Tasks 558 // Build a new task queue containing all task currently needed. Tasks
642 // are added in order of priority, highest priority task first. 559 // are added in order of priority, highest priority task first.
643 for (TileVector::iterator it = tiles_that_need_to_be_rasterized_.begin(); 560 for (TileVector::iterator it = tiles_that_need_to_be_rasterized_.begin();
644 it != tiles_that_need_to_be_rasterized_.end(); 561 it != tiles_that_need_to_be_rasterized_.end();
645 ++it) { 562 ++it) {
646 Tile* tile = *it; 563 Tile* tile = *it;
647 ManagedTileState& mts = tile->managed_state(); 564 ManagedTileState& mts = tile->managed_state();
648 565
649 // Skip tile if determined to not require resource. 566 DCHECK(tile->tile_version().requires_resource());
650 if (!tile->tile_version().requires_resource()) 567 DCHECK(!tile->tile_version().resource_);
651 continue;
652
653 // Skip tile if already rasterized.
654 if (tile->tile_version().resource_)
655 continue;
656
657 // TODO(reveman): Remove throttling based on max pending tasks.
658 if (pending_tasks >= max_pending_tasks_)
659 break;
660
661 // TODO(reveman): Remove throttling based on max pending uploads.
662 if (tiles_with_pending_upload_.size() >= kMaxPendingUploads)
663 break;
664
665 // TODO(reveman): Throttle based on shared memory usage rather
666 // than bytes pending upload.
667 size_t new_bytes_pending = bytes_pending_upload;
668 new_bytes_pending += tile->bytes_consumed_if_allocated();
669 if (new_bytes_pending > kMaxPendingUploadBytes)
670 break;
671 bytes_pending_upload = new_bytes_pending;
672 568
673 // Create raster task for this tile if necessary. 569 // Create raster task for this tile if necessary.
674 if (mts.raster_task.is_null()) 570 if (mts.raster_task.is_null())
675 mts.raster_task = CreateRasterTask(tile); 571 mts.raster_task = CreateRasterTask(tile);
676 572
677 // Finally append raster task. 573 // Finally append raster task.
678 tasks.Append(mts.raster_task); 574 tasks.Append(mts.raster_task);
679 pending_tasks++;
680 } 575 }
681 576
682 if (!tasks.empty()) { 577 // Schedule running of |tasks|. This replaces any previously
683 RasterWorkerPool::Task root(&tasks); 578 // scheduled tasks and effectively cancels all tasks not present
684 579 // in |tasks|.
685 // Schedule running of |tasks|. This replaces any previously 580 raster_worker_pool_->ScheduleTasks(&tasks);
686 // scheduled tasks and effectively cancels all tasks not present
687 // in |tasks|.
688 raster_worker_pool_->ScheduleTasks(&root);
689 } else {
690 raster_worker_pool_->ScheduleTasks(NULL);
691 }
692
693 if (did_initialize_visible_tile_) {
694 did_initialize_visible_tile_ = false;
695 client_->DidInitializeVisibleTile();
696 }
697 } 581 }
698 582
699 RasterWorkerPool::Task TileManager::CreateImageDecodeTask( 583 RasterWorkerPool::Task TileManager::CreateImageDecodeTask(
700 Tile* tile, skia::LazyPixelRef* pixel_ref) { 584 Tile* tile, skia::LazyPixelRef* pixel_ref) {
701 TRACE_EVENT0("cc", "TileManager::CreateImageDecodeTask"); 585 TRACE_EVENT0("cc", "TileManager::CreateImageDecodeTask");
702 586
703 return RasterWorkerPool::Task( 587 return RasterWorkerPool::Task(
704 base::Bind(&TileManager::RunImageDecodeTask, 588 base::Bind(&TileManager::RunImageDecodeTask,
705 pixel_ref, 589 pixel_ref,
706 tile->layer_id(), 590 tile->layer_id(),
707 rendering_stats_instrumentation_), 591 rendering_stats_instrumentation_),
708 base::Bind(&TileManager::OnImageDecodeTaskCompleted, 592 base::Bind(&TileManager::OnImageDecodeTaskCompleted,
709 base::Unretained(this), 593 base::Unretained(this),
710 make_scoped_refptr(tile), 594 make_scoped_refptr(tile),
711 pixel_ref->getGenerationID())); 595 pixel_ref->getGenerationID()));
712 } 596 }
713 597
714 void TileManager::OnImageDecodeTaskCompleted(scoped_refptr<Tile> tile, 598 void TileManager::OnImageDecodeTaskCompleted(scoped_refptr<Tile> tile,
715 uint32_t pixel_ref_id, 599 uint32_t pixel_ref_id) {
716 bool was_canceled) {
717 TRACE_EVENT0("cc", "TileManager::OnImageDecodeTaskCompleted"); 600 TRACE_EVENT0("cc", "TileManager::OnImageDecodeTaskCompleted");
718 DCHECK(pending_decode_tasks_.find(pixel_ref_id) != 601 DCHECK(pending_decode_tasks_.find(pixel_ref_id) !=
719 pending_decode_tasks_.end()); 602 pending_decode_tasks_.end());
720 pending_decode_tasks_.erase(pixel_ref_id); 603 pending_decode_tasks_.erase(pixel_ref_id);
721 } 604 }
722 605
723 TileManager::RasterTaskMetadata TileManager::GetRasterTaskMetadata( 606 TileManager::RasterTaskMetadata TileManager::GetRasterTaskMetadata(
724 const Tile& tile) const { 607 const Tile& tile) const {
725 RasterTaskMetadata metadata; 608 RasterTaskMetadata metadata;
726 const ManagedTileState& mts = tile.managed_state(); 609 const ManagedTileState& mts = tile.managed_state();
727 metadata.is_tile_in_pending_tree_now_bin = 610 metadata.is_tile_in_pending_tree_now_bin =
728 mts.tree_bin[PENDING_TREE] == NOW_BIN; 611 mts.tree_bin[PENDING_TREE] == NOW_BIN;
729 metadata.tile_resolution = mts.resolution; 612 metadata.tile_resolution = mts.resolution;
730 metadata.layer_id = tile.layer_id(); 613 metadata.layer_id = tile.layer_id();
731 metadata.tile_id = &tile; 614 metadata.tile_id = &tile;
732 metadata.source_frame_number = tile.source_frame_number(); 615 metadata.source_frame_number = tile.source_frame_number();
733 return metadata; 616 return metadata;
734 } 617 }
735 618
736 RasterWorkerPool::Task TileManager::CreateRasterTask(Tile* tile) { 619 RasterWorkerPool::RasterTask TileManager::CreateRasterTask(Tile* tile) {
737 TRACE_EVENT0("cc", "TileManager::CreateRasterTask"); 620 TRACE_EVENT0("cc", "TileManager::CreateRasterTask");
738 621
739 scoped_ptr<ResourcePool::Resource> resource = 622 scoped_ptr<ResourcePool::Resource> resource =
740 resource_pool_->AcquireResource( 623 resource_pool_->AcquireResource(
741 tile->tile_size_.size(), 624 tile->tile_size_.size(),
742 tile->tile_version().resource_format_); 625 tile->tile_version().resource_format_);
743 resource_pool_->resource_provider()->AcquirePixelBuffer(resource->id()); 626 const Resource* const_resource = resource.get();
744 627
745 DCHECK_EQ(CAN_USE_MEMORY, tile->tile_version().memory_state_); 628 DCHECK_EQ(CAN_USE_MEMORY, tile->tile_version().memory_state_);
746 tile->tile_version().memory_state_ = USING_UNRELEASABLE_MEMORY; 629 tile->tile_version().memory_state_ = USING_UNRELEASABLE_MEMORY;
630 tile->tile_version().resource_id_ = resource->id();
747 631
748 PicturePileImpl::Analysis* analysis = new PicturePileImpl::Analysis; 632 PicturePileImpl::Analysis* analysis = new PicturePileImpl::Analysis;
749 633
750 // MapPixelBuffer() returns NULL if context was lost at the time
751 // AcquirePixelBuffer() was called. For simplicity we still create
752 // a raster task that is essentially a noop in these situations.
753 uint8* buffer = resource_pool_->resource_provider()->MapPixelBuffer(
754 resource->id());
755
756 // Create and queue all image decode tasks that this tile depends on. 634 // Create and queue all image decode tasks that this tile depends on.
757 RasterWorkerPool::Task::Queue decode_tasks; 635 RasterWorkerPool::Task::Set decode_tasks;
758 for (PicturePileImpl::PixelRefIterator iter(tile->content_rect(), 636 for (PicturePileImpl::PixelRefIterator iter(tile->content_rect(),
759 tile->contents_scale(), 637 tile->contents_scale(),
760 tile->picture_pile()); 638 tile->picture_pile());
761 iter; ++iter) { 639 iter; ++iter) {
762 skia::LazyPixelRef* pixel_ref = *iter; 640 skia::LazyPixelRef* pixel_ref = *iter;
763 uint32_t id = pixel_ref->getGenerationID(); 641 uint32_t id = pixel_ref->getGenerationID();
764 642
765 // Append existing image decode task if available. 643 // Append existing image decode task if available.
766 PixelRefMap::iterator decode_task_it = pending_decode_tasks_.find(id); 644 PixelRefMap::iterator decode_task_it = pending_decode_tasks_.find(id);
767 if (decode_task_it != pending_decode_tasks_.end()) { 645 if (decode_task_it != pending_decode_tasks_.end()) {
768 decode_tasks.Append(decode_task_it->second); 646 decode_tasks.Insert(decode_task_it->second);
769 continue; 647 continue;
770 } 648 }
771 649
772 // TODO(qinmin): passing correct image size to PrepareToDecode(). 650 // TODO(qinmin): passing correct image size to PrepareToDecode().
773 if (pixel_ref->PrepareToDecode(skia::LazyPixelRef::PrepareParams())) { 651 if (pixel_ref->PrepareToDecode(skia::LazyPixelRef::PrepareParams())) {
774 rendering_stats_instrumentation_->IncrementDeferredImageCacheHitCount(); 652 rendering_stats_instrumentation_->IncrementDeferredImageCacheHitCount();
775 continue; 653 continue;
776 } 654 }
777 655
778 // Create and append new image decode task for this pixel ref. 656 // Create and append new image decode task for this pixel ref.
779 RasterWorkerPool::Task decode_task = CreateImageDecodeTask( 657 RasterWorkerPool::Task decode_task = CreateImageDecodeTask(
780 tile, pixel_ref); 658 tile, pixel_ref);
781 decode_tasks.Append(decode_task); 659 decode_tasks.Insert(decode_task);
782 pending_decode_tasks_[id] = decode_task; 660 pending_decode_tasks_[id] = decode_task;
783 } 661 }
784 662
785 return RasterWorkerPool::PictureTask( 663 return RasterWorkerPool::RasterTask(
786 tile->picture_pile(), 664 tile->picture_pile(),
665 const_resource,
787 base::Bind(&TileManager::RunAnalyzeAndRasterTask, 666 base::Bind(&TileManager::RunAnalyzeAndRasterTask,
788 base::Bind(&TileManager::RunAnalyzeTask, 667 base::Bind(&TileManager::RunAnalyzeTask,
789 analysis, 668 analysis,
790 tile->content_rect(), 669 tile->content_rect(),
791 tile->contents_scale(), 670 tile->contents_scale(),
792 use_color_estimator_, 671 use_color_estimator_,
793 GetRasterTaskMetadata(*tile), 672 GetRasterTaskMetadata(*tile),
794 rendering_stats_instrumentation_), 673 rendering_stats_instrumentation_),
795 base::Bind(&TileManager::RunRasterTask, 674 base::Bind(&TileManager::RunRasterTask,
796 buffer,
797 analysis, 675 analysis,
798 tile->content_rect(), 676 tile->content_rect(),
799 tile->contents_scale(), 677 tile->contents_scale(),
800 GetRasterTaskMetadata(*tile), 678 GetRasterTaskMetadata(*tile),
801 rendering_stats_instrumentation_)), 679 rendering_stats_instrumentation_)),
802 base::Bind(&TileManager::OnRasterTaskCompleted, 680 base::Bind(&TileManager::OnRasterTaskCompleted,
803 base::Unretained(this), 681 base::Unretained(this),
804 make_scoped_refptr(tile), 682 make_scoped_refptr(tile),
805 base::Passed(&resource), 683 base::Passed(&resource),
806 base::Owned(analysis)), 684 base::Owned(analysis)),
807 &decode_tasks); 685 &decode_tasks);
808 } 686 }
809 687
810 void TileManager::OnRasterTaskCompleted( 688 void TileManager::OnRasterTaskCompleted(
811 scoped_refptr<Tile> tile, 689 scoped_refptr<Tile> tile,
812 scoped_ptr<ResourcePool::Resource> resource, 690 scoped_ptr<ResourcePool::Resource> resource,
813 PicturePileImpl::Analysis* analysis, 691 PicturePileImpl::Analysis* analysis,
814 bool was_canceled) { 692 bool was_canceled) {
815 TRACE_EVENT0("cc", "TileManager::OnRasterTaskCompleted"); 693 TRACE_EVENT0("cc", "TileManager::OnRasterTaskCompleted");
816 694
817 ManagedTileState& mts = tile->managed_state(); 695 ManagedTileState& mts = tile->managed_state();
818 DCHECK(!mts.raster_task.is_null()); 696 DCHECK(!mts.raster_task.is_null());
819 mts.raster_task.Reset(); 697 mts.raster_task.Reset();
820 698
821 // Tile resources can't be freed until upload has completed. 699 // Tile resources can't be freed until task has completed.
822 DCHECK_EQ(USING_UNRELEASABLE_MEMORY, tile->tile_version().memory_state_); 700 DCHECK_EQ(USING_UNRELEASABLE_MEMORY, tile->tile_version().memory_state_);
823 701
824 // Release raster resources.
825 resource_pool_->resource_provider()->UnmapPixelBuffer(resource->id());
826
827 if (was_canceled) { 702 if (was_canceled) {
828 tile->tile_version().memory_state_ = CAN_USE_MEMORY; 703 tile->tile_version().memory_state_ = CAN_USE_MEMORY;
829 resource_pool_->resource_provider()->ReleasePixelBuffer(resource->id());
830 resource_pool_->ReleaseResource(resource.Pass()); 704 resource_pool_->ReleaseResource(resource.Pass());
831 return; 705 return;
832 } 706 }
833 707
834 mts.picture_pile_analysis = *analysis; 708 mts.picture_pile_analysis = *analysis;
835 mts.picture_pile_analyzed = true; 709 mts.picture_pile_analyzed = true;
836 710
837 if (analysis->is_solid_color) { 711 if (analysis->is_solid_color) {
838 tile->tile_version().set_solid_color(analysis->solid_color); 712 tile->tile_version().set_solid_color(analysis->solid_color);
839 resource_pool_->resource_provider()->ReleasePixelBuffer(resource->id());
840 resource_pool_->ReleaseResource(resource.Pass()); 713 resource_pool_->ReleaseResource(resource.Pass());
841 DidFinishTileInitialization(tile); 714 } else {
842 return; 715 tile->tile_version().memory_state_ = USING_RELEASABLE_MEMORY;
716 tile->tile_version().resource_ = resource.Pass();
843 } 717 }
844 718
845 resource_pool_->resource_provider()->BeginSetPixels(resource->id()); 719 DidFinishTileInitialization(tile);
846 has_performed_uploads_since_last_flush_ = true;
847
848 tile->tile_version().resource_ = resource.Pass();
849
850 bytes_pending_upload_ += tile->bytes_consumed_if_allocated();
851 tiles_with_pending_upload_.push(tile);
852
853 if (tile->required_for_activation() &&
854 client_->ShouldForceTileUploadsRequiredForActivationToComplete())
855 ForceTileUploadToComplete(tile);
856 } 720 }
857 721
858 void TileManager::DidFinishTileInitialization(Tile* tile) { 722 void TileManager::DidFinishTileInitialization(Tile* tile) {
859 if (tile->priority(ACTIVE_TREE).distance_to_visible_in_pixels == 0) 723 if (tile->priority(ACTIVE_TREE).distance_to_visible_in_pixels == 0)
860 did_initialize_visible_tile_ = true; 724 did_initialize_visible_tile_ = true;
861 if (tile->required_for_activation()) { 725 if (tile->required_for_activation()) {
862 // It's possible that a tile required for activation is not in this list 726 // It's possible that a tile required for activation is not in this list
863 // if it was marked as being required after being dispatched for 727 // if it was marked as being required after being dispatched for
864 // rasterization but before AssignGPUMemory was called again. 728 // rasterization but before AssignGPUMemory was called again.
865 tiles_that_need_to_be_initialized_for_activation_.erase(tile); 729 tiles_that_need_to_be_initialized_for_activation_.erase(tile);
(...skipping 15 matching lines...) Expand all
881 TRACE_EVENT0("cc", "TileManager::RunImageDecodeTask"); 745 TRACE_EVENT0("cc", "TileManager::RunImageDecodeTask");
882 devtools_instrumentation::ScopedLayerTask image_decode_task( 746 devtools_instrumentation::ScopedLayerTask image_decode_task(
883 devtools_instrumentation::kImageDecodeTask, layer_id); 747 devtools_instrumentation::kImageDecodeTask, layer_id);
884 base::TimeTicks start_time = stats_instrumentation->StartRecording(); 748 base::TimeTicks start_time = stats_instrumentation->StartRecording();
885 pixel_ref->Decode(); 749 pixel_ref->Decode();
886 base::TimeDelta duration = stats_instrumentation->EndRecording(start_time); 750 base::TimeDelta duration = stats_instrumentation->EndRecording(start_time);
887 stats_instrumentation->AddDeferredImageDecode(duration); 751 stats_instrumentation->AddDeferredImageDecode(duration);
888 } 752 }
889 753
890 // static 754 // static
891 void TileManager::RunAnalyzeAndRasterTask( 755 bool TileManager::RunAnalyzeAndRasterTask(
892 const RasterWorkerPool::PictureTask::Callback& analyze_task, 756 const base::Callback<void(PicturePileImpl*)>& analyze_task,
893 const RasterWorkerPool::PictureTask::Callback& raster_task, 757 const RasterWorkerPool::RasterTask::Callback& raster_task,
758 SkDevice* device,
894 PicturePileImpl* picture_pile) { 759 PicturePileImpl* picture_pile) {
895 analyze_task.Run(picture_pile); 760 analyze_task.Run(picture_pile);
896 raster_task.Run(picture_pile); 761 return raster_task.Run(device, picture_pile);
897 } 762 }
898 763
899 // static 764 // static
900 void TileManager::RunAnalyzeTask( 765 void TileManager::RunAnalyzeTask(
901 PicturePileImpl::Analysis* analysis, 766 PicturePileImpl::Analysis* analysis,
902 gfx::Rect rect, 767 gfx::Rect rect,
903 float contents_scale, 768 float contents_scale,
904 bool use_color_estimator, 769 bool use_color_estimator,
905 const RasterTaskMetadata& metadata, 770 const RasterTaskMetadata& metadata,
906 RenderingStatsInstrumentation* stats_instrumentation, 771 RenderingStatsInstrumentation* stats_instrumentation,
(...skipping 22 matching lines...) Expand all
929 scoped_ptr<base::DictionaryValue> res(new base::DictionaryValue()); 794 scoped_ptr<base::DictionaryValue> res(new base::DictionaryValue());
930 res->Set("tile_id", TracedValue::CreateIDRef(tile_id).release()); 795 res->Set("tile_id", TracedValue::CreateIDRef(tile_id).release());
931 res->SetBoolean("is_tile_in_pending_tree_now_bin", 796 res->SetBoolean("is_tile_in_pending_tree_now_bin",
932 is_tile_in_pending_tree_now_bin); 797 is_tile_in_pending_tree_now_bin);
933 res->Set("resolution", TileResolutionAsValue(tile_resolution).release()); 798 res->Set("resolution", TileResolutionAsValue(tile_resolution).release());
934 res->SetInteger("source_frame_number", source_frame_number); 799 res->SetInteger("source_frame_number", source_frame_number);
935 return res.PassAs<base::Value>(); 800 return res.PassAs<base::Value>();
936 } 801 }
937 802
938 // static 803 // static
939 void TileManager::RunRasterTask( 804 bool TileManager::RunRasterTask(
940 uint8* buffer,
941 PicturePileImpl::Analysis* analysis, 805 PicturePileImpl::Analysis* analysis,
942 gfx::Rect rect, 806 gfx::Rect rect,
943 float contents_scale, 807 float contents_scale,
944 const RasterTaskMetadata& metadata, 808 const RasterTaskMetadata& metadata,
945 RenderingStatsInstrumentation* stats_instrumentation, 809 RenderingStatsInstrumentation* stats_instrumentation,
810 SkDevice* device,
946 PicturePileImpl* picture_pile) { 811 PicturePileImpl* picture_pile) {
947 TRACE_EVENT1( 812 TRACE_EVENT1(
948 "cc", "TileManager::RunRasterTask", 813 "cc", "TileManager::RunRasterTask",
949 "metadata", TracedValue::FromValue(metadata.AsValue().release())); 814 "metadata", TracedValue::FromValue(metadata.AsValue().release()));
950 devtools_instrumentation::ScopedLayerTask raster_task( 815 devtools_instrumentation::ScopedLayerTask raster_task(
951 devtools_instrumentation::kRasterTask, metadata.layer_id); 816 devtools_instrumentation::kRasterTask, metadata.layer_id);
952 817
953 DCHECK(picture_pile); 818 DCHECK(picture_pile);
954 DCHECK(analysis); 819 DCHECK(analysis);
955 820 DCHECK(device);
956 // |buffer| can be NULL in lost context situations.
957 if (!buffer)
958 return;
959 821
960 if (analysis->is_solid_color) 822 if (analysis->is_solid_color)
961 return; 823 return false;
962 824
963 SkBitmap bitmap; 825 SkCanvas canvas(device);
964 bitmap.setConfig(SkBitmap::kARGB_8888_Config, rect.width(), rect.height());
965 bitmap.setPixels(buffer);
966 SkDevice device(bitmap);
967 SkCanvas canvas(&device);
968 826
969 if (stats_instrumentation->record_rendering_stats()) { 827 if (stats_instrumentation->record_rendering_stats()) {
970 PicturePileImpl::RasterStats raster_stats; 828 PicturePileImpl::RasterStats raster_stats;
971 picture_pile->RasterToBitmap(&canvas, rect, contents_scale, &raster_stats); 829 picture_pile->RasterToBitmap(&canvas, rect, contents_scale, &raster_stats);
972 stats_instrumentation->AddRaster( 830 stats_instrumentation->AddRaster(
973 raster_stats.total_rasterize_time, 831 raster_stats.total_rasterize_time,
974 raster_stats.best_rasterize_time, 832 raster_stats.best_rasterize_time,
975 raster_stats.total_pixels_rasterized, 833 raster_stats.total_pixels_rasterized,
976 metadata.is_tile_in_pending_tree_now_bin); 834 metadata.is_tile_in_pending_tree_now_bin);
977 835
978 HISTOGRAM_CUSTOM_COUNTS( 836 HISTOGRAM_CUSTOM_COUNTS(
979 "Renderer4.PictureRasterTimeUS", 837 "Renderer4.PictureRasterTimeUS",
980 raster_stats.total_rasterize_time.InMicroseconds(), 838 raster_stats.total_rasterize_time.InMicroseconds(),
981 0, 839 0,
982 100000, 840 100000,
983 100); 841 100);
984 } else { 842 } else {
985 picture_pile->RasterToBitmap(&canvas, rect, contents_scale, NULL); 843 picture_pile->RasterToBitmap(&canvas, rect, contents_scale, NULL);
986 } 844 }
845
846 return true;
987 } 847 }
988 848
989 } // namespace cc 849 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698