Chromium Code Reviews

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: Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | | 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 10
(...skipping 35 matching lines...)
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...)
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...)
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...)
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...)
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...)
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...)
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...)
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...)
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
OLDNEW

Powered by Google App Engine