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

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

Issue 17351017: Re-land: cc: Add raster finished signals to RasterWorkerPool. (Closed) Base URL: http://git.chromium.org/chromium/src.git@new-graph-build
Patch Set: add missing code 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"
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
158 158
159 void TileManager::UnregisterTile(Tile* tile) { 159 void TileManager::UnregisterTile(Tile* tile) {
160 TileVector::iterator raster_iter = 160 TileVector::iterator raster_iter =
161 std::find(tiles_that_need_to_be_rasterized_.begin(), 161 std::find(tiles_that_need_to_be_rasterized_.begin(),
162 tiles_that_need_to_be_rasterized_.end(), 162 tiles_that_need_to_be_rasterized_.end(),
163 tile); 163 tile);
164 if (raster_iter != tiles_that_need_to_be_rasterized_.end()) 164 if (raster_iter != tiles_that_need_to_be_rasterized_.end())
165 tiles_that_need_to_be_rasterized_.erase(raster_iter); 165 tiles_that_need_to_be_rasterized_.erase(raster_iter);
166 166
167 tiles_that_need_to_be_initialized_for_activation_.erase(tile); 167 tiles_that_need_to_be_initialized_for_activation_.erase(tile);
168 oom_tiles_that_need_to_be_initialized_for_activation_.erase(tile);
168 169
169 DCHECK(std::find(tiles_.begin(), tiles_.end(), tile) != tiles_.end()); 170 DCHECK(std::find(tiles_.begin(), tiles_.end(), tile) != tiles_.end());
170 FreeResourcesForTile(tile); 171 FreeResourcesForTile(tile);
171 tiles_.erase(std::remove(tiles_.begin(), tiles_.end(), tile)); 172 tiles_.erase(std::remove(tiles_.begin(), tiles_.end(), tile));
172 } 173 }
173 174
174 bool TileManager::ShouldForceTasksRequiredForActivationToComplete() const { 175 bool TileManager::ShouldForceTasksRequiredForActivationToComplete() const {
175 return client_->ShouldForceTileUploadsRequiredForActivationToComplete(); 176 return client_->ShouldForceTileUploadsRequiredForActivationToComplete();
176 } 177 }
177 178
179 void TileManager::DidFinishedRunningTasks() {
180 if (oom_tiles_that_need_to_be_initialized_for_activation_.empty())
181 return;
182
183 raster_worker_pool_->CheckForCompletedTasks();
184
185 AssignGpuMemoryToTiles();
vmpstr 2013/06/21 18:38:33 Can we make this return true if reassign oom is re
reveman 2013/06/24 16:04:03 I'd rather call reassign unconditionally to keep t
186 ReassignGpuMemoryToOOMTiles();
187
188 if (!tiles_that_need_to_be_rasterized_.empty()) {
189 ScheduleTasks();
190 return;
191 }
192
193 for (TileSet::iterator it =
194 oom_tiles_that_need_to_be_initialized_for_activation_.begin();
195 it != oom_tiles_that_need_to_be_initialized_for_activation_.end();
196 ++it) {
197 Tile* tile = *it;
198 ManagedTileState& mts = tile->managed_state();
199 mts.tile_versions[mts.raster_mode].set_rasterize_on_demand();
200 }
201 oom_tiles_that_need_to_be_initialized_for_activation_.clear();
202
203 client_->NotifyReadyToActivate();
204 }
205
206 void TileManager::DidFinishedRunningTasksRequiredForActivation() {
207 if (!oom_tiles_that_need_to_be_initialized_for_activation_.empty())
vmpstr 2013/06/21 18:38:33 Can you make a comment that explains why this is n
reveman 2013/06/24 16:04:03 Added a comment that explains why we might need to
208 return;
209
210 // TODO(reveman): Push the responsibility of calling CheckForCompletedTasks()
211 // to the LTHI where it can be delayed until it's time to draw.
212 raster_worker_pool_->CheckForCompletedTasks();
213
214 client_->NotifyReadyToActivate();
215 }
216
178 class BinComparator { 217 class BinComparator {
179 public: 218 public:
180 bool operator() (const Tile* a, const Tile* b) const { 219 bool operator() (const Tile* a, const Tile* b) const {
181 const ManagedTileState& ams = a->managed_state(); 220 const ManagedTileState& ams = a->managed_state();
182 const ManagedTileState& bms = b->managed_state(); 221 const ManagedTileState& bms = b->managed_state();
183 if (ams.bin[HIGH_PRIORITY_BIN] != bms.bin[HIGH_PRIORITY_BIN]) 222 if (ams.bin[HIGH_PRIORITY_BIN] != bms.bin[HIGH_PRIORITY_BIN])
184 return ams.bin[HIGH_PRIORITY_BIN] < bms.bin[HIGH_PRIORITY_BIN]; 223 return ams.bin[HIGH_PRIORITY_BIN] < bms.bin[HIGH_PRIORITY_BIN];
185 224
186 if (ams.bin[LOW_PRIORITY_BIN] != bms.bin[LOW_PRIORITY_BIN]) 225 if (ams.bin[LOW_PRIORITY_BIN] != bms.bin[LOW_PRIORITY_BIN])
187 return ams.bin[LOW_PRIORITY_BIN] < bms.bin[LOW_PRIORITY_BIN]; 226 return ams.bin[LOW_PRIORITY_BIN] < bms.bin[LOW_PRIORITY_BIN];
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
294 std::sort(tiles_.begin(), tiles_.end(), BinComparator()); 333 std::sort(tiles_.begin(), tiles_.end(), BinComparator());
295 } 334 }
296 335
297 void TileManager::ManageTiles() { 336 void TileManager::ManageTiles() {
298 TRACE_EVENT0("cc", "TileManager::ManageTiles"); 337 TRACE_EVENT0("cc", "TileManager::ManageTiles");
299 AssignBinsToTiles(); 338 AssignBinsToTiles();
300 SortTiles(); 339 SortTiles();
301 AssignGpuMemoryToTiles(); 340 AssignGpuMemoryToTiles();
302 CleanUpUnusedImageDecodeTasks(); 341 CleanUpUnusedImageDecodeTasks();
303 342
304 // This could have changed after AssignGpuMemoryToTiles.
305 if (AreTilesRequiredForActivationReady())
306 client_->NotifyReadyToActivate();
307
308 TRACE_EVENT_INSTANT1( 343 TRACE_EVENT_INSTANT1(
309 "cc", "DidManage", TRACE_EVENT_SCOPE_THREAD, 344 "cc", "DidManage", TRACE_EVENT_SCOPE_THREAD,
310 "state", TracedValue::FromValue(BasicStateAsValue().release())); 345 "state", TracedValue::FromValue(BasicStateAsValue().release()));
311 346
312 // Finally, schedule rasterizer tasks. 347 // Finally, schedule rasterizer tasks.
313 ScheduleTasks(); 348 ScheduleTasks();
314 } 349 }
315 350
316 void TileManager::CheckForCompletedTileUploads() { 351 void TileManager::CheckForCompletedTileUploads() {
317 raster_worker_pool_->CheckForCompletedTasks(); 352 raster_worker_pool_->CheckForCompletedTasks();
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
402 return raster_mode; 437 return raster_mode;
403 } 438 }
404 439
405 void TileManager::AssignGpuMemoryToTiles() { 440 void TileManager::AssignGpuMemoryToTiles() {
406 TRACE_EVENT0("cc", "TileManager::AssignGpuMemoryToTiles"); 441 TRACE_EVENT0("cc", "TileManager::AssignGpuMemoryToTiles");
407 442
408 // Now give memory out to the tiles until we're out, and build 443 // Now give memory out to the tiles until we're out, and build
409 // the needs-to-be-rasterized queue. 444 // the needs-to-be-rasterized queue.
410 tiles_that_need_to_be_rasterized_.clear(); 445 tiles_that_need_to_be_rasterized_.clear();
411 tiles_that_need_to_be_initialized_for_activation_.clear(); 446 tiles_that_need_to_be_initialized_for_activation_.clear();
447 oom_tiles_that_need_to_be_initialized_for_activation_.clear();
412 448
413 size_t bytes_releasable = 0; 449 size_t bytes_releasable = 0;
414 for (TileVector::const_iterator it = tiles_.begin(); 450 for (TileVector::const_iterator it = tiles_.begin();
415 it != tiles_.end(); 451 it != tiles_.end();
416 ++it) { 452 ++it) {
417 const Tile* tile = *it; 453 const Tile* tile = *it;
418 const ManagedTileState& mts = tile->managed_state(); 454 const ManagedTileState& mts = tile->managed_state();
419 for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) { 455 for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) {
420 if (mts.tile_versions[mode].resource_) 456 if (mts.tile_versions[mode].resource_)
421 bytes_releasable += tile->bytes_consumed_if_allocated(); 457 bytes_releasable += tile->bytes_consumed_if_allocated();
422 } 458 }
423 } 459 }
424 460
425 // Cast to prevent overflow. 461 // Cast to prevent overflow.
426 int64 bytes_available = 462 int64 bytes_available =
427 static_cast<int64>(bytes_releasable) + 463 static_cast<int64>(bytes_releasable) +
428 static_cast<int64>(global_state_.memory_limit_in_bytes) - 464 static_cast<int64>(global_state_.memory_limit_in_bytes) -
429 static_cast<int64>(resource_pool_->acquired_memory_usage_bytes()); 465 static_cast<int64>(resource_pool_->acquired_memory_usage_bytes());
430 466
431 size_t bytes_allocatable = 467 size_t bytes_allocatable =
432 std::max(static_cast<int64>(0), bytes_available); 468 std::max(static_cast<int64>(0), bytes_available);
433 469
434 size_t bytes_that_exceeded_memory_budget_in_now_bin = 0; 470 size_t bytes_that_exceeded_memory_budget_in_now_bin = 0;
435 size_t bytes_left = bytes_allocatable; 471 size_t bytes_left = bytes_allocatable;
436 size_t bytes_oom_in_now_bin_on_pending_tree = 0;
437 TileVector tiles_requiring_memory_but_oomed;
438 bool higher_priority_tile_oomed = false; 472 bool higher_priority_tile_oomed = false;
439 for (TileVector::iterator it = tiles_.begin(); 473 for (TileVector::iterator it = tiles_.begin();
440 it != tiles_.end(); 474 it != tiles_.end();
441 ++it) { 475 ++it) {
442 Tile* tile = *it; 476 Tile* tile = *it;
443 ManagedTileState& mts = tile->managed_state(); 477 ManagedTileState& mts = tile->managed_state();
444 478
445 // Pick the better version out of the one we already set, 479 // Pick the better version out of the one we already set,
446 // and the one that is required. 480 // and the one that is required.
447 mts.raster_mode = std::min(mts.raster_mode, DetermineRasterMode(tile)); 481 mts.raster_mode = std::min(mts.raster_mode, DetermineRasterMode(tile));
(...skipping 19 matching lines...) Expand all
467 tile_bytes += tile->bytes_consumed_if_allocated(); 501 tile_bytes += tile->bytes_consumed_if_allocated();
468 } 502 }
469 503
470 // If we don't have the required version, and it's not in flight 504 // If we don't have the required version, and it's not in flight
471 // then we'll have to pay to create a new task. 505 // then we'll have to pay to create a new task.
472 if (!tile_version.resource_ && tile_version.raster_task_.is_null()) 506 if (!tile_version.resource_ && tile_version.raster_task_.is_null())
473 tile_bytes += tile->bytes_consumed_if_allocated(); 507 tile_bytes += tile->bytes_consumed_if_allocated();
474 508
475 // Tile is OOM. 509 // Tile is OOM.
476 if (tile_bytes > bytes_left) { 510 if (tile_bytes > bytes_left) {
477 mts.tile_versions[mts.raster_mode].set_rasterize_on_demand(); 511 if (tile->required_for_activation())
478 if (mts.tree_bin[PENDING_TREE] == NOW_BIN) { 512 oom_tiles_that_need_to_be_initialized_for_activation_.insert(tile);
479 tiles_requiring_memory_but_oomed.push_back(tile);
480 bytes_oom_in_now_bin_on_pending_tree += tile_bytes;
481 }
482 FreeResourcesForTile(tile); 513 FreeResourcesForTile(tile);
483 higher_priority_tile_oomed = true; 514 higher_priority_tile_oomed = true;
484 continue; 515 continue;
485 } 516 }
486 517
487 tile_version.set_use_resource(); 518 tile_version.set_use_resource();
488 bytes_left -= tile_bytes; 519 bytes_left -= tile_bytes;
489 520
490 // Tile shouldn't be rasterized if we've failed to assign 521 // Tile shouldn't be rasterized if we've failed to assign
491 // gpu memory to a higher priority tile. This is important for 522 // gpu memory to a higher priority tile. This is important for
492 // two reasons: 523 // two reasons:
493 // 1. Tile size should not impact raster priority. 524 // 1. Tile size should not impact raster priority.
494 // 2. Tile with unreleasable memory could otherwise incorrectly 525 // 2. Tile with unreleasable memory could otherwise incorrectly
495 // be added as it's not affected by |bytes_allocatable|. 526 // be added as it's not affected by |bytes_allocatable|.
496 if (higher_priority_tile_oomed) 527 if (higher_priority_tile_oomed)
497 continue; 528 continue;
498 529
499 if (!tile_version.resource_) 530 if (!tile_version.resource_)
500 tiles_that_need_to_be_rasterized_.push_back(tile); 531 tiles_that_need_to_be_rasterized_.push_back(tile);
501 532
502 if (!tile->IsReadyToDraw(NULL) && 533 if (!tile->IsReadyToDraw(NULL) &&
503 tile->required_for_activation()) { 534 tile->required_for_activation()) {
504 AddRequiredTileForActivation(tile); 535 AddRequiredTileForActivation(tile);
505 } 536 }
506 } 537 }
507 538
508 // In OOM situation, we iterate tiles_, remove the memory for active tree
509 // and not the now bin. And give them to bytes_oom_in_now_bin_on_pending_tree
510 if (!tiles_requiring_memory_but_oomed.empty()) {
511 size_t bytes_freed = 0;
512 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) {
513 Tile* tile = *it;
514 ManagedTileState& mts = tile->managed_state();
515 if (mts.tree_bin[PENDING_TREE] == NEVER_BIN &&
516 mts.tree_bin[ACTIVE_TREE] != NOW_BIN) {
517 size_t bytes_that_can_be_freed = 0;
518 for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) {
519 ManagedTileState::TileVersion& tile_version =
520 mts.tile_versions[mode];
521 if (tile_version.resource_) {
522 DCHECK(!tile->required_for_activation());
523 bytes_that_can_be_freed += tile->bytes_consumed_if_allocated();
524 }
525 }
526
527 if (bytes_that_can_be_freed > 0) {
528 FreeResourcesForTile(tile);
529 bytes_freed += bytes_that_can_be_freed;
530 mts.tile_versions[mts.raster_mode].set_rasterize_on_demand();
531 TileVector::iterator it = std::find(
532 tiles_that_need_to_be_rasterized_.begin(),
533 tiles_that_need_to_be_rasterized_.end(),
534 tile);
535 if (it != tiles_that_need_to_be_rasterized_.end())
536 tiles_that_need_to_be_rasterized_.erase(it);
537 }
538 }
539
540 if (bytes_oom_in_now_bin_on_pending_tree <= bytes_freed)
541 break;
542 }
543
544 for (TileVector::iterator it = tiles_requiring_memory_but_oomed.begin();
545 it != tiles_requiring_memory_but_oomed.end() && bytes_freed > 0;
546 ++it) {
547 Tile* tile = *it;
548 ManagedTileState& mts = tile->managed_state();
549 size_t bytes_needed = tile->bytes_consumed_if_allocated();
550 if (bytes_needed > bytes_freed)
551 continue;
552 mts.tile_versions[mts.raster_mode].set_use_resource();
553 bytes_freed -= bytes_needed;
554 tiles_that_need_to_be_rasterized_.push_back(tile);
555 if (tile->required_for_activation())
556 AddRequiredTileForActivation(tile);
557 }
558 }
559
560 ever_exceeded_memory_budget_ |= 539 ever_exceeded_memory_budget_ |=
561 bytes_that_exceeded_memory_budget_in_now_bin > 0; 540 bytes_that_exceeded_memory_budget_in_now_bin > 0;
562 if (ever_exceeded_memory_budget_) { 541 if (ever_exceeded_memory_budget_) {
563 TRACE_COUNTER_ID2("cc", "over_memory_budget", this, 542 TRACE_COUNTER_ID2("cc", "over_memory_budget", this,
564 "budget", global_state_.memory_limit_in_bytes, 543 "budget", global_state_.memory_limit_in_bytes,
565 "over", bytes_that_exceeded_memory_budget_in_now_bin); 544 "over", bytes_that_exceeded_memory_budget_in_now_bin);
566 } 545 }
567 memory_stats_from_last_assign_.total_budget_in_bytes = 546 memory_stats_from_last_assign_.total_budget_in_bytes =
568 global_state_.memory_limit_in_bytes; 547 global_state_.memory_limit_in_bytes;
569 memory_stats_from_last_assign_.bytes_allocated = 548 memory_stats_from_last_assign_.bytes_allocated =
570 bytes_allocatable - bytes_left; 549 bytes_allocatable - bytes_left;
571 memory_stats_from_last_assign_.bytes_unreleasable = 550 memory_stats_from_last_assign_.bytes_unreleasable =
572 bytes_allocatable - bytes_releasable; 551 bytes_allocatable - bytes_releasable;
573 memory_stats_from_last_assign_.bytes_over = 552 memory_stats_from_last_assign_.bytes_over =
574 bytes_that_exceeded_memory_budget_in_now_bin; 553 bytes_that_exceeded_memory_budget_in_now_bin;
575 } 554 }
576 555
556 void TileManager::ReassignGpuMemoryToOOMTiles() {
557 TRACE_EVENT0("cc", "TileManager::ReassignGpuMemoryToOOMTiles");
558
559 size_t bytes_oom_for_required_tiles = 0;
560 TileVector tiles_requiring_memory_but_oomed;
561 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) {
vmpstr 2013/06/21 18:38:33 Isn't this just a loop over oom_tiles_that_need_to
reveman 2013/06/24 16:04:03 Yes, but it adds tiles to |tiles_requiring_memory_
vmpstr 2013/06/24 16:34:03 Oh I didn't realize that it was a set, my bad.
562 Tile* tile = *it;
563 if (oom_tiles_that_need_to_be_initialized_for_activation_.find(tile) ==
564 oom_tiles_that_need_to_be_initialized_for_activation_.end())
565 continue;
566
567 tiles_requiring_memory_but_oomed.push_back(tile);
568 bytes_oom_for_required_tiles += tile->bytes_consumed_if_allocated();
569 }
570
571 // In OOM situation, we iterate tiles_, remove the memory for active tree
572 // and not the now bin. And give them to bytes_oom_for_required_tiles
573 size_t bytes_freed = 0;
574 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) {
vmpstr 2013/06/21 18:38:33 You should early out before this if nothing is OOM
reveman 2013/06/24 16:04:03 Done.
575 Tile* tile = *it;
576 ManagedTileState& mts = tile->managed_state();
577 if (mts.tree_bin[PENDING_TREE] == NEVER_BIN &&
578 mts.tree_bin[ACTIVE_TREE] != NOW_BIN) {
579 size_t bytes_that_can_be_freed = 0;
580 for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) {
581 ManagedTileState::TileVersion& tile_version = mts.tile_versions[mode];
582 if (tile_version.resource_) {
583 DCHECK(!tile->required_for_activation());
584 bytes_that_can_be_freed += tile->bytes_consumed_if_allocated();
585 }
586 }
587
588 if (bytes_that_can_be_freed > 0) {
589 FreeResourcesForTile(tile);
590 bytes_freed += bytes_that_can_be_freed;
591 TileVector::iterator it = std::find(
592 tiles_that_need_to_be_rasterized_.begin(),
593 tiles_that_need_to_be_rasterized_.end(),
594 tile);
595 if (it != tiles_that_need_to_be_rasterized_.end())
596 tiles_that_need_to_be_rasterized_.erase(it);
597 }
598 }
599
600 if (bytes_oom_for_required_tiles <= bytes_freed)
601 break;
602 }
603
604 for (TileVector::iterator it = tiles_requiring_memory_but_oomed.begin();
605 it != tiles_requiring_memory_but_oomed.end() && bytes_freed > 0;
606 ++it) {
607 Tile* tile = *it;
608 ManagedTileState& mts = tile->managed_state();
609 size_t bytes_needed = tile->bytes_consumed_if_allocated();
610 if (bytes_needed > bytes_freed)
611 continue;
612 mts.tile_versions[mts.raster_mode].set_use_resource();
613 bytes_freed -= bytes_needed;
614 tiles_that_need_to_be_rasterized_.push_back(tile);
615 AddRequiredTileForActivation(tile);
616 oom_tiles_that_need_to_be_initialized_for_activation_.erase(tile);
617 }
618 }
619
577 void TileManager::CleanUpUnusedImageDecodeTasks() { 620 void TileManager::CleanUpUnusedImageDecodeTasks() {
578 // Calculate a set of layers that are used by at least one tile. 621 // Calculate a set of layers that are used by at least one tile.
579 base::hash_set<int> used_layers; 622 base::hash_set<int> used_layers;
580 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) 623 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it)
581 used_layers.insert((*it)->layer_id()); 624 used_layers.insert((*it)->layer_id());
582 625
583 // Now calculate the set of layers in |image_decode_tasks_| that are not used 626 // Now calculate the set of layers in |image_decode_tasks_| that are not used
584 // by any tile. 627 // by any tile.
585 std::vector<int> unused_layers; 628 std::vector<int> unused_layers;
586 for (LayerPixelRefTaskMap::iterator it = image_decode_tasks_.begin(); 629 for (LayerPixelRefTaskMap::iterator it = image_decode_tasks_.begin();
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
800 } 843 }
801 844
802 void TileManager::DidTileTreeBinChange(Tile* tile, 845 void TileManager::DidTileTreeBinChange(Tile* tile,
803 TileManagerBin new_tree_bin, 846 TileManagerBin new_tree_bin,
804 WhichTree tree) { 847 WhichTree tree) {
805 ManagedTileState& mts = tile->managed_state(); 848 ManagedTileState& mts = tile->managed_state();
806 mts.tree_bin[tree] = new_tree_bin; 849 mts.tree_bin[tree] = new_tree_bin;
807 } 850 }
808 851
809 } // namespace cc 852 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698