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

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

Issue 367833003: cc: Start using raster/eviction iterators. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 6 years, 2 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/resources/picture_layer_tiling.h ('k') | cc/resources/picture_layer_tiling_perftest.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/picture_layer_tiling.h" 5 #include "cc/resources/picture_layer_tiling.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <cmath> 8 #include <cmath>
9 #include <limits> 9 #include <limits>
10 #include <set> 10 #include <set>
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
47 return a_is_occluded; 47 return a_is_occluded;
48 48
49 // Or if a is farther away from visible. 49 // Or if a is farther away from visible.
50 return a_priority.distance_to_visible > b_priority.distance_to_visible; 50 return a_priority.distance_to_visible > b_priority.distance_to_visible;
51 } 51 }
52 52
53 private: 53 private:
54 TreePriority tree_priority_; 54 TreePriority tree_priority_;
55 }; 55 };
56 56
57 void ReleaseTile(Tile* tile, WhichTree tree) {
58 // Reset priority as tile is ref-counted and might still be used
59 // even though we no longer hold a reference to it here anymore.
60 tile->SetPriority(tree, TilePriority());
61 tile->set_shared(false);
62 }
63
64 } // namespace 57 } // namespace
65 58
66 scoped_ptr<PictureLayerTiling> PictureLayerTiling::Create( 59 scoped_ptr<PictureLayerTiling> PictureLayerTiling::Create(
67 float contents_scale, 60 float contents_scale,
68 const gfx::Size& layer_bounds, 61 const gfx::Size& layer_bounds,
69 PictureLayerTilingClient* client) { 62 PictureLayerTilingClient* client) {
70 return make_scoped_ptr(new PictureLayerTiling(contents_scale, 63 return make_scoped_ptr(new PictureLayerTiling(contents_scale,
71 layer_bounds, 64 layer_bounds,
72 client)); 65 client));
73 } 66 }
74 67
75 PictureLayerTiling::PictureLayerTiling(float contents_scale, 68 PictureLayerTiling::PictureLayerTiling(float contents_scale,
76 const gfx::Size& layer_bounds, 69 const gfx::Size& layer_bounds,
77 PictureLayerTilingClient* client) 70 PictureLayerTilingClient* client)
78 : contents_scale_(contents_scale), 71 : contents_scale_(contents_scale),
79 layer_bounds_(layer_bounds), 72 layer_bounds_(layer_bounds),
80 resolution_(NON_IDEAL_RESOLUTION), 73 resolution_(NON_IDEAL_RESOLUTION),
81 client_(client), 74 client_(client),
82 tiling_data_(gfx::Size(), gfx::Size(), true), 75 tiling_data_(gfx::Size(), gfx::Size(), true),
83 last_impl_frame_time_in_seconds_(0.0), 76 last_impl_frame_time_in_seconds_(0.0),
77 content_to_screen_scale_(0.f),
78 can_require_tiles_for_activation_(false),
84 has_visible_rect_tiles_(false), 79 has_visible_rect_tiles_(false),
85 has_skewport_rect_tiles_(false), 80 has_skewport_rect_tiles_(false),
86 has_soon_border_rect_tiles_(false), 81 has_soon_border_rect_tiles_(false),
87 has_eventually_rect_tiles_(false), 82 has_eventually_rect_tiles_(false),
88 eviction_tiles_cache_valid_(false), 83 eviction_tiles_cache_valid_(false),
89 eviction_cache_tree_priority_(SAME_PRIORITY_FOR_BOTH_TREES) { 84 eviction_cache_tree_priority_(SAME_PRIORITY_FOR_BOTH_TREES) {
90 gfx::Size content_bounds = 85 gfx::Size content_bounds =
91 gfx::ToCeiledSize(gfx::ScaleSize(layer_bounds, contents_scale)); 86 gfx::ToCeiledSize(gfx::ScaleSize(layer_bounds, contents_scale));
92 gfx::Size tile_size = client_->CalculateTileSize(content_bounds); 87 gfx::Size tile_size = client_->CalculateTileSize(content_bounds);
93 if (tile_size.IsEmpty()) { 88 if (tile_size.IsEmpty()) {
94 layer_bounds_ = gfx::Size(); 89 layer_bounds_ = gfx::Size();
95 content_bounds = gfx::Size(); 90 content_bounds = gfx::Size();
96 } 91 }
97 92
98 DCHECK(!gfx::ToFlooredSize( 93 DCHECK(!gfx::ToFlooredSize(
99 gfx::ScaleSize(layer_bounds, contents_scale)).IsEmpty()) << 94 gfx::ScaleSize(layer_bounds, contents_scale)).IsEmpty()) <<
100 "Tiling created with scale too small as contents become empty." << 95 "Tiling created with scale too small as contents become empty." <<
101 " Layer bounds: " << layer_bounds.ToString() << 96 " Layer bounds: " << layer_bounds.ToString() <<
102 " Contents scale: " << contents_scale; 97 " Contents scale: " << contents_scale;
103 98
104 tiling_data_.SetTilingSize(content_bounds); 99 tiling_data_.SetTilingSize(content_bounds);
105 tiling_data_.SetMaxTextureSize(tile_size); 100 tiling_data_.SetMaxTextureSize(tile_size);
106 } 101 }
107 102
108 PictureLayerTiling::~PictureLayerTiling() { 103 PictureLayerTiling::~PictureLayerTiling() {
109 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) 104 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it)
110 ReleaseTile(it->second.get(), client_->GetTree()); 105 it->second->set_shared(false);
111 } 106 }
112 107
113 void PictureLayerTiling::SetClient(PictureLayerTilingClient* client) { 108 void PictureLayerTiling::SetClient(PictureLayerTilingClient* client) {
114 client_ = client; 109 client_ = client;
115 } 110 }
116 111
117 Tile* PictureLayerTiling::CreateTile(int i, 112 Tile* PictureLayerTiling::CreateTile(int i,
118 int j, 113 int j,
119 const PictureLayerTiling* twin_tiling) { 114 const PictureLayerTiling* twin_tiling) {
120 TileMapKey key(i, j); 115 TileMapKey key(i, j);
121 DCHECK(tiles_.find(key) == tiles_.end()); 116 DCHECK(tiles_.find(key) == tiles_.end());
122 117
123 gfx::Rect paint_rect = tiling_data_.TileBoundsWithBorder(i, j); 118 gfx::Rect paint_rect = tiling_data_.TileBoundsWithBorder(i, j);
124 gfx::Rect tile_rect = paint_rect; 119 gfx::Rect tile_rect = paint_rect;
125 tile_rect.set_size(tiling_data_.max_texture_size()); 120 tile_rect.set_size(tiling_data_.max_texture_size());
126 121
127 // Check our twin for a valid tile. 122 // Check our twin for a valid tile.
128 if (twin_tiling && 123 if (twin_tiling &&
129 tiling_data_.max_texture_size() == 124 tiling_data_.max_texture_size() ==
130 twin_tiling->tiling_data_.max_texture_size()) { 125 twin_tiling->tiling_data_.max_texture_size()) {
131 if (Tile* candidate_tile = twin_tiling->TileAt(i, j)) { 126 if (Tile* candidate_tile = twin_tiling->TileAt(i, j)) {
132 gfx::Rect rect = 127 gfx::Rect rect =
133 gfx::ScaleToEnclosingRect(paint_rect, 1.0f / contents_scale_); 128 gfx::ScaleToEnclosingRect(paint_rect, 1.0f / contents_scale_);
134 if (!client_->GetInvalidation()->Intersects(rect)) { 129 if (!client_->GetInvalidation()->Intersects(rect)) {
135 DCHECK(!candidate_tile->is_shared()); 130 DCHECK(!candidate_tile->is_shared());
131 DCHECK_EQ(i, candidate_tile->tiling_i_index());
132 DCHECK_EQ(j, candidate_tile->tiling_j_index());
136 candidate_tile->set_shared(true); 133 candidate_tile->set_shared(true);
137 tiles_[key] = candidate_tile; 134 tiles_[key] = candidate_tile;
138 return candidate_tile; 135 return candidate_tile;
139 } 136 }
140 } 137 }
141 } 138 }
142 139
143 // Create a new tile because our twin didn't have a valid one. 140 // Create a new tile because our twin didn't have a valid one.
144 scoped_refptr<Tile> tile = client_->CreateTile(this, tile_rect); 141 scoped_refptr<Tile> tile = client_->CreateTile(this, tile_rect);
145 if (tile.get()) { 142 if (tile.get()) {
146 DCHECK(!tile->is_shared()); 143 DCHECK(!tile->is_shared());
144 tile->set_tiling_index(i, j);
147 tiles_[key] = tile; 145 tiles_[key] = tile;
148 } 146 }
149 return tile.get(); 147 return tile.get();
150 } 148 }
151 149
152 void PictureLayerTiling::CreateMissingTilesInLiveTilesRect() { 150 void PictureLayerTiling::CreateMissingTilesInLiveTilesRect() {
153 const PictureLayerTiling* twin_tiling = client_->GetTwinTiling(this); 151 const PictureLayerTiling* twin_tiling = client_->GetTwinTiling(this);
154 bool include_borders = false; 152 bool include_borders = false;
155 for (TilingData::Iterator iter( 153 for (TilingData::Iterator iter(
156 &tiling_data_, live_tiles_rect_, include_borders); 154 &tiling_data_, live_tiles_rect_, include_borders);
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after
459 gfx::Size PictureLayerTiling::CoverageIterator::texture_size() const { 457 gfx::Size PictureLayerTiling::CoverageIterator::texture_size() const {
460 return tiling_->tiling_data_.max_texture_size(); 458 return tiling_->tiling_data_.max_texture_size();
461 } 459 }
462 460
463 bool PictureLayerTiling::RemoveTileAt(int i, 461 bool PictureLayerTiling::RemoveTileAt(int i,
464 int j, 462 int j,
465 PictureLayerTiling* recycled_twin) { 463 PictureLayerTiling* recycled_twin) {
466 TileMap::iterator found = tiles_.find(TileMapKey(i, j)); 464 TileMap::iterator found = tiles_.find(TileMapKey(i, j));
467 if (found == tiles_.end()) 465 if (found == tiles_.end())
468 return false; 466 return false;
469 ReleaseTile(found->second.get(), client_->GetTree()); 467 found->second->set_shared(false);
470 tiles_.erase(found); 468 tiles_.erase(found);
471 if (recycled_twin) { 469 if (recycled_twin) {
472 // Recycled twin does not also have a recycled twin, so pass NULL. 470 // Recycled twin does not also have a recycled twin, so pass NULL.
473 recycled_twin->RemoveTileAt(i, j, NULL); 471 recycled_twin->RemoveTileAt(i, j, NULL);
474 } 472 }
475 return true; 473 return true;
476 } 474 }
477 475
478 void PictureLayerTiling::Reset() { 476 void PictureLayerTiling::Reset() {
479 live_tiles_rect_ = gfx::Rect(); 477 live_tiles_rect_ = gfx::Rect();
480 PictureLayerTiling* recycled_twin = client_->GetRecycledTwinTiling(this); 478 PictureLayerTiling* recycled_twin = client_->GetRecycledTwinTiling(this);
481 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) { 479 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) {
482 ReleaseTile(it->second.get(), client_->GetTree()); 480 it->second->set_shared(false);
483 if (recycled_twin) 481 if (recycled_twin)
484 recycled_twin->RemoveTileAt(it->first.first, it->first.second, NULL); 482 recycled_twin->RemoveTileAt(it->first.first, it->first.second, NULL);
485 } 483 }
486 tiles_.clear(); 484 tiles_.clear();
487 } 485 }
488 486
489 gfx::Rect PictureLayerTiling::ComputeSkewport( 487 gfx::Rect PictureLayerTiling::ComputeSkewport(
490 double current_frame_time_in_seconds, 488 double current_frame_time_in_seconds,
491 const gfx::Rect& visible_rect_in_content_space) const { 489 const gfx::Rect& visible_rect_in_content_space) const {
492 gfx::Rect skewport = visible_rect_in_content_space; 490 gfx::Rect skewport = visible_rect_in_content_space;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
527 extrapolation_multiplier * (old_bottom - new_bottom)); 525 extrapolation_multiplier * (old_bottom - new_bottom));
528 526
529 // Clip the skewport to |max_skewport|. 527 // Clip the skewport to |max_skewport|.
530 skewport.Intersect(max_skewport); 528 skewport.Intersect(max_skewport);
531 529
532 // Finally, ensure that visible rect is contained in the skewport. 530 // Finally, ensure that visible rect is contained in the skewport.
533 skewport.Union(visible_rect_in_content_space); 531 skewport.Union(visible_rect_in_content_space);
534 return skewport; 532 return skewport;
535 } 533 }
536 534
537 void PictureLayerTiling::UpdateTilePriorities( 535 void PictureLayerTiling::ComputeTilePriorityRects(
538 WhichTree tree, 536 WhichTree tree,
539 const gfx::Rect& viewport_in_layer_space, 537 const gfx::Rect& viewport_in_layer_space,
540 float ideal_contents_scale, 538 float ideal_contents_scale,
541 double current_frame_time_in_seconds, 539 double current_frame_time_in_seconds,
542 const Occlusion& occlusion_in_layer_space) { 540 const Occlusion& occlusion_in_layer_space) {
543 if (!NeedsUpdateForFrameAtTime(current_frame_time_in_seconds)) { 541 if (!NeedsUpdateForFrameAtTime(current_frame_time_in_seconds)) {
544 // This should never be zero for the purposes of has_ever_been_updated(). 542 // This should never be zero for the purposes of has_ever_been_updated().
545 DCHECK_NE(current_frame_time_in_seconds, 0.0); 543 DCHECK_NE(current_frame_time_in_seconds, 0.0);
546 return; 544 return;
547 } 545 }
548 546
549 gfx::Rect visible_rect_in_content_space = 547 gfx::Rect visible_rect_in_content_space =
550 gfx::ScaleToEnclosingRect(viewport_in_layer_space, contents_scale_); 548 gfx::ScaleToEnclosingRect(viewport_in_layer_space, contents_scale_);
551 549
552 if (tiling_size().IsEmpty()) { 550 if (tiling_size().IsEmpty()) {
553 last_impl_frame_time_in_seconds_ = current_frame_time_in_seconds; 551 last_impl_frame_time_in_seconds_ = current_frame_time_in_seconds;
554 last_visible_rect_in_content_space_ = visible_rect_in_content_space; 552 last_visible_rect_in_content_space_ = visible_rect_in_content_space;
555 return; 553 return;
556 } 554 }
557 555
556 // Calculate the skewport.
557 gfx::Rect skewport = ComputeSkewport(current_frame_time_in_seconds,
558 visible_rect_in_content_space);
559 DCHECK(skewport.Contains(visible_rect_in_content_space));
560
561 // Calculate the eventually/live tiles rect.
558 size_t max_tiles_for_interest_area = client_->GetMaxTilesForInterestArea(); 562 size_t max_tiles_for_interest_area = client_->GetMaxTilesForInterestArea();
559 563
560 gfx::Size tile_size = tiling_data_.max_texture_size(); 564 gfx::Size tile_size = tiling_data_.max_texture_size();
561 int64 eventually_rect_area = 565 int64 eventually_rect_area =
562 max_tiles_for_interest_area * tile_size.width() * tile_size.height(); 566 max_tiles_for_interest_area * tile_size.width() * tile_size.height();
563 567
564 gfx::Rect skewport = ComputeSkewport(current_frame_time_in_seconds,
565 visible_rect_in_content_space);
566 DCHECK(skewport.Contains(visible_rect_in_content_space));
567
568 gfx::Rect eventually_rect = 568 gfx::Rect eventually_rect =
569 ExpandRectEquallyToAreaBoundedBy(visible_rect_in_content_space, 569 ExpandRectEquallyToAreaBoundedBy(visible_rect_in_content_space,
570 eventually_rect_area, 570 eventually_rect_area,
571 gfx::Rect(tiling_size()), 571 gfx::Rect(tiling_size()),
572 &expansion_cache_); 572 &expansion_cache_);
573 573
574 DCHECK(eventually_rect.IsEmpty() || 574 DCHECK(eventually_rect.IsEmpty() ||
575 gfx::Rect(tiling_size()).Contains(eventually_rect)) 575 gfx::Rect(tiling_size()).Contains(eventually_rect))
576 << "tiling_size: " << tiling_size().ToString() 576 << "tiling_size: " << tiling_size().ToString()
577 << " eventually_rect: " << eventually_rect.ToString(); 577 << " eventually_rect: " << eventually_rect.ToString();
578 578
579 // Calculate the soon border rect.
580 content_to_screen_scale_ = ideal_contents_scale / contents_scale_;
581 gfx::Rect soon_border_rect = visible_rect_in_content_space;
582 float border = kSoonBorderDistanceInScreenPixels / content_to_screen_scale_;
583 soon_border_rect.Inset(-border, -border, -border, -border);
584
585 // Update the tiling state.
579 SetLiveTilesRect(eventually_rect); 586 SetLiveTilesRect(eventually_rect);
580 587
581 last_impl_frame_time_in_seconds_ = current_frame_time_in_seconds; 588 last_impl_frame_time_in_seconds_ = current_frame_time_in_seconds;
582 last_visible_rect_in_content_space_ = visible_rect_in_content_space; 589 last_visible_rect_in_content_space_ = visible_rect_in_content_space;
583 590
584 eviction_tiles_cache_valid_ = false; 591 eviction_tiles_cache_valid_ = false;
585 592
586 TilePriority now_priority(resolution_, TilePriority::NOW, 0);
587 float content_to_screen_scale = ideal_contents_scale / contents_scale_;
588
589 // Assign now priority to all visible tiles.
590 bool include_borders = false;
591 has_visible_rect_tiles_ = false;
592 for (TilingData::Iterator iter(
593 &tiling_data_, visible_rect_in_content_space, include_borders);
594 iter;
595 ++iter) {
596 TileMap::iterator find = tiles_.find(iter.index());
597 if (find == tiles_.end())
598 continue;
599 has_visible_rect_tiles_ = true;
600 Tile* tile = find->second.get();
601
602 tile->SetPriority(tree, now_priority);
603
604 // Set whether tile is occluded or not.
605 gfx::Rect tile_query_rect = ScaleToEnclosingRect(
606 IntersectRects(tile->content_rect(), visible_rect_in_content_space),
607 1.0f / contents_scale_);
608 bool is_occluded = occlusion_in_layer_space.IsOccluded(tile_query_rect);
609 tile->set_is_occluded(tree, is_occluded);
610 }
611
612 // Assign soon priority to skewport tiles.
613 has_skewport_rect_tiles_ = false;
614 for (TilingData::DifferenceIterator iter(
615 &tiling_data_, skewport, visible_rect_in_content_space);
616 iter;
617 ++iter) {
618 TileMap::iterator find = tiles_.find(iter.index());
619 if (find == tiles_.end())
620 continue;
621 has_skewport_rect_tiles_ = true;
622 Tile* tile = find->second.get();
623
624 gfx::Rect tile_bounds =
625 tiling_data_.TileBounds(iter.index_x(), iter.index_y());
626
627 float distance_to_visible =
628 visible_rect_in_content_space.ManhattanInternalDistance(tile_bounds) *
629 content_to_screen_scale;
630
631 TilePriority priority(resolution_, TilePriority::SOON, distance_to_visible);
632 tile->SetPriority(tree, priority);
633 }
634
635 // Assign eventually priority to interest rect tiles.
636 has_eventually_rect_tiles_ = false;
637 for (TilingData::DifferenceIterator iter(
638 &tiling_data_, eventually_rect, skewport);
639 iter;
640 ++iter) {
641 TileMap::iterator find = tiles_.find(iter.index());
642 if (find == tiles_.end())
643 continue;
644 has_eventually_rect_tiles_ = true;
645 Tile* tile = find->second.get();
646
647 gfx::Rect tile_bounds =
648 tiling_data_.TileBounds(iter.index_x(), iter.index_y());
649
650 float distance_to_visible =
651 visible_rect_in_content_space.ManhattanInternalDistance(tile_bounds) *
652 content_to_screen_scale;
653 TilePriority priority(
654 resolution_, TilePriority::EVENTUALLY, distance_to_visible);
655 tile->SetPriority(tree, priority);
656 }
657
658 // Upgrade the priority on border tiles to be SOON.
659 gfx::Rect soon_border_rect = visible_rect_in_content_space;
660 float border = kSoonBorderDistanceInScreenPixels / content_to_screen_scale;
661 soon_border_rect.Inset(-border, -border, -border, -border);
662 has_soon_border_rect_tiles_ = false;
663 for (TilingData::DifferenceIterator iter(
664 &tiling_data_, soon_border_rect, skewport);
665 iter;
666 ++iter) {
667 TileMap::iterator find = tiles_.find(iter.index());
668 if (find == tiles_.end())
669 continue;
670 has_soon_border_rect_tiles_ = true;
671 Tile* tile = find->second.get();
672
673 TilePriority priority(resolution_,
674 TilePriority::SOON,
675 tile->priority(tree).distance_to_visible);
676 tile->SetPriority(tree, priority);
677 }
678
679 // Update iteration rects.
680 current_visible_rect_ = visible_rect_in_content_space; 593 current_visible_rect_ = visible_rect_in_content_space;
681 current_skewport_rect_ = skewport; 594 current_skewport_rect_ = skewport;
682 current_soon_border_rect_ = soon_border_rect; 595 current_soon_border_rect_ = soon_border_rect;
683 current_eventually_rect_ = eventually_rect; 596 current_eventually_rect_ = eventually_rect;
597 current_occlusion_in_layer_space_ = occlusion_in_layer_space;
598
599 // Update has_*_tiles state.
600 gfx::Rect tiling_rect(tiling_size());
601
602 has_visible_rect_tiles_ = tiling_rect.Intersects(current_visible_rect_);
603 has_skewport_rect_tiles_ = tiling_rect.Intersects(current_skewport_rect_);
604 has_soon_border_rect_tiles_ =
605 tiling_rect.Intersects(current_soon_border_rect_);
606 has_eventually_rect_tiles_ = tiling_rect.Intersects(current_eventually_rect_);
684 } 607 }
685 608
686 void PictureLayerTiling::SetLiveTilesRect( 609 void PictureLayerTiling::SetLiveTilesRect(
687 const gfx::Rect& new_live_tiles_rect) { 610 const gfx::Rect& new_live_tiles_rect) {
688 DCHECK(new_live_tiles_rect.IsEmpty() || 611 DCHECK(new_live_tiles_rect.IsEmpty() ||
689 gfx::Rect(tiling_size()).Contains(new_live_tiles_rect)) 612 gfx::Rect(tiling_size()).Contains(new_live_tiles_rect))
690 << "tiling_size: " << tiling_size().ToString() 613 << "tiling_size: " << tiling_size().ToString()
691 << " new_live_tiles_rect: " << new_live_tiles_rect.ToString(); 614 << " new_live_tiles_rect: " << new_live_tiles_rect.ToString();
692 if (live_tiles_rect_ == new_live_tiles_rect) 615 if (live_tiles_rect_ == new_live_tiles_rect)
693 return; 616 return;
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
734 DCHECK(tiling_data_.TileBounds(it->first.first, it->first.second) 657 DCHECK(tiling_data_.TileBounds(it->first.first, it->first.second)
735 .Intersects(live_tiles_rect_)) 658 .Intersects(live_tiles_rect_))
736 << this << " " << it->first.first << "," << it->first.second 659 << this << " " << it->first.first << "," << it->first.second
737 << " tile bounds " 660 << " tile bounds "
738 << tiling_data_.TileBounds(it->first.first, it->first.second).ToString() 661 << tiling_data_.TileBounds(it->first.first, it->first.second).ToString()
739 << " live_tiles_rect " << live_tiles_rect_.ToString(); 662 << " live_tiles_rect " << live_tiles_rect_.ToString();
740 } 663 }
741 #endif 664 #endif
742 } 665 }
743 666
744 void PictureLayerTiling::DidBecomeRecycled() { 667 bool PictureLayerTiling::IsTileOccluded(const Tile* tile) const {
745 // DidBecomeActive below will set the active priority for tiles that are 668 DCHECK(tile);
746 // still in the tree. Calling this first on an active tiling that is becoming 669
747 // recycled takes care of tiles that are no longer in the active tree (eg. 670 if (!current_occlusion_in_layer_space_.HasOcclusion())
748 // due to a pending invalidation). 671 return false;
749 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) { 672
750 it->second->SetPriority(ACTIVE_TREE, TilePriority()); 673 gfx::Rect tile_query_rect =
674 gfx::IntersectRects(tile->content_rect(), current_visible_rect_);
675
676 // Explicitly check if the tile is outside the viewport. If so, we need to
677 // return false, since occlusion for this tile is unknown.
678 // TODO(vmpstr): Since the current visible rect is really a viewport in
679 // layer space, we should probably clip tile query rect to tiling bounds
680 // or live tiles rect.
681 if (tile_query_rect.IsEmpty())
682 return false;
683
684 if (contents_scale_ != 1.f) {
685 tile_query_rect =
686 gfx::ScaleToEnclosingRect(tile_query_rect, 1.0f / contents_scale_);
751 } 687 }
688
689 return current_occlusion_in_layer_space_.IsOccluded(tile_query_rect);
752 } 690 }
753 691
754 void PictureLayerTiling::DidBecomeActive() { 692 bool PictureLayerTiling::IsTileRequiredForActivation(const Tile* tile) const {
755 PicturePileImpl* active_pile = client_->GetPile(); 693 DCHECK_EQ(PENDING_TREE, client_->GetTree());
756 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) {
757 it->second->SetPriority(ACTIVE_TREE, it->second->priority(PENDING_TREE));
758 it->second->SetPriority(PENDING_TREE, TilePriority());
759 694
760 // Tile holds a ref onto a picture pile. If the tile never gets invalidated 695 // Note that although this function will determine whether tile is required
761 // and recreated, then that picture pile ref could exist indefinitely. To 696 // for activation assuming that it is in visible (ie in the viewport). That is
762 // prevent this, ask the client to update the pile to its own ref. This 697 // to say, even if the tile is outside of the viewport, it will be treated as
763 // will cause PicturePileImpls to get deleted once the corresponding 698 // if it was inside (there are no explicit checks for this). Hence, this
764 // PictureLayerImpl and any in flight raster jobs go out of scope. 699 // function is only called for visible tiles to ensure we don't block
765 it->second->set_picture_pile(active_pile); 700 // activation on tiles outside of the viewport.
701
702 // If we are not allowed to mark tiles as required for activation, then don't
703 // do it.
704 if (!can_require_tiles_for_activation_)
705 return false;
706
707 if (resolution_ != HIGH_RESOLUTION)
708 return false;
709
710 if (IsTileOccluded(tile))
711 return false;
712
713 if (client_->RequiresHighResToDraw())
714 return true;
715
716 const PictureLayerTiling* twin_tiling = client_->GetTwinTiling(this);
717 if (!twin_tiling)
718 return true;
719
720 if (twin_tiling->layer_bounds() != layer_bounds())
721 return true;
722
723 if (twin_tiling->current_visible_rect_ != current_visible_rect_)
724 return true;
725
726 Tile* twin_tile =
727 twin_tiling->TileAt(tile->tiling_i_index(), tile->tiling_j_index());
728 // If twin tile is missing, it might not have a recording, so we don't need
729 // this tile to be required for activation.
730 if (!twin_tile)
731 return false;
732
733 return true;
734 }
735
736 void PictureLayerTiling::UpdateTileAndTwinPriority(Tile* tile) const {
737 UpdateTilePriority(tile);
738
739 const PictureLayerTiling* twin_tiling = client_->GetTwinTiling(this);
740 if (!tile->is_shared() || !twin_tiling) {
741 WhichTree tree = client_->GetTree();
742 WhichTree twin_tree = tree == ACTIVE_TREE ? PENDING_TREE : ACTIVE_TREE;
743 tile->SetPriority(twin_tree, TilePriority());
744 tile->set_is_occluded(twin_tree, false);
745 if (twin_tree == PENDING_TREE)
746 tile->set_required_for_activation(false);
747 return;
766 } 748 }
749
750 twin_tiling->UpdateTilePriority(tile);
751 }
752
753 void PictureLayerTiling::UpdateTilePriority(Tile* tile) const {
754 // TODO(vmpstr): This code should return the priority instead of setting it on
755 // the tile. This should be a part of the change to move tile priority from
756 // tiles into iterators.
757 WhichTree tree = client_->GetTree();
758
759 DCHECK_EQ(TileAt(tile->tiling_i_index(), tile->tiling_j_index()), tile);
760 gfx::Rect tile_bounds =
761 tiling_data_.TileBounds(tile->tiling_i_index(), tile->tiling_j_index());
762
763 if (current_visible_rect_.Intersects(tile_bounds)) {
764 tile->SetPriority(tree, TilePriority(resolution_, TilePriority::NOW, 0));
765 if (tree == PENDING_TREE)
766 tile->set_required_for_activation(IsTileRequiredForActivation(tile));
767 tile->set_is_occluded(tree, IsTileOccluded(tile));
768 return;
769 }
770
771 if (tree == PENDING_TREE)
772 tile->set_required_for_activation(false);
773 tile->set_is_occluded(tree, false);
774
775 DCHECK_GT(content_to_screen_scale_, 0.f);
776 float distance_to_visible =
777 current_visible_rect_.ManhattanInternalDistance(tile_bounds) *
778 content_to_screen_scale_;
779
780 if (current_soon_border_rect_.Intersects(tile_bounds) ||
781 current_skewport_rect_.Intersects(tile_bounds)) {
782 tile->SetPriority(
783 tree,
784 TilePriority(resolution_, TilePriority::SOON, distance_to_visible));
785 return;
786 }
787
788 tile->SetPriority(
789 tree,
790 TilePriority(resolution_, TilePriority::EVENTUALLY, distance_to_visible));
767 } 791 }
768 792
769 void PictureLayerTiling::GetAllTilesForTracing( 793 void PictureLayerTiling::GetAllTilesForTracing(
770 std::set<const Tile*>* tiles) const { 794 std::set<const Tile*>* tiles) const {
771 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) 795 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it)
772 tiles->insert(it->second.get()); 796 tiles->insert(it->second.get());
773 } 797 }
774 798
775 void PictureLayerTiling::AsValueInto(base::debug::TracedValue* state) const { 799 void PictureLayerTiling::AsValueInto(base::debug::TracedValue* state) const {
776 state->SetInteger("num_tiles", tiles_.size()); 800 state->SetInteger("num_tiles", tiles_.size());
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
947 return; 971 return;
948 972
949 eviction_tiles_now_.clear(); 973 eviction_tiles_now_.clear();
950 eviction_tiles_now_and_required_for_activation_.clear(); 974 eviction_tiles_now_and_required_for_activation_.clear();
951 eviction_tiles_soon_.clear(); 975 eviction_tiles_soon_.clear();
952 eviction_tiles_soon_and_required_for_activation_.clear(); 976 eviction_tiles_soon_and_required_for_activation_.clear();
953 eviction_tiles_eventually_.clear(); 977 eviction_tiles_eventually_.clear();
954 eviction_tiles_eventually_and_required_for_activation_.clear(); 978 eviction_tiles_eventually_and_required_for_activation_.clear();
955 979
956 for (TileMap::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { 980 for (TileMap::iterator it = tiles_.begin(); it != tiles_.end(); ++it) {
957 // TODO(vmpstr): This should update the priority if UpdateTilePriorities
958 // changes not to do this.
959 Tile* tile = it->second.get(); 981 Tile* tile = it->second.get();
982 UpdateTileAndTwinPriority(tile);
960 const TilePriority& priority = 983 const TilePriority& priority =
961 tile->priority_for_tree_priority(tree_priority); 984 tile->priority_for_tree_priority(tree_priority);
962 switch (priority.priority_bin) { 985 switch (priority.priority_bin) {
963 case TilePriority::EVENTUALLY: 986 case TilePriority::EVENTUALLY:
964 if (tile->required_for_activation()) 987 if (tile->required_for_activation())
965 eviction_tiles_eventually_and_required_for_activation_.push_back( 988 eviction_tiles_eventually_and_required_for_activation_.push_back(
966 tile); 989 tile);
967 else 990 else
968 eviction_tiles_eventually_.push_back(tile); 991 eviction_tiles_eventually_.push_back(tile);
969 break; 992 break;
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1024 return &eviction_tiles_now_and_required_for_activation_; 1047 return &eviction_tiles_now_and_required_for_activation_;
1025 } 1048 }
1026 NOTREACHED(); 1049 NOTREACHED();
1027 return &eviction_tiles_eventually_; 1050 return &eviction_tiles_eventually_;
1028 } 1051 }
1029 1052
1030 PictureLayerTiling::TilingRasterTileIterator::TilingRasterTileIterator() 1053 PictureLayerTiling::TilingRasterTileIterator::TilingRasterTileIterator()
1031 : tiling_(NULL), current_tile_(NULL) {} 1054 : tiling_(NULL), current_tile_(NULL) {}
1032 1055
1033 PictureLayerTiling::TilingRasterTileIterator::TilingRasterTileIterator( 1056 PictureLayerTiling::TilingRasterTileIterator::TilingRasterTileIterator(
1034 PictureLayerTiling* tiling, 1057 PictureLayerTiling* tiling)
1035 WhichTree tree) 1058 : tiling_(tiling), phase_(VISIBLE_RECT), current_tile_(NULL) {
1036 : tiling_(tiling), phase_(VISIBLE_RECT), tree_(tree), current_tile_(NULL) {
1037 if (!tiling_->has_visible_rect_tiles_) { 1059 if (!tiling_->has_visible_rect_tiles_) {
1038 AdvancePhase(); 1060 AdvancePhase();
1039 return; 1061 return;
1040 } 1062 }
1041 1063
1042 visible_iterator_ = TilingData::Iterator(&tiling_->tiling_data_, 1064 visible_iterator_ = TilingData::Iterator(&tiling_->tiling_data_,
1043 tiling_->current_visible_rect_, 1065 tiling_->current_visible_rect_,
1044 false /* include_borders */); 1066 false /* include_borders */);
1045 if (!visible_iterator_) { 1067 if (!visible_iterator_) {
1046 AdvancePhase(); 1068 AdvancePhase();
1047 return; 1069 return;
1048 } 1070 }
1049 1071
1050 current_tile_ = 1072 current_tile_ =
1051 tiling_->TileAt(visible_iterator_.index_x(), visible_iterator_.index_y()); 1073 tiling_->TileAt(visible_iterator_.index_x(), visible_iterator_.index_y());
1052 if (!current_tile_ || !TileNeedsRaster(current_tile_)) 1074 if (!current_tile_ || !TileNeedsRaster(current_tile_)) {
1053 ++(*this); 1075 ++(*this);
1076 return;
1077 }
1078 tiling_->UpdateTileAndTwinPriority(current_tile_);
1054 } 1079 }
1055 1080
1056 PictureLayerTiling::TilingRasterTileIterator::~TilingRasterTileIterator() {} 1081 PictureLayerTiling::TilingRasterTileIterator::~TilingRasterTileIterator() {}
1057 1082
1058 void PictureLayerTiling::TilingRasterTileIterator::AdvancePhase() { 1083 void PictureLayerTiling::TilingRasterTileIterator::AdvancePhase() {
1059 DCHECK_LT(phase_, EVENTUALLY_RECT); 1084 DCHECK_LT(phase_, EVENTUALLY_RECT);
1060 1085
1061 do { 1086 do {
1062 phase_ = static_cast<Phase>(phase_ + 1); 1087 phase_ = static_cast<Phase>(phase_ + 1);
1063 switch (phase_) { 1088 switch (phase_) {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1104 if (current_tile_ && TileNeedsRaster(current_tile_)) 1129 if (current_tile_ && TileNeedsRaster(current_tile_))
1105 break; 1130 break;
1106 ++spiral_iterator_; 1131 ++spiral_iterator_;
1107 } 1132 }
1108 1133
1109 if (!spiral_iterator_ && phase_ == EVENTUALLY_RECT) { 1134 if (!spiral_iterator_ && phase_ == EVENTUALLY_RECT) {
1110 current_tile_ = NULL; 1135 current_tile_ = NULL;
1111 break; 1136 break;
1112 } 1137 }
1113 } while (!spiral_iterator_); 1138 } while (!spiral_iterator_);
1139
1140 if (current_tile_)
1141 tiling_->UpdateTileAndTwinPriority(current_tile_);
1114 } 1142 }
1115 1143
1116 PictureLayerTiling::TilingRasterTileIterator& 1144 PictureLayerTiling::TilingRasterTileIterator&
1117 PictureLayerTiling::TilingRasterTileIterator:: 1145 PictureLayerTiling::TilingRasterTileIterator::
1118 operator++() { 1146 operator++() {
1119 current_tile_ = NULL; 1147 current_tile_ = NULL;
1120 while (!current_tile_ || !TileNeedsRaster(current_tile_)) { 1148 while (!current_tile_ || !TileNeedsRaster(current_tile_)) {
1121 std::pair<int, int> next_index; 1149 std::pair<int, int> next_index;
1122 switch (phase_) { 1150 switch (phase_) {
1123 case VISIBLE_RECT: 1151 case VISIBLE_RECT:
(...skipping 17 matching lines...) Expand all
1141 ++spiral_iterator_; 1169 ++spiral_iterator_;
1142 if (!spiral_iterator_) { 1170 if (!spiral_iterator_) {
1143 current_tile_ = NULL; 1171 current_tile_ = NULL;
1144 return *this; 1172 return *this;
1145 } 1173 }
1146 next_index = spiral_iterator_.index(); 1174 next_index = spiral_iterator_.index();
1147 break; 1175 break;
1148 } 1176 }
1149 current_tile_ = tiling_->TileAt(next_index.first, next_index.second); 1177 current_tile_ = tiling_->TileAt(next_index.first, next_index.second);
1150 } 1178 }
1179
1180 if (current_tile_)
1181 tiling_->UpdateTileAndTwinPriority(current_tile_);
1151 return *this; 1182 return *this;
1152 } 1183 }
1153 1184
1154 PictureLayerTiling::TilingEvictionTileIterator::TilingEvictionTileIterator() 1185 PictureLayerTiling::TilingEvictionTileIterator::TilingEvictionTileIterator()
1155 : eviction_tiles_(NULL), current_eviction_tiles_index_(0u) { 1186 : eviction_tiles_(NULL), current_eviction_tiles_index_(0u) {
1156 } 1187 }
1157 1188
1158 PictureLayerTiling::TilingEvictionTileIterator::TilingEvictionTileIterator( 1189 PictureLayerTiling::TilingEvictionTileIterator::TilingEvictionTileIterator(
1159 PictureLayerTiling* tiling, 1190 PictureLayerTiling* tiling,
1160 TreePriority tree_priority, 1191 TreePriority tree_priority,
(...skipping 30 matching lines...) Expand all
1191 DCHECK(*this); 1222 DCHECK(*this);
1192 do { 1223 do {
1193 ++current_eviction_tiles_index_; 1224 ++current_eviction_tiles_index_;
1194 } while (current_eviction_tiles_index_ != eviction_tiles_->size() && 1225 } while (current_eviction_tiles_index_ != eviction_tiles_->size() &&
1195 !(*eviction_tiles_)[current_eviction_tiles_index_]->HasResources()); 1226 !(*eviction_tiles_)[current_eviction_tiles_index_]->HasResources());
1196 1227
1197 return *this; 1228 return *this;
1198 } 1229 }
1199 1230
1200 } // namespace cc 1231 } // namespace cc
OLDNEW
« no previous file with comments | « cc/resources/picture_layer_tiling.h ('k') | cc/resources/picture_layer_tiling_perftest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698