Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 <limits> | 8 #include <limits> |
| 9 #include <string> | 9 #include <string> |
| 10 | 10 |
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 239 skia::RefPtr<SkPixelRef> pixel_ref_; | 239 skia::RefPtr<SkPixelRef> pixel_ref_; |
| 240 int layer_id_; | 240 int layer_id_; |
| 241 RenderingStatsInstrumentation* rendering_stats_; | 241 RenderingStatsInstrumentation* rendering_stats_; |
| 242 const base::Callback<void(bool was_canceled)> reply_; | 242 const base::Callback<void(bool was_canceled)> reply_; |
| 243 | 243 |
| 244 DISALLOW_COPY_AND_ASSIGN(ImageDecodeTaskImpl); | 244 DISALLOW_COPY_AND_ASSIGN(ImageDecodeTaskImpl); |
| 245 }; | 245 }; |
| 246 | 246 |
| 247 const size_t kScheduledRasterTasksLimit = 32u; | 247 const size_t kScheduledRasterTasksLimit = 32u; |
| 248 | 248 |
| 249 // Memory limit policy works by mapping some bin states to the NEVER bin. | |
| 250 const ManagedTileBin kBinPolicyMap[NUM_TILE_MEMORY_LIMIT_POLICIES][NUM_BINS] = { | |
| 251 // [ALLOW_NOTHING] | |
| 252 {NEVER_BIN, // [NOW_AND_READY_TO_DRAW_BIN] | |
| 253 NEVER_BIN, // [NOW_BIN] | |
| 254 NEVER_BIN, // [SOON_BIN] | |
| 255 NEVER_BIN, // [EVENTUALLY_AND_ACTIVE_BIN] | |
| 256 NEVER_BIN, // [EVENTUALLY_BIN] | |
| 257 NEVER_BIN, // [AT_LAST_AND_ACTIVE_BIN] | |
| 258 NEVER_BIN, // [AT_LAST_BIN] | |
| 259 NEVER_BIN // [NEVER_BIN] | |
| 260 }, | |
| 261 // [ALLOW_ABSOLUTE_MINIMUM] | |
| 262 {NOW_AND_READY_TO_DRAW_BIN, // [NOW_AND_READY_TO_DRAW_BIN] | |
| 263 NOW_BIN, // [NOW_BIN] | |
| 264 NEVER_BIN, // [SOON_BIN] | |
| 265 NEVER_BIN, // [EVENTUALLY_AND_ACTIVE_BIN] | |
| 266 NEVER_BIN, // [EVENTUALLY_BIN] | |
| 267 NEVER_BIN, // [AT_LAST_AND_ACTIVE_BIN] | |
| 268 NEVER_BIN, // [AT_LAST_BIN] | |
| 269 NEVER_BIN // [NEVER_BIN] | |
| 270 }, | |
| 271 // [ALLOW_PREPAINT_ONLY] | |
| 272 {NOW_AND_READY_TO_DRAW_BIN, // [NOW_AND_READY_TO_DRAW_BIN] | |
| 273 NOW_BIN, // [NOW_BIN] | |
| 274 SOON_BIN, // [SOON_BIN] | |
| 275 NEVER_BIN, // [EVENTUALLY_AND_ACTIVE_BIN] | |
| 276 NEVER_BIN, // [EVENTUALLY_BIN] | |
| 277 NEVER_BIN, // [AT_LAST_AND_ACTIVE_BIN] | |
| 278 NEVER_BIN, // [AT_LAST_BIN] | |
| 279 NEVER_BIN // [NEVER_BIN] | |
| 280 }, | |
| 281 // [ALLOW_ANYTHING] | |
| 282 {NOW_AND_READY_TO_DRAW_BIN, // [NOW_AND_READY_TO_DRAW_BIN] | |
| 283 NOW_BIN, // [NOW_BIN] | |
| 284 SOON_BIN, // [SOON_BIN] | |
| 285 EVENTUALLY_AND_ACTIVE_BIN, // [EVENTUALLY_AND_ACTIVE_BIN] | |
| 286 EVENTUALLY_BIN, // [EVENTUALLY_BIN] | |
| 287 AT_LAST_AND_ACTIVE_BIN, // [AT_LAST_AND_ACTIVE_BIN] | |
| 288 AT_LAST_BIN, // [AT_LAST_BIN] | |
| 289 NEVER_BIN // [NEVER_BIN] | |
| 290 }}; | |
| 291 | |
| 292 // Ready to draw works by mapping NOW_BIN to NOW_AND_READY_TO_DRAW_BIN. | |
| 293 const ManagedTileBin kBinReadyToDrawMap[2][NUM_BINS] = { | |
| 294 // Not ready | |
| 295 {NOW_AND_READY_TO_DRAW_BIN, // [NOW_AND_READY_TO_DRAW_BIN] | |
| 296 NOW_BIN, // [NOW_BIN] | |
| 297 SOON_BIN, // [SOON_BIN] | |
| 298 EVENTUALLY_AND_ACTIVE_BIN, // [EVENTUALLY_AND_ACTIVE_BIN] | |
| 299 EVENTUALLY_BIN, // [EVENTUALLY_BIN] | |
| 300 AT_LAST_AND_ACTIVE_BIN, // [AT_LAST_AND_ACTIVE_BIN] | |
| 301 AT_LAST_BIN, // [AT_LAST_BIN] | |
| 302 NEVER_BIN // [NEVER_BIN] | |
| 303 }, | |
| 304 // Ready | |
| 305 {NOW_AND_READY_TO_DRAW_BIN, // [NOW_AND_READY_TO_DRAW_BIN] | |
| 306 NOW_AND_READY_TO_DRAW_BIN, // [NOW_BIN] | |
| 307 SOON_BIN, // [SOON_BIN] | |
| 308 EVENTUALLY_AND_ACTIVE_BIN, // [EVENTUALLY_AND_ACTIVE_BIN] | |
| 309 EVENTUALLY_BIN, // [EVENTUALLY_BIN] | |
| 310 AT_LAST_AND_ACTIVE_BIN, // [AT_LAST_AND_ACTIVE_BIN] | |
| 311 AT_LAST_BIN, // [AT_LAST_BIN] | |
| 312 NEVER_BIN // [NEVER_BIN] | |
| 313 }}; | |
| 314 | |
| 315 // Active works by mapping some bin stats to equivalent _ACTIVE_BIN state. | |
| 316 const ManagedTileBin kBinIsActiveMap[2][NUM_BINS] = { | |
| 317 // Inactive | |
| 318 {NOW_AND_READY_TO_DRAW_BIN, // [NOW_AND_READY_TO_DRAW_BIN] | |
| 319 NOW_BIN, // [NOW_BIN] | |
| 320 SOON_BIN, // [SOON_BIN] | |
| 321 EVENTUALLY_AND_ACTIVE_BIN, // [EVENTUALLY_AND_ACTIVE_BIN] | |
| 322 EVENTUALLY_BIN, // [EVENTUALLY_BIN] | |
| 323 AT_LAST_AND_ACTIVE_BIN, // [AT_LAST_AND_ACTIVE_BIN] | |
| 324 AT_LAST_BIN, // [AT_LAST_BIN] | |
| 325 NEVER_BIN // [NEVER_BIN] | |
| 326 }, | |
| 327 // Active | |
| 328 {NOW_AND_READY_TO_DRAW_BIN, // [NOW_AND_READY_TO_DRAW_BIN] | |
| 329 NOW_BIN, // [NOW_BIN] | |
| 330 SOON_BIN, // [SOON_BIN] | |
| 331 EVENTUALLY_AND_ACTIVE_BIN, // [EVENTUALLY_AND_ACTIVE_BIN] | |
| 332 EVENTUALLY_AND_ACTIVE_BIN, // [EVENTUALLY_BIN] | |
| 333 AT_LAST_AND_ACTIVE_BIN, // [AT_LAST_AND_ACTIVE_BIN] | |
| 334 AT_LAST_AND_ACTIVE_BIN, // [AT_LAST_BIN] | |
| 335 NEVER_BIN // [NEVER_BIN] | |
| 336 }}; | |
| 337 | |
| 338 // Determine bin based on three categories of tiles: things we need now, | |
| 339 // things we need soon, and eventually. | |
| 340 inline ManagedTileBin BinFromTilePriority(const TilePriority& prio) { | |
| 341 const float kBackflingGuardDistancePixels = 314.0f; | |
| 342 | |
| 343 if (prio.priority_bin == TilePriority::NOW) | |
| 344 return NOW_BIN; | |
| 345 | |
| 346 if (prio.priority_bin == TilePriority::SOON || | |
| 347 prio.distance_to_visible < kBackflingGuardDistancePixels) | |
| 348 return SOON_BIN; | |
| 349 | |
| 350 if (prio.distance_to_visible == std::numeric_limits<float>::infinity()) | |
| 351 return NEVER_BIN; | |
| 352 | |
| 353 return EVENTUALLY_BIN; | |
| 354 } | |
| 355 | |
| 356 } // namespace | 249 } // namespace |
| 357 | 250 |
| 358 RasterTaskCompletionStats::RasterTaskCompletionStats() | 251 RasterTaskCompletionStats::RasterTaskCompletionStats() |
| 359 : completed_count(0u), canceled_count(0u) {} | 252 : completed_count(0u), canceled_count(0u) {} |
| 360 | 253 |
| 361 scoped_ptr<base::Value> RasterTaskCompletionStatsAsValue( | 254 scoped_ptr<base::Value> RasterTaskCompletionStatsAsValue( |
| 362 const RasterTaskCompletionStats& stats) { | 255 const RasterTaskCompletionStats& stats) { |
| 363 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); | 256 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); |
| 364 state->SetInteger("completed_count", stats.completed_count); | 257 state->SetInteger("completed_count", stats.completed_count); |
| 365 state->SetInteger("canceled_count", stats.canceled_count); | 258 state->SetInteger("canceled_count", stats.canceled_count); |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 387 TileManager::TileManager( | 280 TileManager::TileManager( |
| 388 TileManagerClient* client, | 281 TileManagerClient* client, |
| 389 ResourcePool* resource_pool, | 282 ResourcePool* resource_pool, |
| 390 Rasterizer* rasterizer, | 283 Rasterizer* rasterizer, |
| 391 Rasterizer* gpu_rasterizer, | 284 Rasterizer* gpu_rasterizer, |
| 392 size_t max_raster_usage_bytes, | 285 size_t max_raster_usage_bytes, |
| 393 bool use_rasterize_on_demand, | 286 bool use_rasterize_on_demand, |
| 394 RenderingStatsInstrumentation* rendering_stats_instrumentation) | 287 RenderingStatsInstrumentation* rendering_stats_instrumentation) |
| 395 : client_(client), | 288 : client_(client), |
| 396 resource_pool_(resource_pool), | 289 resource_pool_(resource_pool), |
| 397 prioritized_tiles_dirty_(false), | |
| 398 all_tiles_that_need_to_be_rasterized_have_memory_(true), | 290 all_tiles_that_need_to_be_rasterized_have_memory_(true), |
| 399 all_tiles_required_for_activation_have_memory_(true), | 291 all_tiles_required_for_activation_have_memory_(true), |
| 400 memory_required_bytes_(0), | |
| 401 memory_nice_to_have_bytes_(0), | |
| 402 bytes_releasable_(0), | 292 bytes_releasable_(0), |
| 403 resources_releasable_(0), | 293 resources_releasable_(0), |
| 404 max_raster_usage_bytes_(max_raster_usage_bytes), | 294 max_raster_usage_bytes_(max_raster_usage_bytes), |
| 405 ever_exceeded_memory_budget_(false), | 295 ever_exceeded_memory_budget_(false), |
| 406 rendering_stats_instrumentation_(rendering_stats_instrumentation), | 296 rendering_stats_instrumentation_(rendering_stats_instrumentation), |
| 407 did_initialize_visible_tile_(false), | 297 did_initialize_visible_tile_(false), |
| 408 did_check_for_completed_tasks_since_last_schedule_tasks_(true), | 298 did_check_for_completed_tasks_since_last_schedule_tasks_(true), |
| 409 use_rasterize_on_demand_(use_rasterize_on_demand) { | 299 use_rasterize_on_demand_(use_rasterize_on_demand) { |
| 410 Rasterizer* rasterizers[NUM_RASTERIZER_TYPES] = { | 300 Rasterizer* rasterizers[NUM_RASTERIZER_TYPES] = { |
| 411 rasterizer, // RASTERIZER_TYPE_DEFAULT | 301 rasterizer, // RASTERIZER_TYPE_DEFAULT |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 437 | 327 |
| 438 for (std::vector<PictureLayerImpl*>::iterator it = layers_.begin(); | 328 for (std::vector<PictureLayerImpl*>::iterator it = layers_.begin(); |
| 439 it != layers_.end(); | 329 it != layers_.end(); |
| 440 ++it) { | 330 ++it) { |
| 441 (*it)->DidUnregisterLayer(); | 331 (*it)->DidUnregisterLayer(); |
| 442 } | 332 } |
| 443 layers_.clear(); | 333 layers_.clear(); |
| 444 } | 334 } |
| 445 | 335 |
| 446 void TileManager::Release(Tile* tile) { | 336 void TileManager::Release(Tile* tile) { |
| 447 prioritized_tiles_dirty_ = true; | |
| 448 released_tiles_.push_back(tile); | 337 released_tiles_.push_back(tile); |
| 449 } | 338 } |
| 450 | 339 |
| 451 void TileManager::DidChangeTilePriority(Tile* tile) { | |
| 452 prioritized_tiles_dirty_ = true; | |
| 453 } | |
| 454 | |
| 455 bool TileManager::ShouldForceTasksRequiredForActivationToComplete() const { | 340 bool TileManager::ShouldForceTasksRequiredForActivationToComplete() const { |
| 456 return global_state_.tree_priority != SMOOTHNESS_TAKES_PRIORITY; | 341 return global_state_.tree_priority != SMOOTHNESS_TAKES_PRIORITY; |
| 457 } | 342 } |
| 458 | 343 |
| 459 void TileManager::CleanUpReleasedTiles() { | 344 void TileManager::CleanUpReleasedTiles() { |
| 460 for (std::vector<Tile*>::iterator it = released_tiles_.begin(); | 345 for (std::vector<Tile*>::iterator it = released_tiles_.begin(); |
| 461 it != released_tiles_.end(); | 346 it != released_tiles_.end(); |
| 462 ++it) { | 347 ++it) { |
| 463 Tile* tile = *it; | 348 Tile* tile = *it; |
| 464 ManagedTileState& mts = tile->managed_state(); | 349 ManagedTileState& mts = tile->managed_state(); |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 478 used_layer_counts_.erase(layer_it); | 363 used_layer_counts_.erase(layer_it); |
| 479 image_decode_tasks_.erase(tile->layer_id()); | 364 image_decode_tasks_.erase(tile->layer_id()); |
| 480 } | 365 } |
| 481 | 366 |
| 482 delete tile; | 367 delete tile; |
| 483 } | 368 } |
| 484 | 369 |
| 485 released_tiles_.clear(); | 370 released_tiles_.clear(); |
| 486 } | 371 } |
| 487 | 372 |
| 488 void TileManager::UpdatePrioritizedTileSetIfNeeded() { | |
| 489 if (!prioritized_tiles_dirty_) | |
| 490 return; | |
| 491 | |
| 492 CleanUpReleasedTiles(); | |
| 493 | |
| 494 prioritized_tiles_.Clear(); | |
| 495 GetTilesWithAssignedBins(&prioritized_tiles_); | |
| 496 prioritized_tiles_dirty_ = false; | |
| 497 } | |
| 498 | |
| 499 void TileManager::DidFinishRunningTasks() { | 373 void TileManager::DidFinishRunningTasks() { |
| 500 TRACE_EVENT0("cc", "TileManager::DidFinishRunningTasks"); | 374 TRACE_EVENT0("cc", "TileManager::DidFinishRunningTasks"); |
| 501 | 375 |
| 502 bool memory_usage_above_limit = resource_pool_->total_memory_usage_bytes() > | 376 bool memory_usage_above_limit = resource_pool_->total_memory_usage_bytes() > |
| 503 global_state_.soft_memory_limit_in_bytes; | 377 global_state_.soft_memory_limit_in_bytes; |
| 504 | 378 |
| 505 // When OOM, keep re-assigning memory until we reach a steady state | 379 // When OOM, keep re-assigning memory until we reach a steady state |
| 506 // where top-priority tiles are initialized. | 380 // where top-priority tiles are initialized. |
| 507 if (all_tiles_that_need_to_be_rasterized_have_memory_ && | 381 if (all_tiles_that_need_to_be_rasterized_have_memory_ && |
| 508 !memory_usage_above_limit) | 382 !memory_usage_above_limit) |
| 509 return; | 383 return; |
| 510 | 384 |
| 511 rasterizer_delegate_->CheckForCompletedTasks(); | 385 rasterizer_delegate_->CheckForCompletedTasks(); |
| 512 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; | 386 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; |
| 513 | 387 |
| 514 TileVector tiles_that_need_to_be_rasterized; | 388 TileVector tiles_that_need_to_be_rasterized; |
| 515 AssignGpuMemoryToTiles(&prioritized_tiles_, | 389 AssignGpuMemoryToTiles(&tiles_that_need_to_be_rasterized); |
| 516 &tiles_that_need_to_be_rasterized); | |
| 517 | 390 |
| 518 // |tiles_that_need_to_be_rasterized| will be empty when we reach a | 391 // |tiles_that_need_to_be_rasterized| will be empty when we reach a |
| 519 // steady memory state. Keep scheduling tasks until we reach this state. | 392 // steady memory state. Keep scheduling tasks until we reach this state. |
| 520 if (!tiles_that_need_to_be_rasterized.empty()) { | 393 if (!tiles_that_need_to_be_rasterized.empty()) { |
| 521 ScheduleTasks(tiles_that_need_to_be_rasterized); | 394 ScheduleTasks(tiles_that_need_to_be_rasterized); |
| 522 return; | 395 return; |
| 523 } | 396 } |
| 524 | 397 |
| 525 resource_pool_->ReduceResourceUsage(); | 398 resource_pool_->ReduceResourceUsage(); |
| 526 | 399 |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 556 // activation are initialized when no tiles are OOM. We need to | 429 // activation are initialized when no tiles are OOM. We need to |
| 557 // wait for DidFinishRunningTasks() to be called, try to re-assign | 430 // wait for DidFinishRunningTasks() to be called, try to re-assign |
| 558 // memory and in worst case use on-demand raster when tiles | 431 // memory and in worst case use on-demand raster when tiles |
| 559 // required for activation are OOM. | 432 // required for activation are OOM. |
| 560 if (!all_tiles_required_for_activation_have_memory_) | 433 if (!all_tiles_required_for_activation_have_memory_) |
| 561 return; | 434 return; |
| 562 | 435 |
| 563 client_->NotifyReadyToActivate(); | 436 client_->NotifyReadyToActivate(); |
| 564 } | 437 } |
| 565 | 438 |
| 566 void TileManager::GetTilesWithAssignedBins(PrioritizedTileSet* tiles) { | |
| 567 TRACE_EVENT0("cc", "TileManager::GetTilesWithAssignedBins"); | |
| 568 | |
| 569 // Compute new stats to be return by GetMemoryStats(). | |
| 570 memory_required_bytes_ = 0; | |
| 571 memory_nice_to_have_bytes_ = 0; | |
| 572 | |
| 573 const TileMemoryLimitPolicy memory_policy = global_state_.memory_limit_policy; | |
| 574 const TreePriority tree_priority = global_state_.tree_priority; | |
| 575 | |
| 576 // For each tree, bin into different categories of tiles. | |
| 577 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) { | |
| 578 Tile* tile = it->second; | |
| 579 ManagedTileState& mts = tile->managed_state(); | |
| 580 | |
| 581 const ManagedTileState::TileVersion& tile_version = | |
| 582 tile->GetTileVersionForDrawing(); | |
| 583 bool tile_is_ready_to_draw = tile_version.IsReadyToDraw(); | |
| 584 bool tile_is_active = tile_is_ready_to_draw || | |
| 585 mts.tile_versions[mts.raster_mode].raster_task_; | |
| 586 | |
| 587 // Get the active priority and bin. | |
| 588 TilePriority active_priority = tile->priority(ACTIVE_TREE); | |
| 589 ManagedTileBin active_bin = BinFromTilePriority(active_priority); | |
| 590 | |
| 591 // Get the pending priority and bin. | |
| 592 TilePriority pending_priority = tile->priority(PENDING_TREE); | |
| 593 ManagedTileBin pending_bin = BinFromTilePriority(pending_priority); | |
| 594 | |
| 595 bool pending_is_low_res = pending_priority.resolution == LOW_RESOLUTION; | |
| 596 bool pending_is_non_ideal = | |
| 597 pending_priority.resolution == NON_IDEAL_RESOLUTION; | |
| 598 bool active_is_non_ideal = | |
| 599 active_priority.resolution == NON_IDEAL_RESOLUTION; | |
| 600 | |
| 601 // Adjust pending bin state for low res tiles. This prevents | |
| 602 // pending tree low-res tiles from being initialized before | |
| 603 // high-res tiles. | |
| 604 if (pending_is_low_res) | |
| 605 pending_bin = std::max(pending_bin, EVENTUALLY_BIN); | |
| 606 | |
| 607 // Adjust bin state based on if ready to draw. | |
| 608 active_bin = kBinReadyToDrawMap[tile_is_ready_to_draw][active_bin]; | |
| 609 pending_bin = kBinReadyToDrawMap[tile_is_ready_to_draw][pending_bin]; | |
| 610 | |
| 611 // Adjust bin state based on if active. | |
| 612 active_bin = kBinIsActiveMap[tile_is_active][active_bin]; | |
| 613 pending_bin = kBinIsActiveMap[tile_is_active][pending_bin]; | |
| 614 | |
| 615 // We never want to paint new non-ideal tiles, as we always have | |
| 616 // a high-res tile covering that content (paint that instead). | |
| 617 if (!tile_is_ready_to_draw && active_is_non_ideal) | |
| 618 active_bin = NEVER_BIN; | |
| 619 if (!tile_is_ready_to_draw && pending_is_non_ideal) | |
| 620 pending_bin = NEVER_BIN; | |
| 621 | |
| 622 // Compute combined bin. | |
| 623 ManagedTileBin combined_bin = std::min(active_bin, pending_bin); | |
| 624 | |
| 625 if (!tile_is_ready_to_draw || tile_version.requires_resource()) { | |
| 626 // The bin that the tile would have if the GPU memory manager had | |
| 627 // a maximally permissive policy, send to the GPU memory manager | |
| 628 // to determine policy. | |
| 629 ManagedTileBin gpu_memmgr_stats_bin = combined_bin; | |
| 630 if ((gpu_memmgr_stats_bin == NOW_BIN) || | |
| 631 (gpu_memmgr_stats_bin == NOW_AND_READY_TO_DRAW_BIN)) | |
| 632 memory_required_bytes_ += BytesConsumedIfAllocated(tile); | |
| 633 if (gpu_memmgr_stats_bin != NEVER_BIN) | |
| 634 memory_nice_to_have_bytes_ += BytesConsumedIfAllocated(tile); | |
| 635 } | |
| 636 | |
| 637 ManagedTileBin tree_bin[NUM_TREES]; | |
| 638 tree_bin[ACTIVE_TREE] = kBinPolicyMap[memory_policy][active_bin]; | |
| 639 tree_bin[PENDING_TREE] = kBinPolicyMap[memory_policy][pending_bin]; | |
| 640 | |
| 641 TilePriority tile_priority; | |
| 642 switch (tree_priority) { | |
| 643 case SAME_PRIORITY_FOR_BOTH_TREES: | |
| 644 mts.bin = kBinPolicyMap[memory_policy][combined_bin]; | |
| 645 tile_priority = tile->combined_priority(); | |
| 646 break; | |
| 647 case SMOOTHNESS_TAKES_PRIORITY: | |
| 648 mts.bin = tree_bin[ACTIVE_TREE]; | |
| 649 tile_priority = active_priority; | |
| 650 break; | |
| 651 case NEW_CONTENT_TAKES_PRIORITY: | |
| 652 mts.bin = tree_bin[PENDING_TREE]; | |
| 653 tile_priority = pending_priority; | |
| 654 break; | |
| 655 } | |
| 656 | |
| 657 // Bump up the priority if we determined it's NEVER_BIN on one tree, | |
| 658 // but is still required on the other tree. | |
| 659 bool is_in_never_bin_on_both_trees = tree_bin[ACTIVE_TREE] == NEVER_BIN && | |
| 660 tree_bin[PENDING_TREE] == NEVER_BIN; | |
| 661 | |
| 662 if (mts.bin == NEVER_BIN && !is_in_never_bin_on_both_trees) | |
| 663 mts.bin = tile_is_active ? AT_LAST_AND_ACTIVE_BIN : AT_LAST_BIN; | |
| 664 | |
| 665 mts.resolution = tile_priority.resolution; | |
| 666 mts.priority_bin = tile_priority.priority_bin; | |
| 667 mts.distance_to_visible = tile_priority.distance_to_visible; | |
| 668 mts.required_for_activation = tile_priority.required_for_activation; | |
| 669 | |
| 670 mts.visible_and_ready_to_draw = | |
| 671 tree_bin[ACTIVE_TREE] == NOW_AND_READY_TO_DRAW_BIN; | |
| 672 | |
| 673 // If the tile is in NEVER_BIN and it does not have an active task, then we | |
| 674 // can release the resources early. If it does have the task however, we | |
| 675 // should keep it in the prioritized tile set to ensure that AssignGpuMemory | |
| 676 // can visit it. | |
| 677 if (mts.bin == NEVER_BIN && | |
| 678 !mts.tile_versions[mts.raster_mode].raster_task_) { | |
| 679 FreeResourcesForTile(tile); | |
| 680 continue; | |
| 681 } | |
| 682 | |
| 683 // Insert the tile into a priority set. | |
| 684 tiles->InsertTile(tile, mts.bin); | |
| 685 } | |
| 686 } | |
| 687 | |
| 688 void TileManager::ManageTiles(const GlobalStateThatImpactsTilePriority& state) { | 439 void TileManager::ManageTiles(const GlobalStateThatImpactsTilePriority& state) { |
| 689 TRACE_EVENT0("cc", "TileManager::ManageTiles"); | 440 TRACE_EVENT0("cc", "TileManager::ManageTiles"); |
| 690 | 441 |
| 691 // Update internal state. | 442 // Update internal state. |
| 692 if (state != global_state_) { | 443 global_state_ = state; |
| 693 global_state_ = state; | 444 |
| 694 prioritized_tiles_dirty_ = true; | 445 // TODO(vmpstr): See if we still need to keep tiles alive when layers release |
| 695 } | 446 // them. |
| 447 CleanUpReleasedTiles(); | |
| 696 | 448 |
| 697 // We need to call CheckForCompletedTasks() once in-between each call | 449 // We need to call CheckForCompletedTasks() once in-between each call |
| 698 // to ScheduleTasks() to prevent canceled tasks from being scheduled. | 450 // to ScheduleTasks() to prevent canceled tasks from being scheduled. |
| 699 if (!did_check_for_completed_tasks_since_last_schedule_tasks_) { | 451 if (!did_check_for_completed_tasks_since_last_schedule_tasks_) { |
| 700 rasterizer_delegate_->CheckForCompletedTasks(); | 452 rasterizer_delegate_->CheckForCompletedTasks(); |
| 701 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; | 453 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; |
| 702 } | 454 } |
| 703 | 455 |
| 704 UpdatePrioritizedTileSetIfNeeded(); | |
| 705 | |
| 706 TileVector tiles_that_need_to_be_rasterized; | 456 TileVector tiles_that_need_to_be_rasterized; |
| 707 AssignGpuMemoryToTiles(&prioritized_tiles_, | 457 AssignGpuMemoryToTiles(&tiles_that_need_to_be_rasterized); |
| 708 &tiles_that_need_to_be_rasterized); | |
| 709 | 458 |
| 710 // Finally, schedule rasterizer tasks. | 459 // Finally, schedule rasterizer tasks. |
| 711 ScheduleTasks(tiles_that_need_to_be_rasterized); | 460 ScheduleTasks(tiles_that_need_to_be_rasterized); |
| 712 | 461 |
| 713 TRACE_EVENT_INSTANT1("cc", | 462 TRACE_EVENT_INSTANT1("cc", |
| 714 "DidManage", | 463 "DidManage", |
| 715 TRACE_EVENT_SCOPE_THREAD, | 464 TRACE_EVENT_SCOPE_THREAD, |
| 716 "state", | 465 "state", |
| 717 TracedValue::FromValue(BasicStateAsValue().release())); | 466 TracedValue::FromValue(BasicStateAsValue().release())); |
| 718 | 467 |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 740 | 489 |
| 741 bool did_initialize_visible_tile = did_initialize_visible_tile_; | 490 bool did_initialize_visible_tile = did_initialize_visible_tile_; |
| 742 did_initialize_visible_tile_ = false; | 491 did_initialize_visible_tile_ = false; |
| 743 return did_initialize_visible_tile; | 492 return did_initialize_visible_tile; |
| 744 } | 493 } |
| 745 | 494 |
| 746 void TileManager::GetMemoryStats(size_t* memory_required_bytes, | 495 void TileManager::GetMemoryStats(size_t* memory_required_bytes, |
| 747 size_t* memory_nice_to_have_bytes, | 496 size_t* memory_nice_to_have_bytes, |
| 748 size_t* memory_allocated_bytes, | 497 size_t* memory_allocated_bytes, |
| 749 size_t* memory_used_bytes) const { | 498 size_t* memory_used_bytes) const { |
| 750 *memory_required_bytes = memory_required_bytes_; | 499 *memory_required_bytes = resource_pool_->total_memory_usage_bytes(); |
| 751 *memory_nice_to_have_bytes = memory_nice_to_have_bytes_; | 500 *memory_nice_to_have_bytes = resource_pool_->total_memory_usage_bytes(); |
|
reveman
2014/04/28 19:39:18
what's our plan for computing these properly?
vmpstr
2014/04/28 20:56:42
That's a good question. There's no good way for us
reveman
2014/04/28 21:43:15
The end result is that these values are used by th
vmpstr
2014/04/28 22:44:38
Yeah that's the thing that always made me a bit he
reveman
2014/05/20 23:01:00
Doesn't have to be precise. I don't think memory_r
| |
| 752 *memory_allocated_bytes = resource_pool_->total_memory_usage_bytes(); | 501 *memory_allocated_bytes = resource_pool_->total_memory_usage_bytes(); |
| 753 *memory_used_bytes = resource_pool_->acquired_memory_usage_bytes(); | 502 *memory_used_bytes = resource_pool_->acquired_memory_usage_bytes(); |
| 754 } | 503 } |
| 755 | 504 |
| 756 scoped_ptr<base::Value> TileManager::BasicStateAsValue() const { | 505 scoped_ptr<base::Value> TileManager::BasicStateAsValue() const { |
| 757 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); | 506 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); |
| 758 state->SetInteger("tile_count", tiles_.size()); | 507 state->SetInteger("tile_count", tiles_.size()); |
| 759 state->Set("global_state", global_state_.AsValue().release()); | 508 state->Set("global_state", global_state_.AsValue().release()); |
| 760 state->Set("memory_requirements", GetMemoryRequirementsAsValue().release()); | 509 state->Set("memory_requirements", GetMemoryRequirementsAsValue().release()); |
| 761 return state.PassAs<base::Value>(); | 510 return state.PassAs<base::Value>(); |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 782 &memory_used_bytes); | 531 &memory_used_bytes); |
| 783 requirements->SetInteger("memory_required_bytes", memory_required_bytes); | 532 requirements->SetInteger("memory_required_bytes", memory_required_bytes); |
| 784 requirements->SetInteger("memory_nice_to_have_bytes", | 533 requirements->SetInteger("memory_nice_to_have_bytes", |
| 785 memory_nice_to_have_bytes); | 534 memory_nice_to_have_bytes); |
| 786 requirements->SetInteger("memory_allocated_bytes", memory_allocated_bytes); | 535 requirements->SetInteger("memory_allocated_bytes", memory_allocated_bytes); |
| 787 requirements->SetInteger("memory_used_bytes", memory_used_bytes); | 536 requirements->SetInteger("memory_used_bytes", memory_used_bytes); |
| 788 return requirements.PassAs<base::Value>(); | 537 return requirements.PassAs<base::Value>(); |
| 789 } | 538 } |
| 790 | 539 |
| 791 void TileManager::AssignGpuMemoryToTiles( | 540 void TileManager::AssignGpuMemoryToTiles( |
| 792 PrioritizedTileSet* tiles, | |
| 793 TileVector* tiles_that_need_to_be_rasterized) { | 541 TileVector* tiles_that_need_to_be_rasterized) { |
| 794 TRACE_EVENT0("cc", "TileManager::AssignGpuMemoryToTiles"); | 542 TRACE_EVENT0("cc", "TileManager::AssignGpuMemoryToTiles"); |
| 795 | 543 |
| 796 // Maintain the list of released resources that can potentially be re-used | 544 // Maintain the list of released resources that can potentially be re-used |
| 797 // or deleted. | 545 // or deleted. |
| 798 // If this operation becomes expensive too, only do this after some | 546 // If this operation becomes expensive too, only do this after some |
| 799 // resource(s) was returned. Note that in that case, one also need to | 547 // resource(s) was returned. Note that in that case, one also need to |
| 800 // invalidate when releasing some resource from the pool. | 548 // invalidate when releasing some resource from the pool. |
| 801 resource_pool_->CheckBusyResources(); | 549 resource_pool_->CheckBusyResources(); |
| 802 | 550 |
| 803 // Now give memory out to the tiles until we're out, and build | 551 // Now give memory out to the tiles until we're out, and build |
| 804 // the needs-to-be-rasterized queue. | 552 // the needs-to-be-rasterized queue. |
| 805 all_tiles_that_need_to_be_rasterized_have_memory_ = true; | 553 all_tiles_that_need_to_be_rasterized_have_memory_ = true; |
| 806 all_tiles_required_for_activation_have_memory_ = true; | 554 all_tiles_required_for_activation_have_memory_ = true; |
| 807 | 555 |
| 808 // Cast to prevent overflow. | 556 // Cast to prevent overflow. |
| 809 int64 soft_bytes_available = | 557 int64 soft_bytes_available = |
| 810 static_cast<int64>(bytes_releasable_) + | |
| 811 static_cast<int64>(global_state_.soft_memory_limit_in_bytes) - | 558 static_cast<int64>(global_state_.soft_memory_limit_in_bytes) - |
| 812 static_cast<int64>(resource_pool_->acquired_memory_usage_bytes()); | 559 static_cast<int64>(resource_pool_->acquired_memory_usage_bytes()); |
| 813 int64 hard_bytes_available = | 560 int64 hard_bytes_available = |
| 814 static_cast<int64>(bytes_releasable_) + | |
| 815 static_cast<int64>(global_state_.hard_memory_limit_in_bytes) - | 561 static_cast<int64>(global_state_.hard_memory_limit_in_bytes) - |
| 816 static_cast<int64>(resource_pool_->acquired_memory_usage_bytes()); | 562 static_cast<int64>(resource_pool_->acquired_memory_usage_bytes()); |
| 817 int resources_available = resources_releasable_ + | 563 int resources_available = global_state_.num_resources_limit - |
| 818 global_state_.num_resources_limit - | |
| 819 resource_pool_->acquired_resource_count(); | 564 resource_pool_->acquired_resource_count(); |
| 820 size_t soft_bytes_allocatable = | 565 |
| 821 std::max(static_cast<int64>(0), soft_bytes_available); | 566 EvictionTileIterator eviction_it(this, global_state_.tree_priority); |
| 822 size_t hard_bytes_allocatable = | 567 bool evicted_tiles_required_for_activation = false; |
| 823 std::max(static_cast<int64>(0), hard_bytes_available); | 568 |
| 824 size_t resources_allocatable = std::max(0, resources_available); | 569 // Evict resources if we're OOM before processing any tiles. |
| 570 while (hard_bytes_available < 0 || resources_available < 0) { | |
|
reveman
2014/04/28 19:39:18
can you fold this into the loop below instead of d
vmpstr
2014/04/28 20:56:42
It has to be outside of the loop since the raster
reveman
2014/04/28 21:43:15
It's not clear to me why these eviction cases need
vmpstr
2014/04/28 22:44:38
I kind of reworked this a bit (I put the memory li
| |
| 571 if (!eviction_it) | |
| 572 break; | |
| 573 | |
| 574 Tile* eviction_tile = *eviction_it; | |
| 575 const TilePriority& eviction_priority = | |
| 576 eviction_tile->priority_for_tree_priority(global_state_.tree_priority); | |
| 577 size_t eviction_bytes_if_allocated = | |
| 578 BytesConsumedIfAllocated(eviction_tile); | |
| 579 ManagedTileState& eviction_mts = eviction_tile->managed_state(); | |
| 580 for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) { | |
| 581 if (eviction_mts.tile_versions[mode].resource_) { | |
| 582 hard_bytes_available += eviction_bytes_if_allocated; | |
| 583 if (eviction_priority.priority_bin != TilePriority::NOW) | |
| 584 soft_bytes_available += eviction_bytes_if_allocated; | |
| 585 resources_available++; | |
| 586 } | |
| 587 } | |
| 588 FreeResourcesForTile(eviction_tile); | |
| 589 ++eviction_it; | |
| 590 | |
| 591 evicted_tiles_required_for_activation |= | |
| 592 eviction_tile->required_for_activation(); | |
| 593 } | |
| 594 | |
| 595 int64 soft_bytes_allocatable = soft_bytes_available; | |
| 596 int64 hard_bytes_allocatable = hard_bytes_available; | |
| 597 int resources_allocatable = resources_available; | |
| 825 | 598 |
| 826 size_t bytes_that_exceeded_memory_budget = 0; | 599 size_t bytes_that_exceeded_memory_budget = 0; |
| 827 size_t soft_bytes_left = soft_bytes_allocatable; | 600 int64 soft_bytes_left = soft_bytes_allocatable; |
| 828 size_t hard_bytes_left = hard_bytes_allocatable; | 601 int64 hard_bytes_left = hard_bytes_allocatable; |
| 829 | 602 |
| 830 size_t resources_left = resources_allocatable; | 603 int* resources_left = &resources_allocatable; |
| 831 bool oomed_soft = false; | 604 bool oomed_soft = false; |
| 832 bool oomed_hard = false; | 605 bool oomed_hard = false; |
| 833 bool have_hit_soft_memory = false; // Soft memory comes after hard. | 606 bool have_hit_soft_memory = false; // Soft memory comes after hard. |
| 834 | 607 |
| 835 // Memory we assign to raster tasks now will be deducted from our memory | 608 // Memory we assign to raster tasks now will be deducted from our memory |
| 836 // in future iterations if priorities change. By assigning at most half | 609 // in future iterations if priorities change. By assigning at most half |
| 837 // the raster limit, we will always have another 50% left even if priorities | 610 // the raster limit, we will always have another 50% left even if priorities |
| 838 // change completely (assuming we check for completed/cancelled rasters | 611 // change completely (assuming we check for completed/cancelled rasters |
| 839 // between each call to this function). | 612 // between each call to this function). |
| 840 size_t max_raster_bytes = max_raster_usage_bytes_ / 2; | 613 size_t max_raster_bytes = max_raster_usage_bytes_ / 2; |
| 841 size_t raster_bytes = 0; | 614 size_t raster_bytes = 0; |
| 842 | 615 |
| 843 unsigned schedule_priority = 1u; | 616 unsigned schedule_priority = 1u; |
| 844 for (PrioritizedTileSet::Iterator it(tiles, true); it; ++it) { | 617 for (RasterTileIterator it(this, global_state_.tree_priority); it; ++it) { |
| 845 Tile* tile = *it; | 618 Tile* tile = *it; |
| 619 TilePriority priority = | |
| 620 tile->priority_for_tree_priority(global_state_.tree_priority); | |
| 621 | |
| 622 bool tile_violates_memory_policy = false; | |
| 623 switch (global_state_.memory_limit_policy) { | |
| 624 case ALLOW_NOTHING: | |
| 625 tile_violates_memory_policy = true; | |
| 626 break; | |
| 627 case ALLOW_ABSOLUTE_MINIMUM: | |
| 628 tile_violates_memory_policy = priority.priority_bin > TilePriority::NOW; | |
| 629 break; | |
| 630 case ALLOW_PREPAINT_ONLY: | |
| 631 tile_violates_memory_policy = | |
| 632 priority.priority_bin > TilePriority::SOON; | |
| 633 break; | |
| 634 case ALLOW_ANYTHING: | |
| 635 case NUM_TILE_MEMORY_LIMIT_POLICIES: | |
| 636 break; | |
| 637 } | |
| 638 | |
| 639 if (tile_violates_memory_policy) | |
| 640 break; | |
| 641 | |
| 846 ManagedTileState& mts = tile->managed_state(); | 642 ManagedTileState& mts = tile->managed_state(); |
| 847 | 643 |
| 848 mts.scheduled_priority = schedule_priority++; | 644 mts.scheduled_priority = schedule_priority++; |
| 849 | 645 |
| 850 mts.raster_mode = tile->DetermineOverallRasterMode(); | 646 mts.raster_mode = tile->DetermineOverallRasterMode(); |
| 851 | 647 |
| 852 ManagedTileState::TileVersion& tile_version = | 648 ManagedTileState::TileVersion& tile_version = |
| 853 mts.tile_versions[mts.raster_mode]; | 649 mts.tile_versions[mts.raster_mode]; |
| 854 | 650 |
| 855 // If this tile doesn't need a resource, then nothing to do. | 651 // If this version is ready to draw, then nothing to do. |
| 856 if (!tile_version.requires_resource()) | 652 if (tile_version.IsReadyToDraw()) |
| 857 continue; | 653 continue; |
| 858 | 654 |
| 859 // If the tile is not needed, free it up. | 655 const bool tile_uses_hard_limit = |
| 860 if (mts.bin == NEVER_BIN) { | 656 priority.priority_bin == TilePriority::NOW; |
| 861 FreeResourcesForTile(tile); | |
| 862 continue; | |
| 863 } | |
| 864 | 657 |
| 865 const bool tile_uses_hard_limit = mts.bin <= NOW_BIN; | |
| 866 const size_t bytes_if_allocated = BytesConsumedIfAllocated(tile); | 658 const size_t bytes_if_allocated = BytesConsumedIfAllocated(tile); |
| 867 const size_t raster_bytes_if_rastered = raster_bytes + bytes_if_allocated; | 659 const size_t raster_bytes_if_rastered = raster_bytes + bytes_if_allocated; |
| 868 const size_t tile_bytes_left = | 660 int64* tile_bytes_left = |
| 869 (tile_uses_hard_limit) ? hard_bytes_left : soft_bytes_left; | 661 (tile_uses_hard_limit) ? &hard_bytes_left : &soft_bytes_left; |
| 870 | 662 |
| 871 // Hard-limit is reserved for tiles that would cause a calamity | 663 // Hard-limit is reserved for tiles that would cause a calamity |
| 872 // if they were to go away, so by definition they are the highest | 664 // if they were to go away, so by definition they are the highest |
| 873 // priority memory, and must be at the front of the list. | 665 // priority memory, and must be at the front of the list. |
| 874 DCHECK(!(have_hit_soft_memory && tile_uses_hard_limit)); | 666 DCHECK(!(have_hit_soft_memory && tile_uses_hard_limit)); |
| 875 have_hit_soft_memory |= !tile_uses_hard_limit; | 667 have_hit_soft_memory |= !tile_uses_hard_limit; |
| 876 | 668 |
| 877 size_t tile_bytes = 0; | 669 int64 tile_bytes = 0; |
| 878 size_t tile_resources = 0; | 670 int tile_resources = 0; |
| 879 | 671 |
| 880 // It costs to maintain a resource. | 672 // It costs to maintain a resource. |
| 881 for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) { | 673 for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) { |
| 882 if (mts.tile_versions[mode].resource_) { | 674 if (mts.tile_versions[mode].resource_) { |
| 883 tile_bytes += bytes_if_allocated; | 675 tile_bytes += bytes_if_allocated; |
| 884 tile_resources++; | 676 tile_resources++; |
| 885 } | 677 } |
| 886 } | 678 } |
| 887 | 679 |
| 888 // Allow lower priority tiles with initialized resources to keep | 680 // If we don't have the required version, and it's not in flight |
| 889 // their memory by only assigning memory to new raster tasks if | 681 // then we'll have to pay to create a new task. |
| 890 // they can be scheduled. | 682 if (!tile_version.resource_ && !tile_version.raster_task_) { |
| 891 if (raster_bytes_if_rastered <= max_raster_bytes) { | 683 tile_bytes += bytes_if_allocated; |
| 892 // If we don't have the required version, and it's not in flight | 684 tile_resources++; |
| 893 // then we'll have to pay to create a new task. | |
| 894 if (!tile_version.resource_ && !tile_version.raster_task_) { | |
| 895 tile_bytes += bytes_if_allocated; | |
| 896 tile_resources++; | |
| 897 } | |
| 898 } | 685 } |
| 899 | 686 |
| 900 // Tile is OOM. | 687 // Handle OOM tiles. |
| 901 if (tile_bytes > tile_bytes_left || tile_resources > resources_left) { | 688 while (tile_bytes > *tile_bytes_left || tile_resources > *resources_left) { |
| 902 FreeResourcesForTile(tile); | 689 if (!eviction_it) |
| 690 break; | |
| 903 | 691 |
| 692 Tile* eviction_tile = *eviction_it; | |
| 693 DCHECK(eviction_tile); | |
| 694 | |
| 695 TilePriority eviction_priority = | |
| 696 eviction_tile->priority_for_tree_priority( | |
| 697 global_state_.tree_priority); | |
| 698 | |
| 699 if (!priority.IsHigherPriorityThan(eviction_priority)) | |
| 700 break; | |
| 701 | |
| 702 size_t eviction_tile_bytes = 0; | |
| 703 size_t eviction_tile_resources = 0; | |
| 704 size_t eviction_bytes_if_allocated = BytesConsumedIfAllocated(tile); | |
| 705 ManagedTileState& eviction_mts = eviction_tile->managed_state(); | |
| 706 for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) { | |
| 707 if (eviction_mts.tile_versions[mode].resource_) { | |
| 708 eviction_tile_bytes += eviction_bytes_if_allocated; | |
| 709 eviction_tile_resources++; | |
| 710 } | |
| 711 } | |
| 712 | |
| 713 FreeResourcesForTile(eviction_tile); | |
| 714 ++eviction_it; | |
| 715 | |
| 716 evicted_tiles_required_for_activation |= | |
| 717 eviction_tile->required_for_activation(); | |
| 718 | |
| 719 *tile_bytes_left += eviction_tile_bytes; | |
| 720 *resources_left += eviction_tile_resources; | |
| 721 } | |
| 722 | |
| 723 // Tile is still OOM. | |
| 724 if (tile_bytes > *tile_bytes_left || tile_resources > *resources_left) { | |
| 904 // This tile was already on screen and now its resources have been | 725 // This tile was already on screen and now its resources have been |
| 905 // released. In order to prevent checkerboarding, set this tile as | 726 // released. In order to prevent checkerboarding, set this tile as |
| 906 // rasterize on demand immediately. | 727 // rasterize on demand immediately. |
| 907 if (mts.visible_and_ready_to_draw && use_rasterize_on_demand_) | 728 if (mts.visible_and_ready_to_draw && use_rasterize_on_demand_) |
| 908 tile_version.set_rasterize_on_demand(); | 729 tile_version.set_rasterize_on_demand(); |
| 909 | 730 |
| 910 oomed_soft = true; | 731 oomed_soft = true; |
| 911 if (tile_uses_hard_limit) { | 732 if (tile_uses_hard_limit) { |
| 912 oomed_hard = true; | 733 oomed_hard = true; |
| 913 bytes_that_exceeded_memory_budget += tile_bytes; | 734 bytes_that_exceeded_memory_budget += tile_bytes; |
| 914 } | 735 } |
| 915 } else { | 736 } else { |
| 916 resources_left -= tile_resources; | 737 *resources_left -= tile_resources; |
| 917 hard_bytes_left -= tile_bytes; | 738 hard_bytes_left -= tile_bytes; |
| 918 soft_bytes_left = | 739 soft_bytes_left = |
| 919 (soft_bytes_left > tile_bytes) ? soft_bytes_left - tile_bytes : 0; | 740 (soft_bytes_left > tile_bytes) ? soft_bytes_left - tile_bytes : 0; |
| 920 if (tile_version.resource_) | 741 if (tile_version.resource_) |
| 921 continue; | 742 continue; |
| 922 } | 743 } |
| 923 | 744 |
| 924 DCHECK(!tile_version.resource_); | 745 DCHECK(!tile_version.resource_); |
| 925 | 746 |
| 926 // Tile shouldn't be rasterized if |tiles_that_need_to_be_rasterized| | 747 // Tile shouldn't be rasterized if |tiles_that_need_to_be_rasterized| |
| 927 // has reached it's limit or we've failed to assign gpu memory to this | 748 // has reached it's limit or we've failed to assign gpu memory to this |
| 928 // or any higher priority tile. Preventing tiles that fit into memory | 749 // or any higher priority tile. Preventing tiles that fit into memory |
| 929 // budget to be rasterized when higher priority tile is oom is | 750 // budget to be rasterized when higher priority tile is oom is |
| 930 // important for two reasons: | 751 // important for two reasons: |
| 931 // 1. Tile size should not impact raster priority. | 752 // 1. Tile size should not impact raster priority. |
| 932 // 2. Tiles with existing raster task could otherwise incorrectly | 753 // 2. Tiles with existing raster task could otherwise incorrectly |
| 933 // be added as they are not affected by |bytes_allocatable|. | 754 // be added as they are not affected by |bytes_allocatable|. |
| 934 bool can_schedule_tile = | 755 bool can_schedule_tile = |
| 935 !oomed_soft && raster_bytes_if_rastered <= max_raster_bytes && | 756 !oomed_soft && raster_bytes_if_rastered <= max_raster_bytes && |
| 936 tiles_that_need_to_be_rasterized->size() < kScheduledRasterTasksLimit; | 757 tiles_that_need_to_be_rasterized->size() < kScheduledRasterTasksLimit; |
| 937 | 758 |
| 938 if (!can_schedule_tile) { | 759 if (!can_schedule_tile) { |
| 939 all_tiles_that_need_to_be_rasterized_have_memory_ = false; | 760 all_tiles_that_need_to_be_rasterized_have_memory_ = false; |
| 940 if (tile->required_for_activation()) | 761 all_tiles_required_for_activation_have_memory_ = |
| 941 all_tiles_required_for_activation_have_memory_ = false; | 762 !it.HasTilesRequiredForActivation() && |
| 942 it.DisablePriorityOrdering(); | 763 !evicted_tiles_required_for_activation; |
| 943 continue; | 764 break; |
| 944 } | 765 } |
| 945 | 766 |
| 946 raster_bytes = raster_bytes_if_rastered; | 767 raster_bytes = raster_bytes_if_rastered; |
| 947 tiles_that_need_to_be_rasterized->push_back(tile); | 768 tiles_that_need_to_be_rasterized->push_back(tile); |
| 948 } | 769 } |
| 949 | 770 |
| 950 // OOM reporting uses hard-limit, soft-OOM is normal depending on limit. | 771 // OOM reporting uses hard-limit, soft-OOM is normal depending on limit. |
| 951 ever_exceeded_memory_budget_ |= oomed_hard; | 772 ever_exceeded_memory_budget_ |= oomed_hard; |
| 952 if (ever_exceeded_memory_budget_) { | 773 if (ever_exceeded_memory_budget_) { |
| 953 TRACE_COUNTER_ID2("cc", | 774 TRACE_COUNTER_ID2("cc", |
| (...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1218 content_rect, | 1039 content_rect, |
| 1219 opaque_rect, | 1040 opaque_rect, |
| 1220 contents_scale, | 1041 contents_scale, |
| 1221 layer_id, | 1042 layer_id, |
| 1222 source_frame_number, | 1043 source_frame_number, |
| 1223 flags)); | 1044 flags)); |
| 1224 DCHECK(tiles_.find(tile->id()) == tiles_.end()); | 1045 DCHECK(tiles_.find(tile->id()) == tiles_.end()); |
| 1225 | 1046 |
| 1226 tiles_[tile->id()] = tile; | 1047 tiles_[tile->id()] = tile; |
| 1227 used_layer_counts_[tile->layer_id()]++; | 1048 used_layer_counts_[tile->layer_id()]++; |
| 1228 prioritized_tiles_dirty_ = true; | |
| 1229 return tile; | 1049 return tile; |
| 1230 } | 1050 } |
| 1231 | 1051 |
| 1232 void TileManager::RegisterPictureLayerImpl(PictureLayerImpl* layer) { | 1052 void TileManager::RegisterPictureLayerImpl(PictureLayerImpl* layer) { |
| 1233 DCHECK(std::find(layers_.begin(), layers_.end(), layer) == layers_.end()); | 1053 DCHECK(std::find(layers_.begin(), layers_.end(), layer) == layers_.end()); |
| 1234 layers_.push_back(layer); | 1054 layers_.push_back(layer); |
| 1235 } | 1055 } |
| 1236 | 1056 |
| 1237 void TileManager::UnregisterPictureLayerImpl(PictureLayerImpl* layer) { | 1057 void TileManager::UnregisterPictureLayerImpl(PictureLayerImpl* layer) { |
| 1238 std::vector<PictureLayerImpl*>::iterator it = | 1058 std::vector<PictureLayerImpl*>::iterator it = |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1315 | 1135 |
| 1316 if (paired_iterator.PeekTile(tree_priority_) != NULL) { | 1136 if (paired_iterator.PeekTile(tree_priority_) != NULL) { |
| 1317 paired_iterators_.push_back(paired_iterator); | 1137 paired_iterators_.push_back(paired_iterator); |
| 1318 iterator_heap_.push_back(&paired_iterators_.back()); | 1138 iterator_heap_.push_back(&paired_iterators_.back()); |
| 1319 } | 1139 } |
| 1320 } | 1140 } |
| 1321 | 1141 |
| 1322 std::make_heap(iterator_heap_.begin(), iterator_heap_.end(), comparator_); | 1142 std::make_heap(iterator_heap_.begin(), iterator_heap_.end(), comparator_); |
| 1323 } | 1143 } |
| 1324 | 1144 |
| 1145 TileManager::RasterTileIterator::RasterTileIterator( | |
| 1146 const RasterTileIterator& other) | |
| 1147 : comparator_(other.comparator_) { | |
| 1148 *this = other; | |
| 1149 } | |
| 1150 | |
| 1151 TileManager::RasterTileIterator& TileManager::RasterTileIterator::operator=( | |
| 1152 const RasterTileIterator& other) { | |
| 1153 paired_iterators_ = other.paired_iterators_; | |
| 1154 tree_priority_ = other.tree_priority_; | |
| 1155 comparator_ = other.comparator_; | |
| 1156 | |
| 1157 iterator_heap_.reserve(paired_iterators_.size()); | |
| 1158 for (size_t i = 0; i < paired_iterators_.size(); ++i) { | |
| 1159 if (paired_iterators_[i].PeekTile(tree_priority_) != NULL) | |
| 1160 iterator_heap_.push_back(&paired_iterators_[i]); | |
| 1161 } | |
| 1162 std::make_heap(iterator_heap_.begin(), iterator_heap_.end(), comparator_); | |
| 1163 return *this; | |
| 1164 } | |
| 1165 | |
| 1325 TileManager::RasterTileIterator::~RasterTileIterator() {} | 1166 TileManager::RasterTileIterator::~RasterTileIterator() {} |
| 1326 | 1167 |
| 1168 bool TileManager::RasterTileIterator::HasTilesRequiredForActivation() const { | |
| 1169 for (std::vector<PairedPictureLayerIterator*>::const_iterator it = | |
| 1170 iterator_heap_.begin(); | |
| 1171 it != iterator_heap_.end(); | |
| 1172 ++it) { | |
| 1173 const PairedPictureLayerIterator* pair = *it; | |
| 1174 | |
| 1175 // Tiles required for activation can only come from pending layers. | |
| 1176 if (pair->pending_iterator.HasTilesRequiredForActivation()) | |
| 1177 return true; | |
| 1178 } | |
| 1179 return false; | |
| 1180 } | |
| 1181 | |
| 1327 TileManager::RasterTileIterator& TileManager::RasterTileIterator::operator++() { | 1182 TileManager::RasterTileIterator& TileManager::RasterTileIterator::operator++() { |
| 1328 DCHECK(*this); | 1183 DCHECK(*this); |
| 1329 | 1184 |
| 1330 std::pop_heap(iterator_heap_.begin(), iterator_heap_.end(), comparator_); | 1185 std::pop_heap(iterator_heap_.begin(), iterator_heap_.end(), comparator_); |
| 1331 PairedPictureLayerIterator* paired_iterator = iterator_heap_.back(); | 1186 PairedPictureLayerIterator* paired_iterator = iterator_heap_.back(); |
| 1332 iterator_heap_.pop_back(); | 1187 iterator_heap_.pop_back(); |
| 1333 | 1188 |
| 1334 paired_iterator->PopTile(tree_priority_); | 1189 paired_iterator->PopTile(tree_priority_); |
| 1335 if (paired_iterator->PeekTile(tree_priority_) != NULL) { | 1190 if (paired_iterator->PeekTile(tree_priority_) != NULL) { |
| 1336 iterator_heap_.push_back(paired_iterator); | 1191 iterator_heap_.push_back(paired_iterator); |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1449 | 1304 |
| 1450 Tile* a_tile = **a_pair.first; | 1305 Tile* a_tile = **a_pair.first; |
| 1451 Tile* b_tile = **b_pair.first; | 1306 Tile* b_tile = **b_pair.first; |
| 1452 | 1307 |
| 1453 const TilePriority& a_priority = | 1308 const TilePriority& a_priority = |
| 1454 a_tile->priority_for_tree_priority(tree_priority_); | 1309 a_tile->priority_for_tree_priority(tree_priority_); |
| 1455 const TilePriority& b_priority = | 1310 const TilePriority& b_priority = |
| 1456 b_tile->priority_for_tree_priority(tree_priority_); | 1311 b_tile->priority_for_tree_priority(tree_priority_); |
| 1457 bool prioritize_low_res = tree_priority_ == SMOOTHNESS_TAKES_PRIORITY; | 1312 bool prioritize_low_res = tree_priority_ == SMOOTHNESS_TAKES_PRIORITY; |
| 1458 | 1313 |
| 1459 if (b_priority.resolution != a_priority.resolution) { | 1314 if (b_priority.priority_bin == a_priority.priority_bin && |
| 1315 b_priority.resolution != a_priority.resolution) { | |
| 1460 return (prioritize_low_res && b_priority.resolution == LOW_RESOLUTION) || | 1316 return (prioritize_low_res && b_priority.resolution == LOW_RESOLUTION) || |
| 1461 (!prioritize_low_res && b_priority.resolution == HIGH_RESOLUTION) || | 1317 (!prioritize_low_res && b_priority.resolution == HIGH_RESOLUTION) || |
| 1462 (a_priority.resolution == NON_IDEAL_RESOLUTION); | 1318 (a_priority.resolution == NON_IDEAL_RESOLUTION); |
| 1463 } | 1319 } |
| 1464 | 1320 |
| 1465 return b_priority.IsHigherPriorityThan(a_priority); | 1321 return b_priority.IsHigherPriorityThan(a_priority); |
| 1466 } | 1322 } |
| 1467 | 1323 |
| 1468 TileManager::EvictionTileIterator::EvictionTileIterator() | 1324 TileManager::EvictionTileIterator::EvictionTileIterator() |
| 1469 : comparator_(SAME_PRIORITY_FOR_BOTH_TREES) {} | 1325 : initialized_(true), |
| 1326 tile_manager_(NULL), | |
| 1327 comparator_(SAME_PRIORITY_FOR_BOTH_TREES) { | |
| 1328 } | |
| 1329 | |
| 1330 TileManager::EvictionTileIterator::EvictionTileIterator( | |
| 1331 const EvictionTileIterator& other) | |
| 1332 : comparator_(other.comparator_) { | |
| 1333 *this = other; | |
| 1334 } | |
| 1335 | |
| 1336 TileManager::EvictionTileIterator& TileManager::EvictionTileIterator::operator=( | |
| 1337 const EvictionTileIterator& other) { | |
| 1338 paired_iterators_ = other.paired_iterators_; | |
| 1339 tree_priority_ = other.tree_priority_; | |
| 1340 comparator_ = other.comparator_; | |
| 1341 initialized_ = other.initialized_; | |
| 1342 tile_manager_ = other.tile_manager_; | |
| 1343 | |
| 1344 iterator_heap_.reserve(paired_iterators_.size()); | |
| 1345 for (size_t i = 0; i < paired_iterators_.size(); ++i) { | |
| 1346 if (paired_iterators_[i].PeekTile(tree_priority_) != NULL) | |
| 1347 iterator_heap_.push_back(&paired_iterators_[i]); | |
| 1348 } | |
| 1349 std::make_heap(iterator_heap_.begin(), iterator_heap_.end(), comparator_); | |
| 1350 return *this; | |
| 1351 } | |
| 1470 | 1352 |
| 1471 TileManager::EvictionTileIterator::EvictionTileIterator( | 1353 TileManager::EvictionTileIterator::EvictionTileIterator( |
| 1472 TileManager* tile_manager, | 1354 TileManager* tile_manager, |
| 1473 TreePriority tree_priority) | 1355 TreePriority tree_priority) |
| 1474 : tree_priority_(tree_priority), comparator_(tree_priority) { | 1356 : initialized_(false), |
| 1357 tile_manager_(tile_manager), | |
| 1358 tree_priority_(tree_priority), | |
| 1359 comparator_(tree_priority) { | |
| 1360 } | |
| 1361 | |
| 1362 void TileManager::EvictionTileIterator::Initialize() { | |
| 1475 std::vector<TileManager::PairedPictureLayer> paired_layers; | 1363 std::vector<TileManager::PairedPictureLayer> paired_layers; |
| 1476 | 1364 |
| 1477 tile_manager->GetPairedPictureLayers(&paired_layers); | 1365 tile_manager_->GetPairedPictureLayers(&paired_layers); |
| 1478 | 1366 |
| 1479 paired_iterators_.reserve(paired_layers.size()); | 1367 paired_iterators_.reserve(paired_layers.size()); |
| 1480 iterator_heap_.reserve(paired_layers.size()); | 1368 iterator_heap_.reserve(paired_layers.size()); |
| 1481 for (std::vector<TileManager::PairedPictureLayer>::iterator it = | 1369 for (std::vector<TileManager::PairedPictureLayer>::iterator it = |
| 1482 paired_layers.begin(); | 1370 paired_layers.begin(); |
| 1483 it != paired_layers.end(); | 1371 it != paired_layers.end(); |
| 1484 ++it) { | 1372 ++it) { |
| 1485 PairedPictureLayerIterator paired_iterator; | 1373 PairedPictureLayerIterator paired_iterator; |
| 1486 if (it->active_layer) { | 1374 if (it->active_layer) { |
| 1487 paired_iterator.active_iterator = | 1375 paired_iterator.active_iterator = |
| 1488 PictureLayerImpl::LayerEvictionTileIterator(it->active_layer, | 1376 PictureLayerImpl::LayerEvictionTileIterator(it->active_layer, |
| 1489 tree_priority_); | 1377 tree_priority_); |
| 1490 } | 1378 } |
| 1491 | 1379 |
| 1492 if (it->pending_layer) { | 1380 if (it->pending_layer) { |
| 1493 paired_iterator.pending_iterator = | 1381 paired_iterator.pending_iterator = |
| 1494 PictureLayerImpl::LayerEvictionTileIterator(it->pending_layer, | 1382 PictureLayerImpl::LayerEvictionTileIterator(it->pending_layer, |
| 1495 tree_priority_); | 1383 tree_priority_); |
| 1496 } | 1384 } |
| 1497 | 1385 |
| 1498 if (paired_iterator.PeekTile(tree_priority_) != NULL) { | 1386 if (paired_iterator.PeekTile(tree_priority_) != NULL) { |
| 1499 paired_iterators_.push_back(paired_iterator); | 1387 paired_iterators_.push_back(paired_iterator); |
| 1500 iterator_heap_.push_back(&paired_iterators_.back()); | 1388 iterator_heap_.push_back(&paired_iterators_.back()); |
| 1501 } | 1389 } |
| 1502 } | 1390 } |
| 1503 | 1391 |
| 1504 std::make_heap(iterator_heap_.begin(), iterator_heap_.end(), comparator_); | 1392 std::make_heap(iterator_heap_.begin(), iterator_heap_.end(), comparator_); |
| 1393 initialized_ = true; | |
| 1505 } | 1394 } |
| 1506 | 1395 |
| 1507 TileManager::EvictionTileIterator::~EvictionTileIterator() {} | 1396 TileManager::EvictionTileIterator::~EvictionTileIterator() {} |
| 1508 | 1397 |
| 1509 TileManager::EvictionTileIterator& TileManager::EvictionTileIterator:: | 1398 TileManager::EvictionTileIterator& TileManager::EvictionTileIterator:: |
| 1510 operator++() { | 1399 operator++() { |
| 1400 DCHECK(initialized_); | |
| 1401 | |
| 1511 std::pop_heap(iterator_heap_.begin(), iterator_heap_.end(), comparator_); | 1402 std::pop_heap(iterator_heap_.begin(), iterator_heap_.end(), comparator_); |
| 1512 PairedPictureLayerIterator* paired_iterator = iterator_heap_.back(); | 1403 PairedPictureLayerIterator* paired_iterator = iterator_heap_.back(); |
| 1513 iterator_heap_.pop_back(); | 1404 iterator_heap_.pop_back(); |
| 1514 | 1405 |
| 1515 paired_iterator->PopTile(tree_priority_); | 1406 paired_iterator->PopTile(tree_priority_); |
| 1516 if (paired_iterator->PeekTile(tree_priority_) != NULL) { | 1407 if (paired_iterator->PeekTile(tree_priority_) != NULL) { |
| 1517 iterator_heap_.push_back(paired_iterator); | 1408 iterator_heap_.push_back(paired_iterator); |
| 1518 std::push_heap(iterator_heap_.begin(), iterator_heap_.end(), comparator_); | 1409 std::push_heap(iterator_heap_.begin(), iterator_heap_.end(), comparator_); |
| 1519 } | 1410 } |
| 1520 return *this; | 1411 return *this; |
| 1521 } | 1412 } |
| 1522 | 1413 |
| 1523 TileManager::EvictionTileIterator::operator bool() const { | 1414 TileManager::EvictionTileIterator::operator bool() { |
| 1415 if (!initialized_) | |
| 1416 Initialize(); | |
| 1417 | |
| 1524 return !iterator_heap_.empty(); | 1418 return !iterator_heap_.empty(); |
| 1525 } | 1419 } |
| 1526 | 1420 |
| 1527 Tile* TileManager::EvictionTileIterator::operator*() { | 1421 Tile* TileManager::EvictionTileIterator::operator*() { |
| 1422 DCHECK(initialized_); | |
| 1528 DCHECK(*this); | 1423 DCHECK(*this); |
| 1529 return iterator_heap_.front()->PeekTile(tree_priority_); | 1424 return iterator_heap_.front()->PeekTile(tree_priority_); |
| 1530 } | 1425 } |
| 1531 | 1426 |
| 1532 TileManager::EvictionTileIterator::PairedPictureLayerIterator:: | 1427 TileManager::EvictionTileIterator::PairedPictureLayerIterator:: |
| 1533 PairedPictureLayerIterator() {} | 1428 PairedPictureLayerIterator() {} |
| 1534 | 1429 |
| 1535 TileManager::EvictionTileIterator::PairedPictureLayerIterator:: | 1430 TileManager::EvictionTileIterator::PairedPictureLayerIterator:: |
| 1536 ~PairedPictureLayerIterator() {} | 1431 ~PairedPictureLayerIterator() {} |
| 1537 | 1432 |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1624 | 1519 |
| 1625 if (b_priority.resolution != a_priority.resolution) { | 1520 if (b_priority.resolution != a_priority.resolution) { |
| 1626 return (prioritize_low_res && b_priority.resolution == LOW_RESOLUTION) || | 1521 return (prioritize_low_res && b_priority.resolution == LOW_RESOLUTION) || |
| 1627 (!prioritize_low_res && b_priority.resolution == HIGH_RESOLUTION) || | 1522 (!prioritize_low_res && b_priority.resolution == HIGH_RESOLUTION) || |
| 1628 (a_priority.resolution == NON_IDEAL_RESOLUTION); | 1523 (a_priority.resolution == NON_IDEAL_RESOLUTION); |
| 1629 } | 1524 } |
| 1630 return a_priority.IsHigherPriorityThan(b_priority); | 1525 return a_priority.IsHigherPriorityThan(b_priority); |
| 1631 } | 1526 } |
| 1632 | 1527 |
| 1633 } // namespace cc | 1528 } // namespace cc |
| OLD | NEW |