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

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

Issue 736753002: cc: Implement geometry-based tile eviction (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2012 The Chromium Authors. All rights reserved. 1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "cc/resources/picture_layer_tiling.h" 5 #include "cc/resources/picture_layer_tiling.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <cmath> 8 #include <cmath>
9 #include <limits> 9 #include <limits>
10 #include <set> 10 #include <set>
11 11
12 #include "base/debug/trace_event.h" 12 #include "base/debug/trace_event.h"
13 #include "base/debug/trace_event_argument.h" 13 #include "base/debug/trace_event_argument.h"
14 #include "base/logging.h" 14 #include "base/logging.h"
15 #include "cc/base/math_util.h" 15 #include "cc/base/math_util.h"
16 #include "cc/resources/tile.h" 16 #include "cc/resources/tile.h"
17 #include "cc/resources/tile_priority.h" 17 #include "cc/resources/tile_priority.h"
18 #include "ui/gfx/geometry/point_conversions.h" 18 #include "ui/gfx/geometry/point_conversions.h"
19 #include "ui/gfx/geometry/rect_conversions.h" 19 #include "ui/gfx/geometry/rect_conversions.h"
20 #include "ui/gfx/geometry/safe_integer_conversions.h" 20 #include "ui/gfx/geometry/safe_integer_conversions.h"
21 #include "ui/gfx/geometry/size_conversions.h" 21 #include "ui/gfx/geometry/size_conversions.h"
22 22
23 namespace cc { 23 namespace cc {
24 namespace { 24 namespace {
25 25
26 const float kSoonBorderDistanceInScreenPixels = 312.f; 26 const float kSoonBorderDistanceInScreenPixels = 312.f;
27 27
28 class TileEvictionOrder {
29 public:
30 explicit TileEvictionOrder(TreePriority tree_priority)
31 : tree_priority_(tree_priority) {}
32 ~TileEvictionOrder() {}
33
34 bool operator()(const Tile* a, const Tile* b) {
35 const TilePriority& a_priority =
36 a->priority_for_tree_priority(tree_priority_);
37 const TilePriority& b_priority =
38 b->priority_for_tree_priority(tree_priority_);
39
40 DCHECK(a_priority.priority_bin == b_priority.priority_bin);
41 DCHECK(a->required_for_activation() == b->required_for_activation());
42
43 // Or if a is occluded and b is unoccluded.
44 bool a_is_occluded = a->is_occluded_for_tree_priority(tree_priority_);
45 bool b_is_occluded = b->is_occluded_for_tree_priority(tree_priority_);
46 if (a_is_occluded != b_is_occluded)
47 return a_is_occluded;
48
49 // Or if a is farther away from visible.
50 return a_priority.distance_to_visible > b_priority.distance_to_visible;
51 }
52
53 private:
54 TreePriority tree_priority_;
55 };
56
57 } // namespace 28 } // namespace
58 29
59 scoped_ptr<PictureLayerTiling> PictureLayerTiling::Create( 30 scoped_ptr<PictureLayerTiling> PictureLayerTiling::Create(
60 float contents_scale, 31 float contents_scale,
61 const gfx::Size& layer_bounds, 32 const gfx::Size& layer_bounds,
62 PictureLayerTilingClient* client) { 33 PictureLayerTilingClient* client) {
63 return make_scoped_ptr(new PictureLayerTiling(contents_scale, 34 return make_scoped_ptr(new PictureLayerTiling(contents_scale,
64 layer_bounds, 35 layer_bounds,
65 client)); 36 client));
66 } 37 }
67 38
68 PictureLayerTiling::PictureLayerTiling(float contents_scale, 39 PictureLayerTiling::PictureLayerTiling(float contents_scale,
69 const gfx::Size& layer_bounds, 40 const gfx::Size& layer_bounds,
70 PictureLayerTilingClient* client) 41 PictureLayerTilingClient* client)
71 : contents_scale_(contents_scale), 42 : contents_scale_(contents_scale),
72 layer_bounds_(layer_bounds), 43 layer_bounds_(layer_bounds),
73 resolution_(NON_IDEAL_RESOLUTION), 44 resolution_(NON_IDEAL_RESOLUTION),
74 client_(client), 45 client_(client),
75 tiling_data_(gfx::Size(), gfx::Size(), kBorderTexels), 46 tiling_data_(gfx::Size(), gfx::Size(), kBorderTexels),
76 last_impl_frame_time_in_seconds_(0.0), 47 last_impl_frame_time_in_seconds_(0.0),
77 can_require_tiles_for_activation_(false), 48 can_require_tiles_for_activation_(false),
78 current_content_to_screen_scale_(0.f), 49 current_content_to_screen_scale_(0.f),
79 has_visible_rect_tiles_(false), 50 has_visible_rect_tiles_(false),
80 has_skewport_rect_tiles_(false), 51 has_skewport_rect_tiles_(false),
81 has_soon_border_rect_tiles_(false), 52 has_soon_border_rect_tiles_(false),
82 has_eventually_rect_tiles_(false), 53 has_eventually_rect_tiles_(false) {
83 eviction_tiles_cache_valid_(false),
84 eviction_cache_tree_priority_(SAME_PRIORITY_FOR_BOTH_TREES) {
85 gfx::Size content_bounds = 54 gfx::Size content_bounds =
86 gfx::ToCeiledSize(gfx::ScaleSize(layer_bounds, contents_scale)); 55 gfx::ToCeiledSize(gfx::ScaleSize(layer_bounds, contents_scale));
87 gfx::Size tile_size = client_->CalculateTileSize(content_bounds); 56 gfx::Size tile_size = client_->CalculateTileSize(content_bounds);
88 if (tile_size.IsEmpty()) { 57 if (tile_size.IsEmpty()) {
89 layer_bounds_ = gfx::Size(); 58 layer_bounds_ = gfx::Size();
90 content_bounds = gfx::Size(); 59 content_bounds = gfx::Size();
91 } 60 }
92 61
93 DCHECK(!gfx::ToFlooredSize( 62 DCHECK(!gfx::ToFlooredSize(
94 gfx::ScaleSize(layer_bounds, contents_scale)).IsEmpty()) << 63 gfx::ScaleSize(layer_bounds, contents_scale)).IsEmpty()) <<
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
134 } 103 }
135 } 104 }
136 105
137 // Create a new tile because our twin didn't have a valid one. 106 // Create a new tile because our twin didn't have a valid one.
138 scoped_refptr<Tile> tile = client_->CreateTile(this, tile_rect); 107 scoped_refptr<Tile> tile = client_->CreateTile(this, tile_rect);
139 if (tile.get()) { 108 if (tile.get()) {
140 DCHECK(!tile->is_shared()); 109 DCHECK(!tile->is_shared());
141 tile->set_tiling_index(i, j); 110 tile->set_tiling_index(i, j);
142 tiles_[key] = tile; 111 tiles_[key] = tile;
143 } 112 }
144 eviction_tiles_cache_valid_ = false;
145 return tile.get(); 113 return tile.get();
146 } 114 }
147 115
148 void PictureLayerTiling::CreateMissingTilesInLiveTilesRect() { 116 void PictureLayerTiling::CreateMissingTilesInLiveTilesRect() {
149 const PictureLayerTiling* twin_tiling = 117 const PictureLayerTiling* twin_tiling =
150 client_->GetPendingOrActiveTwinTiling(this); 118 client_->GetPendingOrActiveTwinTiling(this);
151 bool include_borders = false; 119 bool include_borders = false;
152 for (TilingData::Iterator iter( 120 for (TilingData::Iterator iter(
153 &tiling_data_, live_tiles_rect_, include_borders); 121 &tiling_data_, live_tiles_rect_, include_borders);
154 iter; 122 iter;
(...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after
502 } 470 }
503 471
504 bool PictureLayerTiling::RemoveTileAt(int i, 472 bool PictureLayerTiling::RemoveTileAt(int i,
505 int j, 473 int j,
506 PictureLayerTiling* recycled_twin) { 474 PictureLayerTiling* recycled_twin) {
507 TileMap::iterator found = tiles_.find(TileMapKey(i, j)); 475 TileMap::iterator found = tiles_.find(TileMapKey(i, j));
508 if (found == tiles_.end()) 476 if (found == tiles_.end())
509 return false; 477 return false;
510 found->second->set_shared(false); 478 found->second->set_shared(false);
511 tiles_.erase(found); 479 tiles_.erase(found);
512 eviction_tiles_cache_valid_ = false;
513 if (recycled_twin) { 480 if (recycled_twin) {
514 // Recycled twin does not also have a recycled twin, so pass NULL. 481 // Recycled twin does not also have a recycled twin, so pass NULL.
515 recycled_twin->RemoveTileAt(i, j, NULL); 482 recycled_twin->RemoveTileAt(i, j, NULL);
516 } 483 }
517 return true; 484 return true;
518 } 485 }
519 486
520 void PictureLayerTiling::Reset() { 487 void PictureLayerTiling::Reset() {
521 live_tiles_rect_ = gfx::Rect(); 488 live_tiles_rect_ = gfx::Rect();
522 PictureLayerTiling* recycled_twin = client_->GetRecycledTwinTiling(this); 489 PictureLayerTiling* recycled_twin = client_->GetRecycledTwinTiling(this);
523 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) { 490 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) {
524 it->second->set_shared(false); 491 it->second->set_shared(false);
525 if (recycled_twin) 492 if (recycled_twin)
526 recycled_twin->RemoveTileAt(it->first.first, it->first.second, NULL); 493 recycled_twin->RemoveTileAt(it->first.first, it->first.second, NULL);
527 } 494 }
528 tiles_.clear(); 495 tiles_.clear();
529 eviction_tiles_cache_valid_ = false;
530 } 496 }
531 497
532 gfx::Rect PictureLayerTiling::ComputeSkewport( 498 gfx::Rect PictureLayerTiling::ComputeSkewport(
533 double current_frame_time_in_seconds, 499 double current_frame_time_in_seconds,
534 const gfx::Rect& visible_rect_in_content_space) const { 500 const gfx::Rect& visible_rect_in_content_space) const {
535 gfx::Rect skewport = visible_rect_in_content_space; 501 gfx::Rect skewport = visible_rect_in_content_space;
536 if (last_impl_frame_time_in_seconds_ == 0.0) 502 if (last_impl_frame_time_in_seconds_ == 0.0)
537 return skewport; 503 return skewport;
538 504
539 double time_delta = 505 double time_delta =
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
651 current_eventually_rect_ = eventually_rect; 617 current_eventually_rect_ = eventually_rect;
652 current_occlusion_in_layer_space_ = occlusion_in_layer_space; 618 current_occlusion_in_layer_space_ = occlusion_in_layer_space;
653 current_content_to_screen_scale_ = content_to_screen_scale; 619 current_content_to_screen_scale_ = content_to_screen_scale;
654 620
655 gfx::Rect tiling_rect(tiling_size()); 621 gfx::Rect tiling_rect(tiling_size());
656 has_visible_rect_tiles_ = tiling_rect.Intersects(current_visible_rect_); 622 has_visible_rect_tiles_ = tiling_rect.Intersects(current_visible_rect_);
657 has_skewport_rect_tiles_ = tiling_rect.Intersects(current_skewport_rect_); 623 has_skewport_rect_tiles_ = tiling_rect.Intersects(current_skewport_rect_);
658 has_soon_border_rect_tiles_ = 624 has_soon_border_rect_tiles_ =
659 tiling_rect.Intersects(current_soon_border_rect_); 625 tiling_rect.Intersects(current_soon_border_rect_);
660 has_eventually_rect_tiles_ = tiling_rect.Intersects(current_eventually_rect_); 626 has_eventually_rect_tiles_ = tiling_rect.Intersects(current_eventually_rect_);
661
662 eviction_tiles_cache_valid_ = false;
663 } 627 }
664 628
665 void PictureLayerTiling::SetLiveTilesRect( 629 void PictureLayerTiling::SetLiveTilesRect(
666 const gfx::Rect& new_live_tiles_rect) { 630 const gfx::Rect& new_live_tiles_rect) {
667 DCHECK(new_live_tiles_rect.IsEmpty() || 631 DCHECK(new_live_tiles_rect.IsEmpty() ||
668 gfx::Rect(tiling_size()).Contains(new_live_tiles_rect)) 632 gfx::Rect(tiling_size()).Contains(new_live_tiles_rect))
669 << "tiling_size: " << tiling_size().ToString() 633 << "tiling_size: " << tiling_size().ToString()
670 << " new_live_tiles_rect: " << new_live_tiles_rect.ToString(); 634 << " new_live_tiles_rect: " << new_live_tiles_rect.ToString();
671 if (live_tiles_rect_ == new_live_tiles_rect) 635 if (live_tiles_rect_ == new_live_tiles_rect)
672 return; 636 return;
(...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after
1041 if (delta < event.distance) 1005 if (delta < event.distance)
1042 break; 1006 break;
1043 } 1007 }
1044 1008
1045 gfx::Rect result(origin_x, origin_y, width, height); 1009 gfx::Rect result(origin_x, origin_y, width, height);
1046 if (cache) 1010 if (cache)
1047 cache->previous_result = result; 1011 cache->previous_result = result;
1048 return result; 1012 return result;
1049 } 1013 }
1050 1014
1051 void PictureLayerTiling::UpdateEvictionCacheIfNeeded(
1052 TreePriority tree_priority) {
1053 if (eviction_tiles_cache_valid_ &&
1054 eviction_cache_tree_priority_ == tree_priority)
1055 return;
1056
1057 eviction_tiles_now_.clear();
1058 eviction_tiles_now_and_required_for_activation_.clear();
1059 eviction_tiles_soon_.clear();
1060 eviction_tiles_soon_and_required_for_activation_.clear();
1061 eviction_tiles_eventually_.clear();
1062 eviction_tiles_eventually_and_required_for_activation_.clear();
1063
1064 for (TileMap::iterator it = tiles_.begin(); it != tiles_.end(); ++it) {
1065 Tile* tile = it->second.get();
1066 UpdateTileAndTwinPriority(tile);
1067 const TilePriority& priority =
1068 tile->priority_for_tree_priority(tree_priority);
1069 switch (priority.priority_bin) {
1070 case TilePriority::EVENTUALLY:
1071 if (tile->required_for_activation())
1072 eviction_tiles_eventually_and_required_for_activation_.push_back(
1073 tile);
1074 else
1075 eviction_tiles_eventually_.push_back(tile);
1076 break;
1077 case TilePriority::SOON:
1078 if (tile->required_for_activation())
1079 eviction_tiles_soon_and_required_for_activation_.push_back(tile);
1080 else
1081 eviction_tiles_soon_.push_back(tile);
1082 break;
1083 case TilePriority::NOW:
1084 if (tile->required_for_activation())
1085 eviction_tiles_now_and_required_for_activation_.push_back(tile);
1086 else
1087 eviction_tiles_now_.push_back(tile);
1088 break;
1089 }
1090 }
1091
1092 // TODO(vmpstr): Do this lazily. One option is to have a "sorted" flag that
1093 // can be updated for each of the queues.
1094 TileEvictionOrder sort_order(tree_priority);
1095 std::sort(eviction_tiles_now_.begin(), eviction_tiles_now_.end(), sort_order);
1096 std::sort(eviction_tiles_now_and_required_for_activation_.begin(),
1097 eviction_tiles_now_and_required_for_activation_.end(),
1098 sort_order);
1099 std::sort(
1100 eviction_tiles_soon_.begin(), eviction_tiles_soon_.end(), sort_order);
1101 std::sort(eviction_tiles_soon_and_required_for_activation_.begin(),
1102 eviction_tiles_soon_and_required_for_activation_.end(),
1103 sort_order);
1104 std::sort(eviction_tiles_eventually_.begin(),
1105 eviction_tiles_eventually_.end(),
1106 sort_order);
1107 std::sort(eviction_tiles_eventually_and_required_for_activation_.begin(),
1108 eviction_tiles_eventually_and_required_for_activation_.end(),
1109 sort_order);
1110
1111 eviction_tiles_cache_valid_ = true;
1112 eviction_cache_tree_priority_ = tree_priority;
1113 }
1114
1115 const std::vector<Tile*>* PictureLayerTiling::GetEvictionTiles(
1116 TreePriority tree_priority,
1117 EvictionCategory category) {
1118 UpdateEvictionCacheIfNeeded(tree_priority);
1119 switch (category) {
1120 case EVENTUALLY:
1121 return &eviction_tiles_eventually_;
1122 case EVENTUALLY_AND_REQUIRED_FOR_ACTIVATION:
1123 return &eviction_tiles_eventually_and_required_for_activation_;
1124 case SOON:
1125 return &eviction_tiles_soon_;
1126 case SOON_AND_REQUIRED_FOR_ACTIVATION:
1127 return &eviction_tiles_soon_and_required_for_activation_;
1128 case NOW:
1129 return &eviction_tiles_now_;
1130 case NOW_AND_REQUIRED_FOR_ACTIVATION:
1131 return &eviction_tiles_now_and_required_for_activation_;
1132 }
1133 NOTREACHED();
1134 return &eviction_tiles_eventually_;
1135 }
1136
1137 PictureLayerTiling::TilingRasterTileIterator::TilingRasterTileIterator() 1015 PictureLayerTiling::TilingRasterTileIterator::TilingRasterTileIterator()
1138 : tiling_(NULL), current_tile_(NULL) {} 1016 : tiling_(NULL), current_tile_(NULL) {}
1139 1017
1140 PictureLayerTiling::TilingRasterTileIterator::TilingRasterTileIterator( 1018 PictureLayerTiling::TilingRasterTileIterator::TilingRasterTileIterator(
1141 PictureLayerTiling* tiling) 1019 PictureLayerTiling* tiling)
1142 : tiling_(tiling), phase_(VISIBLE_RECT), current_tile_(NULL) { 1020 : tiling_(tiling), phase_(VISIBLE_RECT), current_tile_(NULL) {
1143 if (!tiling_->has_visible_rect_tiles_) { 1021 if (!tiling_->has_visible_rect_tiles_) {
1144 AdvancePhase(); 1022 AdvancePhase();
1145 return; 1023 return;
1146 } 1024 }
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
1260 } 1138 }
1261 current_tile_ = tiling_->TileAt(next_index.first, next_index.second); 1139 current_tile_ = tiling_->TileAt(next_index.first, next_index.second);
1262 } 1140 }
1263 1141
1264 if (current_tile_) 1142 if (current_tile_)
1265 tiling_->UpdateTileAndTwinPriority(current_tile_); 1143 tiling_->UpdateTileAndTwinPriority(current_tile_);
1266 return *this; 1144 return *this;
1267 } 1145 }
1268 1146
1269 } // namespace cc 1147 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698