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(); |
342 continue; | |
343 | 363 |
344 const ManagedTileState& mts = tile->managed_state(); | 364 TileRasterMode mode; |
365 if (tile->IsReadyToDraw(&mode)) { | |
366 if (!mts.tile_versions[mode].requires_resource()) | |
reveman
2013/06/06 06:02:02
use one if statement with && instead
vmpstr
2013/06/06 15:20:22
Done.
| |
367 continue; | |
368 } | |
369 | |
345 size_t tile_bytes = tile->bytes_consumed_if_allocated(); | 370 size_t tile_bytes = tile->bytes_consumed_if_allocated(); |
346 if (mts.gpu_memmgr_stats_bin == NOW_BIN) | 371 if (mts.gpu_memmgr_stats_bin == NOW_BIN) |
347 *memory_required_bytes += tile_bytes; | 372 *memory_required_bytes += tile_bytes; |
348 if (mts.gpu_memmgr_stats_bin != NEVER_BIN) | 373 if (mts.gpu_memmgr_stats_bin != NEVER_BIN) |
349 *memory_nice_to_have_bytes += tile_bytes; | 374 *memory_nice_to_have_bytes += tile_bytes; |
350 } | 375 } |
351 } | 376 } |
352 | 377 |
353 scoped_ptr<base::Value> TileManager::BasicStateAsValue() const { | 378 scoped_ptr<base::Value> TileManager::BasicStateAsValue() const { |
354 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); | 379 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
386 } | 411 } |
387 | 412 |
388 void TileManager::AddRequiredTileForActivation(Tile* tile) { | 413 void TileManager::AddRequiredTileForActivation(Tile* tile) { |
389 DCHECK(std::find(tiles_that_need_to_be_initialized_for_activation_.begin(), | 414 DCHECK(std::find(tiles_that_need_to_be_initialized_for_activation_.begin(), |
390 tiles_that_need_to_be_initialized_for_activation_.end(), | 415 tiles_that_need_to_be_initialized_for_activation_.end(), |
391 tile) == | 416 tile) == |
392 tiles_that_need_to_be_initialized_for_activation_.end()); | 417 tiles_that_need_to_be_initialized_for_activation_.end()); |
393 tiles_that_need_to_be_initialized_for_activation_.insert(tile); | 418 tiles_that_need_to_be_initialized_for_activation_.insert(tile); |
394 } | 419 } |
395 | 420 |
421 TileRasterMode TileManager::DetermineRasterMode(const Tile* tile) const { | |
422 DCHECK(tile); | |
423 DCHECK(tile->picture_pile()); | |
424 | |
425 TileRasterMode raster_mode; | |
426 | |
427 if (tile->managed_state().resolution == LOW_RESOLUTION) | |
428 raster_mode = LOW_QUALITY_RASTER_MODE; | |
429 else if (!tile->picture_pile()->can_use_lcd_text()) | |
430 raster_mode = HIGH_QUALITY_NO_LCD_RASTER_MODE; | |
431 else | |
432 raster_mode = HIGH_QUALITY_RASTER_MODE; | |
433 | |
434 return raster_mode; | |
435 } | |
436 | |
396 void TileManager::AssignGpuMemoryToTiles() { | 437 void TileManager::AssignGpuMemoryToTiles() { |
397 TRACE_EVENT0("cc", "TileManager::AssignGpuMemoryToTiles"); | 438 TRACE_EVENT0("cc", "TileManager::AssignGpuMemoryToTiles"); |
398 | 439 |
399 // Now give memory out to the tiles until we're out, and build | 440 // Now give memory out to the tiles until we're out, and build |
400 // the needs-to-be-rasterized queue. | 441 // the needs-to-be-rasterized queue. |
401 tiles_that_need_to_be_rasterized_.clear(); | 442 tiles_that_need_to_be_rasterized_.clear(); |
402 tiles_that_need_to_be_initialized_for_activation_.clear(); | 443 tiles_that_need_to_be_initialized_for_activation_.clear(); |
403 | 444 |
404 size_t bytes_releasable = 0; | 445 size_t bytes_releasable = 0; |
405 for (TileVector::const_iterator it = tiles_.begin(); | 446 for (TileVector::const_iterator it = tiles_.begin(); |
406 it != tiles_.end(); | 447 it != tiles_.end(); |
407 ++it) { | 448 ++it) { |
408 const Tile* tile = *it; | 449 const Tile* tile = *it; |
409 if (tile->tile_version().resource_) | 450 const ManagedTileState& mts = tile->managed_state(); |
410 bytes_releasable += tile->bytes_consumed_if_allocated(); | 451 for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) { |
452 if (mts.tile_versions[mode].resource_) | |
453 bytes_releasable += tile->bytes_consumed_if_allocated(); | |
454 } | |
411 } | 455 } |
412 | 456 |
413 // Cast to prevent overflow. | 457 // Cast to prevent overflow. |
414 int64 bytes_available = | 458 int64 bytes_available = |
415 static_cast<int64>(bytes_releasable) + | 459 static_cast<int64>(bytes_releasable) + |
416 static_cast<int64>(global_state_.memory_limit_in_bytes) - | 460 static_cast<int64>(global_state_.memory_limit_in_bytes) - |
417 static_cast<int64>(resource_pool_->acquired_memory_usage_bytes()); | 461 static_cast<int64>(resource_pool_->acquired_memory_usage_bytes()); |
418 | 462 |
419 size_t bytes_allocatable = | 463 size_t bytes_allocatable = |
420 std::max(static_cast<int64>(0), bytes_available); | 464 std::max(static_cast<int64>(0), bytes_available); |
421 | 465 |
422 size_t bytes_that_exceeded_memory_budget_in_now_bin = 0; | 466 size_t bytes_that_exceeded_memory_budget_in_now_bin = 0; |
423 size_t bytes_left = bytes_allocatable; | 467 size_t bytes_left = bytes_allocatable; |
424 size_t bytes_oom_in_now_bin_on_pending_tree = 0; | 468 size_t bytes_oom_in_now_bin_on_pending_tree = 0; |
425 TileVector tiles_requiring_memory_but_oomed; | 469 TileVector tiles_requiring_memory_but_oomed; |
426 bool higher_priority_tile_oomed = false; | 470 bool higher_priority_tile_oomed = false; |
427 for (TileVector::iterator it = tiles_.begin(); | 471 for (TileVector::iterator it = tiles_.begin(); |
428 it != tiles_.end(); | 472 it != tiles_.end(); |
429 ++it) { | 473 ++it) { |
430 Tile* tile = *it; | 474 Tile* tile = *it; |
431 ManagedTileState& mts = tile->managed_state(); | 475 ManagedTileState& mts = tile->managed_state(); |
432 ManagedTileState::TileVersion& tile_version = tile->tile_version(); | 476 |
477 TileRasterMode ready_mode; | |
478 TileRasterMode desired_mode = DetermineRasterMode(tile); | |
479 if (tile->IsReadyToDraw(&ready_mode) && (ready_mode > desired_mode)) | |
vmpstr
2013/06/06 02:08:35
That should read ready_mode < desired_mode. I'll f
reveman
2013/06/06 06:02:02
why IsReadyToDraw? If you prevent new tasks from b
vmpstr
2013/06/06 15:20:22
Good point, changed this to min
| |
480 desired_mode = ready_mode; | |
481 | |
482 mts.raster_mode = desired_mode; | |
483 ManagedTileState::TileVersion& tile_version = | |
484 mts.tile_versions[mts.raster_mode]; | |
433 | 485 |
434 // If this tile doesn't need a resource, then nothing to do. | 486 // If this tile doesn't need a resource, then nothing to do. |
435 if (!tile_version.requires_resource()) | 487 if (!tile_version.requires_resource()) |
436 continue; | 488 continue; |
437 | 489 |
438 // If the tile is not needed, free it up. | 490 // If the tile is not needed, free it up. |
439 if (mts.is_in_never_bin_on_both_trees()) { | 491 if (mts.is_in_never_bin_on_both_trees()) { |
440 FreeResourcesForTile(tile); | 492 FreeResourcesForTile(tile); |
441 continue; | 493 continue; |
442 } | 494 } |
443 | 495 |
444 size_t tile_bytes = 0; | 496 size_t tile_bytes = 0; |
445 | 497 |
446 // It costs to maintain a resource. | 498 // It costs to maintain a resource. |
447 if (tile_version.resource_) | 499 for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) { |
448 tile_bytes += tile->bytes_consumed_if_allocated(); | 500 if (mts.tile_versions[mode].resource_) |
501 tile_bytes += tile->bytes_consumed_if_allocated(); | |
502 } | |
449 | 503 |
450 // It will cost to allocate a resource. | 504 // If we don't have the required version, and it's not in flight |
451 // Note that this is separate from the above condition, | 505 // then we'll have to pay to create a new task. |
452 // so that it's clear why we're adding memory. | 506 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(); | 507 tile_bytes += tile->bytes_consumed_if_allocated(); |
455 | 508 |
456 // Tile is OOM. | 509 // Tile is OOM. |
457 if (tile_bytes > bytes_left) { | 510 if (tile_bytes > bytes_left) { |
458 tile->tile_version().set_rasterize_on_demand(); | 511 mts.tile_versions[mts.raster_mode].set_rasterize_on_demand(); |
459 if (mts.tree_bin[PENDING_TREE] == NOW_BIN) { | 512 if (mts.tree_bin[PENDING_TREE] == NOW_BIN) { |
460 tiles_requiring_memory_but_oomed.push_back(tile); | 513 tiles_requiring_memory_but_oomed.push_back(tile); |
461 bytes_oom_in_now_bin_on_pending_tree += tile_bytes; | 514 bytes_oom_in_now_bin_on_pending_tree += tile_bytes; |
462 } | 515 } |
463 FreeResourcesForTile(tile); | 516 FreeResourcesForTile(tile); |
464 higher_priority_tile_oomed = true; | 517 higher_priority_tile_oomed = true; |
465 continue; | 518 continue; |
466 } | 519 } |
467 | 520 |
468 tile_version.set_use_resource(); | 521 tile_version.set_use_resource(); |
469 bytes_left -= tile_bytes; | 522 bytes_left -= tile_bytes; |
470 | 523 |
471 // Tile shouldn't be rasterized if we've failed to assign | 524 // Tile shouldn't be rasterized if we've failed to assign |
472 // gpu memory to a higher priority tile. This is important for | 525 // gpu memory to a higher priority tile. This is important for |
473 // two reasons: | 526 // two reasons: |
474 // 1. Tile size should not impact raster priority. | 527 // 1. Tile size should not impact raster priority. |
475 // 2. Tile with unreleasable memory could otherwise incorrectly | 528 // 2. Tile with unreleasable memory could otherwise incorrectly |
476 // be added as it's not affected by |bytes_allocatable|. | 529 // be added as it's not affected by |bytes_allocatable|. |
477 if (higher_priority_tile_oomed) | 530 if (higher_priority_tile_oomed) |
478 continue; | 531 continue; |
479 | 532 |
480 if (!tile_version.resource_) | 533 if (!tile_version.resource_) |
481 tiles_that_need_to_be_rasterized_.push_back(tile); | 534 tiles_that_need_to_be_rasterized_.push_back(tile); |
482 | 535 |
483 if (!tile_version.resource_ && tile->required_for_activation()) | 536 if (!tile->IsReadyToDraw(NULL) && |
537 tile->required_for_activation()) { | |
484 AddRequiredTileForActivation(tile); | 538 AddRequiredTileForActivation(tile); |
539 } | |
485 } | 540 } |
486 | 541 |
487 // In OOM situation, we iterate tiles_, remove the memory for active tree | 542 // 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 | 543 // 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()) { | 544 if (!tiles_requiring_memory_but_oomed.empty()) { |
490 size_t bytes_freed = 0; | 545 size_t bytes_freed = 0; |
491 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { | 546 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { |
492 Tile* tile = *it; | 547 Tile* tile = *it; |
493 ManagedTileState& mts = tile->managed_state(); | 548 ManagedTileState& mts = tile->managed_state(); |
494 ManagedTileState::TileVersion& tile_version = tile->tile_version(); | 549 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) { | 550 mts.tree_bin[ACTIVE_TREE] != NOW_BIN) { |
498 DCHECK(!tile->required_for_activation()); | 551 bool has_memory = false; |
499 FreeResourcesForTile(tile); | 552 for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) { |
500 tile_version.set_rasterize_on_demand(); | 553 ManagedTileState::TileVersion& tile_version = |
501 bytes_freed += tile->bytes_consumed_if_allocated(); | 554 mts.tile_versions[mode]; |
502 TileVector::iterator it = std::find( | 555 if (tile_version.resource_) { |
503 tiles_that_need_to_be_rasterized_.begin(), | 556 DCHECK(!tile->required_for_activation()); |
504 tiles_that_need_to_be_rasterized_.end(), | 557 bytes_freed += tile->bytes_consumed_if_allocated(); |
505 tile); | 558 has_memory = true; |
506 if (it != tiles_that_need_to_be_rasterized_.end()) | 559 } |
507 tiles_that_need_to_be_rasterized_.erase(it); | 560 } |
508 if (bytes_oom_in_now_bin_on_pending_tree <= bytes_freed) | 561 |
509 break; | 562 if (has_memory) { |
reveman
2013/06/06 06:02:02
is this conditional necessary?
vmpstr
2013/06/06 15:20:22
I changed this a bit. I prefer to still keep this
| |
563 FreeResourcesForTile(tile); | |
564 mts.tile_versions[mts.raster_mode].set_rasterize_on_demand(); | |
565 TileVector::iterator it = std::find( | |
566 tiles_that_need_to_be_rasterized_.begin(), | |
567 tiles_that_need_to_be_rasterized_.end(), | |
568 tile); | |
569 if (it != tiles_that_need_to_be_rasterized_.end()) | |
570 tiles_that_need_to_be_rasterized_.erase(it); | |
571 } | |
510 } | 572 } |
573 | |
574 if (bytes_oom_in_now_bin_on_pending_tree <= bytes_freed) | |
575 break; | |
511 } | 576 } |
512 | 577 |
513 for (TileVector::iterator it = tiles_requiring_memory_but_oomed.begin(); | 578 for (TileVector::iterator it = tiles_requiring_memory_but_oomed.begin(); |
514 it != tiles_requiring_memory_but_oomed.end() && bytes_freed > 0; | 579 it != tiles_requiring_memory_but_oomed.end() && bytes_freed > 0; |
515 ++it) { | 580 ++it) { |
516 Tile* tile = *it; | 581 Tile* tile = *it; |
582 ManagedTileState& mts = tile->managed_state(); | |
517 size_t bytes_needed = tile->bytes_consumed_if_allocated(); | 583 size_t bytes_needed = tile->bytes_consumed_if_allocated(); |
518 if (bytes_needed > bytes_freed) | 584 if (bytes_needed > bytes_freed) |
519 continue; | 585 continue; |
520 tile->tile_version().set_use_resource(); | 586 mts.tile_versions[mts.raster_mode].set_use_resource(); |
521 bytes_freed -= bytes_needed; | 587 bytes_freed -= bytes_needed; |
522 tiles_that_need_to_be_rasterized_.push_back(tile); | 588 tiles_that_need_to_be_rasterized_.push_back(tile); |
523 if (tile->required_for_activation()) | 589 if (tile->required_for_activation()) |
524 AddRequiredTileForActivation(tile); | 590 AddRequiredTileForActivation(tile); |
525 } | 591 } |
526 } | 592 } |
527 | 593 |
528 ever_exceeded_memory_budget_ |= | 594 ever_exceeded_memory_budget_ |= |
529 bytes_that_exceeded_memory_budget_in_now_bin > 0; | 595 bytes_that_exceeded_memory_budget_in_now_bin > 0; |
530 if (ever_exceeded_memory_budget_) { | 596 if (ever_exceeded_memory_budget_) { |
531 TRACE_COUNTER_ID2("cc", "over_memory_budget", this, | 597 TRACE_COUNTER_ID2("cc", "over_memory_budget", this, |
532 "budget", global_state_.memory_limit_in_bytes, | 598 "budget", global_state_.memory_limit_in_bytes, |
533 "over", bytes_that_exceeded_memory_budget_in_now_bin); | 599 "over", bytes_that_exceeded_memory_budget_in_now_bin); |
534 } | 600 } |
535 memory_stats_from_last_assign_.total_budget_in_bytes = | 601 memory_stats_from_last_assign_.total_budget_in_bytes = |
536 global_state_.memory_limit_in_bytes; | 602 global_state_.memory_limit_in_bytes; |
537 memory_stats_from_last_assign_.bytes_allocated = | 603 memory_stats_from_last_assign_.bytes_allocated = |
538 bytes_allocatable - bytes_left; | 604 bytes_allocatable - bytes_left; |
539 memory_stats_from_last_assign_.bytes_unreleasable = | 605 memory_stats_from_last_assign_.bytes_unreleasable = |
540 bytes_allocatable - bytes_releasable; | 606 bytes_allocatable - bytes_releasable; |
541 memory_stats_from_last_assign_.bytes_over = | 607 memory_stats_from_last_assign_.bytes_over = |
542 bytes_that_exceeded_memory_budget_in_now_bin; | 608 bytes_that_exceeded_memory_budget_in_now_bin; |
543 } | 609 } |
544 | 610 |
545 void TileManager::FreeResourcesForTile(Tile* tile) { | 611 void TileManager::FreeResourcesForTile(Tile* tile) { |
546 if (tile->tile_version().resource_) { | 612 ManagedTileState& mts = tile->managed_state(); |
547 resource_pool_->ReleaseResource( | 613 for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) { |
548 tile->tile_version().resource_.Pass()); | 614 if (mts.tile_versions[mode].resource_) { |
615 resource_pool_->ReleaseResource( | |
616 mts.tile_versions[mode].resource_.Pass()); | |
617 } | |
reveman
2013/06/06 06:02:02
maybe move the inner part of this loop to a FreeRe
vmpstr
2013/06/06 15:20:22
Done.
| |
549 } | 618 } |
550 } | 619 } |
551 | 620 |
621 void TileManager::FreeUnusedResourcesForTile(Tile* tile) { | |
622 ManagedTileState& mts = tile->managed_state(); | |
623 TileRasterMode used_mode; | |
624 bool version_is_used = tile->IsReadyToDraw(&used_mode); | |
625 for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) { | |
626 if ((!version_is_used || mode != used_mode) && | |
627 mts.tile_versions[mode].resource_) { | |
628 resource_pool_->ReleaseResource( | |
629 mts.tile_versions[mode].resource_.Pass()); | |
630 } | |
631 } | |
632 } | |
633 | |
552 void TileManager::ScheduleTasks() { | 634 void TileManager::ScheduleTasks() { |
553 TRACE_EVENT0("cc", "TileManager::ScheduleTasks"); | 635 TRACE_EVENT0("cc", "TileManager::ScheduleTasks"); |
554 RasterWorkerPool::RasterTask::Queue tasks; | 636 RasterWorkerPool::RasterTask::Queue tasks; |
555 | 637 |
556 // Build a new task queue containing all task currently needed. Tasks | 638 // Build a new task queue containing all task currently needed. Tasks |
557 // are added in order of priority, highest priority task first. | 639 // are added in order of priority, highest priority task first. |
558 for (TileVector::iterator it = tiles_that_need_to_be_rasterized_.begin(); | 640 for (TileVector::iterator it = tiles_that_need_to_be_rasterized_.begin(); |
559 it != tiles_that_need_to_be_rasterized_.end(); | 641 it != tiles_that_need_to_be_rasterized_.end(); |
560 ++it) { | 642 ++it) { |
561 Tile* tile = *it; | 643 Tile* tile = *it; |
562 ManagedTileState& mts = tile->managed_state(); | 644 ManagedTileState& mts = tile->managed_state(); |
645 ManagedTileState::TileVersion& tile_version = | |
646 mts.tile_versions[mts.raster_mode]; | |
563 | 647 |
564 DCHECK(tile->tile_version().requires_resource()); | 648 DCHECK(tile_version.requires_resource()); |
565 DCHECK(!tile->tile_version().resource_); | |
reveman
2013/06/06 06:02:02
Why has this DCHECK been removed?
vmpstr
2013/06/06 15:20:22
Whoops. Added it back.
| |
566 | 649 |
567 // Create raster task for this tile if necessary. | 650 if (tile_version.raster_task_.is_null()) |
568 if (mts.raster_task.is_null()) | 651 tile_version.raster_task_ = CreateRasterTask(tile); |
569 mts.raster_task = CreateRasterTask(tile); | |
570 | 652 |
571 // Finally append raster task. | 653 tasks.Append(tile_version.raster_task_); |
572 tasks.Append(mts.raster_task); | |
573 } | 654 } |
574 | 655 |
575 // Schedule running of |tasks|. This replaces any previously | 656 // Schedule running of |tasks|. This replaces any previously |
576 // scheduled tasks and effectively cancels all tasks not present | 657 // scheduled tasks and effectively cancels all tasks not present |
577 // in |tasks|. | 658 // in |tasks|. |
578 raster_worker_pool_->ScheduleTasks(&tasks); | 659 raster_worker_pool_->ScheduleTasks(&tasks); |
579 } | 660 } |
580 | 661 |
581 RasterWorkerPool::Task TileManager::CreateImageDecodeTask( | 662 RasterWorkerPool::Task TileManager::CreateImageDecodeTask( |
582 Tile* tile, skia::LazyPixelRef* pixel_ref) { | 663 Tile* tile, skia::LazyPixelRef* pixel_ref) { |
(...skipping 21 matching lines...) Expand all Loading... | |
604 TileManager::RasterTaskMetadata TileManager::GetRasterTaskMetadata( | 685 TileManager::RasterTaskMetadata TileManager::GetRasterTaskMetadata( |
605 const Tile& tile) const { | 686 const Tile& tile) const { |
606 RasterTaskMetadata metadata; | 687 RasterTaskMetadata metadata; |
607 const ManagedTileState& mts = tile.managed_state(); | 688 const ManagedTileState& mts = tile.managed_state(); |
608 metadata.is_tile_in_pending_tree_now_bin = | 689 metadata.is_tile_in_pending_tree_now_bin = |
609 mts.tree_bin[PENDING_TREE] == NOW_BIN; | 690 mts.tree_bin[PENDING_TREE] == NOW_BIN; |
610 metadata.tile_resolution = mts.resolution; | 691 metadata.tile_resolution = mts.resolution; |
611 metadata.layer_id = tile.layer_id(); | 692 metadata.layer_id = tile.layer_id(); |
612 metadata.tile_id = &tile; | 693 metadata.tile_id = &tile; |
613 metadata.source_frame_number = tile.source_frame_number(); | 694 metadata.source_frame_number = tile.source_frame_number(); |
695 metadata.raster_mode = mts.raster_mode; | |
614 return metadata; | 696 return metadata; |
615 } | 697 } |
616 | 698 |
617 RasterWorkerPool::RasterTask TileManager::CreateRasterTask(Tile* tile) { | 699 RasterWorkerPool::RasterTask TileManager::CreateRasterTask(Tile* tile) { |
618 TRACE_EVENT0("cc", "TileManager::CreateRasterTask"); | 700 TRACE_EVENT0("cc", "TileManager::CreateRasterTask"); |
619 | 701 |
702 ManagedTileState& mts = tile->managed_state(); | |
703 | |
620 scoped_ptr<ResourcePool::Resource> resource = | 704 scoped_ptr<ResourcePool::Resource> resource = |
621 resource_pool_->AcquireResource( | 705 resource_pool_->AcquireResource( |
622 tile->tile_size_.size(), | 706 tile->tile_size_.size(), |
623 tile->tile_version().resource_format_); | 707 mts.tile_versions[mts.raster_mode].resource_format_); |
624 const Resource* const_resource = resource.get(); | 708 const Resource* const_resource = resource.get(); |
625 | 709 |
626 tile->tile_version().resource_id_ = resource->id(); | 710 mts.tile_versions[mts.raster_mode].resource_id_ = resource->id(); |
627 | 711 |
628 PicturePileImpl::Analysis* analysis = new PicturePileImpl::Analysis; | 712 PicturePileImpl::Analysis* analysis = new PicturePileImpl::Analysis; |
629 | 713 |
630 // Create and queue all image decode tasks that this tile depends on. | 714 // Create and queue all image decode tasks that this tile depends on. |
631 RasterWorkerPool::Task::Set decode_tasks; | 715 RasterWorkerPool::Task::Set decode_tasks; |
632 for (PicturePileImpl::PixelRefIterator iter(tile->content_rect(), | 716 for (PicturePileImpl::PixelRefIterator iter(tile->content_rect(), |
633 tile->contents_scale(), | 717 tile->contents_scale(), |
634 tile->picture_pile()); | 718 tile->picture_pile()); |
635 iter; ++iter) { | 719 iter; ++iter) { |
636 skia::LazyPixelRef* pixel_ref = *iter; | 720 skia::LazyPixelRef* pixel_ref = *iter; |
(...skipping 12 matching lines...) Expand all Loading... | |
649 continue; | 733 continue; |
650 } | 734 } |
651 | 735 |
652 // Create and append new image decode task for this pixel ref. | 736 // Create and append new image decode task for this pixel ref. |
653 RasterWorkerPool::Task decode_task = CreateImageDecodeTask( | 737 RasterWorkerPool::Task decode_task = CreateImageDecodeTask( |
654 tile, pixel_ref); | 738 tile, pixel_ref); |
655 decode_tasks.Insert(decode_task); | 739 decode_tasks.Insert(decode_task); |
656 pending_decode_tasks_[id] = decode_task; | 740 pending_decode_tasks_[id] = decode_task; |
657 } | 741 } |
658 | 742 |
743 RasterTaskMetadata metadata = GetRasterTaskMetadata(*tile); | |
659 return RasterWorkerPool::RasterTask( | 744 return RasterWorkerPool::RasterTask( |
660 tile->picture_pile(), | 745 tile->picture_pile(), |
661 const_resource, | 746 const_resource, |
662 base::Bind(&TileManager::RunAnalyzeAndRasterTask, | 747 base::Bind(&TileManager::RunAnalyzeAndRasterTask, |
663 base::Bind(&TileManager::RunAnalyzeTask, | 748 base::Bind(&TileManager::RunAnalyzeTask, |
664 analysis, | 749 analysis, |
665 tile->content_rect(), | 750 tile->content_rect(), |
666 tile->contents_scale(), | 751 tile->contents_scale(), |
667 use_color_estimator_, | 752 use_color_estimator_, |
668 GetRasterTaskMetadata(*tile), | 753 metadata, |
669 rendering_stats_instrumentation_), | 754 rendering_stats_instrumentation_), |
670 base::Bind(&TileManager::RunRasterTask, | 755 base::Bind(&TileManager::RunRasterTask, |
671 analysis, | 756 analysis, |
672 tile->content_rect(), | 757 tile->content_rect(), |
673 tile->contents_scale(), | 758 tile->contents_scale(), |
674 GetRasterTaskMetadata(*tile), | 759 metadata, |
675 rendering_stats_instrumentation_)), | 760 rendering_stats_instrumentation_)), |
676 base::Bind(&TileManager::OnRasterTaskCompleted, | 761 base::Bind(&TileManager::OnRasterTaskCompleted, |
677 base::Unretained(this), | 762 base::Unretained(this), |
678 make_scoped_refptr(tile), | 763 make_scoped_refptr(tile), |
679 base::Passed(&resource), | 764 base::Passed(&resource), |
680 base::Owned(analysis)), | 765 base::Owned(analysis), |
766 metadata.raster_mode), | |
681 &decode_tasks); | 767 &decode_tasks); |
682 } | 768 } |
683 | 769 |
684 void TileManager::OnRasterTaskCompleted( | 770 void TileManager::OnRasterTaskCompleted( |
685 scoped_refptr<Tile> tile, | 771 scoped_refptr<Tile> tile, |
686 scoped_ptr<ResourcePool::Resource> resource, | 772 scoped_ptr<ResourcePool::Resource> resource, |
687 PicturePileImpl::Analysis* analysis, | 773 PicturePileImpl::Analysis* analysis, |
774 TileRasterMode raster_mode, | |
688 bool was_canceled) { | 775 bool was_canceled) { |
689 TRACE_EVENT1("cc", "TileManager::OnRasterTaskCompleted", | 776 TRACE_EVENT1("cc", "TileManager::OnRasterTaskCompleted", |
690 "was_canceled", was_canceled); | 777 "was_canceled", was_canceled); |
691 | 778 |
692 ManagedTileState& mts = tile->managed_state(); | 779 ManagedTileState& mts = tile->managed_state(); |
693 DCHECK(!mts.raster_task.is_null()); | 780 ManagedTileState::TileVersion& tile_version = |
694 mts.raster_task.Reset(); | 781 mts.tile_versions[raster_mode]; |
782 DCHECK(!mts.tile_versions[raster_mode].raster_task_.is_null()); | |
783 tile_version.raster_task_.Reset(); | |
784 tile_version.forced_upload_ = false; | |
695 | 785 |
696 if (was_canceled) { | 786 if (was_canceled) { |
697 resource_pool_->ReleaseResource(resource.Pass()); | 787 resource_pool_->ReleaseResource(resource.Pass()); |
698 return; | 788 return; |
699 } | 789 } |
700 | 790 |
701 mts.picture_pile_analysis = *analysis; | 791 mts.picture_pile_analysis = *analysis; |
702 mts.picture_pile_analyzed = true; | 792 mts.picture_pile_analyzed = true; |
703 | 793 |
704 if (analysis->is_solid_color) { | 794 if (analysis->is_solid_color) { |
705 tile->tile_version().set_solid_color(analysis->solid_color); | 795 tile_version.set_solid_color(analysis->solid_color); |
706 resource_pool_->ReleaseResource(resource.Pass()); | 796 resource_pool_->ReleaseResource(resource.Pass()); |
707 } else { | 797 } else { |
708 tile->tile_version().resource_ = resource.Pass(); | 798 tile_version.resource_ = resource.Pass(); |
709 } | 799 } |
710 | 800 |
801 FreeUnusedResourcesForTile(tile.get()); | |
802 | |
711 DidFinishTileInitialization(tile.get()); | 803 DidFinishTileInitialization(tile.get()); |
712 } | 804 } |
713 | 805 |
714 void TileManager::DidFinishTileInitialization(Tile* tile) { | 806 void TileManager::DidFinishTileInitialization(Tile* tile) { |
715 if (tile->priority(ACTIVE_TREE).distance_to_visible_in_pixels == 0) | 807 if (tile->priority(ACTIVE_TREE).distance_to_visible_in_pixels == 0) |
716 did_initialize_visible_tile_ = true; | 808 did_initialize_visible_tile_ = true; |
717 if (tile->required_for_activation()) { | 809 if (tile->required_for_activation()) { |
718 // It's possible that a tile required for activation is not in this list | 810 // It's possible that a tile required for activation is not in this list |
719 // if it was marked as being required after being dispatched for | 811 // if it was marked as being required after being dispatched for |
720 // rasterization but before AssignGPUMemory was called again. | 812 // rasterization but before AssignGPUMemory was called again. |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
784 analysis->is_solid_color &= use_color_estimator; | 876 analysis->is_solid_color &= use_color_estimator; |
785 } | 877 } |
786 | 878 |
787 scoped_ptr<base::Value> TileManager::RasterTaskMetadata::AsValue() const { | 879 scoped_ptr<base::Value> TileManager::RasterTaskMetadata::AsValue() const { |
788 scoped_ptr<base::DictionaryValue> res(new base::DictionaryValue()); | 880 scoped_ptr<base::DictionaryValue> res(new base::DictionaryValue()); |
789 res->Set("tile_id", TracedValue::CreateIDRef(tile_id).release()); | 881 res->Set("tile_id", TracedValue::CreateIDRef(tile_id).release()); |
790 res->SetBoolean("is_tile_in_pending_tree_now_bin", | 882 res->SetBoolean("is_tile_in_pending_tree_now_bin", |
791 is_tile_in_pending_tree_now_bin); | 883 is_tile_in_pending_tree_now_bin); |
792 res->Set("resolution", TileResolutionAsValue(tile_resolution).release()); | 884 res->Set("resolution", TileResolutionAsValue(tile_resolution).release()); |
793 res->SetInteger("source_frame_number", source_frame_number); | 885 res->SetInteger("source_frame_number", source_frame_number); |
886 res->SetInteger("raster_mode", raster_mode); | |
794 return res.PassAs<base::Value>(); | 887 return res.PassAs<base::Value>(); |
795 } | 888 } |
796 | 889 |
797 // static | 890 // static |
798 bool TileManager::RunRasterTask( | 891 bool TileManager::RunRasterTask( |
799 PicturePileImpl::Analysis* analysis, | 892 PicturePileImpl::Analysis* analysis, |
800 gfx::Rect rect, | 893 gfx::Rect rect, |
801 float contents_scale, | 894 float contents_scale, |
802 const RasterTaskMetadata& metadata, | 895 const RasterTaskMetadata& metadata, |
803 RenderingStatsInstrumentation* stats_instrumentation, | 896 RenderingStatsInstrumentation* stats_instrumentation, |
804 SkDevice* device, | 897 SkDevice* device, |
805 PicturePileImpl* picture_pile) { | 898 PicturePileImpl* picture_pile) { |
806 TRACE_EVENT1( | 899 TRACE_EVENT1( |
807 "cc", "TileManager::RunRasterTask", | 900 "cc", "TileManager::RunRasterTask", |
808 "metadata", TracedValue::FromValue(metadata.AsValue().release())); | 901 "metadata", TracedValue::FromValue(metadata.AsValue().release())); |
809 devtools_instrumentation::ScopedLayerTask raster_task( | 902 devtools_instrumentation::ScopedLayerTask raster_task( |
810 devtools_instrumentation::kRasterTask, metadata.layer_id); | 903 devtools_instrumentation::kRasterTask, metadata.layer_id); |
811 | 904 |
812 DCHECK(picture_pile); | 905 DCHECK(picture_pile); |
813 DCHECK(analysis); | 906 DCHECK(analysis); |
814 DCHECK(device); | 907 DCHECK(device); |
815 | 908 |
816 if (analysis->is_solid_color) | 909 if (analysis->is_solid_color) |
817 return false; | 910 return false; |
818 | 911 |
819 SkCanvas canvas(device); | 912 SkCanvas canvas(device); |
820 | 913 |
914 skia::RefPtr<SkDrawFilter> draw_filter; | |
915 switch (metadata.raster_mode) { | |
916 case LOW_QUALITY_RASTER_MODE: | |
917 draw_filter = skia::AdoptRef(new skia::PaintSimplifier); | |
918 break; | |
919 case HIGH_QUALITY_NO_LCD_RASTER_MODE: | |
920 draw_filter = skia::AdoptRef(new DisableLCDTextFilter); | |
921 break; | |
922 case HIGH_QUALITY_RASTER_MODE: | |
923 break; | |
924 case NUM_RASTER_MODES: | |
925 default: | |
926 NOTREACHED(); | |
927 } | |
928 | |
929 canvas.setDrawFilter(draw_filter.get()); | |
930 | |
821 if (stats_instrumentation->record_rendering_stats()) { | 931 if (stats_instrumentation->record_rendering_stats()) { |
822 PicturePileImpl::RasterStats raster_stats; | 932 PicturePileImpl::RasterStats raster_stats; |
823 picture_pile->RasterToBitmap(&canvas, rect, contents_scale, &raster_stats); | 933 picture_pile->RasterToBitmap(&canvas, rect, contents_scale, &raster_stats); |
824 stats_instrumentation->AddRaster( | 934 stats_instrumentation->AddRaster( |
825 raster_stats.total_rasterize_time, | 935 raster_stats.total_rasterize_time, |
826 raster_stats.best_rasterize_time, | 936 raster_stats.best_rasterize_time, |
827 raster_stats.total_pixels_rasterized, | 937 raster_stats.total_pixels_rasterized, |
828 metadata.is_tile_in_pending_tree_now_bin); | 938 metadata.is_tile_in_pending_tree_now_bin); |
829 | 939 |
830 HISTOGRAM_CUSTOM_COUNTS( | 940 HISTOGRAM_CUSTOM_COUNTS( |
831 "Renderer4.PictureRasterTimeUS", | 941 "Renderer4.PictureRasterTimeUS", |
832 raster_stats.total_rasterize_time.InMicroseconds(), | 942 raster_stats.total_rasterize_time.InMicroseconds(), |
833 0, | 943 0, |
834 100000, | 944 100000, |
835 100); | 945 100); |
836 } else { | 946 } else { |
837 picture_pile->RasterToBitmap(&canvas, rect, contents_scale, NULL); | 947 picture_pile->RasterToBitmap(&canvas, rect, contents_scale, NULL); |
838 } | 948 } |
839 | 949 |
840 return true; | 950 return true; |
841 } | 951 } |
842 | 952 |
843 } // namespace cc | 953 } // namespace cc |
OLD | NEW |