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 | 10 |
(...skipping 35 matching lines...) Loading... | |
46 return a_is_occluded; | 46 return a_is_occluded; |
47 | 47 |
48 // Or if a is farther away from visible. | 48 // Or if a is farther away from visible. |
49 return a_priority.distance_to_visible > b_priority.distance_to_visible; | 49 return a_priority.distance_to_visible > b_priority.distance_to_visible; |
50 } | 50 } |
51 | 51 |
52 private: | 52 private: |
53 TreePriority tree_priority_; | 53 TreePriority tree_priority_; |
54 }; | 54 }; |
55 | 55 |
56 void ReleaseTile(Tile* tile, WhichTree tree) { | |
57 // Reset priority as tile is ref-counted and might still be used | |
58 // even though we no longer hold a reference to it here anymore. | |
59 tile->SetPriority(tree, TilePriority()); | |
60 } | |
61 | |
62 } // namespace | 56 } // namespace |
63 | 57 |
64 scoped_ptr<PictureLayerTiling> PictureLayerTiling::Create( | 58 scoped_ptr<PictureLayerTiling> PictureLayerTiling::Create( |
65 float contents_scale, | 59 float contents_scale, |
66 const gfx::Size& layer_bounds, | 60 const gfx::Size& layer_bounds, |
67 PictureLayerTilingClient* client) { | 61 PictureLayerTilingClient* client) { |
68 return make_scoped_ptr(new PictureLayerTiling(contents_scale, | 62 return make_scoped_ptr(new PictureLayerTiling(contents_scale, |
69 layer_bounds, | 63 layer_bounds, |
70 client)); | 64 client)); |
71 } | 65 } |
72 | 66 |
73 PictureLayerTiling::PictureLayerTiling(float contents_scale, | 67 PictureLayerTiling::PictureLayerTiling(float contents_scale, |
74 const gfx::Size& layer_bounds, | 68 const gfx::Size& layer_bounds, |
75 PictureLayerTilingClient* client) | 69 PictureLayerTilingClient* client) |
76 : contents_scale_(contents_scale), | 70 : contents_scale_(contents_scale), |
77 layer_bounds_(layer_bounds), | 71 layer_bounds_(layer_bounds), |
78 resolution_(NON_IDEAL_RESOLUTION), | 72 resolution_(NON_IDEAL_RESOLUTION), |
79 client_(client), | 73 client_(client), |
80 tiling_data_(gfx::Size(), gfx::Size(), true), | 74 tiling_data_(gfx::Size(), gfx::Size(), true), |
81 last_impl_frame_time_in_seconds_(0.0), | 75 last_impl_frame_time_in_seconds_(0.0), |
76 content_to_screen_scale_(1.0f), | |
82 has_visible_rect_tiles_(false), | 77 has_visible_rect_tiles_(false), |
83 has_skewport_rect_tiles_(false), | 78 has_skewport_rect_tiles_(false), |
84 has_soon_border_rect_tiles_(false), | 79 has_soon_border_rect_tiles_(false), |
85 has_eventually_rect_tiles_(false), | 80 has_eventually_rect_tiles_(false), |
86 eviction_tiles_cache_valid_(false), | 81 eviction_tiles_cache_valid_(false), |
87 eviction_cache_tree_priority_(SAME_PRIORITY_FOR_BOTH_TREES) { | 82 eviction_cache_tree_priority_(SAME_PRIORITY_FOR_BOTH_TREES) { |
88 gfx::Size content_bounds = | 83 gfx::Size content_bounds = |
89 gfx::ToCeiledSize(gfx::ScaleSize(layer_bounds, contents_scale)); | 84 gfx::ToCeiledSize(gfx::ScaleSize(layer_bounds, contents_scale)); |
90 gfx::Size tile_size = client_->CalculateTileSize(content_bounds); | 85 gfx::Size tile_size = client_->CalculateTileSize(content_bounds); |
91 | 86 |
92 DCHECK(!gfx::ToFlooredSize( | 87 DCHECK(!gfx::ToFlooredSize( |
93 gfx::ScaleSize(layer_bounds, contents_scale)).IsEmpty()) << | 88 gfx::ScaleSize(layer_bounds, contents_scale)).IsEmpty()) << |
94 "Tiling created with scale too small as contents become empty." << | 89 "Tiling created with scale too small as contents become empty." << |
95 " Layer bounds: " << layer_bounds.ToString() << | 90 " Layer bounds: " << layer_bounds.ToString() << |
96 " Contents scale: " << contents_scale; | 91 " Contents scale: " << contents_scale; |
97 | 92 |
98 tiling_data_.SetTilingSize(content_bounds); | 93 tiling_data_.SetTilingSize(content_bounds); |
99 tiling_data_.SetMaxTextureSize(tile_size); | 94 tiling_data_.SetMaxTextureSize(tile_size); |
100 } | 95 } |
101 | 96 |
102 PictureLayerTiling::~PictureLayerTiling() { | 97 PictureLayerTiling::~PictureLayerTiling() { |
103 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) | |
104 ReleaseTile(it->second.get(), client_->GetTree()); | |
105 } | 98 } |
106 | 99 |
107 void PictureLayerTiling::SetClient(PictureLayerTilingClient* client) { | 100 void PictureLayerTiling::SetClient(PictureLayerTilingClient* client) { |
108 client_ = client; | 101 client_ = client; |
109 } | 102 } |
110 | 103 |
111 Tile* PictureLayerTiling::CreateTile(int i, | 104 Tile* PictureLayerTiling::CreateTile(int i, |
112 int j, | 105 int j, |
113 const PictureLayerTiling* twin_tiling) { | 106 const PictureLayerTiling* twin_tiling) { |
114 TileMapKey key(i, j); | 107 TileMapKey key(i, j); |
115 DCHECK(tiles_.find(key) == tiles_.end()); | 108 DCHECK(tiles_.find(key) == tiles_.end()); |
116 | 109 |
117 gfx::Rect paint_rect = tiling_data_.TileBoundsWithBorder(i, j); | 110 gfx::Rect paint_rect = tiling_data_.TileBoundsWithBorder(i, j); |
118 gfx::Rect tile_rect = paint_rect; | 111 gfx::Rect tile_rect = paint_rect; |
119 tile_rect.set_size(tiling_data_.max_texture_size()); | 112 tile_rect.set_size(tiling_data_.max_texture_size()); |
120 | 113 |
121 // Check our twin for a valid tile. | 114 // Check our twin for a valid tile. |
122 if (twin_tiling && | 115 if (twin_tiling && |
123 tiling_data_.max_texture_size() == | 116 tiling_data_.max_texture_size() == |
124 twin_tiling->tiling_data_.max_texture_size()) { | 117 twin_tiling->tiling_data_.max_texture_size()) { |
125 if (Tile* candidate_tile = twin_tiling->TileAt(i, j)) { | 118 if (Tile* candidate_tile = twin_tiling->TileAt(i, j)) { |
126 gfx::Rect rect = | 119 gfx::Rect rect = |
127 gfx::ScaleToEnclosingRect(paint_rect, 1.0f / contents_scale_); | 120 gfx::ScaleToEnclosingRect(paint_rect, 1.0f / contents_scale_); |
128 if (!client_->GetInvalidation()->Intersects(rect)) { | 121 if (!client_->GetInvalidation()->Intersects(rect)) { |
122 DCHECK_EQ(i, candidate_tile->tiling_i_index()); | |
123 DCHECK_EQ(j, candidate_tile->tiling_j_index()); | |
129 tiles_[key] = candidate_tile; | 124 tiles_[key] = candidate_tile; |
130 return candidate_tile; | 125 return candidate_tile; |
131 } | 126 } |
132 } | 127 } |
133 } | 128 } |
134 | 129 |
135 // Create a new tile because our twin didn't have a valid one. | 130 // Create a new tile because our twin didn't have a valid one. |
136 scoped_refptr<Tile> tile = client_->CreateTile(this, tile_rect); | 131 scoped_refptr<Tile> tile = client_->CreateTile(this, tile_rect); |
137 if (tile.get()) | 132 if (tile.get()) { |
133 tile->set_tiling_index(i, j); | |
138 tiles_[key] = tile; | 134 tiles_[key] = tile; |
135 } | |
139 return tile.get(); | 136 return tile.get(); |
140 } | 137 } |
141 | 138 |
142 void PictureLayerTiling::CreateMissingTilesInLiveTilesRect() { | 139 void PictureLayerTiling::CreateMissingTilesInLiveTilesRect() { |
143 const PictureLayerTiling* twin_tiling = client_->GetTwinTiling(this); | 140 const PictureLayerTiling* twin_tiling = client_->GetTwinTiling(this); |
144 bool include_borders = true; | 141 bool include_borders = true; |
145 for (TilingData::Iterator iter( | 142 for (TilingData::Iterator iter( |
146 &tiling_data_, live_tiles_rect_, include_borders); | 143 &tiling_data_, live_tiles_rect_, include_borders); |
147 iter; | 144 iter; |
148 ++iter) { | 145 ++iter) { |
(...skipping 67 matching lines...) Loading... | |
216 bool include_borders = true; | 213 bool include_borders = true; |
217 for (TilingData::Iterator iter( | 214 for (TilingData::Iterator iter( |
218 &tiling_data_, content_rect, include_borders); | 215 &tiling_data_, content_rect, include_borders); |
219 iter; | 216 iter; |
220 ++iter) { | 217 ++iter) { |
221 TileMapKey key(iter.index()); | 218 TileMapKey key(iter.index()); |
222 TileMap::iterator find = tiles_.find(key); | 219 TileMap::iterator find = tiles_.find(key); |
223 if (find == tiles_.end()) | 220 if (find == tiles_.end()) |
224 continue; | 221 continue; |
225 | 222 |
226 ReleaseTile(find->second.get(), client_->GetTree()); | |
227 | |
228 tiles_.erase(find); | 223 tiles_.erase(find); |
229 new_tile_keys.push_back(key); | 224 new_tile_keys.push_back(key); |
230 } | 225 } |
231 } | 226 } |
232 | 227 |
233 if (recreate_invalidated_tiles && !new_tile_keys.empty()) { | 228 if (recreate_invalidated_tiles && !new_tile_keys.empty()) { |
234 for (size_t i = 0; i < new_tile_keys.size(); ++i) { | 229 for (size_t i = 0; i < new_tile_keys.size(); ++i) { |
235 // Don't try to share a tile with the twin layer, it's been invalidated so | 230 // Don't try to share a tile with the twin layer, it's been invalidated so |
236 // we have to make our own tile here. | 231 // we have to make our own tile here. |
237 const PictureLayerTiling* twin_tiling = NULL; | 232 const PictureLayerTiling* twin_tiling = NULL; |
(...skipping 147 matching lines...) Loading... | |
385 | 380 |
386 return texture_rect; | 381 return texture_rect; |
387 } | 382 } |
388 | 383 |
389 gfx::Size PictureLayerTiling::CoverageIterator::texture_size() const { | 384 gfx::Size PictureLayerTiling::CoverageIterator::texture_size() const { |
390 return tiling_->tiling_data_.max_texture_size(); | 385 return tiling_->tiling_data_.max_texture_size(); |
391 } | 386 } |
392 | 387 |
393 void PictureLayerTiling::Reset() { | 388 void PictureLayerTiling::Reset() { |
394 live_tiles_rect_ = gfx::Rect(); | 389 live_tiles_rect_ = gfx::Rect(); |
395 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) | |
396 ReleaseTile(it->second.get(), client_->GetTree()); | |
397 tiles_.clear(); | 390 tiles_.clear(); |
398 } | 391 } |
399 | 392 |
400 gfx::Rect PictureLayerTiling::ComputeSkewport( | 393 gfx::Rect PictureLayerTiling::ComputeSkewport( |
401 double current_frame_time_in_seconds, | 394 double current_frame_time_in_seconds, |
402 const gfx::Rect& visible_rect_in_content_space) const { | 395 const gfx::Rect& visible_rect_in_content_space) const { |
403 gfx::Rect skewport = visible_rect_in_content_space; | 396 gfx::Rect skewport = visible_rect_in_content_space; |
404 if (last_impl_frame_time_in_seconds_ == 0.0) | 397 if (last_impl_frame_time_in_seconds_ == 0.0) |
405 return skewport; | 398 return skewport; |
406 | 399 |
(...skipping 54 matching lines...) Loading... | |
461 | 454 |
462 gfx::Rect visible_rect_in_content_space = | 455 gfx::Rect visible_rect_in_content_space = |
463 gfx::ScaleToEnclosingRect(visible_layer_rect, contents_scale_); | 456 gfx::ScaleToEnclosingRect(visible_layer_rect, contents_scale_); |
464 | 457 |
465 if (tiling_size().IsEmpty()) { | 458 if (tiling_size().IsEmpty()) { |
466 last_impl_frame_time_in_seconds_ = current_frame_time_in_seconds; | 459 last_impl_frame_time_in_seconds_ = current_frame_time_in_seconds; |
467 last_visible_rect_in_content_space_ = visible_rect_in_content_space; | 460 last_visible_rect_in_content_space_ = visible_rect_in_content_space; |
468 return; | 461 return; |
469 } | 462 } |
470 | 463 |
464 // Calculate the skewport. | |
465 gfx::Rect skewport = ComputeSkewport(current_frame_time_in_seconds, | |
466 visible_rect_in_content_space); | |
467 DCHECK(skewport.Contains(visible_rect_in_content_space)); | |
468 | |
469 // Calculate the eventually/live tiles rect. | |
471 size_t max_tiles_for_interest_area = client_->GetMaxTilesForInterestArea(); | 470 size_t max_tiles_for_interest_area = client_->GetMaxTilesForInterestArea(); |
472 | 471 |
473 gfx::Size tile_size = tiling_data_.max_texture_size(); | 472 gfx::Size tile_size = tiling_data_.max_texture_size(); |
474 int64 eventually_rect_area = | 473 int64 eventually_rect_area = |
475 max_tiles_for_interest_area * tile_size.width() * tile_size.height(); | 474 max_tiles_for_interest_area * tile_size.width() * tile_size.height(); |
476 | 475 |
477 gfx::Rect skewport = ComputeSkewport(current_frame_time_in_seconds, | |
478 visible_rect_in_content_space); | |
479 DCHECK(skewport.Contains(visible_rect_in_content_space)); | |
480 | |
481 gfx::Rect eventually_rect = | 476 gfx::Rect eventually_rect = |
482 ExpandRectEquallyToAreaBoundedBy(visible_rect_in_content_space, | 477 ExpandRectEquallyToAreaBoundedBy(visible_rect_in_content_space, |
483 eventually_rect_area, | 478 eventually_rect_area, |
484 gfx::Rect(tiling_size()), | 479 gfx::Rect(tiling_size()), |
485 &expansion_cache_); | 480 &expansion_cache_); |
486 | 481 |
487 DCHECK(eventually_rect.IsEmpty() || | 482 DCHECK(eventually_rect.IsEmpty() || |
488 gfx::Rect(tiling_size()).Contains(eventually_rect)) | 483 gfx::Rect(tiling_size()).Contains(eventually_rect)) |
489 << "tiling_size: " << tiling_size().ToString() | 484 << "tiling_size: " << tiling_size().ToString() |
490 << " eventually_rect: " << eventually_rect.ToString(); | 485 << " eventually_rect: " << eventually_rect.ToString(); |
491 | 486 |
487 // Calculate the soon border rect. | |
488 content_to_screen_scale_ = 1.0f / (contents_scale_ * ideal_contents_scale); | |
USE eero AT chromium.org
2014/08/19 08:40:20
This should be
content_to_screen_scale_ = ideal_
vmpstr
2014/08/19 18:04:33
Good point, I'll rebase.
| |
489 gfx::Rect soon_border_rect = visible_rect_in_content_space; | |
490 float border = kSoonBorderDistanceInScreenPixels / content_to_screen_scale_; | |
491 soon_border_rect.Inset(-border, -border, -border, -border); | |
492 | |
493 // Update the tiling state. | |
492 SetLiveTilesRect(eventually_rect); | 494 SetLiveTilesRect(eventually_rect); |
493 | 495 |
494 last_impl_frame_time_in_seconds_ = current_frame_time_in_seconds; | 496 last_impl_frame_time_in_seconds_ = current_frame_time_in_seconds; |
495 last_visible_rect_in_content_space_ = visible_rect_in_content_space; | 497 last_visible_rect_in_content_space_ = visible_rect_in_content_space; |
496 | 498 |
497 eviction_tiles_cache_valid_ = false; | 499 eviction_tiles_cache_valid_ = false; |
498 | 500 |
499 TilePriority now_priority(resolution_, TilePriority::NOW, 0); | |
500 float content_to_screen_scale = | |
501 1.0f / (contents_scale_ * ideal_contents_scale); | |
502 | |
503 // Assign now priority to all visible tiles. | |
504 bool include_borders = true; | |
505 has_visible_rect_tiles_ = false; | |
506 for (TilingData::Iterator iter( | |
507 &tiling_data_, visible_rect_in_content_space, include_borders); | |
508 iter; | |
509 ++iter) { | |
510 TileMap::iterator find = tiles_.find(iter.index()); | |
511 if (find == tiles_.end()) | |
512 continue; | |
513 has_visible_rect_tiles_ = true; | |
514 Tile* tile = find->second.get(); | |
515 | |
516 tile->SetPriority(tree, now_priority); | |
517 | |
518 // Set whether tile is occluded or not. | |
519 bool is_occluded = false; | |
520 if (occlusion_tracker) { | |
521 gfx::Rect tile_query_rect = ScaleToEnclosingRect( | |
522 IntersectRects(tile->content_rect(), visible_rect_in_content_space), | |
523 1.0f / contents_scale_); | |
524 // TODO(vmpstr): Remove render_target and draw_transform from the | |
525 // parameters so they can be hidden from the tiling. | |
526 is_occluded = occlusion_tracker->Occluded( | |
527 render_target, tile_query_rect, draw_transform); | |
528 } | |
529 tile->set_is_occluded(tree, is_occluded); | |
530 } | |
531 | |
532 // Assign soon priority to skewport tiles. | |
533 has_skewport_rect_tiles_ = false; | |
534 for (TilingData::DifferenceIterator iter( | |
535 &tiling_data_, skewport, visible_rect_in_content_space); | |
536 iter; | |
537 ++iter) { | |
538 TileMap::iterator find = tiles_.find(iter.index()); | |
539 if (find == tiles_.end()) | |
540 continue; | |
541 has_skewport_rect_tiles_ = true; | |
542 Tile* tile = find->second.get(); | |
543 | |
544 gfx::Rect tile_bounds = | |
545 tiling_data_.TileBounds(iter.index_x(), iter.index_y()); | |
546 | |
547 float distance_to_visible = | |
548 visible_rect_in_content_space.ManhattanInternalDistance(tile_bounds) * | |
549 content_to_screen_scale; | |
550 | |
551 TilePriority priority(resolution_, TilePriority::SOON, distance_to_visible); | |
552 tile->SetPriority(tree, priority); | |
553 } | |
554 | |
555 // Assign eventually priority to interest rect tiles. | |
556 has_eventually_rect_tiles_ = false; | |
557 for (TilingData::DifferenceIterator iter( | |
558 &tiling_data_, eventually_rect, skewport); | |
559 iter; | |
560 ++iter) { | |
561 TileMap::iterator find = tiles_.find(iter.index()); | |
562 if (find == tiles_.end()) | |
563 continue; | |
564 has_eventually_rect_tiles_ = true; | |
565 Tile* tile = find->second.get(); | |
566 | |
567 gfx::Rect tile_bounds = | |
568 tiling_data_.TileBounds(iter.index_x(), iter.index_y()); | |
569 | |
570 float distance_to_visible = | |
571 visible_rect_in_content_space.ManhattanInternalDistance(tile_bounds) * | |
572 content_to_screen_scale; | |
573 TilePriority priority( | |
574 resolution_, TilePriority::EVENTUALLY, distance_to_visible); | |
575 tile->SetPriority(tree, priority); | |
576 } | |
577 | |
578 // Upgrade the priority on border tiles to be SOON. | |
579 gfx::Rect soon_border_rect = visible_rect_in_content_space; | |
580 float border = kSoonBorderDistanceInScreenPixels / content_to_screen_scale; | |
581 soon_border_rect.Inset(-border, -border, -border, -border); | |
582 has_soon_border_rect_tiles_ = false; | |
583 for (TilingData::DifferenceIterator iter( | |
584 &tiling_data_, soon_border_rect, skewport); | |
585 iter; | |
586 ++iter) { | |
587 TileMap::iterator find = tiles_.find(iter.index()); | |
588 if (find == tiles_.end()) | |
589 continue; | |
590 has_soon_border_rect_tiles_ = true; | |
591 Tile* tile = find->second.get(); | |
592 | |
593 TilePriority priority(resolution_, | |
594 TilePriority::SOON, | |
595 tile->priority(tree).distance_to_visible); | |
596 tile->SetPriority(tree, priority); | |
597 } | |
598 | |
599 // Update iteration rects. | 501 // Update iteration rects. |
600 current_visible_rect_ = visible_rect_in_content_space; | 502 current_visible_rect_ = visible_rect_in_content_space; |
601 current_skewport_rect_ = skewport; | 503 current_skewport_rect_ = skewport; |
602 current_soon_border_rect_ = soon_border_rect; | 504 current_soon_border_rect_ = soon_border_rect; |
603 current_eventually_rect_ = eventually_rect; | 505 current_eventually_rect_ = eventually_rect; |
506 | |
507 // Update has_*_tiles state. | |
508 const gfx::Rect& tiling_rect = gfx::Rect(tiling_size()); | |
509 | |
510 has_visible_rect_tiles_ = tiling_rect.Intersects(current_visible_rect_); | |
511 has_skewport_rect_tiles_ = tiling_rect.Intersects(current_skewport_rect_); | |
512 has_soon_border_rect_tiles_ = | |
513 tiling_rect.Intersects(current_soon_border_rect_); | |
514 has_eventually_rect_tiles_ = tiling_rect.Intersects(current_eventually_rect_); | |
515 | |
516 // Update occlusion. | |
517 occlusion_set_.clear(); | |
518 if (occlusion_tracker) { | |
519 bool include_borders = true; | |
520 for (TilingData::Iterator iter( | |
521 &tiling_data_, visible_rect_in_content_space, include_borders); | |
522 iter; | |
523 ++iter) { | |
524 gfx::Rect paint_rect = | |
525 tiling_data_.TileBoundsWithBorder(iter.index_x(), iter.index_y()); | |
526 gfx::Rect tile_rect = paint_rect; | |
527 tile_rect.set_size(tiling_data_.max_texture_size()); | |
528 gfx::Rect tile_query_rect = ScaleToEnclosingRect( | |
529 IntersectRects(tile_rect, visible_rect_in_content_space), | |
530 1.0f / contents_scale_); | |
531 bool is_occluded = occlusion_tracker->Occluded( | |
532 render_target, tile_query_rect, draw_transform); | |
533 if (!is_occluded) | |
534 continue; | |
535 occlusion_set_.insert(iter.index()); | |
536 } | |
537 } | |
604 } | 538 } |
605 | 539 |
606 void PictureLayerTiling::SetLiveTilesRect( | 540 void PictureLayerTiling::SetLiveTilesRect( |
607 const gfx::Rect& new_live_tiles_rect) { | 541 const gfx::Rect& new_live_tiles_rect) { |
608 DCHECK(new_live_tiles_rect.IsEmpty() || | 542 DCHECK(new_live_tiles_rect.IsEmpty() || |
609 gfx::Rect(tiling_size()).Contains(new_live_tiles_rect)) | 543 gfx::Rect(tiling_size()).Contains(new_live_tiles_rect)) |
610 << "tiling_size: " << tiling_size().ToString() | 544 << "tiling_size: " << tiling_size().ToString() |
611 << " new_live_tiles_rect: " << new_live_tiles_rect.ToString(); | 545 << " new_live_tiles_rect: " << new_live_tiles_rect.ToString(); |
612 if (live_tiles_rect_ == new_live_tiles_rect) | 546 if (live_tiles_rect_ == new_live_tiles_rect) |
613 return; | 547 return; |
614 | 548 |
615 // Iterate to delete all tiles outside of our new live_tiles rect. | 549 // Iterate to delete all tiles outside of our new live_tiles rect. |
616 for (TilingData::DifferenceIterator iter(&tiling_data_, | 550 for (TilingData::DifferenceIterator iter(&tiling_data_, |
617 live_tiles_rect_, | 551 live_tiles_rect_, |
618 new_live_tiles_rect); | 552 new_live_tiles_rect); |
619 iter; | 553 iter; |
620 ++iter) { | 554 ++iter) { |
621 TileMapKey key(iter.index()); | 555 TileMapKey key(iter.index()); |
622 TileMap::iterator found = tiles_.find(key); | 556 TileMap::iterator found = tiles_.find(key); |
623 // If the tile was outside of the recorded region, it won't exist even | 557 // If the tile was outside of the recorded region, it won't exist even |
624 // though it was in the live rect. | 558 // though it was in the live rect. |
625 if (found != tiles_.end()) { | 559 if (found != tiles_.end()) |
626 ReleaseTile(found->second.get(), client_->GetTree()); | |
627 tiles_.erase(found); | 560 tiles_.erase(found); |
628 } | |
629 } | 561 } |
630 | 562 |
631 const PictureLayerTiling* twin_tiling = client_->GetTwinTiling(this); | 563 const PictureLayerTiling* twin_tiling = client_->GetTwinTiling(this); |
632 | 564 |
633 // Iterate to allocate new tiles for all regions with newly exposed area. | 565 // Iterate to allocate new tiles for all regions with newly exposed area. |
634 for (TilingData::DifferenceIterator iter(&tiling_data_, | 566 for (TilingData::DifferenceIterator iter(&tiling_data_, |
635 new_live_tiles_rect, | 567 new_live_tiles_rect, |
636 live_tiles_rect_); | 568 live_tiles_rect_); |
637 iter; | 569 iter; |
638 ++iter) { | 570 ++iter) { |
639 TileMapKey key(iter.index()); | 571 TileMapKey key(iter.index()); |
640 CreateTile(key.first, key.second, twin_tiling); | 572 CreateTile(key.first, key.second, twin_tiling); |
641 } | 573 } |
642 | 574 |
643 live_tiles_rect_ = new_live_tiles_rect; | 575 live_tiles_rect_ = new_live_tiles_rect; |
644 } | 576 } |
645 | 577 |
646 void PictureLayerTiling::DidBecomeRecycled() { | 578 bool PictureLayerTiling::IsTileOccluded(const Tile* tile) const { |
647 // DidBecomeActive below will set the active priority for tiles that are | 579 DCHECK(tile); |
648 // still in the tree. Calling this first on an active tiling that is becoming | 580 bool is_occluded = occlusion_set_.count(std::make_pair( |
649 // recycled takes care of tiles that are no longer in the active tree (eg. | 581 tile->tiling_i_index(), tile->tiling_j_index())) != 0; |
650 // due to a pending invalidation). | 582 return is_occluded; |
651 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) { | |
652 it->second->SetPriority(ACTIVE_TREE, TilePriority()); | |
653 } | |
654 } | 583 } |
655 | 584 |
656 void PictureLayerTiling::DidBecomeActive() { | 585 bool PictureLayerTiling::IsTileRequiredForActivation(const Tile* tile) const { |
657 PicturePileImpl* active_pile = client_->GetPile(); | 586 if (resolution_ != HIGH_RESOLUTION) |
658 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) { | 587 return false; |
659 it->second->SetPriority(ACTIVE_TREE, it->second->priority(PENDING_TREE)); | |
660 it->second->SetPriority(PENDING_TREE, TilePriority()); | |
661 | 588 |
662 // Tile holds a ref onto a picture pile. If the tile never gets invalidated | 589 WhichTree tree = client_->GetTree(); |
663 // and recreated, then that picture pile ref could exist indefinitely. To | 590 if (tree != PENDING_TREE) |
664 // prevent this, ask the client to update the pile to its own ref. This | 591 return false; |
665 // will cause PicturePileImpls and their clones to get deleted once the | 592 |
666 // corresponding PictureLayerImpl and any in flight raster jobs go out of | 593 if (IsTileOccluded(tile)) |
667 // scope. | 594 return false; |
668 it->second->set_picture_pile(active_pile); | 595 |
596 if (client_->RequiresHighResToDraw()) | |
597 return true; | |
598 | |
599 const PictureLayerTiling* twin_tiling = client_->GetTwinTiling(this); | |
600 if (!twin_tiling) | |
601 return true; | |
602 | |
603 if (twin_tiling->layer_bounds() != layer_bounds()) | |
604 return true; | |
605 | |
606 if (twin_tiling->current_visible_rect_ != current_visible_rect_) | |
607 return true; | |
608 | |
609 Tile* twin_tile = | |
610 twin_tiling->TileAt(tile->tiling_i_index(), tile->tiling_j_index()); | |
danakj
2014/08/18 19:29:13
:( We do this every time we want to see if we can
vmpstr
2014/08/18 19:49:52
I'll do this in a separate patch.
| |
611 if (!twin_tile || twin_tile == tile) | |
612 return false; | |
613 | |
614 return true; | |
615 } | |
616 | |
617 void PictureLayerTiling::UpdateTileAndTwinPriority(Tile* tile) const { | |
618 const PictureLayerTiling* twin_tiling = client_->GetTwinTiling(this); | |
619 if (twin_tiling) | |
620 twin_tiling->UpdateTilePriority(tile); | |
621 UpdateTilePriority(tile); | |
622 } | |
623 | |
624 void PictureLayerTiling::UpdateTilePriority(Tile* tile) const { | |
625 WhichTree tree = client_->GetTree(); | |
626 | |
627 if (tree == PENDING_TREE) | |
628 tile->set_required_for_activation(false); | |
629 tile->set_is_occluded(tree, false); | |
630 | |
631 if (TileAt(tile->tiling_i_index(), tile->tiling_j_index()) != tile) { | |
632 tile->SetPriority(tree, TilePriority()); | |
633 return; | |
669 } | 634 } |
635 | |
636 gfx::Rect tile_bounds = tiling_data_.TileBoundsWithBorder( | |
637 tile->tiling_i_index(), tile->tiling_j_index()); | |
638 | |
639 if (current_visible_rect_.Intersects(tile_bounds)) { | |
640 tile->SetPriority(tree, TilePriority(resolution_, TilePriority::NOW, 0)); | |
641 if (tree == PENDING_TREE) | |
642 tile->set_required_for_activation(IsTileRequiredForActivation(tile)); | |
643 tile->set_is_occluded(tree, IsTileOccluded(tile)); | |
644 return; | |
645 } | |
646 | |
647 float distance_to_visible = | |
648 current_visible_rect_.ManhattanInternalDistance(tile_bounds) * | |
649 content_to_screen_scale_; | |
650 | |
651 if (current_soon_border_rect_.Intersects(tile_bounds) || | |
652 current_skewport_rect_.Intersects(tile_bounds)) { | |
653 tile->SetPriority( | |
654 tree, | |
655 TilePriority(resolution_, TilePriority::SOON, distance_to_visible)); | |
656 return; | |
657 } | |
658 | |
659 tile->SetPriority( | |
660 tree, | |
661 TilePriority(resolution_, TilePriority::EVENTUALLY, distance_to_visible)); | |
670 } | 662 } |
671 | 663 |
672 void PictureLayerTiling::AsValueInto(base::debug::TracedValue* state) const { | 664 void PictureLayerTiling::AsValueInto(base::debug::TracedValue* state) const { |
673 state->SetInteger("num_tiles", tiles_.size()); | 665 state->SetInteger("num_tiles", tiles_.size()); |
674 state->SetDouble("content_scale", contents_scale_); | 666 state->SetDouble("content_scale", contents_scale_); |
675 state->BeginDictionary("tiling_size"); | 667 state->BeginDictionary("tiling_size"); |
676 MathUtil::AddToTracedValue(tiling_size(), state); | 668 MathUtil::AddToTracedValue(tiling_size(), state); |
677 state->EndDictionary(); | 669 state->EndDictionary(); |
678 } | 670 } |
679 | 671 |
(...skipping 162 matching lines...) Loading... | |
842 return; | 834 return; |
843 | 835 |
844 eviction_tiles_now_.clear(); | 836 eviction_tiles_now_.clear(); |
845 eviction_tiles_now_and_rfa_.clear(); | 837 eviction_tiles_now_and_rfa_.clear(); |
846 eviction_tiles_soon_.clear(); | 838 eviction_tiles_soon_.clear(); |
847 eviction_tiles_soon_and_rfa_.clear(); | 839 eviction_tiles_soon_and_rfa_.clear(); |
848 eviction_tiles_eventually_.clear(); | 840 eviction_tiles_eventually_.clear(); |
849 eviction_tiles_eventually_and_rfa_.clear(); | 841 eviction_tiles_eventually_and_rfa_.clear(); |
850 | 842 |
851 for (TileMap::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { | 843 for (TileMap::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { |
852 // TODO(vmpstr): This should update the priority if UpdateTilePriorities | |
853 // changes not to do this. | |
854 Tile* tile = it->second; | 844 Tile* tile = it->second; |
845 UpdateTileAndTwinPriority(tile); | |
855 const TilePriority& priority = | 846 const TilePriority& priority = |
856 tile->priority_for_tree_priority(tree_priority); | 847 tile->priority_for_tree_priority(tree_priority); |
857 switch (priority.priority_bin) { | 848 switch (priority.priority_bin) { |
858 case TilePriority::EVENTUALLY: | 849 case TilePriority::EVENTUALLY: |
859 if (tile->required_for_activation()) | 850 if (tile->required_for_activation()) |
860 eviction_tiles_eventually_and_rfa_.push_back(tile); | 851 eviction_tiles_eventually_and_rfa_.push_back(tile); |
861 else | 852 else |
862 eviction_tiles_eventually_.push_back(tile); | 853 eviction_tiles_eventually_.push_back(tile); |
863 break; | 854 break; |
864 case TilePriority::SOON: | 855 case TilePriority::SOON: |
(...skipping 71 matching lines...) Loading... | |
936 visible_iterator_ = TilingData::Iterator(&tiling_->tiling_data_, | 927 visible_iterator_ = TilingData::Iterator(&tiling_->tiling_data_, |
937 tiling_->current_visible_rect_, | 928 tiling_->current_visible_rect_, |
938 true /* include_borders */); | 929 true /* include_borders */); |
939 if (!visible_iterator_) { | 930 if (!visible_iterator_) { |
940 AdvancePhase(); | 931 AdvancePhase(); |
941 return; | 932 return; |
942 } | 933 } |
943 | 934 |
944 current_tile_ = | 935 current_tile_ = |
945 tiling_->TileAt(visible_iterator_.index_x(), visible_iterator_.index_y()); | 936 tiling_->TileAt(visible_iterator_.index_x(), visible_iterator_.index_y()); |
946 if (!current_tile_ || !TileNeedsRaster(current_tile_)) | 937 if (!current_tile_ || !TileNeedsRaster(current_tile_)) { |
947 ++(*this); | 938 ++(*this); |
939 return; | |
940 } | |
941 tiling_->UpdateTileAndTwinPriority(current_tile_); | |
948 } | 942 } |
949 | 943 |
950 PictureLayerTiling::TilingRasterTileIterator::~TilingRasterTileIterator() {} | 944 PictureLayerTiling::TilingRasterTileIterator::~TilingRasterTileIterator() {} |
951 | 945 |
952 void PictureLayerTiling::TilingRasterTileIterator::AdvancePhase() { | 946 void PictureLayerTiling::TilingRasterTileIterator::AdvancePhase() { |
953 DCHECK_LT(phase_, EVENTUALLY_RECT); | 947 DCHECK_LT(phase_, EVENTUALLY_RECT); |
954 | 948 |
955 do { | 949 do { |
956 phase_ = static_cast<Phase>(phase_ + 1); | 950 phase_ = static_cast<Phase>(phase_ + 1); |
957 switch (phase_) { | 951 switch (phase_) { |
(...skipping 40 matching lines...) Loading... | |
998 if (current_tile_ && TileNeedsRaster(current_tile_)) | 992 if (current_tile_ && TileNeedsRaster(current_tile_)) |
999 break; | 993 break; |
1000 ++spiral_iterator_; | 994 ++spiral_iterator_; |
1001 } | 995 } |
1002 | 996 |
1003 if (!spiral_iterator_ && phase_ == EVENTUALLY_RECT) { | 997 if (!spiral_iterator_ && phase_ == EVENTUALLY_RECT) { |
1004 current_tile_ = NULL; | 998 current_tile_ = NULL; |
1005 break; | 999 break; |
1006 } | 1000 } |
1007 } while (!spiral_iterator_); | 1001 } while (!spiral_iterator_); |
1002 | |
1003 if (current_tile_) | |
1004 tiling_->UpdateTileAndTwinPriority(current_tile_); | |
1008 } | 1005 } |
1009 | 1006 |
1010 PictureLayerTiling::TilingRasterTileIterator& | 1007 PictureLayerTiling::TilingRasterTileIterator& |
1011 PictureLayerTiling::TilingRasterTileIterator:: | 1008 PictureLayerTiling::TilingRasterTileIterator:: |
1012 operator++() { | 1009 operator++() { |
1013 current_tile_ = NULL; | 1010 current_tile_ = NULL; |
1014 while (!current_tile_ || !TileNeedsRaster(current_tile_)) { | 1011 while (!current_tile_ || !TileNeedsRaster(current_tile_)) { |
1015 std::pair<int, int> next_index; | 1012 std::pair<int, int> next_index; |
1016 switch (phase_) { | 1013 switch (phase_) { |
1017 case VISIBLE_RECT: | 1014 case VISIBLE_RECT: |
(...skipping 17 matching lines...) Loading... | |
1035 ++spiral_iterator_; | 1032 ++spiral_iterator_; |
1036 if (!spiral_iterator_) { | 1033 if (!spiral_iterator_) { |
1037 current_tile_ = NULL; | 1034 current_tile_ = NULL; |
1038 return *this; | 1035 return *this; |
1039 } | 1036 } |
1040 next_index = spiral_iterator_.index(); | 1037 next_index = spiral_iterator_.index(); |
1041 break; | 1038 break; |
1042 } | 1039 } |
1043 current_tile_ = tiling_->TileAt(next_index.first, next_index.second); | 1040 current_tile_ = tiling_->TileAt(next_index.first, next_index.second); |
1044 } | 1041 } |
1042 | |
1043 if (current_tile_) | |
1044 tiling_->UpdateTileAndTwinPriority(current_tile_); | |
1045 return *this; | 1045 return *this; |
1046 } | 1046 } |
1047 | 1047 |
1048 PictureLayerTiling::TilingEvictionTileIterator::TilingEvictionTileIterator() | 1048 PictureLayerTiling::TilingEvictionTileIterator::TilingEvictionTileIterator() |
1049 : eviction_tiles_(NULL), current_eviction_tiles_index_(0u) { | 1049 : eviction_tiles_(NULL), current_eviction_tiles_index_(0u) { |
1050 } | 1050 } |
1051 | 1051 |
1052 PictureLayerTiling::TilingEvictionTileIterator::TilingEvictionTileIterator( | 1052 PictureLayerTiling::TilingEvictionTileIterator::TilingEvictionTileIterator( |
1053 PictureLayerTiling* tiling, | 1053 PictureLayerTiling* tiling, |
1054 TreePriority tree_priority, | 1054 TreePriority tree_priority, |
(...skipping 30 matching lines...) Loading... | |
1085 DCHECK(*this); | 1085 DCHECK(*this); |
1086 do { | 1086 do { |
1087 ++current_eviction_tiles_index_; | 1087 ++current_eviction_tiles_index_; |
1088 } while (current_eviction_tiles_index_ != eviction_tiles_->size() && | 1088 } while (current_eviction_tiles_index_ != eviction_tiles_->size() && |
1089 !(*eviction_tiles_)[current_eviction_tiles_index_]->HasResources()); | 1089 !(*eviction_tiles_)[current_eviction_tiles_index_]->HasResources()); |
1090 | 1090 |
1091 return *this; | 1091 return *this; |
1092 } | 1092 } |
1093 | 1093 |
1094 } // namespace cc | 1094 } // namespace cc |
OLD | NEW |