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

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
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_(1.0f),
danakj 2014/10/08 18:46:25 can this be 0 to indicate it is set before we use
vmpstr 2014/10/08 22:38:34 Done.
78 can_require_tiles_for_activation_(true),
danakj 2014/10/08 18:46:26 can this be false? we should set it before we use
vmpstr 2014/10/08 22:38:34 Done.
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 // TODO(vmpstr): Skip this work if occlusion is empty (this needs a bool
danakj 2014/10/08 18:46:25 This bool function exists now right?
vmpstr 2014/10/08 22:38:34 Done.
747 // recycled takes care of tiles that are no longer in the active tree (eg. 670 // function on occlusion).
748 // due to a pending invalidation). 671 gfx::Rect tile_query_rect =
749 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) { 672 IntersectRects(tile->content_rect(), current_visible_rect_);
danakj 2014/10/08 18:46:25 nit: gfx::IntersectRects
vmpstr 2014/10/08 22:38:34 Done.
750 it->second->SetPriority(ACTIVE_TREE, TilePriority()); 673
674 if (contents_scale_ != 1.f) {
675 tile_query_rect =
676 ScaleToEnclosingRect(tile_query_rect, 1.0f / contents_scale_);
danakj 2014/10/08 18:46:26 nit: gfx::ScaleToE..
vmpstr 2014/10/08 22:38:34 Done.
751 } 677 }
678
679 // Explicitly check if the tile is outside the viewport. If so, we need to
680 // return false, since occlusion for this tile is unknown.
681 // TODO(vmpstr): Since the current visible rect is really a viewport in
682 // layer space, we should probably clip tile query rect to tiling bounds
683 // or live tiles rect.
684 if (tile_query_rect.IsEmpty())
danakj 2014/10/08 18:46:25 nit: do this before scaling, scaling shouldn't mak
vmpstr 2014/10/08 22:38:34 Done.
685 return false;
686 return current_occlusion_in_layer_space_.IsOccluded(tile_query_rect);
752 } 687 }
753 688
754 void PictureLayerTiling::DidBecomeActive() { 689 bool PictureLayerTiling::IsTileRequiredForActivation(const Tile* tile) const {
danakj 2014/10/08 18:46:25 can you add a comment somewhere here saying this i
vmpstr 2014/10/08 22:38:34 Done.
755 PicturePileImpl* active_pile = client_->GetPile(); 690 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 691
760 // Tile holds a ref onto a picture pile. If the tile never gets invalidated 692 // If we are not allowed to mark tiles as required for activation, then don't
761 // and recreated, then that picture pile ref could exist indefinitely. To 693 // do it.
762 // prevent this, ask the client to update the pile to its own ref. This 694 if (!can_require_tiles_for_activation_)
763 // will cause PicturePileImpls to get deleted once the corresponding 695 return false;
764 // PictureLayerImpl and any in flight raster jobs go out of scope. 696
765 it->second->set_picture_pile(active_pile); 697 if (resolution_ != HIGH_RESOLUTION)
698 return false;
699
700 if (IsTileOccluded(tile))
701 return false;
702
703 if (client_->RequiresHighResToDraw())
704 return true;
705
706 const PictureLayerTiling* twin_tiling = client_->GetTwinTiling(this);
707 if (!twin_tiling)
708 return true;
709
710 if (twin_tiling->layer_bounds() != layer_bounds())
711 return true;
712
713 if (twin_tiling->current_visible_rect_ != current_visible_rect_)
714 return true;
715
716 Tile* twin_tile =
717 twin_tiling->TileAt(tile->tiling_i_index(), tile->tiling_j_index());
718 // If twin tile is missing, it might not have a recording, so we don't need
719 // this tile to be required for activation.
720 if (!twin_tile)
721 return false;
722
723 return true;
724 }
725
726 void PictureLayerTiling::UpdateTileAndTwinPriority(Tile* tile) const {
727 UpdateTilePriority(tile);
728
729 const PictureLayerTiling* twin_tiling = client_->GetTwinTiling(this);
730 if (!tile->is_shared() || !twin_tiling) {
731 WhichTree tree = client_->GetTree();
732 WhichTree twin_tree = tree == ACTIVE_TREE ? PENDING_TREE : ACTIVE_TREE;
733 tile->SetPriority(twin_tree, TilePriority());
734 tile->set_is_occluded(twin_tree, false);
735 if (twin_tree == PENDING_TREE)
danakj 2014/10/08 18:46:25 nit: it's probly cheaper to just set_required all
vmpstr 2014/10/08 22:38:34 Not really harmless in general, since we have to e
736 tile->set_required_for_activation(false);
737 return;
766 } 738 }
739
740 twin_tiling->UpdateTilePriority(tile);
741 }
742
743 void PictureLayerTiling::UpdateTilePriority(Tile* tile) const {
744 // TODO(vmpstr): This code should return the priority instead of setting it on
745 // the tile. This should be a part of the change to move tile priority from
746 // tiles into iterators.
747 WhichTree tree = client_->GetTree();
748
749 if (tree == PENDING_TREE)
danakj 2014/10/08 18:46:26 same here, can just set false always?
vmpstr 2014/10/08 22:38:34 We have ensure that we don't set that from the act
750 tile->set_required_for_activation(false);
751 tile->set_is_occluded(tree, false);
danakj 2014/10/08 18:46:26 move these below the early out so we don't set the
vmpstr 2014/10/08 22:38:34 Done.
752
753 DCHECK_EQ(TileAt(tile->tiling_i_index(), tile->tiling_j_index()), tile);
754 gfx::Rect tile_bounds =
755 tiling_data_.TileBounds(tile->tiling_i_index(), tile->tiling_j_index());
756
757 if (current_visible_rect_.Intersects(tile_bounds)) {
758 tile->SetPriority(tree, TilePriority(resolution_, TilePriority::NOW, 0));
759 if (tree == PENDING_TREE)
760 tile->set_required_for_activation(IsTileRequiredForActivation(tile));
761 tile->set_is_occluded(tree, IsTileOccluded(tile));
762 return;
763 }
764
765 float distance_to_visible =
766 current_visible_rect_.ManhattanInternalDistance(tile_bounds) *
767 content_to_screen_scale_;
768
769 if (current_soon_border_rect_.Intersects(tile_bounds) ||
770 current_skewport_rect_.Intersects(tile_bounds)) {
771 tile->SetPriority(
772 tree,
773 TilePriority(resolution_, TilePriority::SOON, distance_to_visible));
774 return;
775 }
776
777 tile->SetPriority(
778 tree,
779 TilePriority(resolution_, TilePriority::EVENTUALLY, distance_to_visible));
767 } 780 }
768 781
769 void PictureLayerTiling::GetAllTilesForTracing( 782 void PictureLayerTiling::GetAllTilesForTracing(
770 std::set<const Tile*>* tiles) const { 783 std::set<const Tile*>* tiles) const {
771 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) 784 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it)
772 tiles->insert(it->second.get()); 785 tiles->insert(it->second.get());
773 } 786 }
774 787
775 void PictureLayerTiling::AsValueInto(base::debug::TracedValue* state) const { 788 void PictureLayerTiling::AsValueInto(base::debug::TracedValue* state) const {
776 state->SetInteger("num_tiles", tiles_.size()); 789 state->SetInteger("num_tiles", tiles_.size());
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
947 return; 960 return;
948 961
949 eviction_tiles_now_.clear(); 962 eviction_tiles_now_.clear();
950 eviction_tiles_now_and_required_for_activation_.clear(); 963 eviction_tiles_now_and_required_for_activation_.clear();
951 eviction_tiles_soon_.clear(); 964 eviction_tiles_soon_.clear();
952 eviction_tiles_soon_and_required_for_activation_.clear(); 965 eviction_tiles_soon_and_required_for_activation_.clear();
953 eviction_tiles_eventually_.clear(); 966 eviction_tiles_eventually_.clear();
954 eviction_tiles_eventually_and_required_for_activation_.clear(); 967 eviction_tiles_eventually_and_required_for_activation_.clear();
955 968
956 for (TileMap::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { 969 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(); 970 Tile* tile = it->second.get();
971 UpdateTileAndTwinPriority(tile);
960 const TilePriority& priority = 972 const TilePriority& priority =
961 tile->priority_for_tree_priority(tree_priority); 973 tile->priority_for_tree_priority(tree_priority);
962 switch (priority.priority_bin) { 974 switch (priority.priority_bin) {
963 case TilePriority::EVENTUALLY: 975 case TilePriority::EVENTUALLY:
964 if (tile->required_for_activation()) 976 if (tile->required_for_activation())
965 eviction_tiles_eventually_and_required_for_activation_.push_back( 977 eviction_tiles_eventually_and_required_for_activation_.push_back(
966 tile); 978 tile);
967 else 979 else
968 eviction_tiles_eventually_.push_back(tile); 980 eviction_tiles_eventually_.push_back(tile);
969 break; 981 break;
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1024 return &eviction_tiles_now_and_required_for_activation_; 1036 return &eviction_tiles_now_and_required_for_activation_;
1025 } 1037 }
1026 NOTREACHED(); 1038 NOTREACHED();
1027 return &eviction_tiles_eventually_; 1039 return &eviction_tiles_eventually_;
1028 } 1040 }
1029 1041
1030 PictureLayerTiling::TilingRasterTileIterator::TilingRasterTileIterator() 1042 PictureLayerTiling::TilingRasterTileIterator::TilingRasterTileIterator()
1031 : tiling_(NULL), current_tile_(NULL) {} 1043 : tiling_(NULL), current_tile_(NULL) {}
1032 1044
1033 PictureLayerTiling::TilingRasterTileIterator::TilingRasterTileIterator( 1045 PictureLayerTiling::TilingRasterTileIterator::TilingRasterTileIterator(
1034 PictureLayerTiling* tiling, 1046 PictureLayerTiling* tiling)
1035 WhichTree tree) 1047 : 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_) { 1048 if (!tiling_->has_visible_rect_tiles_) {
1038 AdvancePhase(); 1049 AdvancePhase();
1039 return; 1050 return;
1040 } 1051 }
1041 1052
1042 visible_iterator_ = TilingData::Iterator(&tiling_->tiling_data_, 1053 visible_iterator_ = TilingData::Iterator(&tiling_->tiling_data_,
1043 tiling_->current_visible_rect_, 1054 tiling_->current_visible_rect_,
1044 false /* include_borders */); 1055 false /* include_borders */);
1045 if (!visible_iterator_) { 1056 if (!visible_iterator_) {
1046 AdvancePhase(); 1057 AdvancePhase();
1047 return; 1058 return;
1048 } 1059 }
1049 1060
1050 current_tile_ = 1061 current_tile_ =
1051 tiling_->TileAt(visible_iterator_.index_x(), visible_iterator_.index_y()); 1062 tiling_->TileAt(visible_iterator_.index_x(), visible_iterator_.index_y());
1052 if (!current_tile_ || !TileNeedsRaster(current_tile_)) 1063 if (!current_tile_ || !TileNeedsRaster(current_tile_)) {
1053 ++(*this); 1064 ++(*this);
1065 return;
1066 }
1067 tiling_->UpdateTileAndTwinPriority(current_tile_);
danakj 2014/10/08 18:46:26 while iterating you always update the priority of
vmpstr 2014/10/08 22:38:34 The priority is only updated for returned values.
danakj 2014/10/08 23:38:01 Right, but if the first tile in the iterator didn'
danakj 2014/10/08 23:39:27 Or would operator bool be false? I'm not sure why
vmpstr 2014/10/09 00:01:42 operator* can only return a tile that needs raster
danakj 2014/10/09 00:03:26 Oh, ok ++ above would end up with a NULL tile in t
1054 } 1068 }
1055 1069
1056 PictureLayerTiling::TilingRasterTileIterator::~TilingRasterTileIterator() {} 1070 PictureLayerTiling::TilingRasterTileIterator::~TilingRasterTileIterator() {}
1057 1071
1058 void PictureLayerTiling::TilingRasterTileIterator::AdvancePhase() { 1072 void PictureLayerTiling::TilingRasterTileIterator::AdvancePhase() {
1059 DCHECK_LT(phase_, EVENTUALLY_RECT); 1073 DCHECK_LT(phase_, EVENTUALLY_RECT);
1060 1074
1061 do { 1075 do {
1062 phase_ = static_cast<Phase>(phase_ + 1); 1076 phase_ = static_cast<Phase>(phase_ + 1);
1063 switch (phase_) { 1077 switch (phase_) {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1104 if (current_tile_ && TileNeedsRaster(current_tile_)) 1118 if (current_tile_ && TileNeedsRaster(current_tile_))
1105 break; 1119 break;
1106 ++spiral_iterator_; 1120 ++spiral_iterator_;
1107 } 1121 }
1108 1122
1109 if (!spiral_iterator_ && phase_ == EVENTUALLY_RECT) { 1123 if (!spiral_iterator_ && phase_ == EVENTUALLY_RECT) {
1110 current_tile_ = NULL; 1124 current_tile_ = NULL;
1111 break; 1125 break;
1112 } 1126 }
1113 } while (!spiral_iterator_); 1127 } while (!spiral_iterator_);
1128
1129 if (current_tile_)
1130 tiling_->UpdateTileAndTwinPriority(current_tile_);
1114 } 1131 }
1115 1132
1116 PictureLayerTiling::TilingRasterTileIterator& 1133 PictureLayerTiling::TilingRasterTileIterator&
1117 PictureLayerTiling::TilingRasterTileIterator:: 1134 PictureLayerTiling::TilingRasterTileIterator::
1118 operator++() { 1135 operator++() {
1119 current_tile_ = NULL; 1136 current_tile_ = NULL;
1120 while (!current_tile_ || !TileNeedsRaster(current_tile_)) { 1137 while (!current_tile_ || !TileNeedsRaster(current_tile_)) {
1121 std::pair<int, int> next_index; 1138 std::pair<int, int> next_index;
1122 switch (phase_) { 1139 switch (phase_) {
1123 case VISIBLE_RECT: 1140 case VISIBLE_RECT:
(...skipping 17 matching lines...) Expand all
1141 ++spiral_iterator_; 1158 ++spiral_iterator_;
1142 if (!spiral_iterator_) { 1159 if (!spiral_iterator_) {
1143 current_tile_ = NULL; 1160 current_tile_ = NULL;
1144 return *this; 1161 return *this;
1145 } 1162 }
1146 next_index = spiral_iterator_.index(); 1163 next_index = spiral_iterator_.index();
1147 break; 1164 break;
1148 } 1165 }
1149 current_tile_ = tiling_->TileAt(next_index.first, next_index.second); 1166 current_tile_ = tiling_->TileAt(next_index.first, next_index.second);
1150 } 1167 }
1168
1169 if (current_tile_)
1170 tiling_->UpdateTileAndTwinPriority(current_tile_);
1151 return *this; 1171 return *this;
1152 } 1172 }
1153 1173
1154 PictureLayerTiling::TilingEvictionTileIterator::TilingEvictionTileIterator() 1174 PictureLayerTiling::TilingEvictionTileIterator::TilingEvictionTileIterator()
1155 : eviction_tiles_(NULL), current_eviction_tiles_index_(0u) { 1175 : eviction_tiles_(NULL), current_eviction_tiles_index_(0u) {
1156 } 1176 }
1157 1177
1158 PictureLayerTiling::TilingEvictionTileIterator::TilingEvictionTileIterator( 1178 PictureLayerTiling::TilingEvictionTileIterator::TilingEvictionTileIterator(
1159 PictureLayerTiling* tiling, 1179 PictureLayerTiling* tiling,
1160 TreePriority tree_priority, 1180 TreePriority tree_priority,
(...skipping 30 matching lines...) Expand all
1191 DCHECK(*this); 1211 DCHECK(*this);
1192 do { 1212 do {
1193 ++current_eviction_tiles_index_; 1213 ++current_eviction_tiles_index_;
1194 } while (current_eviction_tiles_index_ != eviction_tiles_->size() && 1214 } while (current_eviction_tiles_index_ != eviction_tiles_->size() &&
1195 !(*eviction_tiles_)[current_eviction_tiles_index_]->HasResources()); 1215 !(*eviction_tiles_)[current_eviction_tiles_index_]->HasResources());
1196 1216
1197 return *this; 1217 return *this;
1198 } 1218 }
1199 1219
1200 } // namespace cc 1220 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698