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

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

Powered by Google App Engine
This is Rietveld 408576698