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

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

Issue 16178002: Revert 202363 "cc: Cancel and re-prioritize worker pool tasks." (Closed) Base URL: svn://svn.chromium.org/chrome/
Patch Set: 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 | Annotate | Revision Log
« no previous file with comments | « trunk/src/cc/resources/tile_manager.h ('k') | trunk/src/cc/test/fake_tile_manager.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Property Changes:
Deleted: svn:mergeinfo
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"
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
128 ResourceProvider* resource_provider, 128 ResourceProvider* resource_provider,
129 scoped_ptr<RasterWorkerPool> raster_worker_pool, 129 scoped_ptr<RasterWorkerPool> raster_worker_pool,
130 size_t num_raster_threads, 130 size_t num_raster_threads,
131 bool use_color_estimator, 131 bool use_color_estimator,
132 RenderingStatsInstrumentation* rendering_stats_instrumentation, 132 RenderingStatsInstrumentation* rendering_stats_instrumentation,
133 bool use_map_image) 133 bool use_map_image)
134 : client_(client), 134 : client_(client),
135 resource_pool_(ResourcePool::Create(resource_provider)), 135 resource_pool_(ResourcePool::Create(resource_provider)),
136 raster_worker_pool_(raster_worker_pool.Pass()), 136 raster_worker_pool_(raster_worker_pool.Pass()),
137 manage_tiles_pending_(false), 137 manage_tiles_pending_(false),
138 manage_tiles_call_count_(0),
138 bytes_pending_upload_(0), 139 bytes_pending_upload_(0),
139 has_performed_uploads_since_last_flush_(false), 140 has_performed_uploads_since_last_flush_(false),
140 ever_exceeded_memory_budget_(false), 141 ever_exceeded_memory_budget_(false),
141 rendering_stats_instrumentation_(rendering_stats_instrumentation), 142 rendering_stats_instrumentation_(rendering_stats_instrumentation),
142 use_color_estimator_(use_color_estimator), 143 use_color_estimator_(use_color_estimator),
143 did_initialize_visible_tile_(false), 144 did_initialize_visible_tile_(false),
145 pending_tasks_(0),
144 max_pending_tasks_(kMaxNumPendingTasksPerThread * num_raster_threads) { 146 max_pending_tasks_(kMaxNumPendingTasksPerThread * num_raster_threads) {
145 raster_worker_pool_->SetClient(this); 147 raster_worker_pool_->SetClient(this);
146 } 148 }
147 149
148 TileManager::~TileManager() { 150 TileManager::~TileManager() {
149 // Reset global state and manage. This should cause 151 // Reset global state and manage. This should cause
150 // our memory usage to drop to zero. 152 // our memory usage to drop to zero.
151 global_state_ = GlobalStateThatImpactsTilePriority(); 153 global_state_ = GlobalStateThatImpactsTilePriority();
152 AssignGpuMemoryToTiles(); 154 AssignGpuMemoryToTiles();
153 // This should finish all pending tasks and release any uninitialized 155 // This should finish all pending tasks and release any uninitialized
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
300 TRACE_EVENT0("cc", "TileManager::SortTiles"); 302 TRACE_EVENT0("cc", "TileManager::SortTiles");
301 303
302 // Sort by bin, resolution and time until needed. 304 // Sort by bin, resolution and time until needed.
303 std::sort(tiles_.begin(), tiles_.end(), BinComparator()); 305 std::sort(tiles_.begin(), tiles_.end(), BinComparator());
304 } 306 }
305 307
306 void TileManager::ManageTiles() { 308 void TileManager::ManageTiles() {
307 TRACE_EVENT0("cc", "TileManager::ManageTiles"); 309 TRACE_EVENT0("cc", "TileManager::ManageTiles");
308 310
309 manage_tiles_pending_ = false; 311 manage_tiles_pending_ = false;
312 ++manage_tiles_call_count_;
310 313
311 AssignBinsToTiles(); 314 AssignBinsToTiles();
312 SortTiles(); 315 SortTiles();
313 AssignGpuMemoryToTiles(); 316 AssignGpuMemoryToTiles();
314 317
315 TRACE_EVENT_INSTANT1( 318 TRACE_EVENT_INSTANT1(
316 "cc", "DidManage", TRACE_EVENT_SCOPE_THREAD, 319 "cc", "DidManage", TRACE_EVENT_SCOPE_THREAD,
317 "state", TracedValue::FromValue(BasicStateAsValue().release())); 320 "state", TracedValue::FromValue(BasicStateAsValue().release()));
318 321
319 // Finally, schedule rasterizer tasks. 322 // Finally, kick the rasterizer.
320 ScheduleTasks(); 323 DispatchMoreTasks();
321 } 324 }
322 325
323 void TileManager::CheckForCompletedTileUploads() { 326 void TileManager::CheckForCompletedTileUploads() {
324 while (!tiles_with_pending_upload_.empty()) { 327 while (!tiles_with_pending_upload_.empty()) {
325 Tile* tile = tiles_with_pending_upload_.front(); 328 Tile* tile = tiles_with_pending_upload_.front();
326 DCHECK(tile->tile_version().resource_); 329 DCHECK(tile->tile_version().resource_);
327 330
328 // Set pixel tasks complete in the order they are posted. 331 // Set pixel tasks complete in the order they are posted.
329 if (!resource_pool_->resource_provider()->DidSetPixelsComplete( 332 if (!resource_pool_->resource_provider()->DidSetPixelsComplete(
330 tile->tile_version().resource_->id())) { 333 tile->tile_version().resource_->id())) {
331 break; 334 break;
332 } 335 }
333 336
334 // It's now safe to release the pixel buffer. 337 // It's now safe to release the pixel buffer.
335 resource_pool_->resource_provider()->ReleasePixelBuffer( 338 resource_pool_->resource_provider()->ReleasePixelBuffer(
336 tile->tile_version().resource_->id()); 339 tile->tile_version().resource_->id());
337 340
338 bytes_pending_upload_ -= tile->bytes_consumed_if_allocated(); 341 bytes_pending_upload_ -= tile->bytes_consumed_if_allocated();
339 bool was_forced = tile->tile_version().forced_upload_; 342 bool was_forced = tile->tile_version().forced_upload_;
340 // Reset forced_upload_ since we now got the upload completed notification. 343 // Reset forced_upload_ since we now got the upload completed notification.
341 tile->tile_version().forced_upload_ = false; 344 tile->tile_version().forced_upload_ = false;
342 tile->tile_version().memory_state_ = USING_RELEASABLE_MEMORY; 345 tile->tile_version().memory_state_ = USING_RELEASABLE_MEMORY;
343 if (!was_forced) 346 if (!was_forced)
344 DidFinishTileInitialization(tile); 347 DidFinishTileInitialization(tile);
345 348
346 tiles_with_pending_upload_.pop(); 349 tiles_with_pending_upload_.pop();
347 } 350 }
348 351
349 ScheduleTasks(); 352 DispatchMoreTasks();
350 } 353 }
351 354
352 void TileManager::AbortPendingTileUploads() { 355 void TileManager::AbortPendingTileUploads() {
353 while (!tiles_with_pending_upload_.empty()) { 356 while (!tiles_with_pending_upload_.empty()) {
354 Tile* tile = tiles_with_pending_upload_.front(); 357 Tile* tile = tiles_with_pending_upload_.front();
355 DCHECK(tile->tile_version().resource_); 358 DCHECK(tile->tile_version().resource_);
356 359
357 resource_pool_->resource_provider()->AbortSetPixels( 360 resource_pool_->resource_provider()->AbortSetPixels(
358 tile->tile_version().resource_->id()); 361 tile->tile_version().resource_->id());
359 resource_pool_->resource_provider()->ReleasePixelBuffer( 362 resource_pool_->resource_provider()->ReleasePixelBuffer(
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
459 tiles_that_need_to_be_initialized_for_activation_.insert(tile); 462 tiles_that_need_to_be_initialized_for_activation_.insert(tile);
460 } 463 }
461 464
462 void TileManager::DidFinishDispatchingWorkerPoolCompletionCallbacks() { 465 void TileManager::DidFinishDispatchingWorkerPoolCompletionCallbacks() {
463 // If a flush is needed, do it now before starting to dispatch more tasks. 466 // If a flush is needed, do it now before starting to dispatch more tasks.
464 if (has_performed_uploads_since_last_flush_) { 467 if (has_performed_uploads_since_last_flush_) {
465 resource_pool_->resource_provider()->ShallowFlushIfSupported(); 468 resource_pool_->resource_provider()->ShallowFlushIfSupported();
466 has_performed_uploads_since_last_flush_ = false; 469 has_performed_uploads_since_last_flush_ = false;
467 } 470 }
468 471
469 ScheduleTasks(); 472 DispatchMoreTasks();
470 } 473 }
471 474
472 void TileManager::AssignGpuMemoryToTiles() { 475 void TileManager::AssignGpuMemoryToTiles() {
473 TRACE_EVENT0("cc", "TileManager::AssignGpuMemoryToTiles"); 476 TRACE_EVENT0("cc", "TileManager::AssignGpuMemoryToTiles");
474 size_t unreleasable_bytes = 0; 477 size_t unreleasable_bytes = 0;
475 478
476 // Now give memory out to the tiles until we're out, and build 479 // Now give memory out to the tiles until we're out, and build
477 // the needs-to-be-rasterized queue. 480 // the needs-to-be-rasterized queue.
478 tiles_that_need_to_be_rasterized_.clear(); 481 tiles_that_need_to_be_rasterized_.clear();
479 tiles_that_need_to_be_initialized_for_activation_.clear(); 482 tiles_that_need_to_be_initialized_for_activation_.clear();
480 483
481 // By clearing the tiles_that_need_to_be_rasterized_ vector list 484 // By clearing the tiles_that_need_to_be_rasterized_ vector list
482 // above we move all tiles currently waiting for raster to idle state. 485 // above we move all tiles currently waiting for raster to idle state.
483 // Some memory cannot be released. We figure out how much in this 486 // Some memory cannot be released. We figure out how much in this
484 // loop. 487 // loop as well.
485 for (TileVector::const_iterator it = tiles_.begin(); 488 for (TileVector::const_iterator it = tiles_.begin();
486 it != tiles_.end(); 489 it != tiles_.end();
487 ++it) { 490 ++it) {
488 const Tile* tile = *it; 491 const Tile* tile = *it;
489 if (tile->tile_version().memory_state_ == USING_UNRELEASABLE_MEMORY) 492 if (tile->tile_version().memory_state_ == USING_UNRELEASABLE_MEMORY)
490 unreleasable_bytes += tile->bytes_consumed_if_allocated(); 493 unreleasable_bytes += tile->bytes_consumed_if_allocated();
491 } 494 }
492 495
493 // Global state's memory limit can decrease, causing 496 // Global state's memory limit can decrease, causing
494 // it to be less than unreleasable_bytes 497 // it to be less than unreleasable_bytes
495 size_t bytes_allocatable = 498 size_t bytes_allocatable =
496 global_state_.memory_limit_in_bytes > unreleasable_bytes ? 499 global_state_.memory_limit_in_bytes > unreleasable_bytes ?
497 global_state_.memory_limit_in_bytes - unreleasable_bytes : 500 global_state_.memory_limit_in_bytes - unreleasable_bytes :
498 0; 501 0;
499 size_t bytes_that_exceeded_memory_budget_in_now_bin = 0; 502 size_t bytes_that_exceeded_memory_budget_in_now_bin = 0;
500 size_t bytes_left = bytes_allocatable; 503 size_t bytes_left = bytes_allocatable;
501 size_t bytes_oom_in_now_bin_on_pending_tree = 0; 504 size_t bytes_oom_in_now_bin_on_pending_tree = 0;
502 TileVector tiles_requiring_memory_but_oomed; 505 TileVector tiles_requiring_memory_but_oomed;
503 bool higher_priority_tile_oomed = false;
504 for (TileVector::iterator it = tiles_.begin(); 506 for (TileVector::iterator it = tiles_.begin();
505 it != tiles_.end(); 507 it != tiles_.end();
506 ++it) { 508 ++it) {
507 Tile* tile = *it; 509 Tile* tile = *it;
508 ManagedTileState& mts = tile->managed_state(); 510 ManagedTileState& mts = tile->managed_state();
509 ManagedTileState::TileVersion& tile_version = tile->tile_version(); 511 ManagedTileState::TileVersion& tile_version = tile->tile_version();
510 512
511 // If this tile doesn't need a resource, then nothing to do. 513 // If this tile doesn't need a resource, then nothing to do.
512 if (!tile_version.requires_resource()) 514 if (!tile_version.requires_resource())
513 continue; 515 continue;
514 516
515 size_t tile_bytes = tile->bytes_consumed_if_allocated(); 517 // If the memory is unreleasable, then we do not need to do anything.
516 // Memory is already reserved for tile with unreleasable memory 518 if (tile_version.memory_state_ == USING_UNRELEASABLE_MEMORY) {
517 // so adding it to |tiles_that_need_to_be_rasterized_| doesn't 519 if (tile->required_for_activation()) {
518 // affect bytes_allocatable. 520 AddRequiredTileForActivation(tile);
519 if (tile_version.memory_state_ == USING_UNRELEASABLE_MEMORY) 521 // If after rasterizing, this tile has become required or the client has
520 tile_bytes = 0; 522 // changed its mind about forcing tiles, do that now.
521 523 if (!tile->tile_version().forced_upload_ &&
522 // If the tile is not needed, free it up. 524 client_->ShouldForceTileUploadsRequiredForActivationToComplete()) {
523 if (mts.is_in_never_bin_on_both_trees()) { 525 ForceTileUploadToComplete(tile);
524 if (tile_version.memory_state_ != USING_UNRELEASABLE_MEMORY) { 526 }
525 FreeResourcesForTile(tile);
526 tile_version.memory_state_ = NOT_ALLOWED_TO_USE_MEMORY;
527 } 527 }
528 continue; 528 continue;
529 } 529 }
530 530
531 size_t tile_bytes = tile->bytes_consumed_if_allocated();
532 // If the tile is not needed, free it up.
533 if (mts.is_in_never_bin_on_both_trees()) {
534 FreeResourcesForTile(tile);
535 tile_version.memory_state_ = NOT_ALLOWED_TO_USE_MEMORY;
536 continue;
537 }
531 // Tile is OOM. 538 // Tile is OOM.
532 if (tile_bytes > bytes_left) { 539 if (tile_bytes > bytes_left) {
540 FreeResourcesForTile(tile);
533 tile->tile_version().set_rasterize_on_demand(); 541 tile->tile_version().set_rasterize_on_demand();
534 if (mts.tree_bin[PENDING_TREE] == NOW_BIN) { 542 if (mts.tree_bin[PENDING_TREE] == NOW_BIN) {
535 tiles_requiring_memory_but_oomed.push_back(tile); 543 tiles_requiring_memory_but_oomed.push_back(tile);
536 bytes_oom_in_now_bin_on_pending_tree += tile_bytes; 544 bytes_oom_in_now_bin_on_pending_tree += tile_bytes;
537 } 545 }
538 FreeResourcesForTile(tile);
539 higher_priority_tile_oomed = true;
540 continue; 546 continue;
541 } 547 }
542
543 tile_version.set_use_resource(); 548 tile_version.set_use_resource();
544 bytes_left -= tile_bytes; 549 bytes_left -= tile_bytes;
545 550 if (!tile_version.resource_ &&
546 // Tile shouldn't be rasterized if we've failed to assign 551 tile_version.memory_state_ == CAN_USE_MEMORY) {
547 // gpu memory to a higher priority tile. This is important for
548 // two reasons:
549 // 1. Tile size should not impact raster priority.
550 // 2. Tile with unreleasable memory could otherwise incorrectly
551 // be added as it's not affected by |bytes_allocatable|.
552 if (higher_priority_tile_oomed)
553 continue;
554
555 if (!tile_version.resource_)
556 tiles_that_need_to_be_rasterized_.push_back(tile); 552 tiles_that_need_to_be_rasterized_.push_back(tile);
557 553 }
558 if (!tile_version.resource_ && tile->required_for_activation()) 554 if (!tile_version.resource_ && tile->required_for_activation())
559 AddRequiredTileForActivation(tile); 555 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 } 556 }
571 557
572 // In OOM situation, we iterate tiles_, remove the memory for active tree 558 // 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 559 // 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()) { 560 if (!tiles_requiring_memory_but_oomed.empty()) {
575 size_t bytes_freed = 0; 561 size_t bytes_freed = 0;
576 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { 562 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) {
577 Tile* tile = *it; 563 Tile* tile = *it;
578 ManagedTileState& mts = tile->managed_state(); 564 ManagedTileState& mts = tile->managed_state();
579 ManagedTileState::TileVersion& tile_version = tile->tile_version(); 565 ManagedTileState::TileVersion& tile_version = tile->tile_version();
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
618 "budget", global_state_.memory_limit_in_bytes, 604 "budget", global_state_.memory_limit_in_bytes,
619 "over", bytes_that_exceeded_memory_budget_in_now_bin); 605 "over", bytes_that_exceeded_memory_budget_in_now_bin);
620 } 606 }
621 memory_stats_from_last_assign_.total_budget_in_bytes = 607 memory_stats_from_last_assign_.total_budget_in_bytes =
622 global_state_.memory_limit_in_bytes; 608 global_state_.memory_limit_in_bytes;
623 memory_stats_from_last_assign_.bytes_allocated = 609 memory_stats_from_last_assign_.bytes_allocated =
624 bytes_allocatable - bytes_left; 610 bytes_allocatable - bytes_left;
625 memory_stats_from_last_assign_.bytes_unreleasable = unreleasable_bytes; 611 memory_stats_from_last_assign_.bytes_unreleasable = unreleasable_bytes;
626 memory_stats_from_last_assign_.bytes_over = 612 memory_stats_from_last_assign_.bytes_over =
627 bytes_that_exceeded_memory_budget_in_now_bin; 613 bytes_that_exceeded_memory_budget_in_now_bin;
614
615 // Reverse two tiles_that_need_* vectors such that pop_back gets
616 // the highest priority tile.
617 std::reverse(
618 tiles_that_need_to_be_rasterized_.begin(),
619 tiles_that_need_to_be_rasterized_.end());
628 } 620 }
629 621
630 void TileManager::FreeResourcesForTile(Tile* tile) { 622 void TileManager::FreeResourcesForTile(Tile* tile) {
631 DCHECK_NE(USING_UNRELEASABLE_MEMORY, tile->tile_version().memory_state_); 623 DCHECK(tile->tile_version().memory_state_ != USING_UNRELEASABLE_MEMORY);
632 if (tile->tile_version().resource_) { 624 if (tile->tile_version().resource_) {
633 resource_pool_->ReleaseResource( 625 resource_pool_->ReleaseResource(
634 tile->tile_version().resource_.Pass()); 626 tile->tile_version().resource_.Pass());
635 } 627 }
636 tile->tile_version().memory_state_ = NOT_ALLOWED_TO_USE_MEMORY; 628 tile->tile_version().memory_state_ = NOT_ALLOWED_TO_USE_MEMORY;
637 } 629 }
638 630
639 void TileManager::ScheduleTasks() { 631 bool TileManager::CanDispatchRasterTask(Tile* tile) const {
640 TRACE_EVENT0("cc", "TileManager::ScheduleTasks"); 632 if (pending_tasks_ >= max_pending_tasks_)
641 RasterWorkerPool::Task::Queue tasks; 633 return false;
634 size_t new_bytes_pending = bytes_pending_upload_;
635 new_bytes_pending += tile->bytes_consumed_if_allocated();
636 return new_bytes_pending <= kMaxPendingUploadBytes &&
637 tiles_with_pending_upload_.size() < kMaxPendingUploads;
638 }
642 639
643 size_t bytes_pending_upload = bytes_pending_upload_; 640 void TileManager::DispatchMoreTasks() {
644 unsigned pending_tasks = 0; 641 TileVector tiles_with_image_decoding_tasks;
645 642
646 // Build a new task queue containing all task currently needed. Tasks 643 // Process all tiles in the need_to_be_rasterized queue:
647 // are added in order of priority, highest priority task first. 644 // 1. Dispatch image decode tasks.
648 for (TileVector::iterator it = tiles_that_need_to_be_rasterized_.begin(); 645 // 2. If the image decode isn't done, save the tile for later processing.
649 it != tiles_that_need_to_be_rasterized_.end(); 646 // 3. Attempt to dispatch a raster task, or break out of the loop.
650 ++it) { 647 while (!tiles_that_need_to_be_rasterized_.empty()) {
651 Tile* tile = *it; 648 Tile* tile = tiles_that_need_to_be_rasterized_.back();
652 ManagedTileState& mts = tile->managed_state();
653 649
654 // Skip tile if determined to not require resource. 650 DCHECK(tile->tile_version().requires_resource());
655 if (!tile->tile_version().requires_resource())
656 continue;
657 651
658 // Skip tile if already rasterized. 652 if (DispatchImageDecodeTasksForTile(tile)) {
659 if (tile->tile_version().resource_) 653 tiles_with_image_decoding_tasks.push_back(tile);
660 continue; 654 } else if (!CanDispatchRasterTask(tile)) {
661 655 break;
662 // TODO(reveman): Remove throttling based on max pending tasks. 656 } else {
663 if (pending_tasks >= max_pending_tasks_) 657 DispatchOneRasterTask(tile);
664 break; 658 }
665 659 tiles_that_need_to_be_rasterized_.pop_back();
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
678 // Create raster task for this tile if necessary.
679 if (mts.raster_task.is_null())
680 mts.raster_task = CreateRasterTask(tile);
681
682 // Finally append raster task.
683 tasks.Append(mts.raster_task);
684 pending_tasks++;
685 } 660 }
686 661
687 if (!tasks.empty()) { 662 // Put the saved tiles back into the queue. The order is reversed
688 RasterWorkerPool::Task root(&tasks); 663 // to preserve original ordering.
689 664 tiles_that_need_to_be_rasterized_.insert(
690 // Schedule running of |tasks|. This replaces any previously 665 tiles_that_need_to_be_rasterized_.end(),
691 // scheduled tasks and effectively cancels all tasks not present 666 tiles_with_image_decoding_tasks.rbegin(),
692 // in |tasks|. 667 tiles_with_image_decoding_tasks.rend());
693 raster_worker_pool_->ScheduleTasks(&root);
694 } else {
695 raster_worker_pool_->ScheduleTasks(NULL);
696 }
697 668
698 if (did_initialize_visible_tile_) { 669 if (did_initialize_visible_tile_) {
699 did_initialize_visible_tile_ = false; 670 did_initialize_visible_tile_ = false;
700 client_->DidInitializeVisibleTile(); 671 client_->DidInitializeVisibleTile();
701 } 672 }
702 } 673 }
703 674
704 RasterWorkerPool::Task TileManager::CreateImageDecodeTask( 675 bool TileManager::DispatchImageDecodeTasksForTile(Tile* tile) {
705 Tile* tile, skia::LazyPixelRef* pixel_ref) { 676 TRACE_EVENT0("cc", "TileManager::DispatchImageDecodeTasksForTile");
706 TRACE_EVENT0("cc", "TileManager::CreateImageDecodeTask"); 677 ManagedTileState& mts = tile->managed_state();
678 bool pending_decode_tasks = false;
707 679
708 return RasterWorkerPool::Task(
709 base::Bind(&TileManager::RunImageDecodeTask,
710 pixel_ref,
711 tile->layer_id(),
712 rendering_stats_instrumentation_),
713 base::Bind(&TileManager::OnImageDecodeTaskCompleted,
714 base::Unretained(this),
715 make_scoped_refptr(tile),
716 pixel_ref->getGenerationID()));
717 }
718
719 void TileManager::OnImageDecodeTaskCompleted(scoped_refptr<Tile> tile,
720 uint32_t pixel_ref_id,
721 bool was_canceled) {
722 TRACE_EVENT0("cc", "TileManager::OnImageDecodeTaskCompleted");
723 DCHECK(pending_decode_tasks_.find(pixel_ref_id) !=
724 pending_decode_tasks_.end());
725 pending_decode_tasks_.erase(pixel_ref_id);
726 }
727
728 TileManager::RasterTaskMetadata TileManager::GetRasterTaskMetadata(
729 const Tile& tile) const {
730 RasterTaskMetadata metadata;
731 const ManagedTileState& mts = tile.managed_state();
732 metadata.is_tile_in_pending_tree_now_bin =
733 mts.tree_bin[PENDING_TREE] == NOW_BIN;
734 metadata.tile_resolution = mts.resolution;
735 metadata.layer_id = tile.layer_id();
736 metadata.tile_id = &tile;
737 metadata.source_frame_number = tile.source_frame_number();
738 return metadata;
739 }
740
741 RasterWorkerPool::Task TileManager::CreateRasterTask(Tile* tile) {
742 TRACE_EVENT0("cc", "TileManager::CreateRasterTask");
743
744 scoped_ptr<ResourcePool::Resource> resource =
745 resource_pool_->AcquireResource(
746 tile->tile_size_.size(),
747 tile->tile_version().resource_format_);
748 resource_pool_->resource_provider()->AcquirePixelBuffer(resource->id());
749
750 DCHECK_EQ(CAN_USE_MEMORY, tile->tile_version().memory_state_);
751 tile->tile_version().memory_state_ = USING_UNRELEASABLE_MEMORY;
752
753 PicturePileImpl::Analysis* analysis = new PicturePileImpl::Analysis;
754
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.
762 RasterWorkerPool::Task::Queue decode_tasks;
763 for (PicturePileImpl::PixelRefIterator iter(tile->content_rect(), 680 for (PicturePileImpl::PixelRefIterator iter(tile->content_rect(),
764 tile->contents_scale(), 681 tile->contents_scale(),
765 tile->picture_pile()); 682 tile->picture_pile());
766 iter; ++iter) { 683 iter; ++iter) {
767 skia::LazyPixelRef* pixel_ref = *iter; 684 skia::LazyPixelRef* pixel_ref = *iter;
768 uint32_t id = pixel_ref->getGenerationID(); 685 uint32_t id = pixel_ref->getGenerationID();
769 686
770 // Append existing image decode task if available. 687 // Check if image has already been decoded.
771 PixelRefMap::iterator decode_task_it = pending_decode_tasks_.find(id); 688 if (mts.decoded_pixel_refs.find(id) != mts.decoded_pixel_refs.end())
772 if (decode_task_it != pending_decode_tasks_.end()) { 689 continue;
773 decode_tasks.Append(decode_task_it->second); 690
691 // Check if decode task is already pending.
692 if (pending_decode_tasks_.find(id) != pending_decode_tasks_.end()) {
693 pending_decode_tasks = true;
774 continue; 694 continue;
775 } 695 }
776 696
777 // TODO(qinmin): passing correct image size to PrepareToDecode(). 697 // TODO(qinmin): passing correct image size to PrepareToDecode().
778 if (pixel_ref->PrepareToDecode(skia::LazyPixelRef::PrepareParams())) { 698 if (pixel_ref->PrepareToDecode(skia::LazyPixelRef::PrepareParams())) {
779 rendering_stats_instrumentation_->IncrementDeferredImageCacheHitCount(); 699 rendering_stats_instrumentation_->IncrementDeferredImageCacheHitCount();
700 mts.decoded_pixel_refs.insert(id);
780 continue; 701 continue;
781 } 702 }
782 703
783 // Create and append new image decode task for this pixel ref. 704 if (pending_tasks_ >= max_pending_tasks_)
784 RasterWorkerPool::Task decode_task = CreateImageDecodeTask( 705 break;
785 tile, pixel_ref); 706
786 decode_tasks.Append(decode_task); 707 DispatchOneImageDecodeTask(tile, pixel_ref);
787 pending_decode_tasks_[id] = decode_task; 708 pending_decode_tasks = true;
788 } 709 }
789 710
790 return RasterWorkerPool::PictureTask( 711 return pending_decode_tasks;
712 }
713
714 void TileManager::DispatchOneImageDecodeTask(
715 scoped_refptr<Tile> tile, skia::LazyPixelRef* pixel_ref) {
716 TRACE_EVENT0("cc", "TileManager::DispatchOneImageDecodeTask");
717 uint32_t pixel_ref_id = pixel_ref->getGenerationID();
718 DCHECK(pending_decode_tasks_.end() ==
719 pending_decode_tasks_.find(pixel_ref_id));
720 pending_decode_tasks_.insert(pixel_ref_id);
721
722 raster_worker_pool_->PostTaskAndReply(
723 base::Bind(&TileManager::RunImageDecodeTask,
724 pixel_ref,
725 tile->layer_id(),
726 rendering_stats_instrumentation_),
727 base::Bind(&TileManager::OnImageDecodeTaskCompleted,
728 base::Unretained(this),
729 tile,
730 pixel_ref_id));
731 pending_tasks_++;
732 }
733
734 void TileManager::OnImageDecodeTaskCompleted(
735 scoped_refptr<Tile> tile, uint32_t pixel_ref_id) {
736 TRACE_EVENT0("cc", "TileManager::OnImageDecodeTaskCompleted");
737 ManagedTileState& mts = tile->managed_state();
738 mts.decoded_pixel_refs.insert(pixel_ref_id);
739 pending_decode_tasks_.erase(pixel_ref_id);
740 pending_tasks_--;
741 }
742
743 scoped_ptr<ResourcePool::Resource> TileManager::PrepareTileForRaster(
744 Tile* tile) {
745 scoped_ptr<ResourcePool::Resource> resource = resource_pool_->AcquireResource(
746 tile->tile_size_.size(),
747 tile->tile_version().resource_format_);
748 resource_pool_->resource_provider()->AcquirePixelBuffer(resource->id());
749
750 tile->tile_version().memory_state_ = USING_UNRELEASABLE_MEMORY;
751
752 return resource.Pass();
753 }
754
755 void TileManager::DispatchOneRasterTask(scoped_refptr<Tile> tile) {
756 TRACE_EVENT0("cc", "TileManager::DispatchOneRasterTask");
757 scoped_ptr<ResourcePool::Resource> resource = PrepareTileForRaster(tile);
758 ResourceProvider::ResourceId resource_id = resource->id();
759 PicturePileImpl::Analysis* analysis = new PicturePileImpl::Analysis;
760
761 // MapPixelBuffer() returns NULL if context was lost at the time
762 // AcquirePixelBuffer() was called. For simplicity we still post
763 // a raster task that is essentially a noop in these situations.
764 uint8* buffer = resource_pool_->resource_provider()->MapPixelBuffer(
765 resource_id);
766
767 // skia requires that our buffer be 4-byte aligned
768 CHECK(!(reinterpret_cast<intptr_t>(buffer) & 3));
769
770 raster_worker_pool_->PostRasterTaskAndReply(
791 tile->picture_pile(), 771 tile->picture_pile(),
792 base::Bind(&TileManager::RunAnalyzeAndRasterTask, 772 base::Bind(&TileManager::RunAnalyzeAndRasterTask,
793 base::Bind(&TileManager::RunAnalyzeTask, 773 base::Bind(&TileManager::RunAnalyzeTask,
794 analysis, 774 analysis,
795 tile->content_rect(), 775 tile->content_rect(),
796 tile->contents_scale(), 776 tile->contents_scale(),
797 use_color_estimator_, 777 use_color_estimator_,
798 GetRasterTaskMetadata(*tile), 778 GetRasterTaskMetadata(*tile),
799 rendering_stats_instrumentation_), 779 rendering_stats_instrumentation_),
800 base::Bind(&TileManager::RunRasterTask, 780 base::Bind(&TileManager::RunRasterTask,
801 buffer, 781 buffer,
802 analysis, 782 analysis,
803 tile->content_rect(), 783 tile->content_rect(),
804 tile->contents_scale(), 784 tile->contents_scale(),
805 GetRasterTaskMetadata(*tile), 785 GetRasterTaskMetadata(*tile),
806 rendering_stats_instrumentation_)), 786 rendering_stats_instrumentation_)),
807 base::Bind(&TileManager::OnRasterTaskCompleted, 787 base::Bind(&TileManager::OnRasterTaskCompleted,
808 base::Unretained(this), 788 base::Unretained(this),
809 make_scoped_refptr(tile), 789 tile,
810 base::Passed(&resource), 790 base::Passed(&resource),
811 base::Owned(analysis)), 791 base::Owned(analysis),
812 &decode_tasks); 792 manage_tiles_call_count_));
793 pending_tasks_++;
794 }
795
796 TileManager::RasterTaskMetadata TileManager::GetRasterTaskMetadata(
797 const Tile& tile) const {
798 RasterTaskMetadata metadata;
799 const ManagedTileState& mts = tile.managed_state();
800 metadata.is_tile_in_pending_tree_now_bin =
801 mts.tree_bin[PENDING_TREE] == NOW_BIN;
802 metadata.tile_resolution = mts.resolution;
803 metadata.layer_id = tile.layer_id();
804 metadata.tile_id = &tile;
805 metadata.source_frame_number = tile.source_frame_number();
806 return metadata;
813 } 807 }
814 808
815 void TileManager::OnRasterTaskCompleted( 809 void TileManager::OnRasterTaskCompleted(
816 scoped_refptr<Tile> tile, 810 scoped_refptr<Tile> tile,
817 scoped_ptr<ResourcePool::Resource> resource, 811 scoped_ptr<ResourcePool::Resource> resource,
818 PicturePileImpl::Analysis* analysis, 812 PicturePileImpl::Analysis* analysis,
819 bool was_canceled) { 813 int manage_tiles_call_count_when_dispatched) {
820 TRACE_EVENT0("cc", "TileManager::OnRasterTaskCompleted"); 814 TRACE_EVENT0("cc", "TileManager::OnRasterTaskCompleted");
821 815
822 ManagedTileState& mts = tile->managed_state(); 816 pending_tasks_--;
823 DCHECK(!mts.raster_task.is_null());
824 mts.raster_task.Reset();
825
826 // Tile resources can't be freed until upload has completed.
827 DCHECK_EQ(USING_UNRELEASABLE_MEMORY, tile->tile_version().memory_state_);
828 817
829 // Release raster resources. 818 // Release raster resources.
830 resource_pool_->resource_provider()->UnmapPixelBuffer(resource->id()); 819 resource_pool_->resource_provider()->UnmapPixelBuffer(resource->id());
831 820
832 if (was_canceled) { 821 tile->tile_version().memory_state_ = USING_RELEASABLE_MEMORY;
833 tile->tile_version().memory_state_ = CAN_USE_MEMORY;
834 resource_pool_->resource_provider()->ReleasePixelBuffer(resource->id());
835 resource_pool_->ReleaseResource(resource.Pass());
836 return;
837 }
838 822
839 mts.picture_pile_analysis = *analysis; 823 ManagedTileState& managed_tile_state = tile->managed_state();
840 mts.picture_pile_analyzed = true; 824 managed_tile_state.picture_pile_analysis = *analysis;
825 managed_tile_state.picture_pile_analyzed = true;
841 826
842 if (analysis->is_solid_color) { 827 if (analysis->is_solid_color) {
843 tile->tile_version().set_solid_color(analysis->solid_color); 828 tile->tile_version().set_solid_color(analysis->solid_color);
844 resource_pool_->resource_provider()->ReleasePixelBuffer(resource->id()); 829 resource_pool_->resource_provider()->ReleasePixelBuffer(resource->id());
845 resource_pool_->ReleaseResource(resource.Pass()); 830 resource_pool_->ReleaseResource(resource.Pass());
846 DidFinishTileInitialization(tile); 831 DidFinishTileInitialization(tile);
847 return; 832 return;
848 } 833 }
849 834
850 resource_pool_->resource_provider()->BeginSetPixels(resource->id()); 835 // Tile can be freed after the completion of the raster task. Call
851 has_performed_uploads_since_last_flush_ = true; 836 // AssignGpuMemoryToTiles() to re-assign gpu memory to highest priority
837 // tiles if ManageTiles() was called since task was dispatched. The result
838 // of this could be that this tile is no longer allowed to use gpu
839 // memory and in that case we need to abort initialization and free all
840 // associated resources before calling DispatchMoreTasks().
841 if (manage_tiles_call_count_when_dispatched != manage_tiles_call_count_)
842 AssignGpuMemoryToTiles();
852 843
853 tile->tile_version().resource_ = resource.Pass(); 844 // Finish resource initialization we're still using memory.
845 if (tile->tile_version().memory_state_ == USING_RELEASABLE_MEMORY) {
846 // Tile resources can't be freed until upload has completed.
847 tile->tile_version().memory_state_ = USING_UNRELEASABLE_MEMORY;
854 848
855 bytes_pending_upload_ += tile->bytes_consumed_if_allocated(); 849 resource_pool_->resource_provider()->BeginSetPixels(resource->id());
856 tiles_with_pending_upload_.push(tile); 850 has_performed_uploads_since_last_flush_ = true;
857 851
858 if (tile->required_for_activation() && 852 tile->tile_version().resource_ = resource.Pass();
859 client_->ShouldForceTileUploadsRequiredForActivationToComplete()) 853
860 ForceTileUploadToComplete(tile); 854 bytes_pending_upload_ += tile->bytes_consumed_if_allocated();
855 tiles_with_pending_upload_.push(tile);
856
857 if (tile->required_for_activation() &&
858 client_->ShouldForceTileUploadsRequiredForActivationToComplete())
859 ForceTileUploadToComplete(tile);
860 } else {
861 resource_pool_->resource_provider()->ReleasePixelBuffer(resource->id());
862 resource_pool_->ReleaseResource(resource.Pass());
863 }
861 } 864 }
862 865
863 void TileManager::DidFinishTileInitialization(Tile* tile) { 866 void TileManager::DidFinishTileInitialization(Tile* tile) {
864 if (tile->priority(ACTIVE_TREE).distance_to_visible_in_pixels == 0) 867 if (tile->priority(ACTIVE_TREE).distance_to_visible_in_pixels == 0)
865 did_initialize_visible_tile_ = true; 868 did_initialize_visible_tile_ = true;
866 if (tile->required_for_activation()) { 869 if (tile->required_for_activation()) {
867 // It's possible that a tile required for activation is not in this list 870 // 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 871 // if it was marked as being required after being dispatched for
869 // rasterization but before AssignGPUMemory was called again. 872 // rasterization but before AssignGPUMemory was called again.
870 tiles_that_need_to_be_initialized_for_activation_.erase(tile); 873 tiles_that_need_to_be_initialized_for_activation_.erase(tile);
871 } 874 }
872 } 875 }
873 876
874 void TileManager::DidTileTreeBinChange(Tile* tile, 877 void TileManager::DidTileTreeBinChange(Tile* tile,
875 TileManagerBin new_tree_bin, 878 TileManagerBin new_tree_bin,
876 WhichTree tree) { 879 WhichTree tree) {
877 ManagedTileState& mts = tile->managed_state(); 880 ManagedTileState& mts = tile->managed_state();
878 mts.tree_bin[tree] = new_tree_bin; 881 mts.tree_bin[tree] = new_tree_bin;
879 } 882 }
880 883
881 // static 884 // static
882 void TileManager::RunImageDecodeTask(
883 skia::LazyPixelRef* pixel_ref,
884 int layer_id,
885 RenderingStatsInstrumentation* stats_instrumentation) {
886 TRACE_EVENT0("cc", "TileManager::RunImageDecodeTask");
887 devtools_instrumentation::ScopedLayerTask image_decode_task(
888 devtools_instrumentation::kImageDecodeTask, layer_id);
889 base::TimeTicks start_time = stats_instrumentation->StartRecording();
890 pixel_ref->Decode();
891 base::TimeDelta duration = stats_instrumentation->EndRecording(start_time);
892 stats_instrumentation->AddDeferredImageDecode(duration);
893 }
894
895 // static
896 void TileManager::RunAnalyzeAndRasterTask( 885 void TileManager::RunAnalyzeAndRasterTask(
897 const RasterWorkerPool::PictureTask::Callback& analyze_task, 886 const RasterWorkerPool::RasterCallback& analyze_task,
898 const RasterWorkerPool::PictureTask::Callback& raster_task, 887 const RasterWorkerPool::RasterCallback& raster_task,
899 PicturePileImpl* picture_pile) { 888 PicturePileImpl* picture_pile) {
900 analyze_task.Run(picture_pile); 889 analyze_task.Run(picture_pile);
901 raster_task.Run(picture_pile); 890 raster_task.Run(picture_pile);
902 } 891 }
903 892
904 // static 893 // static
905 void TileManager::RunAnalyzeTask( 894 void TileManager::RunAnalyzeTask(
906 PicturePileImpl::Analysis* analysis, 895 PicturePileImpl::Analysis* analysis,
907 gfx::Rect rect, 896 gfx::Rect rect,
908 float contents_scale, 897 float contents_scale,
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
984 "Renderer4.PictureRasterTimeUS", 973 "Renderer4.PictureRasterTimeUS",
985 raster_stats.total_rasterize_time.InMicroseconds(), 974 raster_stats.total_rasterize_time.InMicroseconds(),
986 0, 975 0,
987 100000, 976 100000,
988 100); 977 100);
989 } else { 978 } else {
990 picture_pile->RasterToBitmap(&canvas, rect, contents_scale, NULL); 979 picture_pile->RasterToBitmap(&canvas, rect, contents_scale, NULL);
991 } 980 }
992 } 981 }
993 982
983 // static
984 void TileManager::RunImageDecodeTask(
985 skia::LazyPixelRef* pixel_ref,
986 int layer_id,
987 RenderingStatsInstrumentation* stats_instrumentation) {
988 TRACE_EVENT0("cc", "TileManager::RunImageDecodeTask");
989 devtools_instrumentation::ScopedLayerTask image_decode_task(
990 devtools_instrumentation::kImageDecodeTask, layer_id);
991 base::TimeTicks start_time = stats_instrumentation->StartRecording();
992 pixel_ref->Decode();
993 base::TimeDelta duration = stats_instrumentation->EndRecording(start_time);
994 stats_instrumentation->AddDeferredImageDecode(duration);
995 }
996
994 } // namespace cc 997 } // namespace cc
OLDNEW
« no previous file with comments | « trunk/src/cc/resources/tile_manager.h ('k') | trunk/src/cc/test/fake_tile_manager.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698