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

Side by Side Diff: cc/picture_layer_tiling.cc

Issue 12280021: cc: Don't discard tiles unless memory is low (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 10 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 | Annotate | Revision Log
« no previous file with comments | « cc/picture_layer_tiling.h ('k') | cc/tile_manager.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/picture_layer_tiling.h" 5 #include "cc/picture_layer_tiling.h"
6 6
7 #include "base/debug/trace_event.h" 7 #include "base/debug/trace_event.h"
8 #include "cc/math_util.h" 8 #include "cc/math_util.h"
9 #include "ui/gfx/point_conversions.h" 9 #include "ui/gfx/point_conversions.h"
10 #include "ui/gfx/rect_conversions.h" 10 #include "ui/gfx/rect_conversions.h"
11 #include "ui/gfx/safe_integer_conversions.h" 11 #include "ui/gfx/safe_integer_conversions.h"
12 #include "ui/gfx/size_conversions.h" 12 #include "ui/gfx/size_conversions.h"
13 13
14 namespace cc { 14 namespace cc {
15 15
16 scoped_ptr<PictureLayerTiling> PictureLayerTiling::Create( 16 scoped_ptr<PictureLayerTiling> PictureLayerTiling::Create(
17 float contents_scale) { 17 float contents_scale) {
18 return make_scoped_ptr(new PictureLayerTiling(contents_scale)); 18 return make_scoped_ptr(new PictureLayerTiling(contents_scale));
19 } 19 }
20 20
21 scoped_ptr<PictureLayerTiling> PictureLayerTiling::Clone() const { 21 scoped_ptr<PictureLayerTiling> PictureLayerTiling::Clone() const {
22 return make_scoped_ptr(new PictureLayerTiling(*this)); 22 PictureLayerTiling* new_tiling = new PictureLayerTiling(*this);
23
24 // The live_tiles_ list was shallow-copied, restore it explicitly.
25 new_tiling->live_tiles_.clear();
26 for (TileList::const_iterator it = live_tiles_.begin();
27 it != live_tiles_.end(); ++it) {
28 const TileHandle* tile_handle = *it;
29 TileMap::iterator find = new_tiling->tiles_.find(tile_handle->key());
30 DCHECK(find != new_tiling->tiles_.end());
31 TileHandle* new_tile_handle = &find->second;
32 new_tile_handle->AddToLiveTileList(new_tiling);
33 }
34
35 return make_scoped_ptr(new_tiling);
23 } 36 }
24 37
25 PictureLayerTiling::PictureLayerTiling(float contents_scale) 38 PictureLayerTiling::PictureLayerTiling(float contents_scale)
26 : client_(NULL), 39 : client_(NULL),
27 contents_scale_(contents_scale), 40 contents_scale_(contents_scale),
28 tiling_data_(gfx::Size(), gfx::Size(), true), 41 tiling_data_(gfx::Size(), gfx::Size(), true),
29 resolution_(NON_IDEAL_RESOLUTION), 42 resolution_(NON_IDEAL_RESOLUTION),
30 last_source_frame_number_(0), 43 last_source_frame_number_(0),
31 last_impl_frame_time_(0) { 44 last_impl_frame_time_(0) {
32 } 45 }
33 46
34 PictureLayerTiling::~PictureLayerTiling() { 47 PictureLayerTiling::~PictureLayerTiling() {
48 tiles_.clear();
49 DCHECK(live_tiles_.empty());
35 } 50 }
36 51
37 void PictureLayerTiling::SetClient(PictureLayerTilingClient* client) { 52 void PictureLayerTiling::SetClient(PictureLayerTilingClient* client) {
38 client_ = client; 53 client_ = client;
39 } 54 }
40 55
41 gfx::Rect PictureLayerTiling::ContentRect() const { 56 gfx::Rect PictureLayerTiling::ContentRect() const {
42 return gfx::Rect(tiling_data_.total_size()); 57 return gfx::Rect(tiling_data_.total_size());
43 } 58 }
44 59
45 gfx::SizeF PictureLayerTiling::ContentSizeF() const { 60 gfx::SizeF PictureLayerTiling::ContentSizeF() const {
46 return gfx::ScaleSize(layer_bounds_, contents_scale_); 61 return gfx::ScaleSize(layer_bounds_, contents_scale_);
47 } 62 }
48 63
49 Tile* PictureLayerTiling::TileAt(int i, int j) const { 64 Tile* PictureLayerTiling::TileAt(int i, int j) const {
50 TileMap::const_iterator iter = tiles_.find(TileMapKey(i, j)); 65 TileMap::const_iterator iter = tiles_.find(TileMapKey(i, j));
51 if (iter == tiles_.end()) 66 if (iter == tiles_.end())
52 return NULL; 67 return NULL;
53 return iter->second.tile(); 68 return iter->second.tile();
54 } 69 }
55 70
56 void PictureLayerTiling::CreateTile(int i, int j) { 71 void PictureLayerTiling::CreateTile(int i, int j) {
57 gfx::Rect tile_rect = tiling_data_.TileBoundsWithBorder(i, j); 72 gfx::Rect tile_rect = tiling_data_.TileBoundsWithBorder(i, j);
58 tile_rect.set_size(tiling_data_.max_texture_size()); 73 tile_rect.set_size(tiling_data_.max_texture_size());
59 TileMapKey key(i, j); 74 TileMapKey key(i, j);
60 DCHECK(tiles_.find(key) == tiles_.end()); 75 DCHECK(tiles_.find(key) == tiles_.end());
61 scoped_refptr<Tile> tile = client_->CreateTile(this, tile_rect); 76 scoped_refptr<Tile> tile = client_->CreateTile(this, tile_rect);
62 if (tile) 77 if (tile)
63 tiles_.insert(make_pair(key, TileHandle(tile))); 78 tiles_.insert(make_pair(key, TileHandle(key, tile)));
64 } 79 }
65 80
66 Region PictureLayerTiling::OpaqueRegionInContentRect( 81 Region PictureLayerTiling::OpaqueRegionInContentRect(
67 const gfx::Rect& content_rect) const { 82 const gfx::Rect& content_rect) const {
68 Region opaque_region; 83 Region opaque_region;
69 // TODO(enne): implement me 84 // TODO(enne): implement me
70 return opaque_region; 85 return opaque_region;
71 } 86 }
72 87
73 void PictureLayerTiling::SetLayerBounds(gfx::Size layer_bounds) { 88 void PictureLayerTiling::SetLayerBounds(gfx::Size layer_bounds) {
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after
394 gfx::Rect inflated_rect = viewport_in_content_space; 409 gfx::Rect inflated_rect = viewport_in_content_space;
395 float adjusted_inset = TilePriority::kMaxDistanceInContentSpace / 410 float adjusted_inset = TilePriority::kMaxDistanceInContentSpace /
396 std::max(contents_scale_, 1.f); 411 std::max(contents_scale_, 1.f);
397 inflated_rect.Inset( 412 inflated_rect.Inset(
398 -adjusted_inset, 413 -adjusted_inset,
399 -adjusted_inset, 414 -adjusted_inset,
400 -adjusted_inset, 415 -adjusted_inset,
401 -adjusted_inset); 416 -adjusted_inset);
402 inflated_rect.Intersect(ContentRect()); 417 inflated_rect.Intersect(ContentRect());
403 418
404 // Iterate through all of the tiles that were live last frame but will 419 // Mark all tiles in the inflated rect as live.
405 // not be live this frame, and mark them as being dead. 420 for (TilingData::Iterator iter(&tiling_data_, inflated_rect);
406 for (TilingData::DifferenceIterator iter(&tiling_data_, 421 iter; ++iter) {
407 last_prioritized_rect_,
408 inflated_rect);
409 iter;
410 ++iter) {
411 TileMap::iterator find = tiles_.find(iter.index()); 422 TileMap::iterator find = tiles_.find(iter.index());
412 if (find == tiles_.end()) 423 if (find == tiles_.end())
413 continue; 424 continue;
425 TileHandle* tile_handle = &find->second;
426 tile_handle->set_should_be_live(true);
427 tile_handle->AddToLiveTileList(this);
428 }
414 429
415 TilePriority priority; 430 // Iterate through all of the tiles that were live last frame but will
416 DCHECK(!priority.is_live); 431 // not be live this frame, and mark them as being dead.
417 TileHandle* tile_handle = &find->second; 432 // TODO(ccameron): merge this loop with the loops below.
418 Tile* tile = tile_handle->tile(); 433 for (TileList::iterator it = live_tiles_.begin();
419 tile->set_priority(tree, priority); 434 it != live_tiles_.end(); ) {
420 tile_handle->UnregisterFromTileManager(); 435 TileHandle* tile_handle = *it;
436 TileList::iterator it_next = it;
437 it_next++;
438 if (!tile_handle->should_be_live() &&
439 !tile_handle->tile()->GetResourceId()) {
440 TilePriority priority;
441 DCHECK(!priority.is_live);
442 tile_handle->tile()->set_priority(tree, priority);
443 tile_handle->RemoveFromLiveTileList();
444 tile_handle->UnregisterFromTileManager();
445 } else {
446 tile_handle->RegisterWithTileManager();
447 // Mark the tile as not live for the next time through.
448 tile_handle->set_should_be_live(false);
449 }
450 it = it_next;
421 } 451 }
452
422 last_prioritized_rect_ = inflated_rect; 453 last_prioritized_rect_ = inflated_rect;
423 454
424 gfx::Rect view_rect(device_viewport); 455 gfx::Rect view_rect(device_viewport);
425 float current_scale = current_layer_contents_scale / contents_scale_; 456 float current_scale = current_layer_contents_scale / contents_scale_;
426 float last_scale = last_layer_contents_scale / contents_scale_; 457 float last_scale = last_layer_contents_scale / contents_scale_;
427 458
428 // Fast path tile priority calculation when both transforms are translations. 459 // Fast path tile priority calculation when both transforms are translations.
429 if (last_screen_transform.IsIdentityOrTranslation() && 460 if (last_screen_transform.IsIdentityOrTranslation() &&
430 current_screen_transform.IsIdentityOrTranslation()) 461 current_screen_transform.IsIdentityOrTranslation())
431 { 462 {
432 gfx::Vector2dF current_offset( 463 gfx::Vector2dF current_offset(
433 current_screen_transform.matrix().get(0, 3), 464 current_screen_transform.matrix().get(0, 3),
434 current_screen_transform.matrix().get(1, 3)); 465 current_screen_transform.matrix().get(1, 3));
435 gfx::Vector2dF last_offset( 466 gfx::Vector2dF last_offset(
436 last_screen_transform.matrix().get(0, 3), 467 last_screen_transform.matrix().get(0, 3),
437 last_screen_transform.matrix().get(1, 3)); 468 last_screen_transform.matrix().get(1, 3));
438 469
439 for (TilingData::Iterator iter(&tiling_data_, inflated_rect); 470 for (TileList::iterator it = live_tiles_.begin();
440 iter; ++iter) { 471 it != live_tiles_.end(); ++it) {
441 TileMap::iterator find = tiles_.find(iter.index()); 472 TileHandle* tile_handle = *it;
442 if (find == tiles_.end())
443 continue;
444 TileHandle* tile_handle = &find->second;
445 Tile* tile = tile_handle->tile(); 473 Tile* tile = tile_handle->tile();
446 tile_handle->RegisterWithTileManager();
447 474
448 gfx::Rect tile_bounds = 475 gfx::Rect tile_bounds =
449 tiling_data_.TileBounds(iter.index_x(), iter.index_y()); 476 tiling_data_.TileBounds(tile_handle->key().first,
477 tile_handle->key().second);
450 gfx::RectF current_screen_rect = gfx::ScaleRect( 478 gfx::RectF current_screen_rect = gfx::ScaleRect(
451 tile_bounds, 479 tile_bounds,
452 current_scale, 480 current_scale,
453 current_scale) + current_offset; 481 current_scale) + current_offset;
454 gfx::RectF last_screen_rect = gfx::ScaleRect( 482 gfx::RectF last_screen_rect = gfx::ScaleRect(
455 tile_bounds, 483 tile_bounds,
456 last_scale, 484 last_scale,
457 last_scale) + last_offset; 485 last_scale) + last_offset;
458 486
459 float distance_to_visible_in_pixels = 487 float distance_to_visible_in_pixels =
460 TilePriority::manhattanDistance(current_screen_rect, view_rect); 488 TilePriority::manhattanDistance(current_screen_rect, view_rect);
461 489
462 float time_to_visible_in_seconds = 490 float time_to_visible_in_seconds =
463 TilePriority::TimeForBoundsToIntersect( 491 TilePriority::TimeForBoundsToIntersect(
464 last_screen_rect, current_screen_rect, time_delta, view_rect); 492 last_screen_rect, current_screen_rect, time_delta, view_rect);
465 TilePriority priority( 493 TilePriority priority(
466 resolution_, 494 resolution_,
467 time_to_visible_in_seconds, 495 time_to_visible_in_seconds,
468 distance_to_visible_in_pixels); 496 distance_to_visible_in_pixels);
469 if (store_screen_space_quads_on_tiles) 497 if (store_screen_space_quads_on_tiles)
470 priority.set_current_screen_quad(gfx::QuadF(current_screen_rect)); 498 priority.set_current_screen_quad(gfx::QuadF(current_screen_rect));
471 tile->set_priority(tree, priority); 499 tile->set_priority(tree, priority);
472 } 500 }
473 } else { 501 } else {
474 for (TilingData::Iterator iter(&tiling_data_, inflated_rect); 502 for (TileList::iterator it = live_tiles_.begin();
475 iter; ++iter) { 503 it != live_tiles_.end(); ++it) {
476 TileMap::iterator find = tiles_.find(iter.index()); 504 TileHandle* tile_handle = *it;
477 if (find == tiles_.end())
478 continue;
479 TileHandle* tile_handle = &find->second;
480 Tile* tile = tile_handle->tile(); 505 Tile* tile = tile_handle->tile();
481 tile_handle->RegisterWithTileManager();
482 506
483 gfx::Rect tile_bounds = 507 gfx::Rect tile_bounds =
484 tiling_data_.TileBounds(iter.index_x(), iter.index_y()); 508 tiling_data_.TileBounds(tile_handle->key().first,
509 tile_handle->key().second);
485 gfx::RectF current_layer_content_rect = gfx::ScaleRect( 510 gfx::RectF current_layer_content_rect = gfx::ScaleRect(
486 tile_bounds, 511 tile_bounds,
487 current_scale, 512 current_scale,
488 current_scale); 513 current_scale);
489 gfx::RectF current_screen_rect = MathUtil::mapClippedRect( 514 gfx::RectF current_screen_rect = MathUtil::mapClippedRect(
490 current_screen_transform, current_layer_content_rect); 515 current_screen_transform, current_layer_content_rect);
491 gfx::RectF last_layer_content_rect = gfx::ScaleRect( 516 gfx::RectF last_layer_content_rect = gfx::ScaleRect(
492 tile_bounds, 517 tile_bounds,
493 last_scale, 518 last_scale,
494 last_scale); 519 last_scale);
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
539 564
540 scoped_ptr<base::Value> PictureLayerTiling::AsValue() const { 565 scoped_ptr<base::Value> PictureLayerTiling::AsValue() const {
541 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); 566 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue());
542 state->SetInteger("num_tiles", tiles_.size()); 567 state->SetInteger("num_tiles", tiles_.size());
543 state->SetDouble("content_scale", contents_scale_); 568 state->SetDouble("content_scale", contents_scale_);
544 state->Set("content_bounds", 569 state->Set("content_bounds",
545 MathUtil::asValue(ContentRect().size()).release()); 570 MathUtil::asValue(ContentRect().size()).release());
546 return state.PassAs<base::Value>(); 571 return state.PassAs<base::Value>();
547 } 572 }
548 573
549 TileHandle::TileHandle(scoped_refptr<Tile> tile) : tile_(tile) { 574 TileHandle::TileHandle(std::pair<int, int> key, scoped_refptr<Tile> tile)
575 : key_(key),
576 tile_(tile),
577 should_be_live_(false),
578 tiling_(NULL) {
579 }
580
581 TileHandle::TileHandle(const TileHandle& tile_handle)
582 : key_(tile_handle.key_),
583 tile_(tile_handle.tile_),
584 managed_tile_state_(tile_handle.managed_tile_state_),
585 should_be_live_(false),
586 tiling_(NULL) {
587 }
588
589 TileHandle::~TileHandle() {
590 RemoveFromLiveTileList();
550 } 591 }
551 592
552 void TileHandle::RegisterWithTileManager() { 593 void TileHandle::RegisterWithTileManager() {
553 if (managed_tile_state_.get()) 594 if (managed_tile_state_.get())
554 return; 595 return;
555 managed_tile_state_ = tile_->tile_manager()->RegisterTile(tile_); 596 managed_tile_state_ = tile_->tile_manager()->RegisterTile(tile_);
556 } 597 }
557 598
558 void TileHandle::UnregisterFromTileManager() { 599 void TileHandle::UnregisterFromTileManager() {
559 managed_tile_state_ = NULL; 600 managed_tile_state_ = NULL;
560 } 601 }
561 602
603 void TileHandle::AddToLiveTileList(PictureLayerTiling* tiling) {
604 if (tiling_) {
605 DCHECK(tiling == tiling_);
606 DCHECK(tiling_live_tile_list_iterator_ != tiling_->live_tiles_.end());
607 return;
608 }
609 tiling_ = tiling;
610 tiling_live_tile_list_iterator_ =
611 tiling_->live_tiles_.insert(tiling_->live_tiles_.begin(), this);
612 }
613
614 void TileHandle::RemoveFromLiveTileList() {
615 if (!tiling_)
616 return;
617 tiling_->live_tiles_.erase(tiling_live_tile_list_iterator_);
618 tiling_live_tile_list_iterator_ = tiling_->live_tiles_.end();
619 tiling_ = NULL;
620 }
621
562 } // namespace cc 622 } // namespace cc
OLDNEW
« no previous file with comments | « cc/picture_layer_tiling.h ('k') | cc/tile_manager.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698