OLD | NEW |
---|---|
1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "cc/resources/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 Loading... | |
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), | |
84 has_visible_rect_tiles_(false), | 78 has_visible_rect_tiles_(false), |
85 has_skewport_rect_tiles_(false), | 79 has_skewport_rect_tiles_(false), |
86 has_soon_border_rect_tiles_(false), | 80 has_soon_border_rect_tiles_(false), |
87 has_eventually_rect_tiles_(false), | 81 has_eventually_rect_tiles_(false), |
88 eviction_tiles_cache_valid_(false), | 82 eviction_tiles_cache_valid_(false), |
89 eviction_cache_tree_priority_(SAME_PRIORITY_FOR_BOTH_TREES) { | 83 eviction_cache_tree_priority_(SAME_PRIORITY_FOR_BOTH_TREES) { |
90 gfx::Size content_bounds = | 84 gfx::Size content_bounds = |
91 gfx::ToCeiledSize(gfx::ScaleSize(layer_bounds, contents_scale)); | 85 gfx::ToCeiledSize(gfx::ScaleSize(layer_bounds, contents_scale)); |
92 gfx::Size tile_size = client_->CalculateTileSize(content_bounds); | 86 gfx::Size tile_size = client_->CalculateTileSize(content_bounds); |
93 if (tile_size.IsEmpty()) { | 87 if (tile_size.IsEmpty()) { |
94 layer_bounds_ = gfx::Size(); | 88 layer_bounds_ = gfx::Size(); |
95 content_bounds = gfx::Size(); | 89 content_bounds = gfx::Size(); |
96 } | 90 } |
97 | 91 |
98 DCHECK(!gfx::ToFlooredSize( | 92 DCHECK(!gfx::ToFlooredSize( |
99 gfx::ScaleSize(layer_bounds, contents_scale)).IsEmpty()) << | 93 gfx::ScaleSize(layer_bounds, contents_scale)).IsEmpty()) << |
100 "Tiling created with scale too small as contents become empty." << | 94 "Tiling created with scale too small as contents become empty." << |
101 " Layer bounds: " << layer_bounds.ToString() << | 95 " Layer bounds: " << layer_bounds.ToString() << |
102 " Contents scale: " << contents_scale; | 96 " Contents scale: " << contents_scale; |
103 | 97 |
104 tiling_data_.SetTilingSize(content_bounds); | 98 tiling_data_.SetTilingSize(content_bounds); |
105 tiling_data_.SetMaxTextureSize(tile_size); | 99 tiling_data_.SetMaxTextureSize(tile_size); |
106 } | 100 } |
107 | 101 |
108 PictureLayerTiling::~PictureLayerTiling() { | 102 PictureLayerTiling::~PictureLayerTiling() { |
109 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) | 103 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) |
110 ReleaseTile(it->second.get(), client_->GetTree()); | 104 it->second->set_shared(false); |
111 } | 105 } |
112 | 106 |
113 void PictureLayerTiling::SetClient(PictureLayerTilingClient* client) { | 107 void PictureLayerTiling::SetClient(PictureLayerTilingClient* client) { |
114 client_ = client; | 108 client_ = client; |
115 } | 109 } |
116 | 110 |
117 Tile* PictureLayerTiling::CreateTile(int i, | 111 Tile* PictureLayerTiling::CreateTile(int i, |
118 int j, | 112 int j, |
119 const PictureLayerTiling* twin_tiling) { | 113 const PictureLayerTiling* twin_tiling) { |
120 TileMapKey key(i, j); | 114 TileMapKey key(i, j); |
121 DCHECK(tiles_.find(key) == tiles_.end()); | 115 DCHECK(tiles_.find(key) == tiles_.end()); |
122 | 116 |
123 gfx::Rect paint_rect = tiling_data_.TileBoundsWithBorder(i, j); | 117 gfx::Rect paint_rect = tiling_data_.TileBoundsWithBorder(i, j); |
124 gfx::Rect tile_rect = paint_rect; | 118 gfx::Rect tile_rect = paint_rect; |
125 tile_rect.set_size(tiling_data_.max_texture_size()); | 119 tile_rect.set_size(tiling_data_.max_texture_size()); |
126 | 120 |
127 // Check our twin for a valid tile. | 121 // Check our twin for a valid tile. |
128 if (twin_tiling && | 122 if (twin_tiling && |
129 tiling_data_.max_texture_size() == | 123 tiling_data_.max_texture_size() == |
130 twin_tiling->tiling_data_.max_texture_size()) { | 124 twin_tiling->tiling_data_.max_texture_size()) { |
131 if (Tile* candidate_tile = twin_tiling->TileAt(i, j)) { | 125 if (Tile* candidate_tile = twin_tiling->TileAt(i, j)) { |
132 gfx::Rect rect = | 126 gfx::Rect rect = |
133 gfx::ScaleToEnclosingRect(paint_rect, 1.0f / contents_scale_); | 127 gfx::ScaleToEnclosingRect(paint_rect, 1.0f / contents_scale_); |
134 if (!client_->GetInvalidation()->Intersects(rect)) { | 128 if (!client_->GetInvalidation()->Intersects(rect)) { |
135 DCHECK(!candidate_tile->is_shared()); | 129 DCHECK(!candidate_tile->is_shared()); |
130 DCHECK_EQ(i, candidate_tile->tiling_i_index()); | |
131 DCHECK_EQ(j, candidate_tile->tiling_j_index()); | |
136 candidate_tile->set_shared(true); | 132 candidate_tile->set_shared(true); |
137 tiles_[key] = candidate_tile; | 133 tiles_[key] = candidate_tile; |
138 return candidate_tile; | 134 return candidate_tile; |
139 } | 135 } |
140 } | 136 } |
141 } | 137 } |
142 | 138 |
143 // Create a new tile because our twin didn't have a valid one. | 139 // Create a new tile because our twin didn't have a valid one. |
144 scoped_refptr<Tile> tile = client_->CreateTile(this, tile_rect); | 140 scoped_refptr<Tile> tile = client_->CreateTile(this, tile_rect); |
145 if (tile.get()) { | 141 if (tile.get()) { |
146 DCHECK(!tile->is_shared()); | 142 DCHECK(!tile->is_shared()); |
143 tile->set_tiling_index(i, j); | |
147 tiles_[key] = tile; | 144 tiles_[key] = tile; |
148 } | 145 } |
149 return tile.get(); | 146 return tile.get(); |
150 } | 147 } |
151 | 148 |
152 void PictureLayerTiling::CreateMissingTilesInLiveTilesRect() { | 149 void PictureLayerTiling::CreateMissingTilesInLiveTilesRect() { |
153 const PictureLayerTiling* twin_tiling = client_->GetTwinTiling(this); | 150 const PictureLayerTiling* twin_tiling = client_->GetTwinTiling(this); |
154 bool include_borders = false; | 151 bool include_borders = false; |
155 for (TilingData::Iterator iter( | 152 for (TilingData::Iterator iter( |
156 &tiling_data_, live_tiles_rect_, include_borders); | 153 &tiling_data_, live_tiles_rect_, include_borders); |
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
459 gfx::Size PictureLayerTiling::CoverageIterator::texture_size() const { | 456 gfx::Size PictureLayerTiling::CoverageIterator::texture_size() const { |
460 return tiling_->tiling_data_.max_texture_size(); | 457 return tiling_->tiling_data_.max_texture_size(); |
461 } | 458 } |
462 | 459 |
463 bool PictureLayerTiling::RemoveTileAt(int i, | 460 bool PictureLayerTiling::RemoveTileAt(int i, |
464 int j, | 461 int j, |
465 PictureLayerTiling* recycled_twin) { | 462 PictureLayerTiling* recycled_twin) { |
466 TileMap::iterator found = tiles_.find(TileMapKey(i, j)); | 463 TileMap::iterator found = tiles_.find(TileMapKey(i, j)); |
467 if (found == tiles_.end()) | 464 if (found == tiles_.end()) |
468 return false; | 465 return false; |
469 ReleaseTile(found->second.get(), client_->GetTree()); | 466 found->second->set_shared(false); |
470 tiles_.erase(found); | 467 tiles_.erase(found); |
471 if (recycled_twin) { | 468 if (recycled_twin) { |
472 // Recycled twin does not also have a recycled twin, so pass NULL. | 469 // Recycled twin does not also have a recycled twin, so pass NULL. |
473 recycled_twin->RemoveTileAt(i, j, NULL); | 470 recycled_twin->RemoveTileAt(i, j, NULL); |
474 } | 471 } |
475 return true; | 472 return true; |
476 } | 473 } |
477 | 474 |
478 void PictureLayerTiling::Reset() { | 475 void PictureLayerTiling::Reset() { |
479 live_tiles_rect_ = gfx::Rect(); | 476 live_tiles_rect_ = gfx::Rect(); |
480 PictureLayerTiling* recycled_twin = client_->GetRecycledTwinTiling(this); | 477 PictureLayerTiling* recycled_twin = client_->GetRecycledTwinTiling(this); |
481 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) { | 478 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) { |
482 ReleaseTile(it->second.get(), client_->GetTree()); | 479 it->second->set_shared(false); |
483 if (recycled_twin) | 480 if (recycled_twin) |
484 recycled_twin->RemoveTileAt(it->first.first, it->first.second, NULL); | 481 recycled_twin->RemoveTileAt(it->first.first, it->first.second, NULL); |
485 } | 482 } |
486 tiles_.clear(); | 483 tiles_.clear(); |
487 } | 484 } |
488 | 485 |
489 gfx::Rect PictureLayerTiling::ComputeSkewport( | 486 gfx::Rect PictureLayerTiling::ComputeSkewport( |
490 double current_frame_time_in_seconds, | 487 double current_frame_time_in_seconds, |
491 const gfx::Rect& visible_rect_in_content_space) const { | 488 const gfx::Rect& visible_rect_in_content_space) const { |
492 gfx::Rect skewport = visible_rect_in_content_space; | 489 gfx::Rect skewport = visible_rect_in_content_space; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
527 extrapolation_multiplier * (old_bottom - new_bottom)); | 524 extrapolation_multiplier * (old_bottom - new_bottom)); |
528 | 525 |
529 // Clip the skewport to |max_skewport|. | 526 // Clip the skewport to |max_skewport|. |
530 skewport.Intersect(max_skewport); | 527 skewport.Intersect(max_skewport); |
531 | 528 |
532 // Finally, ensure that visible rect is contained in the skewport. | 529 // Finally, ensure that visible rect is contained in the skewport. |
533 skewport.Union(visible_rect_in_content_space); | 530 skewport.Union(visible_rect_in_content_space); |
534 return skewport; | 531 return skewport; |
535 } | 532 } |
536 | 533 |
537 void PictureLayerTiling::UpdateTilePriorities( | 534 void PictureLayerTiling::UpdateTilePriorities( |
danakj
2014/09/19 01:41:47
this no longer updates tile priorities, and is sup
vmpstr
2014/09/19 21:22:52
I set this as ComputeTilePriorityRects. Let me kno
| |
538 WhichTree tree, | 535 WhichTree tree, |
539 const gfx::Rect& visible_layer_rect, | 536 const gfx::Rect& visible_layer_rect, |
540 float ideal_contents_scale, | 537 float ideal_contents_scale, |
541 double current_frame_time_in_seconds, | 538 double current_frame_time_in_seconds, |
542 const Occlusion& occlusion_in_layer_space) { | 539 const Occlusion& occlusion_in_layer_space) { |
543 if (!NeedsUpdateForFrameAtTime(current_frame_time_in_seconds)) { | 540 if (!NeedsUpdateForFrameAtTime(current_frame_time_in_seconds)) { |
544 // This should never be zero for the purposes of has_ever_been_updated(). | 541 // This should never be zero for the purposes of has_ever_been_updated(). |
545 DCHECK_NE(current_frame_time_in_seconds, 0.0); | 542 DCHECK_NE(current_frame_time_in_seconds, 0.0); |
546 return; | 543 return; |
547 } | 544 } |
548 | 545 |
549 gfx::Rect visible_rect_in_content_space = | 546 gfx::Rect visible_rect_in_content_space = |
550 gfx::ScaleToEnclosingRect(visible_layer_rect, contents_scale_); | 547 gfx::ScaleToEnclosingRect(visible_layer_rect, contents_scale_); |
551 | 548 |
552 if (tiling_size().IsEmpty()) { | 549 if (tiling_size().IsEmpty()) { |
553 last_impl_frame_time_in_seconds_ = current_frame_time_in_seconds; | 550 last_impl_frame_time_in_seconds_ = current_frame_time_in_seconds; |
554 last_visible_rect_in_content_space_ = visible_rect_in_content_space; | 551 last_visible_rect_in_content_space_ = visible_rect_in_content_space; |
555 return; | 552 return; |
556 } | 553 } |
557 | 554 |
555 // Calculate the skewport. | |
556 gfx::Rect skewport = ComputeSkewport(current_frame_time_in_seconds, | |
557 visible_rect_in_content_space); | |
558 DCHECK(skewport.Contains(visible_rect_in_content_space)); | |
559 | |
560 // Calculate the eventually/live tiles rect. | |
558 size_t max_tiles_for_interest_area = client_->GetMaxTilesForInterestArea(); | 561 size_t max_tiles_for_interest_area = client_->GetMaxTilesForInterestArea(); |
559 | 562 |
560 gfx::Size tile_size = tiling_data_.max_texture_size(); | 563 gfx::Size tile_size = tiling_data_.max_texture_size(); |
561 int64 eventually_rect_area = | 564 int64 eventually_rect_area = |
562 max_tiles_for_interest_area * tile_size.width() * tile_size.height(); | 565 max_tiles_for_interest_area * tile_size.width() * tile_size.height(); |
563 | 566 |
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 = | 567 gfx::Rect eventually_rect = |
569 ExpandRectEquallyToAreaBoundedBy(visible_rect_in_content_space, | 568 ExpandRectEquallyToAreaBoundedBy(visible_rect_in_content_space, |
570 eventually_rect_area, | 569 eventually_rect_area, |
571 gfx::Rect(tiling_size()), | 570 gfx::Rect(tiling_size()), |
572 &expansion_cache_); | 571 &expansion_cache_); |
573 | 572 |
574 DCHECK(eventually_rect.IsEmpty() || | 573 DCHECK(eventually_rect.IsEmpty() || |
575 gfx::Rect(tiling_size()).Contains(eventually_rect)) | 574 gfx::Rect(tiling_size()).Contains(eventually_rect)) |
576 << "tiling_size: " << tiling_size().ToString() | 575 << "tiling_size: " << tiling_size().ToString() |
577 << " eventually_rect: " << eventually_rect.ToString(); | 576 << " eventually_rect: " << eventually_rect.ToString(); |
578 | 577 |
578 // Calculate the soon border rect. | |
579 content_to_screen_scale_ = ideal_contents_scale / contents_scale_; | |
580 gfx::Rect soon_border_rect = visible_rect_in_content_space; | |
581 float border = kSoonBorderDistanceInScreenPixels / content_to_screen_scale_; | |
582 soon_border_rect.Inset(-border, -border, -border, -border); | |
583 | |
584 // Update the tiling state. | |
579 SetLiveTilesRect(eventually_rect); | 585 SetLiveTilesRect(eventually_rect); |
580 | 586 |
581 last_impl_frame_time_in_seconds_ = current_frame_time_in_seconds; | 587 last_impl_frame_time_in_seconds_ = current_frame_time_in_seconds; |
582 last_visible_rect_in_content_space_ = visible_rect_in_content_space; | 588 last_visible_rect_in_content_space_ = visible_rect_in_content_space; |
583 | 589 |
584 eviction_tiles_cache_valid_ = false; | 590 eviction_tiles_cache_valid_ = false; |
585 | 591 |
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; | 592 current_visible_rect_ = visible_rect_in_content_space; |
681 current_skewport_rect_ = skewport; | 593 current_skewport_rect_ = skewport; |
682 current_soon_border_rect_ = soon_border_rect; | 594 current_soon_border_rect_ = soon_border_rect; |
683 current_eventually_rect_ = eventually_rect; | 595 current_eventually_rect_ = eventually_rect; |
596 current_occlusion_in_layer_space_ = occlusion_in_layer_space; | |
597 | |
598 // Update has_*_tiles state. | |
599 const gfx::Rect& tiling_rect = gfx::Rect(tiling_size()); | |
danakj
2014/09/19 01:41:47
why const&? just gfx::Rect tiling_rect(tiling_size
vmpstr
2014/09/19 21:22:53
Done.
| |
600 | |
601 has_visible_rect_tiles_ = tiling_rect.Intersects(current_visible_rect_); | |
602 has_skewport_rect_tiles_ = tiling_rect.Intersects(current_skewport_rect_); | |
603 has_soon_border_rect_tiles_ = | |
604 tiling_rect.Intersects(current_soon_border_rect_); | |
605 has_eventually_rect_tiles_ = tiling_rect.Intersects(current_eventually_rect_); | |
684 } | 606 } |
685 | 607 |
686 void PictureLayerTiling::SetLiveTilesRect( | 608 void PictureLayerTiling::SetLiveTilesRect( |
687 const gfx::Rect& new_live_tiles_rect) { | 609 const gfx::Rect& new_live_tiles_rect) { |
688 DCHECK(new_live_tiles_rect.IsEmpty() || | 610 DCHECK(new_live_tiles_rect.IsEmpty() || |
689 gfx::Rect(tiling_size()).Contains(new_live_tiles_rect)) | 611 gfx::Rect(tiling_size()).Contains(new_live_tiles_rect)) |
690 << "tiling_size: " << tiling_size().ToString() | 612 << "tiling_size: " << tiling_size().ToString() |
691 << " new_live_tiles_rect: " << new_live_tiles_rect.ToString(); | 613 << " new_live_tiles_rect: " << new_live_tiles_rect.ToString(); |
692 if (live_tiles_rect_ == new_live_tiles_rect) | 614 if (live_tiles_rect_ == new_live_tiles_rect) |
693 return; | 615 return; |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
734 DCHECK(tiling_data_.TileBounds(it->first.first, it->first.second) | 656 DCHECK(tiling_data_.TileBounds(it->first.first, it->first.second) |
735 .Intersects(live_tiles_rect_)) | 657 .Intersects(live_tiles_rect_)) |
736 << this << " " << it->first.first << "," << it->first.second | 658 << this << " " << it->first.first << "," << it->first.second |
737 << " tile bounds " | 659 << " tile bounds " |
738 << tiling_data_.TileBounds(it->first.first, it->first.second).ToString() | 660 << tiling_data_.TileBounds(it->first.first, it->first.second).ToString() |
739 << " live_tiles_rect " << live_tiles_rect_.ToString(); | 661 << " live_tiles_rect " << live_tiles_rect_.ToString(); |
740 } | 662 } |
741 #endif | 663 #endif |
742 } | 664 } |
743 | 665 |
744 void PictureLayerTiling::DidBecomeRecycled() { | 666 bool PictureLayerTiling::IsTileOccluded(const Tile* tile) const { |
745 // DidBecomeActive below will set the active priority for tiles that are | 667 DCHECK(tile); |
746 // still in the tree. Calling this first on an active tiling that is becoming | 668 gfx::Rect tile_query_rect = ScaleToEnclosingRect( |
danakj
2014/09/19 01:41:47
This does int->float->int work. Can you do this on
vmpstr
2014/09/19 21:22:52
Done.
| |
747 // recycled takes care of tiles that are no longer in the active tree (eg. | 669 IntersectRects(tile->content_rect(), current_visible_rect_), |
748 // due to a pending invalidation). | 670 1.0f / contents_scale_); |
749 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) { | 671 // Explicitly check if the tile is outside the viewport. If so, we need to |
danakj
2014/09/19 01:41:47
This isn't really right if current_visible_rect_ i
vmpstr
2014/09/19 21:22:52
Done.
| |
750 it->second->SetPriority(ACTIVE_TREE, TilePriority()); | 672 // return false, since occlusion for this tile is unknown. |
751 } | 673 if (tile_query_rect.IsEmpty()) |
674 return false; | |
675 bool is_occluded = | |
676 current_occlusion_in_layer_space_.IsOccluded(tile_query_rect); | |
danakj
2014/09/19 01:41:47
just return this instead of using a variable?
vmpstr
2014/09/19 21:22:52
Done.
| |
677 return is_occluded; | |
752 } | 678 } |
753 | 679 |
754 void PictureLayerTiling::DidBecomeActive() { | 680 bool PictureLayerTiling::IsTileRequiredForActivation(const Tile* tile) const { |
755 PicturePileImpl* active_pile = client_->GetPile(); | 681 if (resolution_ != HIGH_RESOLUTION) |
danakj
2014/09/19 01:41:47
we used to consider tiles that were higher res tha
vmpstr
2014/09/19 21:22:53
Non ideal tilings won't be rasterizing any new con
danakj
2014/09/19 22:30:06
Is that implemented as a different mechanism now?
vmpstr
2014/09/22 18:01:59
This is where we don't rasterize new non-ideal til
| |
756 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) { | 682 return false; |
757 it->second->SetPriority(ACTIVE_TREE, it->second->priority(PENDING_TREE)); | |
758 it->second->SetPriority(PENDING_TREE, TilePriority()); | |
759 | 683 |
760 // Tile holds a ref onto a picture pile. If the tile never gets invalidated | 684 WhichTree tree = client_->GetTree(); |
danakj
2014/09/19 01:41:47
the temp variable not needed
danakj
2014/09/19 01:44:53
can we DCHECK(PENDING_TREE) instead actually? the
vmpstr
2014/09/19 21:22:52
Done.
| |
761 // and recreated, then that picture pile ref could exist indefinitely. To | 685 if (tree != PENDING_TREE) |
762 // prevent this, ask the client to update the pile to its own ref. This | 686 return false; |
763 // will cause PicturePileImpls to get deleted once the corresponding | 687 |
764 // PictureLayerImpl and any in flight raster jobs go out of scope. | 688 if (IsTileOccluded(tile)) |
765 it->second->set_picture_pile(active_pile); | 689 return false; |
690 | |
691 if (client_->RequiresHighResToDraw()) | |
692 return true; | |
693 | |
694 const PictureLayerTiling* twin_tiling = client_->GetTwinTiling(this); | |
695 if (!twin_tiling) | |
696 return true; | |
697 | |
698 if (twin_tiling->layer_bounds() != layer_bounds()) | |
699 return true; | |
700 | |
701 if (twin_tiling->current_visible_rect_ != current_visible_rect_) | |
702 return true; | |
703 | |
704 Tile* twin_tile = | |
705 twin_tiling->TileAt(tile->tiling_i_index(), tile->tiling_j_index()); | |
706 if (!twin_tile || twin_tile == tile) | |
danakj
2014/09/19 01:41:47
there should be some readytodraw checks in here no
vmpstr
2014/09/19 21:22:52
See above.. We did that to mark low res. Suggestio
| |
707 return false; | |
708 | |
709 return true; | |
710 } | |
711 | |
712 void PictureLayerTiling::UpdateTileAndTwinPriority(Tile* tile) const { | |
713 UpdateTilePriority(tile); | |
714 | |
715 const PictureLayerTiling* twin_tiling = client_->GetTwinTiling(this); | |
716 if (!tile->is_shared() || !twin_tiling) { | |
717 WhichTree tree = client_->GetTree(); | |
718 WhichTree twin_tree = tree == ACTIVE_TREE ? PENDING_TREE : ACTIVE_TREE; | |
719 tile->SetPriority(twin_tree, TilePriority()); | |
720 tile->set_is_occluded(twin_tree, false); | |
721 if (twin_tree == PENDING_TREE) | |
722 tile->set_required_for_activation(false); | |
723 return; | |
766 } | 724 } |
725 | |
726 twin_tiling->UpdateTilePriority(tile); | |
727 } | |
728 | |
729 void PictureLayerTiling::UpdateTilePriority(Tile* tile) const { | |
730 WhichTree tree = client_->GetTree(); | |
731 | |
732 if (tree == PENDING_TREE) | |
733 tile->set_required_for_activation(false); | |
734 tile->set_is_occluded(tree, false); | |
735 | |
736 DCHECK_EQ(TileAt(tile->tiling_i_index(), tile->tiling_j_index()), tile); | |
737 gfx::Rect tile_bounds = | |
738 tiling_data_.TileBounds(tile->tiling_i_index(), tile->tiling_j_index()); | |
739 | |
740 if (current_visible_rect_.Intersects(tile_bounds)) { | |
danakj
2014/09/19 01:41:47
here i think we want the actual visible rect of th
vmpstr
2014/09/19 21:22:52
I think this is OK? Tile bounds here are guarantee
danakj
2014/09/19 22:30:06
Yes but consider a small overflow scroll div clipp
vmpstr
2014/09/22 18:01:59
(\sciencedog) But wouldn't we have the visible lay
| |
741 tile->SetPriority(tree, TilePriority(resolution_, TilePriority::NOW, 0)); | |
danakj
2014/09/19 01:41:47
This priority logic is duplicated from the iterato
vmpstr
2014/09/19 21:22:53
I've added a general todo here. I want to move the
| |
742 if (tree == PENDING_TREE) | |
743 tile->set_required_for_activation(IsTileRequiredForActivation(tile)); | |
744 tile->set_is_occluded(tree, IsTileOccluded(tile)); | |
745 return; | |
746 } | |
747 | |
748 float distance_to_visible = | |
749 current_visible_rect_.ManhattanInternalDistance(tile_bounds) * | |
750 content_to_screen_scale_; | |
751 | |
752 if (current_soon_border_rect_.Intersects(tile_bounds) || | |
753 current_skewport_rect_.Intersects(tile_bounds)) { | |
754 tile->SetPriority( | |
755 tree, | |
756 TilePriority(resolution_, TilePriority::SOON, distance_to_visible)); | |
757 return; | |
758 } | |
759 | |
760 tile->SetPriority( | |
761 tree, | |
762 TilePriority(resolution_, TilePriority::EVENTUALLY, distance_to_visible)); | |
767 } | 763 } |
768 | 764 |
769 void PictureLayerTiling::GetAllTilesForTracing( | 765 void PictureLayerTiling::GetAllTilesForTracing( |
770 std::set<const Tile*>* tiles) const { | 766 std::set<const Tile*>* tiles) const { |
771 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) | 767 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) |
772 tiles->insert(it->second.get()); | 768 tiles->insert(it->second.get()); |
773 } | 769 } |
774 | 770 |
775 void PictureLayerTiling::AsValueInto(base::debug::TracedValue* state) const { | 771 void PictureLayerTiling::AsValueInto(base::debug::TracedValue* state) const { |
776 state->SetInteger("num_tiles", tiles_.size()); | 772 state->SetInteger("num_tiles", tiles_.size()); |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
947 return; | 943 return; |
948 | 944 |
949 eviction_tiles_now_.clear(); | 945 eviction_tiles_now_.clear(); |
950 eviction_tiles_now_and_required_for_activation_.clear(); | 946 eviction_tiles_now_and_required_for_activation_.clear(); |
951 eviction_tiles_soon_.clear(); | 947 eviction_tiles_soon_.clear(); |
952 eviction_tiles_soon_and_required_for_activation_.clear(); | 948 eviction_tiles_soon_and_required_for_activation_.clear(); |
953 eviction_tiles_eventually_.clear(); | 949 eviction_tiles_eventually_.clear(); |
954 eviction_tiles_eventually_and_required_for_activation_.clear(); | 950 eviction_tiles_eventually_and_required_for_activation_.clear(); |
955 | 951 |
956 for (TileMap::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { | 952 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(); | 953 Tile* tile = it->second.get(); |
954 UpdateTileAndTwinPriority(tile); | |
danakj
2014/09/19 01:41:47
the tile and it's twin are both in this map right?
vmpstr
2014/09/19 21:22:53
Well.. you're right. But I'm not worried about it
| |
960 const TilePriority& priority = | 955 const TilePriority& priority = |
961 tile->priority_for_tree_priority(tree_priority); | 956 tile->priority_for_tree_priority(tree_priority); |
962 switch (priority.priority_bin) { | 957 switch (priority.priority_bin) { |
963 case TilePriority::EVENTUALLY: | 958 case TilePriority::EVENTUALLY: |
964 if (tile->required_for_activation()) | 959 if (tile->required_for_activation()) |
965 eviction_tiles_eventually_and_required_for_activation_.push_back( | 960 eviction_tiles_eventually_and_required_for_activation_.push_back( |
966 tile); | 961 tile); |
967 else | 962 else |
968 eviction_tiles_eventually_.push_back(tile); | 963 eviction_tiles_eventually_.push_back(tile); |
969 break; | 964 break; |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1042 visible_iterator_ = TilingData::Iterator(&tiling_->tiling_data_, | 1037 visible_iterator_ = TilingData::Iterator(&tiling_->tiling_data_, |
1043 tiling_->current_visible_rect_, | 1038 tiling_->current_visible_rect_, |
1044 false /* include_borders */); | 1039 false /* include_borders */); |
1045 if (!visible_iterator_) { | 1040 if (!visible_iterator_) { |
1046 AdvancePhase(); | 1041 AdvancePhase(); |
1047 return; | 1042 return; |
1048 } | 1043 } |
1049 | 1044 |
1050 current_tile_ = | 1045 current_tile_ = |
1051 tiling_->TileAt(visible_iterator_.index_x(), visible_iterator_.index_y()); | 1046 tiling_->TileAt(visible_iterator_.index_x(), visible_iterator_.index_y()); |
1052 if (!current_tile_ || !TileNeedsRaster(current_tile_)) | 1047 if (!current_tile_ || !TileNeedsRaster(current_tile_)) { |
1053 ++(*this); | 1048 ++(*this); |
1049 return; | |
1050 } | |
1051 tiling_->UpdateTileAndTwinPriority(current_tile_); | |
1054 } | 1052 } |
1055 | 1053 |
1056 PictureLayerTiling::TilingRasterTileIterator::~TilingRasterTileIterator() {} | 1054 PictureLayerTiling::TilingRasterTileIterator::~TilingRasterTileIterator() {} |
1057 | 1055 |
1058 void PictureLayerTiling::TilingRasterTileIterator::AdvancePhase() { | 1056 void PictureLayerTiling::TilingRasterTileIterator::AdvancePhase() { |
1059 DCHECK_LT(phase_, EVENTUALLY_RECT); | 1057 DCHECK_LT(phase_, EVENTUALLY_RECT); |
1060 | 1058 |
1061 do { | 1059 do { |
1062 phase_ = static_cast<Phase>(phase_ + 1); | 1060 phase_ = static_cast<Phase>(phase_ + 1); |
1063 switch (phase_) { | 1061 switch (phase_) { |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1104 if (current_tile_ && TileNeedsRaster(current_tile_)) | 1102 if (current_tile_ && TileNeedsRaster(current_tile_)) |
1105 break; | 1103 break; |
1106 ++spiral_iterator_; | 1104 ++spiral_iterator_; |
1107 } | 1105 } |
1108 | 1106 |
1109 if (!spiral_iterator_ && phase_ == EVENTUALLY_RECT) { | 1107 if (!spiral_iterator_ && phase_ == EVENTUALLY_RECT) { |
1110 current_tile_ = NULL; | 1108 current_tile_ = NULL; |
1111 break; | 1109 break; |
1112 } | 1110 } |
1113 } while (!spiral_iterator_); | 1111 } while (!spiral_iterator_); |
1112 | |
1113 if (current_tile_) | |
1114 tiling_->UpdateTileAndTwinPriority(current_tile_); | |
1114 } | 1115 } |
1115 | 1116 |
1116 PictureLayerTiling::TilingRasterTileIterator& | 1117 PictureLayerTiling::TilingRasterTileIterator& |
1117 PictureLayerTiling::TilingRasterTileIterator:: | 1118 PictureLayerTiling::TilingRasterTileIterator:: |
1118 operator++() { | 1119 operator++() { |
1119 current_tile_ = NULL; | 1120 current_tile_ = NULL; |
1120 while (!current_tile_ || !TileNeedsRaster(current_tile_)) { | 1121 while (!current_tile_ || !TileNeedsRaster(current_tile_)) { |
1121 std::pair<int, int> next_index; | 1122 std::pair<int, int> next_index; |
1122 switch (phase_) { | 1123 switch (phase_) { |
1123 case VISIBLE_RECT: | 1124 case VISIBLE_RECT: |
(...skipping 17 matching lines...) Expand all Loading... | |
1141 ++spiral_iterator_; | 1142 ++spiral_iterator_; |
1142 if (!spiral_iterator_) { | 1143 if (!spiral_iterator_) { |
1143 current_tile_ = NULL; | 1144 current_tile_ = NULL; |
1144 return *this; | 1145 return *this; |
1145 } | 1146 } |
1146 next_index = spiral_iterator_.index(); | 1147 next_index = spiral_iterator_.index(); |
1147 break; | 1148 break; |
1148 } | 1149 } |
1149 current_tile_ = tiling_->TileAt(next_index.first, next_index.second); | 1150 current_tile_ = tiling_->TileAt(next_index.first, next_index.second); |
1150 } | 1151 } |
1152 | |
1153 if (current_tile_) | |
1154 tiling_->UpdateTileAndTwinPriority(current_tile_); | |
1151 return *this; | 1155 return *this; |
1152 } | 1156 } |
1153 | 1157 |
1154 PictureLayerTiling::TilingEvictionTileIterator::TilingEvictionTileIterator() | 1158 PictureLayerTiling::TilingEvictionTileIterator::TilingEvictionTileIterator() |
1155 : eviction_tiles_(NULL), current_eviction_tiles_index_(0u) { | 1159 : eviction_tiles_(NULL), current_eviction_tiles_index_(0u) { |
1156 } | 1160 } |
1157 | 1161 |
1158 PictureLayerTiling::TilingEvictionTileIterator::TilingEvictionTileIterator( | 1162 PictureLayerTiling::TilingEvictionTileIterator::TilingEvictionTileIterator( |
1159 PictureLayerTiling* tiling, | 1163 PictureLayerTiling* tiling, |
1160 TreePriority tree_priority, | 1164 TreePriority tree_priority, |
(...skipping 30 matching lines...) Expand all Loading... | |
1191 DCHECK(*this); | 1195 DCHECK(*this); |
1192 do { | 1196 do { |
1193 ++current_eviction_tiles_index_; | 1197 ++current_eviction_tiles_index_; |
1194 } while (current_eviction_tiles_index_ != eviction_tiles_->size() && | 1198 } while (current_eviction_tiles_index_ != eviction_tiles_->size() && |
1195 !(*eviction_tiles_)[current_eviction_tiles_index_]->HasResources()); | 1199 !(*eviction_tiles_)[current_eviction_tiles_index_]->HasResources()); |
1196 | 1200 |
1197 return *this; | 1201 return *this; |
1198 } | 1202 } |
1199 | 1203 |
1200 } // namespace cc | 1204 } // namespace cc |
OLD | NEW |