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 <string> | 8 #include <string> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
11 #include "base/json/json_writer.h" | 11 #include "base/json/json_writer.h" |
12 #include "base/logging.h" | 12 #include "base/logging.h" |
13 #include "base/metrics/histogram.h" | 13 #include "base/metrics/histogram.h" |
14 #include "cc/debug/devtools_instrumentation.h" | 14 #include "cc/debug/devtools_instrumentation.h" |
15 #include "cc/debug/traced_value.h" | 15 #include "cc/debug/traced_value.h" |
16 #include "cc/resources/image_raster_worker_pool.h" | 16 #include "cc/resources/image_raster_worker_pool.h" |
17 #include "cc/resources/pixel_buffer_raster_worker_pool.h" | 17 #include "cc/resources/pixel_buffer_raster_worker_pool.h" |
18 #include "cc/resources/tile.h" | 18 #include "cc/resources/tile.h" |
| 19 #include "skia/ext/paint_simplifier.h" |
19 #include "third_party/skia/include/core/SkCanvas.h" | 20 #include "third_party/skia/include/core/SkCanvas.h" |
20 #include "ui/gfx/rect_conversions.h" | 21 #include "ui/gfx/rect_conversions.h" |
21 | 22 |
22 namespace cc { | 23 namespace cc { |
23 | 24 |
24 namespace { | 25 namespace { |
25 | 26 |
| 27 class DisableLCDTextFilter : public SkDrawFilter { |
| 28 public: |
| 29 // SkDrawFilter interface. |
| 30 virtual bool filter(SkPaint* paint, SkDrawFilter::Type type) OVERRIDE { |
| 31 if (type != SkDrawFilter::kText_Type) |
| 32 return true; |
| 33 |
| 34 paint->setLCDRenderText(false); |
| 35 return true; |
| 36 } |
| 37 }; |
| 38 |
26 // Determine bin based on three categories of tiles: things we need now, | 39 // Determine bin based on three categories of tiles: things we need now, |
27 // things we need soon, and eventually. | 40 // things we need soon, and eventually. |
28 inline TileManagerBin BinFromTilePriority(const TilePriority& prio) { | 41 inline TileManagerBin BinFromTilePriority(const TilePriority& prio) { |
29 // The amount of time for which we want to have prepainting coverage. | 42 // The amount of time for which we want to have prepainting coverage. |
30 const float kPrepaintingWindowTimeSeconds = 1.0f; | 43 const float kPrepaintingWindowTimeSeconds = 1.0f; |
31 const float kBackflingGuardDistancePixels = 314.0f; | 44 const float kBackflingGuardDistancePixels = 314.0f; |
32 | 45 |
33 if (prio.time_to_visible_in_seconds == 0) | 46 if (prio.time_to_visible_in_seconds == 0) |
34 return NOW_BIN; | 47 return NOW_BIN; |
35 | 48 |
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
299 | 312 |
300 if (!client_->ShouldForceTileUploadsRequiredForActivationToComplete()) | 313 if (!client_->ShouldForceTileUploadsRequiredForActivationToComplete()) |
301 return; | 314 return; |
302 | 315 |
303 TileSet initialized_tiles; | 316 TileSet initialized_tiles; |
304 for (TileSet::iterator it = | 317 for (TileSet::iterator it = |
305 tiles_that_need_to_be_initialized_for_activation_.begin(); | 318 tiles_that_need_to_be_initialized_for_activation_.begin(); |
306 it != tiles_that_need_to_be_initialized_for_activation_.end(); | 319 it != tiles_that_need_to_be_initialized_for_activation_.end(); |
307 ++it) { | 320 ++it) { |
308 Tile* tile = *it; | 321 Tile* tile = *it; |
309 if (!tile->managed_state().raster_task.is_null() && | 322 ManagedTileState& mts = tile->managed_state(); |
310 !tile->tile_version().forced_upload_) { | |
311 if (!raster_worker_pool_->ForceUploadToComplete( | |
312 tile->managed_state().raster_task)) | |
313 continue; | |
314 | 323 |
315 // Setting |forced_upload_| to true makes this tile ready to draw. | 324 for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) { |
316 tile->tile_version().forced_upload_ = true; | 325 ManagedTileState::TileVersion& pending_version = |
317 initialized_tiles.insert(tile); | 326 mts.tile_versions[mode]; |
| 327 if (!pending_version.raster_task_.is_null() && |
| 328 !pending_version.forced_upload_) { |
| 329 if (!raster_worker_pool_->ForceUploadToComplete( |
| 330 pending_version.raster_task_)) { |
| 331 continue; |
| 332 } |
| 333 // Setting |forced_upload_| to true makes this tile version |
| 334 // ready to draw. |
| 335 pending_version.forced_upload_ = true; |
| 336 initialized_tiles.insert(tile); |
| 337 break; |
| 338 } |
318 } | 339 } |
319 } | 340 } |
320 | 341 |
321 for (TileSet::iterator it = initialized_tiles.begin(); | 342 for (TileSet::iterator it = initialized_tiles.begin(); |
322 it != initialized_tiles.end(); | 343 it != initialized_tiles.end(); |
323 ++it) { | 344 ++it) { |
324 Tile* tile = *it; | 345 Tile* tile = *it; |
325 DidFinishTileInitialization(tile); | 346 DidFinishTileInitialization(tile); |
326 DCHECK(tile->tile_version().IsReadyToDraw()); | 347 DCHECK(tile->IsReadyToDraw(NULL)); |
327 } | 348 } |
328 } | 349 } |
329 | 350 |
330 void TileManager::GetMemoryStats( | 351 void TileManager::GetMemoryStats( |
331 size_t* memory_required_bytes, | 352 size_t* memory_required_bytes, |
332 size_t* memory_nice_to_have_bytes, | 353 size_t* memory_nice_to_have_bytes, |
333 size_t* memory_used_bytes) const { | 354 size_t* memory_used_bytes) const { |
334 *memory_required_bytes = 0; | 355 *memory_required_bytes = 0; |
335 *memory_nice_to_have_bytes = 0; | 356 *memory_nice_to_have_bytes = 0; |
336 *memory_used_bytes = resource_pool_->acquired_memory_usage_bytes(); | 357 *memory_used_bytes = resource_pool_->acquired_memory_usage_bytes(); |
337 for (TileVector::const_iterator it = tiles_.begin(); | 358 for (TileVector::const_iterator it = tiles_.begin(); |
338 it != tiles_.end(); | 359 it != tiles_.end(); |
339 ++it) { | 360 ++it) { |
340 const Tile* tile = *it; | 361 const Tile* tile = *it; |
341 if (!tile->tile_version().requires_resource()) | 362 const ManagedTileState& mts = tile->managed_state(); |
| 363 |
| 364 TileRasterMode mode; |
| 365 if (tile->IsReadyToDraw(&mode) && |
| 366 !mts.tile_versions[mode].requires_resource()) |
342 continue; | 367 continue; |
343 | 368 |
344 const ManagedTileState& mts = tile->managed_state(); | |
345 size_t tile_bytes = tile->bytes_consumed_if_allocated(); | 369 size_t tile_bytes = tile->bytes_consumed_if_allocated(); |
346 if (mts.gpu_memmgr_stats_bin == NOW_BIN) | 370 if (mts.gpu_memmgr_stats_bin == NOW_BIN) |
347 *memory_required_bytes += tile_bytes; | 371 *memory_required_bytes += tile_bytes; |
348 if (mts.gpu_memmgr_stats_bin != NEVER_BIN) | 372 if (mts.gpu_memmgr_stats_bin != NEVER_BIN) |
349 *memory_nice_to_have_bytes += tile_bytes; | 373 *memory_nice_to_have_bytes += tile_bytes; |
350 } | 374 } |
351 } | 375 } |
352 | 376 |
353 scoped_ptr<base::Value> TileManager::BasicStateAsValue() const { | 377 scoped_ptr<base::Value> TileManager::BasicStateAsValue() const { |
354 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); | 378 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
386 } | 410 } |
387 | 411 |
388 void TileManager::AddRequiredTileForActivation(Tile* tile) { | 412 void TileManager::AddRequiredTileForActivation(Tile* tile) { |
389 DCHECK(std::find(tiles_that_need_to_be_initialized_for_activation_.begin(), | 413 DCHECK(std::find(tiles_that_need_to_be_initialized_for_activation_.begin(), |
390 tiles_that_need_to_be_initialized_for_activation_.end(), | 414 tiles_that_need_to_be_initialized_for_activation_.end(), |
391 tile) == | 415 tile) == |
392 tiles_that_need_to_be_initialized_for_activation_.end()); | 416 tiles_that_need_to_be_initialized_for_activation_.end()); |
393 tiles_that_need_to_be_initialized_for_activation_.insert(tile); | 417 tiles_that_need_to_be_initialized_for_activation_.insert(tile); |
394 } | 418 } |
395 | 419 |
| 420 TileRasterMode TileManager::DetermineRasterMode(const Tile* tile) const { |
| 421 DCHECK(tile); |
| 422 DCHECK(tile->picture_pile()); |
| 423 |
| 424 TileRasterMode raster_mode; |
| 425 |
| 426 if (tile->managed_state().resolution == LOW_RESOLUTION) |
| 427 raster_mode = LOW_QUALITY_RASTER_MODE; |
| 428 else if (!tile->picture_pile()->can_use_lcd_text()) |
| 429 raster_mode = HIGH_QUALITY_NO_LCD_RASTER_MODE; |
| 430 else |
| 431 raster_mode = HIGH_QUALITY_RASTER_MODE; |
| 432 |
| 433 return raster_mode; |
| 434 } |
| 435 |
396 void TileManager::AssignGpuMemoryToTiles() { | 436 void TileManager::AssignGpuMemoryToTiles() { |
397 TRACE_EVENT0("cc", "TileManager::AssignGpuMemoryToTiles"); | 437 TRACE_EVENT0("cc", "TileManager::AssignGpuMemoryToTiles"); |
398 | 438 |
399 // Now give memory out to the tiles until we're out, and build | 439 // Now give memory out to the tiles until we're out, and build |
400 // the needs-to-be-rasterized queue. | 440 // the needs-to-be-rasterized queue. |
401 tiles_that_need_to_be_rasterized_.clear(); | 441 tiles_that_need_to_be_rasterized_.clear(); |
402 tiles_that_need_to_be_initialized_for_activation_.clear(); | 442 tiles_that_need_to_be_initialized_for_activation_.clear(); |
403 | 443 |
404 size_t bytes_releasable = 0; | 444 size_t bytes_releasable = 0; |
405 for (TileVector::const_iterator it = tiles_.begin(); | 445 for (TileVector::const_iterator it = tiles_.begin(); |
406 it != tiles_.end(); | 446 it != tiles_.end(); |
407 ++it) { | 447 ++it) { |
408 const Tile* tile = *it; | 448 const Tile* tile = *it; |
409 if (tile->tile_version().resource_) | 449 const ManagedTileState& mts = tile->managed_state(); |
410 bytes_releasable += tile->bytes_consumed_if_allocated(); | 450 for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) { |
| 451 if (mts.tile_versions[mode].resource_) |
| 452 bytes_releasable += tile->bytes_consumed_if_allocated(); |
| 453 } |
411 } | 454 } |
412 | 455 |
413 // Cast to prevent overflow. | 456 // Cast to prevent overflow. |
414 int64 bytes_available = | 457 int64 bytes_available = |
415 static_cast<int64>(bytes_releasable) + | 458 static_cast<int64>(bytes_releasable) + |
416 static_cast<int64>(global_state_.memory_limit_in_bytes) - | 459 static_cast<int64>(global_state_.memory_limit_in_bytes) - |
417 static_cast<int64>(resource_pool_->acquired_memory_usage_bytes()); | 460 static_cast<int64>(resource_pool_->acquired_memory_usage_bytes()); |
418 | 461 |
419 size_t bytes_allocatable = | 462 size_t bytes_allocatable = |
420 std::max(static_cast<int64>(0), bytes_available); | 463 std::max(static_cast<int64>(0), bytes_available); |
421 | 464 |
422 size_t bytes_that_exceeded_memory_budget_in_now_bin = 0; | 465 size_t bytes_that_exceeded_memory_budget_in_now_bin = 0; |
423 size_t bytes_left = bytes_allocatable; | 466 size_t bytes_left = bytes_allocatable; |
424 size_t bytes_oom_in_now_bin_on_pending_tree = 0; | 467 size_t bytes_oom_in_now_bin_on_pending_tree = 0; |
425 TileVector tiles_requiring_memory_but_oomed; | 468 TileVector tiles_requiring_memory_but_oomed; |
426 bool higher_priority_tile_oomed = false; | 469 bool higher_priority_tile_oomed = false; |
427 for (TileVector::iterator it = tiles_.begin(); | 470 for (TileVector::iterator it = tiles_.begin(); |
428 it != tiles_.end(); | 471 it != tiles_.end(); |
429 ++it) { | 472 ++it) { |
430 Tile* tile = *it; | 473 Tile* tile = *it; |
431 ManagedTileState& mts = tile->managed_state(); | 474 ManagedTileState& mts = tile->managed_state(); |
432 ManagedTileState::TileVersion& tile_version = tile->tile_version(); | 475 |
| 476 // Pick the better version out of the one we already set, |
| 477 // and the one that is required. |
| 478 mts.raster_mode = std::min(mts.raster_mode, DetermineRasterMode(tile)); |
| 479 |
| 480 ManagedTileState::TileVersion& tile_version = |
| 481 mts.tile_versions[mts.raster_mode]; |
433 | 482 |
434 // If this tile doesn't need a resource, then nothing to do. | 483 // If this tile doesn't need a resource, then nothing to do. |
435 if (!tile_version.requires_resource()) | 484 if (!tile_version.requires_resource()) |
436 continue; | 485 continue; |
437 | 486 |
438 // If the tile is not needed, free it up. | 487 // If the tile is not needed, free it up. |
439 if (mts.is_in_never_bin_on_both_trees()) { | 488 if (mts.is_in_never_bin_on_both_trees()) { |
440 FreeResourcesForTile(tile); | 489 FreeResourcesForTile(tile); |
441 continue; | 490 continue; |
442 } | 491 } |
443 | 492 |
444 size_t tile_bytes = 0; | 493 size_t tile_bytes = 0; |
445 | 494 |
446 // It costs to maintain a resource. | 495 // It costs to maintain a resource. |
447 if (tile_version.resource_) | 496 for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) { |
448 tile_bytes += tile->bytes_consumed_if_allocated(); | 497 if (mts.tile_versions[mode].resource_) |
| 498 tile_bytes += tile->bytes_consumed_if_allocated(); |
| 499 } |
449 | 500 |
450 // It will cost to allocate a resource. | 501 // If we don't have the required version, and it's not in flight |
451 // Note that this is separate from the above condition, | 502 // then we'll have to pay to create a new task. |
452 // so that it's clear why we're adding memory. | 503 if (!tile_version.resource_ && tile_version.raster_task_.is_null()) |
453 if (!tile_version.resource_ && mts.raster_task.is_null()) | |
454 tile_bytes += tile->bytes_consumed_if_allocated(); | 504 tile_bytes += tile->bytes_consumed_if_allocated(); |
455 | 505 |
456 // Tile is OOM. | 506 // Tile is OOM. |
457 if (tile_bytes > bytes_left) { | 507 if (tile_bytes > bytes_left) { |
458 tile->tile_version().set_rasterize_on_demand(); | 508 mts.tile_versions[mts.raster_mode].set_rasterize_on_demand(); |
459 if (mts.tree_bin[PENDING_TREE] == NOW_BIN) { | 509 if (mts.tree_bin[PENDING_TREE] == NOW_BIN) { |
460 tiles_requiring_memory_but_oomed.push_back(tile); | 510 tiles_requiring_memory_but_oomed.push_back(tile); |
461 bytes_oom_in_now_bin_on_pending_tree += tile_bytes; | 511 bytes_oom_in_now_bin_on_pending_tree += tile_bytes; |
462 } | 512 } |
463 FreeResourcesForTile(tile); | 513 FreeResourcesForTile(tile); |
464 higher_priority_tile_oomed = true; | 514 higher_priority_tile_oomed = true; |
465 continue; | 515 continue; |
466 } | 516 } |
467 | 517 |
468 tile_version.set_use_resource(); | 518 tile_version.set_use_resource(); |
469 bytes_left -= tile_bytes; | 519 bytes_left -= tile_bytes; |
470 | 520 |
471 // Tile shouldn't be rasterized if we've failed to assign | 521 // Tile shouldn't be rasterized if we've failed to assign |
472 // gpu memory to a higher priority tile. This is important for | 522 // gpu memory to a higher priority tile. This is important for |
473 // two reasons: | 523 // two reasons: |
474 // 1. Tile size should not impact raster priority. | 524 // 1. Tile size should not impact raster priority. |
475 // 2. Tile with unreleasable memory could otherwise incorrectly | 525 // 2. Tile with unreleasable memory could otherwise incorrectly |
476 // be added as it's not affected by |bytes_allocatable|. | 526 // be added as it's not affected by |bytes_allocatable|. |
477 if (higher_priority_tile_oomed) | 527 if (higher_priority_tile_oomed) |
478 continue; | 528 continue; |
479 | 529 |
480 if (!tile_version.resource_) | 530 if (!tile_version.resource_) |
481 tiles_that_need_to_be_rasterized_.push_back(tile); | 531 tiles_that_need_to_be_rasterized_.push_back(tile); |
482 | 532 |
483 if (!tile_version.resource_ && tile->required_for_activation()) | 533 if (!tile->IsReadyToDraw(NULL) && |
| 534 tile->required_for_activation()) { |
484 AddRequiredTileForActivation(tile); | 535 AddRequiredTileForActivation(tile); |
| 536 } |
485 } | 537 } |
486 | 538 |
487 // In OOM situation, we iterate tiles_, remove the memory for active tree | 539 // In OOM situation, we iterate tiles_, remove the memory for active tree |
488 // and not the now bin. And give them to bytes_oom_in_now_bin_on_pending_tree | 540 // and not the now bin. And give them to bytes_oom_in_now_bin_on_pending_tree |
489 if (!tiles_requiring_memory_but_oomed.empty()) { | 541 if (!tiles_requiring_memory_but_oomed.empty()) { |
490 size_t bytes_freed = 0; | 542 size_t bytes_freed = 0; |
491 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { | 543 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { |
492 Tile* tile = *it; | 544 Tile* tile = *it; |
493 ManagedTileState& mts = tile->managed_state(); | 545 ManagedTileState& mts = tile->managed_state(); |
494 ManagedTileState::TileVersion& tile_version = tile->tile_version(); | 546 if (mts.tree_bin[PENDING_TREE] == NEVER_BIN && |
495 if (tile_version.resource_ && | |
496 mts.tree_bin[PENDING_TREE] == NEVER_BIN && | |
497 mts.tree_bin[ACTIVE_TREE] != NOW_BIN) { | 547 mts.tree_bin[ACTIVE_TREE] != NOW_BIN) { |
498 DCHECK(!tile->required_for_activation()); | 548 size_t bytes_that_can_be_freed = 0; |
499 FreeResourcesForTile(tile); | 549 for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) { |
500 tile_version.set_rasterize_on_demand(); | 550 ManagedTileState::TileVersion& tile_version = |
501 bytes_freed += tile->bytes_consumed_if_allocated(); | 551 mts.tile_versions[mode]; |
502 TileVector::iterator it = std::find( | 552 if (tile_version.resource_) { |
503 tiles_that_need_to_be_rasterized_.begin(), | 553 DCHECK(!tile->required_for_activation()); |
504 tiles_that_need_to_be_rasterized_.end(), | 554 bytes_that_can_be_freed += tile->bytes_consumed_if_allocated(); |
505 tile); | 555 } |
506 if (it != tiles_that_need_to_be_rasterized_.end()) | 556 } |
507 tiles_that_need_to_be_rasterized_.erase(it); | 557 |
508 if (bytes_oom_in_now_bin_on_pending_tree <= bytes_freed) | 558 if (bytes_that_can_be_freed > 0) { |
509 break; | 559 FreeResourcesForTile(tile); |
| 560 bytes_freed += bytes_that_can_be_freed; |
| 561 mts.tile_versions[mts.raster_mode].set_rasterize_on_demand(); |
| 562 TileVector::iterator it = std::find( |
| 563 tiles_that_need_to_be_rasterized_.begin(), |
| 564 tiles_that_need_to_be_rasterized_.end(), |
| 565 tile); |
| 566 if (it != tiles_that_need_to_be_rasterized_.end()) |
| 567 tiles_that_need_to_be_rasterized_.erase(it); |
| 568 } |
510 } | 569 } |
| 570 |
| 571 if (bytes_oom_in_now_bin_on_pending_tree <= bytes_freed) |
| 572 break; |
511 } | 573 } |
512 | 574 |
513 for (TileVector::iterator it = tiles_requiring_memory_but_oomed.begin(); | 575 for (TileVector::iterator it = tiles_requiring_memory_but_oomed.begin(); |
514 it != tiles_requiring_memory_but_oomed.end() && bytes_freed > 0; | 576 it != tiles_requiring_memory_but_oomed.end() && bytes_freed > 0; |
515 ++it) { | 577 ++it) { |
516 Tile* tile = *it; | 578 Tile* tile = *it; |
| 579 ManagedTileState& mts = tile->managed_state(); |
517 size_t bytes_needed = tile->bytes_consumed_if_allocated(); | 580 size_t bytes_needed = tile->bytes_consumed_if_allocated(); |
518 if (bytes_needed > bytes_freed) | 581 if (bytes_needed > bytes_freed) |
519 continue; | 582 continue; |
520 tile->tile_version().set_use_resource(); | 583 mts.tile_versions[mts.raster_mode].set_use_resource(); |
521 bytes_freed -= bytes_needed; | 584 bytes_freed -= bytes_needed; |
522 tiles_that_need_to_be_rasterized_.push_back(tile); | 585 tiles_that_need_to_be_rasterized_.push_back(tile); |
523 if (tile->required_for_activation()) | 586 if (tile->required_for_activation()) |
524 AddRequiredTileForActivation(tile); | 587 AddRequiredTileForActivation(tile); |
525 } | 588 } |
526 } | 589 } |
527 | 590 |
528 ever_exceeded_memory_budget_ |= | 591 ever_exceeded_memory_budget_ |= |
529 bytes_that_exceeded_memory_budget_in_now_bin > 0; | 592 bytes_that_exceeded_memory_budget_in_now_bin > 0; |
530 if (ever_exceeded_memory_budget_) { | 593 if (ever_exceeded_memory_budget_) { |
531 TRACE_COUNTER_ID2("cc", "over_memory_budget", this, | 594 TRACE_COUNTER_ID2("cc", "over_memory_budget", this, |
532 "budget", global_state_.memory_limit_in_bytes, | 595 "budget", global_state_.memory_limit_in_bytes, |
533 "over", bytes_that_exceeded_memory_budget_in_now_bin); | 596 "over", bytes_that_exceeded_memory_budget_in_now_bin); |
534 } | 597 } |
535 memory_stats_from_last_assign_.total_budget_in_bytes = | 598 memory_stats_from_last_assign_.total_budget_in_bytes = |
536 global_state_.memory_limit_in_bytes; | 599 global_state_.memory_limit_in_bytes; |
537 memory_stats_from_last_assign_.bytes_allocated = | 600 memory_stats_from_last_assign_.bytes_allocated = |
538 bytes_allocatable - bytes_left; | 601 bytes_allocatable - bytes_left; |
539 memory_stats_from_last_assign_.bytes_unreleasable = | 602 memory_stats_from_last_assign_.bytes_unreleasable = |
540 bytes_allocatable - bytes_releasable; | 603 bytes_allocatable - bytes_releasable; |
541 memory_stats_from_last_assign_.bytes_over = | 604 memory_stats_from_last_assign_.bytes_over = |
542 bytes_that_exceeded_memory_budget_in_now_bin; | 605 bytes_that_exceeded_memory_budget_in_now_bin; |
543 } | 606 } |
544 | 607 |
| 608 void TileManager::FreeResourceForTile(Tile* tile, TileRasterMode mode) { |
| 609 ManagedTileState& mts = tile->managed_state(); |
| 610 if (mts.tile_versions[mode].resource_) { |
| 611 resource_pool_->ReleaseResource( |
| 612 mts.tile_versions[mode].resource_.Pass()); |
| 613 } |
| 614 mts.tile_versions[mode].resource_id_ = 0; |
| 615 mts.tile_versions[mode].forced_upload_ = false; |
| 616 } |
| 617 |
545 void TileManager::FreeResourcesForTile(Tile* tile) { | 618 void TileManager::FreeResourcesForTile(Tile* tile) { |
546 tile->tile_version().resource_id_ = 0; | 619 for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) { |
547 tile->tile_version().forced_upload_ = false; | 620 FreeResourceForTile(tile, static_cast<TileRasterMode>(mode)); |
548 if (tile->tile_version().resource_) { | |
549 resource_pool_->ReleaseResource( | |
550 tile->tile_version().resource_.Pass()); | |
551 } | 621 } |
552 } | 622 } |
553 | 623 |
| 624 void TileManager::FreeUnusedResourcesForTile(Tile* tile) { |
| 625 TileRasterMode used_mode; |
| 626 bool version_is_used = tile->IsReadyToDraw(&used_mode); |
| 627 for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) { |
| 628 if (!version_is_used || mode != used_mode) |
| 629 FreeResourceForTile(tile, static_cast<TileRasterMode>(mode)); |
| 630 } |
| 631 } |
| 632 |
554 void TileManager::ScheduleTasks() { | 633 void TileManager::ScheduleTasks() { |
555 TRACE_EVENT0("cc", "TileManager::ScheduleTasks"); | 634 TRACE_EVENT0("cc", "TileManager::ScheduleTasks"); |
556 RasterWorkerPool::RasterTask::Queue tasks; | 635 RasterWorkerPool::RasterTask::Queue tasks; |
557 PixelRefSet decoded_images; | 636 PixelRefSet decoded_images; |
558 | 637 |
559 // Build a new task queue containing all task currently needed. Tasks | 638 // Build a new task queue containing all task currently needed. Tasks |
560 // are added in order of priority, highest priority task first. | 639 // are added in order of priority, highest priority task first. |
561 for (TileVector::iterator it = tiles_that_need_to_be_rasterized_.begin(); | 640 for (TileVector::iterator it = tiles_that_need_to_be_rasterized_.begin(); |
562 it != tiles_that_need_to_be_rasterized_.end(); | 641 it != tiles_that_need_to_be_rasterized_.end(); |
563 ++it) { | 642 ++it) { |
564 Tile* tile = *it; | 643 Tile* tile = *it; |
565 ManagedTileState& mts = tile->managed_state(); | 644 ManagedTileState& mts = tile->managed_state(); |
| 645 ManagedTileState::TileVersion& tile_version = |
| 646 mts.tile_versions[mts.raster_mode]; |
566 | 647 |
567 DCHECK(tile->tile_version().requires_resource()); | 648 DCHECK(tile_version.requires_resource()); |
568 DCHECK(!tile->tile_version().resource_); | 649 DCHECK(!tile_version.resource_); |
569 | 650 |
570 // Create raster task for this tile if necessary. | 651 if (tile_version.raster_task_.is_null()) |
571 if (mts.raster_task.is_null()) | 652 tile_version.raster_task_ = CreateRasterTask(tile, &decoded_images); |
572 mts.raster_task = CreateRasterTask(tile, &decoded_images); | |
573 | 653 |
574 // Finally append raster task. | 654 tasks.Append(tile_version.raster_task_); |
575 tasks.Append(mts.raster_task); | |
576 } | 655 } |
577 | 656 |
578 // Schedule running of |tasks|. This replaces any previously | 657 // Schedule running of |tasks|. This replaces any previously |
579 // scheduled tasks and effectively cancels all tasks not present | 658 // scheduled tasks and effectively cancels all tasks not present |
580 // in |tasks|. | 659 // in |tasks|. |
581 raster_worker_pool_->ScheduleTasks(&tasks); | 660 raster_worker_pool_->ScheduleTasks(&tasks); |
582 } | 661 } |
583 | 662 |
584 RasterWorkerPool::Task TileManager::CreateImageDecodeTask( | 663 RasterWorkerPool::Task TileManager::CreateImageDecodeTask( |
585 Tile* tile, skia::LazyPixelRef* pixel_ref) { | 664 Tile* tile, skia::LazyPixelRef* pixel_ref) { |
(...skipping 21 matching lines...) Expand all Loading... |
607 TileManager::RasterTaskMetadata TileManager::GetRasterTaskMetadata( | 686 TileManager::RasterTaskMetadata TileManager::GetRasterTaskMetadata( |
608 const Tile& tile) const { | 687 const Tile& tile) const { |
609 RasterTaskMetadata metadata; | 688 RasterTaskMetadata metadata; |
610 const ManagedTileState& mts = tile.managed_state(); | 689 const ManagedTileState& mts = tile.managed_state(); |
611 metadata.is_tile_in_pending_tree_now_bin = | 690 metadata.is_tile_in_pending_tree_now_bin = |
612 mts.tree_bin[PENDING_TREE] == NOW_BIN; | 691 mts.tree_bin[PENDING_TREE] == NOW_BIN; |
613 metadata.tile_resolution = mts.resolution; | 692 metadata.tile_resolution = mts.resolution; |
614 metadata.layer_id = tile.layer_id(); | 693 metadata.layer_id = tile.layer_id(); |
615 metadata.tile_id = &tile; | 694 metadata.tile_id = &tile; |
616 metadata.source_frame_number = tile.source_frame_number(); | 695 metadata.source_frame_number = tile.source_frame_number(); |
| 696 metadata.raster_mode = mts.raster_mode; |
617 return metadata; | 697 return metadata; |
618 } | 698 } |
619 | 699 |
620 RasterWorkerPool::RasterTask TileManager::CreateRasterTask( | 700 RasterWorkerPool::RasterTask TileManager::CreateRasterTask( |
621 Tile* tile, | 701 Tile* tile, |
622 PixelRefSet* decoded_images) { | 702 PixelRefSet* decoded_images) { |
623 TRACE_EVENT0("cc", "TileManager::CreateRasterTask"); | 703 TRACE_EVENT0("cc", "TileManager::CreateRasterTask"); |
624 | 704 |
| 705 ManagedTileState& mts = tile->managed_state(); |
| 706 |
625 scoped_ptr<ResourcePool::Resource> resource = | 707 scoped_ptr<ResourcePool::Resource> resource = |
626 resource_pool_->AcquireResource( | 708 resource_pool_->AcquireResource( |
627 tile->tile_size_.size(), | 709 tile->tile_size_.size(), |
628 tile->tile_version().resource_format_); | 710 mts.tile_versions[mts.raster_mode].resource_format_); |
629 const Resource* const_resource = resource.get(); | 711 const Resource* const_resource = resource.get(); |
630 | 712 |
631 DCHECK(!tile->tile_version().resource_id_); | 713 DCHECK(!mts.tile_versions[mts.raster_mode].resource_id_); |
632 DCHECK(!tile->tile_version().forced_upload_); | 714 DCHECK(!mts.tile_versions[mts.raster_mode].forced_upload_); |
633 tile->tile_version().resource_id_ = resource->id(); | 715 mts.tile_versions[mts.raster_mode].resource_id_ = resource->id(); |
634 | 716 |
635 PicturePileImpl::Analysis* analysis = new PicturePileImpl::Analysis; | 717 PicturePileImpl::Analysis* analysis = new PicturePileImpl::Analysis; |
636 | 718 |
637 // Create and queue all image decode tasks that this tile depends on. | 719 // Create and queue all image decode tasks that this tile depends on. |
638 RasterWorkerPool::Task::Set decode_tasks; | 720 RasterWorkerPool::Task::Set decode_tasks; |
639 for (PicturePileImpl::PixelRefIterator iter(tile->content_rect(), | 721 for (PicturePileImpl::PixelRefIterator iter(tile->content_rect(), |
640 tile->contents_scale(), | 722 tile->contents_scale(), |
641 tile->picture_pile()); | 723 tile->picture_pile()); |
642 iter; ++iter) { | 724 iter; ++iter) { |
643 skia::LazyPixelRef* pixel_ref = *iter; | 725 skia::LazyPixelRef* pixel_ref = *iter; |
(...skipping 16 matching lines...) Expand all Loading... |
660 continue; | 742 continue; |
661 } | 743 } |
662 | 744 |
663 // Create and append new image decode task for this pixel ref. | 745 // Create and append new image decode task for this pixel ref. |
664 RasterWorkerPool::Task decode_task = CreateImageDecodeTask( | 746 RasterWorkerPool::Task decode_task = CreateImageDecodeTask( |
665 tile, pixel_ref); | 747 tile, pixel_ref); |
666 decode_tasks.Insert(decode_task); | 748 decode_tasks.Insert(decode_task); |
667 pending_decode_tasks_[id] = decode_task; | 749 pending_decode_tasks_[id] = decode_task; |
668 } | 750 } |
669 | 751 |
| 752 RasterTaskMetadata metadata = GetRasterTaskMetadata(*tile); |
670 return RasterWorkerPool::RasterTask( | 753 return RasterWorkerPool::RasterTask( |
671 tile->picture_pile(), | 754 tile->picture_pile(), |
672 const_resource, | 755 const_resource, |
673 base::Bind(&TileManager::RunAnalyzeAndRasterTask, | 756 base::Bind(&TileManager::RunAnalyzeAndRasterTask, |
674 base::Bind(&TileManager::RunAnalyzeTask, | 757 base::Bind(&TileManager::RunAnalyzeTask, |
675 analysis, | 758 analysis, |
676 tile->content_rect(), | 759 tile->content_rect(), |
677 tile->contents_scale(), | 760 tile->contents_scale(), |
678 use_color_estimator_, | 761 use_color_estimator_, |
679 GetRasterTaskMetadata(*tile), | 762 metadata, |
680 rendering_stats_instrumentation_), | 763 rendering_stats_instrumentation_), |
681 base::Bind(&TileManager::RunRasterTask, | 764 base::Bind(&TileManager::RunRasterTask, |
682 analysis, | 765 analysis, |
683 tile->content_rect(), | 766 tile->content_rect(), |
684 tile->contents_scale(), | 767 tile->contents_scale(), |
685 GetRasterTaskMetadata(*tile), | 768 metadata, |
686 rendering_stats_instrumentation_)), | 769 rendering_stats_instrumentation_)), |
687 base::Bind(&TileManager::OnRasterTaskCompleted, | 770 base::Bind(&TileManager::OnRasterTaskCompleted, |
688 base::Unretained(this), | 771 base::Unretained(this), |
689 make_scoped_refptr(tile), | 772 make_scoped_refptr(tile), |
690 base::Passed(&resource), | 773 base::Passed(&resource), |
691 base::Owned(analysis)), | 774 base::Owned(analysis), |
| 775 metadata.raster_mode), |
692 &decode_tasks); | 776 &decode_tasks); |
693 } | 777 } |
694 | 778 |
695 void TileManager::OnRasterTaskCompleted( | 779 void TileManager::OnRasterTaskCompleted( |
696 scoped_refptr<Tile> tile, | 780 scoped_refptr<Tile> tile, |
697 scoped_ptr<ResourcePool::Resource> resource, | 781 scoped_ptr<ResourcePool::Resource> resource, |
698 PicturePileImpl::Analysis* analysis, | 782 PicturePileImpl::Analysis* analysis, |
| 783 TileRasterMode raster_mode, |
699 bool was_canceled) { | 784 bool was_canceled) { |
700 TRACE_EVENT1("cc", "TileManager::OnRasterTaskCompleted", | 785 TRACE_EVENT1("cc", "TileManager::OnRasterTaskCompleted", |
701 "was_canceled", was_canceled); | 786 "was_canceled", was_canceled); |
702 | 787 |
703 ManagedTileState& mts = tile->managed_state(); | 788 ManagedTileState& mts = tile->managed_state(); |
704 DCHECK(!mts.raster_task.is_null()); | 789 ManagedTileState::TileVersion& tile_version = |
705 mts.raster_task.Reset(); | 790 mts.tile_versions[raster_mode]; |
| 791 DCHECK(!tile_version.raster_task_.is_null()); |
| 792 tile_version.raster_task_.Reset(); |
706 | 793 |
707 if (was_canceled) { | 794 if (was_canceled) { |
708 resource_pool_->ReleaseResource(resource.Pass()); | 795 resource_pool_->ReleaseResource(resource.Pass()); |
709 return; | 796 return; |
710 } | 797 } |
711 | 798 |
712 mts.picture_pile_analysis = *analysis; | 799 mts.picture_pile_analysis = *analysis; |
713 mts.picture_pile_analyzed = true; | 800 mts.picture_pile_analyzed = true; |
714 | 801 |
715 if (analysis->is_solid_color) { | 802 if (analysis->is_solid_color) { |
716 tile->tile_version().set_solid_color(analysis->solid_color); | 803 tile_version.set_solid_color(analysis->solid_color); |
717 resource_pool_->ReleaseResource(resource.Pass()); | 804 resource_pool_->ReleaseResource(resource.Pass()); |
718 } else { | 805 } else { |
719 tile->tile_version().resource_ = resource.Pass(); | 806 tile_version.resource_ = resource.Pass(); |
720 tile->tile_version().forced_upload_ = false; | 807 tile_version.forced_upload_ = false; |
721 } | 808 } |
722 | 809 |
| 810 FreeUnusedResourcesForTile(tile.get()); |
| 811 |
723 DidFinishTileInitialization(tile.get()); | 812 DidFinishTileInitialization(tile.get()); |
724 } | 813 } |
725 | 814 |
726 void TileManager::DidFinishTileInitialization(Tile* tile) { | 815 void TileManager::DidFinishTileInitialization(Tile* tile) { |
727 if (tile->priority(ACTIVE_TREE).distance_to_visible_in_pixels == 0) | 816 if (tile->priority(ACTIVE_TREE).distance_to_visible_in_pixels == 0) |
728 did_initialize_visible_tile_ = true; | 817 did_initialize_visible_tile_ = true; |
729 if (tile->required_for_activation()) { | 818 if (tile->required_for_activation()) { |
730 // It's possible that a tile required for activation is not in this list | 819 // It's possible that a tile required for activation is not in this list |
731 // if it was marked as being required after being dispatched for | 820 // if it was marked as being required after being dispatched for |
732 // rasterization but before AssignGPUMemory was called again. | 821 // rasterization but before AssignGPUMemory was called again. |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
796 analysis->is_solid_color &= use_color_estimator; | 885 analysis->is_solid_color &= use_color_estimator; |
797 } | 886 } |
798 | 887 |
799 scoped_ptr<base::Value> TileManager::RasterTaskMetadata::AsValue() const { | 888 scoped_ptr<base::Value> TileManager::RasterTaskMetadata::AsValue() const { |
800 scoped_ptr<base::DictionaryValue> res(new base::DictionaryValue()); | 889 scoped_ptr<base::DictionaryValue> res(new base::DictionaryValue()); |
801 res->Set("tile_id", TracedValue::CreateIDRef(tile_id).release()); | 890 res->Set("tile_id", TracedValue::CreateIDRef(tile_id).release()); |
802 res->SetBoolean("is_tile_in_pending_tree_now_bin", | 891 res->SetBoolean("is_tile_in_pending_tree_now_bin", |
803 is_tile_in_pending_tree_now_bin); | 892 is_tile_in_pending_tree_now_bin); |
804 res->Set("resolution", TileResolutionAsValue(tile_resolution).release()); | 893 res->Set("resolution", TileResolutionAsValue(tile_resolution).release()); |
805 res->SetInteger("source_frame_number", source_frame_number); | 894 res->SetInteger("source_frame_number", source_frame_number); |
| 895 res->SetInteger("raster_mode", raster_mode); |
806 return res.PassAs<base::Value>(); | 896 return res.PassAs<base::Value>(); |
807 } | 897 } |
808 | 898 |
809 // static | 899 // static |
810 bool TileManager::RunRasterTask( | 900 bool TileManager::RunRasterTask( |
811 PicturePileImpl::Analysis* analysis, | 901 PicturePileImpl::Analysis* analysis, |
812 gfx::Rect rect, | 902 gfx::Rect rect, |
813 float contents_scale, | 903 float contents_scale, |
814 const RasterTaskMetadata& metadata, | 904 const RasterTaskMetadata& metadata, |
815 RenderingStatsInstrumentation* stats_instrumentation, | 905 RenderingStatsInstrumentation* stats_instrumentation, |
816 SkDevice* device, | 906 SkDevice* device, |
817 PicturePileImpl* picture_pile) { | 907 PicturePileImpl* picture_pile) { |
818 TRACE_EVENT1( | 908 TRACE_EVENT1( |
819 "cc", "TileManager::RunRasterTask", | 909 "cc", "TileManager::RunRasterTask", |
820 "metadata", TracedValue::FromValue(metadata.AsValue().release())); | 910 "metadata", TracedValue::FromValue(metadata.AsValue().release())); |
821 devtools_instrumentation::ScopedLayerTask raster_task( | 911 devtools_instrumentation::ScopedLayerTask raster_task( |
822 devtools_instrumentation::kRasterTask, metadata.layer_id); | 912 devtools_instrumentation::kRasterTask, metadata.layer_id); |
823 | 913 |
824 DCHECK(picture_pile); | 914 DCHECK(picture_pile); |
825 DCHECK(analysis); | 915 DCHECK(analysis); |
826 DCHECK(device); | 916 DCHECK(device); |
827 | 917 |
828 if (analysis->is_solid_color) | 918 if (analysis->is_solid_color) |
829 return false; | 919 return false; |
830 | 920 |
831 SkCanvas canvas(device); | 921 SkCanvas canvas(device); |
832 | 922 |
| 923 skia::RefPtr<SkDrawFilter> draw_filter; |
| 924 switch (metadata.raster_mode) { |
| 925 case LOW_QUALITY_RASTER_MODE: |
| 926 draw_filter = skia::AdoptRef(new skia::PaintSimplifier); |
| 927 break; |
| 928 case HIGH_QUALITY_NO_LCD_RASTER_MODE: |
| 929 draw_filter = skia::AdoptRef(new DisableLCDTextFilter); |
| 930 break; |
| 931 case HIGH_QUALITY_RASTER_MODE: |
| 932 break; |
| 933 case NUM_RASTER_MODES: |
| 934 default: |
| 935 NOTREACHED(); |
| 936 } |
| 937 |
| 938 canvas.setDrawFilter(draw_filter.get()); |
| 939 |
833 if (stats_instrumentation->record_rendering_stats()) { | 940 if (stats_instrumentation->record_rendering_stats()) { |
834 PicturePileImpl::RasterStats raster_stats; | 941 PicturePileImpl::RasterStats raster_stats; |
835 picture_pile->RasterToBitmap(&canvas, rect, contents_scale, &raster_stats); | 942 picture_pile->RasterToBitmap(&canvas, rect, contents_scale, &raster_stats); |
836 stats_instrumentation->AddRaster( | 943 stats_instrumentation->AddRaster( |
837 raster_stats.total_rasterize_time, | 944 raster_stats.total_rasterize_time, |
838 raster_stats.best_rasterize_time, | 945 raster_stats.best_rasterize_time, |
839 raster_stats.total_pixels_rasterized, | 946 raster_stats.total_pixels_rasterized, |
840 metadata.is_tile_in_pending_tree_now_bin); | 947 metadata.is_tile_in_pending_tree_now_bin); |
841 | 948 |
842 HISTOGRAM_CUSTOM_COUNTS( | 949 HISTOGRAM_CUSTOM_COUNTS( |
843 "Renderer4.PictureRasterTimeUS", | 950 "Renderer4.PictureRasterTimeUS", |
844 raster_stats.total_rasterize_time.InMicroseconds(), | 951 raster_stats.total_rasterize_time.InMicroseconds(), |
845 0, | 952 0, |
846 100000, | 953 100000, |
847 100); | 954 100); |
848 } else { | 955 } else { |
849 picture_pile->RasterToBitmap(&canvas, rect, contents_scale, NULL); | 956 picture_pile->RasterToBitmap(&canvas, rect, contents_scale, NULL); |
850 } | 957 } |
851 | 958 |
852 return true; | 959 return true; |
853 } | 960 } |
854 | 961 |
855 } // namespace cc | 962 } // namespace cc |
OLD | NEW |