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

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: update 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 // Cast to prevent overflow.
421 // it to be less than unreleasable_bytes 414 int64 bytes_available =
415 static_cast<int64>(bytes_releasable) +
416 static_cast<int64>(global_state_.memory_limit_in_bytes) -
417 static_cast<int64>(resource_pool_->acquired_memory_usage_bytes());
418
422 size_t bytes_allocatable = 419 size_t bytes_allocatable =
423 global_state_.memory_limit_in_bytes > unreleasable_bytes ? 420 std::max(static_cast<int64>(0), bytes_available);
424 global_state_.memory_limit_in_bytes - unreleasable_bytes : 421
425 0;
426 size_t bytes_that_exceeded_memory_budget_in_now_bin = 0; 422 size_t bytes_that_exceeded_memory_budget_in_now_bin = 0;
427 size_t bytes_left = bytes_allocatable; 423 size_t bytes_left = bytes_allocatable;
428 size_t bytes_oom_in_now_bin_on_pending_tree = 0; 424 size_t bytes_oom_in_now_bin_on_pending_tree = 0;
429 TileVector tiles_requiring_memory_but_oomed; 425 TileVector tiles_requiring_memory_but_oomed;
430 bool higher_priority_tile_oomed = false; 426 bool higher_priority_tile_oomed = false;
431 for (TileVector::iterator it = tiles_.begin(); 427 for (TileVector::iterator it = tiles_.begin();
432 it != tiles_.end(); 428 it != tiles_.end();
433 ++it) { 429 ++it) {
434 Tile* tile = *it; 430 Tile* tile = *it;
435 ManagedTileState& mts = tile->managed_state(); 431 ManagedTileState& mts = tile->managed_state();
436 ManagedTileState::TileVersion& tile_version = tile->tile_version(); 432 ManagedTileState::TileVersion& tile_version = tile->tile_version();
437 433
438 // If this tile doesn't need a resource, then nothing to do. 434 // If this tile doesn't need a resource, then nothing to do.
439 if (!tile_version.requires_resource()) 435 if (!tile_version.requires_resource())
440 continue; 436 continue;
441 437
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. 438 // If the tile is not needed, free it up.
450 if (mts.is_in_never_bin_on_both_trees()) { 439 if (mts.is_in_never_bin_on_both_trees()) {
451 if (tile_version.memory_state_ != USING_UNRELEASABLE_MEMORY) { 440 FreeResourcesForTile(tile);
452 FreeResourcesForTile(tile);
453 tile_version.memory_state_ = NOT_ALLOWED_TO_USE_MEMORY;
454 }
455 continue; 441 continue;
456 } 442 }
457 443
444 size_t tile_bytes = 0;
445
446 // It costs to maintain a resource.
447 if (tile_version.resource_)
448 tile_bytes += tile->bytes_consumed_if_allocated();
449
450 // It will cost to allocate a resource.
451 // Note that this is separate from the above condition,
452 // so that it's clear why we're adding memory.
453 if (!tile_version.resource_ && mts.raster_task.is_null())
454 tile_bytes += tile->bytes_consumed_if_allocated();
455
458 // Tile is OOM. 456 // Tile is OOM.
459 if (tile_bytes > bytes_left) { 457 if (tile_bytes > bytes_left) {
460 tile->tile_version().set_rasterize_on_demand(); 458 tile->tile_version().set_rasterize_on_demand();
461 if (mts.tree_bin[PENDING_TREE] == NOW_BIN) { 459 if (mts.tree_bin[PENDING_TREE] == NOW_BIN) {
462 tiles_requiring_memory_but_oomed.push_back(tile); 460 tiles_requiring_memory_but_oomed.push_back(tile);
463 bytes_oom_in_now_bin_on_pending_tree += tile_bytes; 461 bytes_oom_in_now_bin_on_pending_tree += tile_bytes;
464 } 462 }
465 FreeResourcesForTile(tile); 463 FreeResourcesForTile(tile);
466 higher_priority_tile_oomed = true; 464 higher_priority_tile_oomed = true;
467 continue; 465 continue;
(...skipping 19 matching lines...) Expand all
487 } 485 }
488 486
489 // In OOM situation, we iterate tiles_, remove the memory for active tree 487 // In OOM situation, we iterate tiles_, remove the memory for active tree
490 // and not the now bin. And give them to bytes_oom_in_now_bin_on_pending_tree 488 // and not the now bin. And give them to bytes_oom_in_now_bin_on_pending_tree
491 if (!tiles_requiring_memory_but_oomed.empty()) { 489 if (!tiles_requiring_memory_but_oomed.empty()) {
492 size_t bytes_freed = 0; 490 size_t bytes_freed = 0;
493 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { 491 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) {
494 Tile* tile = *it; 492 Tile* tile = *it;
495 ManagedTileState& mts = tile->managed_state(); 493 ManagedTileState& mts = tile->managed_state();
496 ManagedTileState::TileVersion& tile_version = tile->tile_version(); 494 ManagedTileState::TileVersion& tile_version = tile->tile_version();
497 if ((tile_version.memory_state_ == CAN_USE_MEMORY || 495 if (tile_version.resource_ &&
498 tile_version.memory_state_ == USING_RELEASABLE_MEMORY) &&
499 mts.tree_bin[PENDING_TREE] == NEVER_BIN && 496 mts.tree_bin[PENDING_TREE] == NEVER_BIN &&
500 mts.tree_bin[ACTIVE_TREE] != NOW_BIN) { 497 mts.tree_bin[ACTIVE_TREE] != NOW_BIN) {
501 DCHECK(!tile->required_for_activation()); 498 DCHECK(!tile->required_for_activation());
502 FreeResourcesForTile(tile); 499 FreeResourcesForTile(tile);
503 tile_version.set_rasterize_on_demand(); 500 tile_version.set_rasterize_on_demand();
504 bytes_freed += tile->bytes_consumed_if_allocated(); 501 bytes_freed += tile->bytes_consumed_if_allocated();
505 TileVector::iterator it = std::find( 502 TileVector::iterator it = std::find(
506 tiles_that_need_to_be_rasterized_.begin(), 503 tiles_that_need_to_be_rasterized_.begin(),
507 tiles_that_need_to_be_rasterized_.end(), 504 tiles_that_need_to_be_rasterized_.end(),
508 tile); 505 tile);
(...skipping 23 matching lines...) Expand all
532 bytes_that_exceeded_memory_budget_in_now_bin > 0; 529 bytes_that_exceeded_memory_budget_in_now_bin > 0;
533 if (ever_exceeded_memory_budget_) { 530 if (ever_exceeded_memory_budget_) {
534 TRACE_COUNTER_ID2("cc", "over_memory_budget", this, 531 TRACE_COUNTER_ID2("cc", "over_memory_budget", this,
535 "budget", global_state_.memory_limit_in_bytes, 532 "budget", global_state_.memory_limit_in_bytes,
536 "over", bytes_that_exceeded_memory_budget_in_now_bin); 533 "over", bytes_that_exceeded_memory_budget_in_now_bin);
537 } 534 }
538 memory_stats_from_last_assign_.total_budget_in_bytes = 535 memory_stats_from_last_assign_.total_budget_in_bytes =
539 global_state_.memory_limit_in_bytes; 536 global_state_.memory_limit_in_bytes;
540 memory_stats_from_last_assign_.bytes_allocated = 537 memory_stats_from_last_assign_.bytes_allocated =
541 bytes_allocatable - bytes_left; 538 bytes_allocatable - bytes_left;
542 memory_stats_from_last_assign_.bytes_unreleasable = unreleasable_bytes; 539 memory_stats_from_last_assign_.bytes_unreleasable =
540 bytes_allocatable - bytes_releasable;
543 memory_stats_from_last_assign_.bytes_over = 541 memory_stats_from_last_assign_.bytes_over =
544 bytes_that_exceeded_memory_budget_in_now_bin; 542 bytes_that_exceeded_memory_budget_in_now_bin;
545 } 543 }
546 544
547 void TileManager::FreeResourcesForTile(Tile* tile) { 545 void TileManager::FreeResourcesForTile(Tile* tile) {
548 DCHECK_NE(USING_UNRELEASABLE_MEMORY, tile->tile_version().memory_state_);
549 if (tile->tile_version().resource_) { 546 if (tile->tile_version().resource_) {
550 resource_pool_->ReleaseResource( 547 resource_pool_->ReleaseResource(
551 tile->tile_version().resource_.Pass()); 548 tile->tile_version().resource_.Pass());
552 } 549 }
553 tile->tile_version().memory_state_ = NOT_ALLOWED_TO_USE_MEMORY;
554 } 550 }
555 551
556 void TileManager::ScheduleTasks() { 552 void TileManager::ScheduleTasks() {
557 TRACE_EVENT0("cc", "TileManager::ScheduleTasks"); 553 TRACE_EVENT0("cc", "TileManager::ScheduleTasks");
558 RasterWorkerPool::RasterTask::Queue tasks; 554 RasterWorkerPool::RasterTask::Queue tasks;
559 555
560 // Build a new task queue containing all task currently needed. Tasks 556 // Build a new task queue containing all task currently needed. Tasks
561 // are added in order of priority, highest priority task first. 557 // are added in order of priority, highest priority task first.
562 for (TileVector::iterator it = tiles_that_need_to_be_rasterized_.begin(); 558 for (TileVector::iterator it = tiles_that_need_to_be_rasterized_.begin();
563 it != tiles_that_need_to_be_rasterized_.end(); 559 it != tiles_that_need_to_be_rasterized_.end();
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
620 616
621 RasterWorkerPool::RasterTask TileManager::CreateRasterTask(Tile* tile) { 617 RasterWorkerPool::RasterTask TileManager::CreateRasterTask(Tile* tile) {
622 TRACE_EVENT0("cc", "TileManager::CreateRasterTask"); 618 TRACE_EVENT0("cc", "TileManager::CreateRasterTask");
623 619
624 scoped_ptr<ResourcePool::Resource> resource = 620 scoped_ptr<ResourcePool::Resource> resource =
625 resource_pool_->AcquireResource( 621 resource_pool_->AcquireResource(
626 tile->tile_size_.size(), 622 tile->tile_size_.size(),
627 tile->tile_version().resource_format_); 623 tile->tile_version().resource_format_);
628 const Resource* const_resource = resource.get(); 624 const Resource* const_resource = resource.get();
629 625
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(); 626 tile->tile_version().resource_id_ = resource->id();
633 627
634 PicturePileImpl::Analysis* analysis = new PicturePileImpl::Analysis; 628 PicturePileImpl::Analysis* analysis = new PicturePileImpl::Analysis;
635 629
636 // Create and queue all image decode tasks that this tile depends on. 630 // Create and queue all image decode tasks that this tile depends on.
637 RasterWorkerPool::Task::Set decode_tasks; 631 RasterWorkerPool::Task::Set decode_tasks;
638 for (PicturePileImpl::PixelRefIterator iter(tile->content_rect(), 632 for (PicturePileImpl::PixelRefIterator iter(tile->content_rect(),
639 tile->contents_scale(), 633 tile->contents_scale(),
640 tile->picture_pile()); 634 tile->picture_pile());
641 iter; ++iter) { 635 iter; ++iter) {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
692 scoped_ptr<ResourcePool::Resource> resource, 686 scoped_ptr<ResourcePool::Resource> resource,
693 PicturePileImpl::Analysis* analysis, 687 PicturePileImpl::Analysis* analysis,
694 bool was_canceled) { 688 bool was_canceled) {
695 TRACE_EVENT1("cc", "TileManager::OnRasterTaskCompleted", 689 TRACE_EVENT1("cc", "TileManager::OnRasterTaskCompleted",
696 "was_canceled", was_canceled); 690 "was_canceled", was_canceled);
697 691
698 ManagedTileState& mts = tile->managed_state(); 692 ManagedTileState& mts = tile->managed_state();
699 DCHECK(!mts.raster_task.is_null()); 693 DCHECK(!mts.raster_task.is_null());
700 mts.raster_task.Reset(); 694 mts.raster_task.Reset();
701 695
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) { 696 if (was_canceled) {
706 tile->tile_version().memory_state_ = CAN_USE_MEMORY;
707 resource_pool_->ReleaseResource(resource.Pass()); 697 resource_pool_->ReleaseResource(resource.Pass());
708 return; 698 return;
709 } 699 }
710 700
711 mts.picture_pile_analysis = *analysis; 701 mts.picture_pile_analysis = *analysis;
712 mts.picture_pile_analyzed = true; 702 mts.picture_pile_analyzed = true;
713 703
714 if (analysis->is_solid_color) { 704 if (analysis->is_solid_color) {
715 tile->tile_version().set_solid_color(analysis->solid_color); 705 tile->tile_version().set_solid_color(analysis->solid_color);
716 resource_pool_->ReleaseResource(resource.Pass()); 706 resource_pool_->ReleaseResource(resource.Pass());
717 } else { 707 } else {
718 tile->tile_version().memory_state_ = USING_RELEASABLE_MEMORY;
719 tile->tile_version().resource_ = resource.Pass(); 708 tile->tile_version().resource_ = resource.Pass();
720 } 709 }
721 710
722 DidFinishTileInitialization(tile.get()); 711 DidFinishTileInitialization(tile.get());
723 } 712 }
724 713
725 void TileManager::DidFinishTileInitialization(Tile* tile) { 714 void TileManager::DidFinishTileInitialization(Tile* tile) {
726 if (tile->priority(ACTIVE_TREE).distance_to_visible_in_pixels == 0) 715 if (tile->priority(ACTIVE_TREE).distance_to_visible_in_pixels == 0)
727 did_initialize_visible_tile_ = true; 716 did_initialize_visible_tile_ = true;
728 if (tile->required_for_activation()) { 717 if (tile->required_for_activation()) {
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
845 100000, 834 100000,
846 100); 835 100);
847 } else { 836 } else {
848 picture_pile->RasterToBitmap(&canvas, rect, contents_scale, NULL); 837 picture_pile->RasterToBitmap(&canvas, rect, contents_scale, NULL);
849 } 838 }
850 839
851 return true; 840 return true;
852 } 841 }
853 842
854 } // namespace cc 843 } // 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