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

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

Issue 15995033: cc: Low quality support for low res tiles (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase fix Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « cc/resources/tile_manager.h ('k') | cc/test/skia_common.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 The Chromium Authors. All rights reserved. 1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "cc/resources/tile_manager.h" 5 #include "cc/resources/tile_manager.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <string> 8 #include <string>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « cc/resources/tile_manager.h ('k') | cc/test/skia_common.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698