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

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

Issue 15715031: cc: Remove memory state from tile management (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: review 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.h ('k') | cc/resources/tile_manager_unittest.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"
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after
300 if (!client_->ShouldForceTileUploadsRequiredForActivationToComplete()) 300 if (!client_->ShouldForceTileUploadsRequiredForActivationToComplete())
301 return; 301 return;
302 302
303 TileSet initialized_tiles; 303 TileSet initialized_tiles;
304 for (TileSet::iterator it = 304 for (TileSet::iterator it =
305 tiles_that_need_to_be_initialized_for_activation_.begin(); 305 tiles_that_need_to_be_initialized_for_activation_.begin();
306 it != tiles_that_need_to_be_initialized_for_activation_.end(); 306 it != tiles_that_need_to_be_initialized_for_activation_.end();
307 ++it) { 307 ++it) {
308 Tile* tile = *it; 308 Tile* tile = *it;
309 if (!tile->managed_state().raster_task.is_null() && 309 if (!tile->managed_state().raster_task.is_null() &&
310 tile->tile_version().memory_state_ == USING_UNRELEASABLE_MEMORY &&
311 !tile->tile_version().forced_upload_) { 310 !tile->tile_version().forced_upload_) {
312 if (!raster_worker_pool_->ForceUploadToComplete( 311 if (!raster_worker_pool_->ForceUploadToComplete(
313 tile->managed_state().raster_task)) 312 tile->managed_state().raster_task))
314 continue; 313 continue;
315 314
316 // Setting |forced_upload_| to true makes this tile ready to draw. 315 // Setting |forced_upload_| to true makes this tile ready to draw.
317 tile->tile_version().forced_upload_ = true; 316 tile->tile_version().forced_upload_ = true;
318 initialized_tiles.insert(tile); 317 initialized_tiles.insert(tile);
319 } 318 }
320 } 319 }
321 320
322 for (TileSet::iterator it = initialized_tiles.begin(); 321 for (TileSet::iterator it = initialized_tiles.begin();
323 it != initialized_tiles.end(); 322 it != initialized_tiles.end();
324 ++it) { 323 ++it) {
325 Tile* tile = *it; 324 Tile* tile = *it;
326 DidFinishTileInitialization(tile); 325 DidFinishTileInitialization(tile);
327 DCHECK(tile->tile_version().IsReadyToDraw()); 326 DCHECK(tile->tile_version().IsReadyToDraw());
328 } 327 }
329 } 328 }
330 329
331 void TileManager::GetMemoryStats( 330 void TileManager::GetMemoryStats(
332 size_t* memory_required_bytes, 331 size_t* memory_required_bytes,
333 size_t* memory_nice_to_have_bytes, 332 size_t* memory_nice_to_have_bytes,
334 size_t* memory_used_bytes) const { 333 size_t* memory_used_bytes) const {
335 *memory_required_bytes = 0; 334 *memory_required_bytes = 0;
336 *memory_nice_to_have_bytes = 0; 335 *memory_nice_to_have_bytes = 0;
337 *memory_used_bytes = 0; 336 *memory_used_bytes = resource_pool_->acquired_memory_usage_bytes();
338 for (TileVector::const_iterator it = tiles_.begin(); 337 for (TileVector::const_iterator it = tiles_.begin();
339 it != tiles_.end(); 338 it != tiles_.end();
340 ++it) { 339 ++it) {
341 const Tile* tile = *it; 340 const Tile* tile = *it;
342 if (!tile->tile_version().requires_resource()) 341 if (!tile->tile_version().requires_resource())
343 continue; 342 continue;
344 343
345 const ManagedTileState& mts = tile->managed_state(); 344 const ManagedTileState& mts = tile->managed_state();
346 size_t tile_bytes = tile->bytes_consumed_if_allocated(); 345 size_t tile_bytes = tile->bytes_consumed_if_allocated();
347 if (mts.gpu_memmgr_stats_bin == NOW_BIN) 346 if (mts.gpu_memmgr_stats_bin == NOW_BIN)
348 *memory_required_bytes += tile_bytes; 347 *memory_required_bytes += tile_bytes;
349 if (mts.gpu_memmgr_stats_bin != NEVER_BIN) 348 if (mts.gpu_memmgr_stats_bin != NEVER_BIN)
350 *memory_nice_to_have_bytes += tile_bytes; 349 *memory_nice_to_have_bytes += tile_bytes;
351 if (tile->tile_version().memory_state_ != NOT_ALLOWED_TO_USE_MEMORY)
352 *memory_used_bytes += tile_bytes;
353 } 350 }
354 } 351 }
355 352
356 scoped_ptr<base::Value> TileManager::BasicStateAsValue() const { 353 scoped_ptr<base::Value> TileManager::BasicStateAsValue() const {
357 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); 354 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue());
358 state->SetInteger("tile_count", tiles_.size()); 355 state->SetInteger("tile_count", tiles_.size());
359 state->Set("global_state", global_state_.AsValue().release()); 356 state->Set("global_state", global_state_.AsValue().release());
360 state->Set("memory_requirements", GetMemoryRequirementsAsValue().release()); 357 state->Set("memory_requirements", GetMemoryRequirementsAsValue().release());
361 return state.PassAs<base::Value>(); 358 return state.PassAs<base::Value>();
362 } 359 }
(...skipping 28 matching lines...) Expand all
391 void TileManager::AddRequiredTileForActivation(Tile* tile) { 388 void TileManager::AddRequiredTileForActivation(Tile* tile) {
392 DCHECK(std::find(tiles_that_need_to_be_initialized_for_activation_.begin(), 389 DCHECK(std::find(tiles_that_need_to_be_initialized_for_activation_.begin(),
393 tiles_that_need_to_be_initialized_for_activation_.end(), 390 tiles_that_need_to_be_initialized_for_activation_.end(),
394 tile) == 391 tile) ==
395 tiles_that_need_to_be_initialized_for_activation_.end()); 392 tiles_that_need_to_be_initialized_for_activation_.end());
396 tiles_that_need_to_be_initialized_for_activation_.insert(tile); 393 tiles_that_need_to_be_initialized_for_activation_.insert(tile);
397 } 394 }
398 395
399 void TileManager::AssignGpuMemoryToTiles() { 396 void TileManager::AssignGpuMemoryToTiles() {
400 TRACE_EVENT0("cc", "TileManager::AssignGpuMemoryToTiles"); 397 TRACE_EVENT0("cc", "TileManager::AssignGpuMemoryToTiles");
401 size_t unreleasable_bytes = 0;
402 398
403 // Now give memory out to the tiles until we're out, and build 399 // Now give memory out to the tiles until we're out, and build
404 // the needs-to-be-rasterized queue. 400 // the needs-to-be-rasterized queue.
405 tiles_that_need_to_be_rasterized_.clear(); 401 tiles_that_need_to_be_rasterized_.clear();
406 tiles_that_need_to_be_initialized_for_activation_.clear(); 402 tiles_that_need_to_be_initialized_for_activation_.clear();
407 403
408 // By clearing the tiles_that_need_to_be_rasterized_ vector list 404 size_t bytes_releasable = 0;
409 // above we move all tiles currently waiting for raster to idle state.
410 // Some memory cannot be released. We figure out how much in this
411 // loop.
412 for (TileVector::const_iterator it = tiles_.begin(); 405 for (TileVector::const_iterator it = tiles_.begin();
413 it != tiles_.end(); 406 it != tiles_.end();
414 ++it) { 407 ++it) {
415 const Tile* tile = *it; 408 const Tile* tile = *it;
416 if (tile->tile_version().memory_state_ == USING_UNRELEASABLE_MEMORY) 409 if (tile->tile_version().resource_)
417 unreleasable_bytes += tile->bytes_consumed_if_allocated(); 410 bytes_releasable += tile->bytes_consumed_if_allocated();
418 } 411 }
419 412
420 // Global state's memory limit can decrease, causing 413 int64 signed_bytes_allocatable =
421 // it to be less than unreleasable_bytes 414 static_cast<int64>(bytes_releasable +
415 global_state_.memory_limit_in_bytes) -
416 static_cast<int64>(resource_pool_->acquired_memory_usage_bytes());
reveman 2013/06/03 19:48:36 consider using: int64 bytes_available = memory_lim
417
422 size_t bytes_allocatable = 418 size_t bytes_allocatable =
423 global_state_.memory_limit_in_bytes > unreleasable_bytes ? 419 std::max(static_cast<int64>(0), signed_bytes_allocatable);
424 global_state_.memory_limit_in_bytes - unreleasable_bytes : 420
425 0;
426 size_t bytes_that_exceeded_memory_budget_in_now_bin = 0; 421 size_t bytes_that_exceeded_memory_budget_in_now_bin = 0;
427 size_t bytes_left = bytes_allocatable; 422 size_t bytes_left = bytes_allocatable;
428 size_t bytes_oom_in_now_bin_on_pending_tree = 0; 423 size_t bytes_oom_in_now_bin_on_pending_tree = 0;
429 TileVector tiles_requiring_memory_but_oomed; 424 TileVector tiles_requiring_memory_but_oomed;
430 bool higher_priority_tile_oomed = false; 425 bool higher_priority_tile_oomed = false;
431 for (TileVector::iterator it = tiles_.begin(); 426 for (TileVector::iterator it = tiles_.begin();
432 it != tiles_.end(); 427 it != tiles_.end();
433 ++it) { 428 ++it) {
434 Tile* tile = *it; 429 Tile* tile = *it;
435 ManagedTileState& mts = tile->managed_state(); 430 ManagedTileState& mts = tile->managed_state();
436 ManagedTileState::TileVersion& tile_version = tile->tile_version(); 431 ManagedTileState::TileVersion& tile_version = tile->tile_version();
437 432
438 // If this tile doesn't need a resource, then nothing to do. 433 // If this tile doesn't need a resource, then nothing to do.
439 if (!tile_version.requires_resource()) 434 if (!tile_version.requires_resource())
440 continue; 435 continue;
441 436
442 size_t tile_bytes = tile->bytes_consumed_if_allocated();
443 // Memory is already reserved for tile with unreleasable memory
444 // so adding it to |tiles_that_need_to_be_rasterized_| doesn't
445 // affect bytes_allocatable.
446 if (tile_version.memory_state_ == USING_UNRELEASABLE_MEMORY)
447 tile_bytes = 0;
448
449 // If the tile is not needed, free it up. 437 // If the tile is not needed, free it up.
450 if (mts.is_in_never_bin_on_both_trees()) { 438 if (mts.is_in_never_bin_on_both_trees()) {
451 if (tile_version.memory_state_ != USING_UNRELEASABLE_MEMORY) { 439 FreeResourcesForTile(tile);
452 FreeResourcesForTile(tile);
453 tile_version.memory_state_ = NOT_ALLOWED_TO_USE_MEMORY;
454 }
455 continue; 440 continue;
456 } 441 }
457 442
443 size_t tile_bytes = 0;
444
445 // It costs to maintain a resource.
446 if (tile_version.resource_)
447 tile_bytes += tile->bytes_consumed_if_allocated();
448
449 // It will cost to allocate a resource.
450 // Note that this is separate from the above condition,
451 // so that it's clear why we're adding memory.
452 if (!tile_version.resource_ && mts.raster_task.is_null())
453 tile_bytes += tile->bytes_consumed_if_allocated();
454
458 // Tile is OOM. 455 // Tile is OOM.
459 if (tile_bytes > bytes_left) { 456 if (tile_bytes > bytes_left) {
460 tile->tile_version().set_rasterize_on_demand(); 457 tile->tile_version().set_rasterize_on_demand();
461 if (mts.tree_bin[PENDING_TREE] == NOW_BIN) { 458 if (mts.tree_bin[PENDING_TREE] == NOW_BIN) {
462 tiles_requiring_memory_but_oomed.push_back(tile); 459 tiles_requiring_memory_but_oomed.push_back(tile);
463 bytes_oom_in_now_bin_on_pending_tree += tile_bytes; 460 bytes_oom_in_now_bin_on_pending_tree += tile_bytes;
464 } 461 }
465 FreeResourcesForTile(tile); 462 FreeResourcesForTile(tile);
466 higher_priority_tile_oomed = true; 463 higher_priority_tile_oomed = true;
467 continue; 464 continue;
(...skipping 19 matching lines...) Expand all
487 } 484 }
488 485
489 // In OOM situation, we iterate tiles_, remove the memory for active tree 486 // In OOM situation, we iterate tiles_, remove the memory for active tree
490 // and not the now bin. And give them to bytes_oom_in_now_bin_on_pending_tree 487 // and not the now bin. And give them to bytes_oom_in_now_bin_on_pending_tree
491 if (!tiles_requiring_memory_but_oomed.empty()) { 488 if (!tiles_requiring_memory_but_oomed.empty()) {
492 size_t bytes_freed = 0; 489 size_t bytes_freed = 0;
493 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { 490 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) {
494 Tile* tile = *it; 491 Tile* tile = *it;
495 ManagedTileState& mts = tile->managed_state(); 492 ManagedTileState& mts = tile->managed_state();
496 ManagedTileState::TileVersion& tile_version = tile->tile_version(); 493 ManagedTileState::TileVersion& tile_version = tile->tile_version();
497 if ((tile_version.memory_state_ == CAN_USE_MEMORY || 494 if (tile_version.resource_ &&
498 tile_version.memory_state_ == USING_RELEASABLE_MEMORY) &&
499 mts.tree_bin[PENDING_TREE] == NEVER_BIN && 495 mts.tree_bin[PENDING_TREE] == NEVER_BIN &&
500 mts.tree_bin[ACTIVE_TREE] != NOW_BIN) { 496 mts.tree_bin[ACTIVE_TREE] != NOW_BIN) {
501 DCHECK(!tile->required_for_activation()); 497 DCHECK(!tile->required_for_activation());
502 FreeResourcesForTile(tile); 498 FreeResourcesForTile(tile);
503 tile_version.set_rasterize_on_demand(); 499 tile_version.set_rasterize_on_demand();
504 bytes_freed += tile->bytes_consumed_if_allocated(); 500 bytes_freed += tile->bytes_consumed_if_allocated();
505 TileVector::iterator it = std::find( 501 TileVector::iterator it = std::find(
506 tiles_that_need_to_be_rasterized_.begin(), 502 tiles_that_need_to_be_rasterized_.begin(),
507 tiles_that_need_to_be_rasterized_.end(), 503 tiles_that_need_to_be_rasterized_.end(),
508 tile); 504 tile);
(...skipping 23 matching lines...) Expand all
532 bytes_that_exceeded_memory_budget_in_now_bin > 0; 528 bytes_that_exceeded_memory_budget_in_now_bin > 0;
533 if (ever_exceeded_memory_budget_) { 529 if (ever_exceeded_memory_budget_) {
534 TRACE_COUNTER_ID2("cc", "over_memory_budget", this, 530 TRACE_COUNTER_ID2("cc", "over_memory_budget", this,
535 "budget", global_state_.memory_limit_in_bytes, 531 "budget", global_state_.memory_limit_in_bytes,
536 "over", bytes_that_exceeded_memory_budget_in_now_bin); 532 "over", bytes_that_exceeded_memory_budget_in_now_bin);
537 } 533 }
538 memory_stats_from_last_assign_.total_budget_in_bytes = 534 memory_stats_from_last_assign_.total_budget_in_bytes =
539 global_state_.memory_limit_in_bytes; 535 global_state_.memory_limit_in_bytes;
540 memory_stats_from_last_assign_.bytes_allocated = 536 memory_stats_from_last_assign_.bytes_allocated =
541 bytes_allocatable - bytes_left; 537 bytes_allocatable - bytes_left;
542 memory_stats_from_last_assign_.bytes_unreleasable = unreleasable_bytes; 538 memory_stats_from_last_assign_.bytes_unreleasable =
539 bytes_allocatable - bytes_releasable;
543 memory_stats_from_last_assign_.bytes_over = 540 memory_stats_from_last_assign_.bytes_over =
544 bytes_that_exceeded_memory_budget_in_now_bin; 541 bytes_that_exceeded_memory_budget_in_now_bin;
545 } 542 }
546 543
547 void TileManager::FreeResourcesForTile(Tile* tile) { 544 void TileManager::FreeResourcesForTile(Tile* tile) {
548 DCHECK_NE(USING_UNRELEASABLE_MEMORY, tile->tile_version().memory_state_);
549 if (tile->tile_version().resource_) { 545 if (tile->tile_version().resource_) {
550 resource_pool_->ReleaseResource( 546 resource_pool_->ReleaseResource(
551 tile->tile_version().resource_.Pass()); 547 tile->tile_version().resource_.Pass());
552 } 548 }
553 tile->tile_version().memory_state_ = NOT_ALLOWED_TO_USE_MEMORY;
554 } 549 }
555 550
556 void TileManager::ScheduleTasks() { 551 void TileManager::ScheduleTasks() {
557 TRACE_EVENT0("cc", "TileManager::ScheduleTasks"); 552 TRACE_EVENT0("cc", "TileManager::ScheduleTasks");
558 RasterWorkerPool::RasterTask::Queue tasks; 553 RasterWorkerPool::RasterTask::Queue tasks;
559 554
560 // Build a new task queue containing all task currently needed. Tasks 555 // Build a new task queue containing all task currently needed. Tasks
561 // are added in order of priority, highest priority task first. 556 // are added in order of priority, highest priority task first.
562 for (TileVector::iterator it = tiles_that_need_to_be_rasterized_.begin(); 557 for (TileVector::iterator it = tiles_that_need_to_be_rasterized_.begin();
563 it != tiles_that_need_to_be_rasterized_.end(); 558 it != tiles_that_need_to_be_rasterized_.end();
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
620 615
621 RasterWorkerPool::RasterTask TileManager::CreateRasterTask(Tile* tile) { 616 RasterWorkerPool::RasterTask TileManager::CreateRasterTask(Tile* tile) {
622 TRACE_EVENT0("cc", "TileManager::CreateRasterTask"); 617 TRACE_EVENT0("cc", "TileManager::CreateRasterTask");
623 618
624 scoped_ptr<ResourcePool::Resource> resource = 619 scoped_ptr<ResourcePool::Resource> resource =
625 resource_pool_->AcquireResource( 620 resource_pool_->AcquireResource(
626 tile->tile_size_.size(), 621 tile->tile_size_.size(),
627 tile->tile_version().resource_format_); 622 tile->tile_version().resource_format_);
628 const Resource* const_resource = resource.get(); 623 const Resource* const_resource = resource.get();
629 624
630 DCHECK_EQ(CAN_USE_MEMORY, tile->tile_version().memory_state_);
631 tile->tile_version().memory_state_ = USING_UNRELEASABLE_MEMORY;
632 tile->tile_version().resource_id_ = resource->id(); 625 tile->tile_version().resource_id_ = resource->id();
633 626
634 PicturePileImpl::Analysis* analysis = new PicturePileImpl::Analysis; 627 PicturePileImpl::Analysis* analysis = new PicturePileImpl::Analysis;
635 628
636 // Create and queue all image decode tasks that this tile depends on. 629 // Create and queue all image decode tasks that this tile depends on.
637 RasterWorkerPool::Task::Set decode_tasks; 630 RasterWorkerPool::Task::Set decode_tasks;
638 for (PicturePileImpl::PixelRefIterator iter(tile->content_rect(), 631 for (PicturePileImpl::PixelRefIterator iter(tile->content_rect(),
639 tile->contents_scale(), 632 tile->contents_scale(),
640 tile->picture_pile()); 633 tile->picture_pile());
641 iter; ++iter) { 634 iter; ++iter) {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
692 scoped_ptr<ResourcePool::Resource> resource, 685 scoped_ptr<ResourcePool::Resource> resource,
693 PicturePileImpl::Analysis* analysis, 686 PicturePileImpl::Analysis* analysis,
694 bool was_canceled) { 687 bool was_canceled) {
695 TRACE_EVENT1("cc", "TileManager::OnRasterTaskCompleted", 688 TRACE_EVENT1("cc", "TileManager::OnRasterTaskCompleted",
696 "was_canceled", was_canceled); 689 "was_canceled", was_canceled);
697 690
698 ManagedTileState& mts = tile->managed_state(); 691 ManagedTileState& mts = tile->managed_state();
699 DCHECK(!mts.raster_task.is_null()); 692 DCHECK(!mts.raster_task.is_null());
700 mts.raster_task.Reset(); 693 mts.raster_task.Reset();
701 694
702 // Tile resources can't be freed until task has completed.
703 DCHECK_EQ(USING_UNRELEASABLE_MEMORY, tile->tile_version().memory_state_);
704
705 if (was_canceled) { 695 if (was_canceled) {
706 tile->tile_version().memory_state_ = CAN_USE_MEMORY;
707 resource_pool_->ReleaseResource(resource.Pass()); 696 resource_pool_->ReleaseResource(resource.Pass());
708 return; 697 return;
709 } 698 }
710 699
711 mts.picture_pile_analysis = *analysis; 700 mts.picture_pile_analysis = *analysis;
712 mts.picture_pile_analyzed = true; 701 mts.picture_pile_analyzed = true;
713 702
714 if (analysis->is_solid_color) { 703 if (analysis->is_solid_color) {
715 tile->tile_version().set_solid_color(analysis->solid_color); 704 tile->tile_version().set_solid_color(analysis->solid_color);
716 resource_pool_->ReleaseResource(resource.Pass()); 705 resource_pool_->ReleaseResource(resource.Pass());
717 } else { 706 } else {
718 tile->tile_version().memory_state_ = USING_RELEASABLE_MEMORY;
719 tile->tile_version().resource_ = resource.Pass(); 707 tile->tile_version().resource_ = resource.Pass();
720 } 708 }
721 709
722 DidFinishTileInitialization(tile.get()); 710 DidFinishTileInitialization(tile.get());
723 } 711 }
724 712
725 void TileManager::DidFinishTileInitialization(Tile* tile) { 713 void TileManager::DidFinishTileInitialization(Tile* tile) {
726 if (tile->priority(ACTIVE_TREE).distance_to_visible_in_pixels == 0) 714 if (tile->priority(ACTIVE_TREE).distance_to_visible_in_pixels == 0)
727 did_initialize_visible_tile_ = true; 715 did_initialize_visible_tile_ = true;
728 if (tile->required_for_activation()) { 716 if (tile->required_for_activation()) {
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
845 100000, 833 100000,
846 100); 834 100);
847 } else { 835 } else {
848 picture_pile->RasterToBitmap(&canvas, rect, contents_scale, NULL); 836 picture_pile->RasterToBitmap(&canvas, rect, contents_scale, NULL);
849 } 837 }
850 838
851 return true; 839 return true;
852 } 840 }
853 841
854 } // namespace cc 842 } // namespace cc
OLDNEW
« no previous file with comments | « cc/resources/tile.h ('k') | cc/resources/tile_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698