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

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: Clean up 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 content_to_screen_scale_(0.f), 48 content_to_screen_scale_(0.f),
78 can_require_tiles_for_activation_(false), 49 can_require_tiles_for_activation_(false),
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 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
138 } 107 }
139 } 108 }
140 109
141 // Create a new tile because our twin didn't have a valid one. 110 // Create a new tile because our twin didn't have a valid one.
142 scoped_refptr<Tile> tile = client_->CreateTile(this, tile_rect); 111 scoped_refptr<Tile> tile = client_->CreateTile(this, tile_rect);
143 if (tile.get()) { 112 if (tile.get()) {
144 DCHECK(!tile->is_shared()); 113 DCHECK(!tile->is_shared());
145 tile->set_tiling_index(i, j); 114 tile->set_tiling_index(i, j);
146 tiles_[key] = tile; 115 tiles_[key] = tile;
147 } 116 }
148 eviction_tiles_cache_valid_ = false;
149 return tile.get(); 117 return tile.get();
150 } 118 }
151 119
152 void PictureLayerTiling::CreateMissingTilesInLiveTilesRect() { 120 void PictureLayerTiling::CreateMissingTilesInLiveTilesRect() {
153 const PictureLayerTiling* twin_tiling = 121 const PictureLayerTiling* twin_tiling =
154 client_->GetPendingOrActiveTwinTiling(this); 122 client_->GetPendingOrActiveTwinTiling(this);
155 bool include_borders = false; 123 bool include_borders = false;
156 for (TilingData::Iterator iter( 124 for (TilingData::Iterator iter(
157 &tiling_data_, live_tiles_rect_, include_borders); 125 &tiling_data_, live_tiles_rect_, include_borders);
158 iter; 126 iter;
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after
461 } 429 }
462 430
463 bool PictureLayerTiling::RemoveTileAt(int i, 431 bool PictureLayerTiling::RemoveTileAt(int i,
464 int j, 432 int j,
465 PictureLayerTiling* recycled_twin) { 433 PictureLayerTiling* recycled_twin) {
466 TileMap::iterator found = tiles_.find(TileMapKey(i, j)); 434 TileMap::iterator found = tiles_.find(TileMapKey(i, j));
467 if (found == tiles_.end()) 435 if (found == tiles_.end())
468 return false; 436 return false;
469 found->second->set_shared(false); 437 found->second->set_shared(false);
470 tiles_.erase(found); 438 tiles_.erase(found);
471 eviction_tiles_cache_valid_ = false;
472 if (recycled_twin) { 439 if (recycled_twin) {
473 // Recycled twin does not also have a recycled twin, so pass NULL. 440 // Recycled twin does not also have a recycled twin, so pass NULL.
474 recycled_twin->RemoveTileAt(i, j, NULL); 441 recycled_twin->RemoveTileAt(i, j, NULL);
475 } 442 }
476 return true; 443 return true;
477 } 444 }
478 445
479 void PictureLayerTiling::Reset() { 446 void PictureLayerTiling::Reset() {
480 live_tiles_rect_ = gfx::Rect(); 447 live_tiles_rect_ = gfx::Rect();
481 PictureLayerTiling* recycled_twin = client_->GetRecycledTwinTiling(this); 448 PictureLayerTiling* recycled_twin = client_->GetRecycledTwinTiling(this);
482 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) { 449 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) {
483 it->second->set_shared(false); 450 it->second->set_shared(false);
484 if (recycled_twin) 451 if (recycled_twin)
485 recycled_twin->RemoveTileAt(it->first.first, it->first.second, NULL); 452 recycled_twin->RemoveTileAt(it->first.first, it->first.second, NULL);
486 } 453 }
487 tiles_.clear(); 454 tiles_.clear();
488 eviction_tiles_cache_valid_ = false;
489 } 455 }
490 456
491 gfx::Rect PictureLayerTiling::ComputeSkewport( 457 gfx::Rect PictureLayerTiling::ComputeSkewport(
492 double current_frame_time_in_seconds, 458 double current_frame_time_in_seconds,
493 const gfx::Rect& visible_rect_in_content_space) const { 459 const gfx::Rect& visible_rect_in_content_space) const {
494 gfx::Rect skewport = visible_rect_in_content_space; 460 gfx::Rect skewport = visible_rect_in_content_space;
495 if (last_impl_frame_time_in_seconds_ == 0.0) 461 if (last_impl_frame_time_in_seconds_ == 0.0)
496 return skewport; 462 return skewport;
497 463
498 double time_delta = 464 double time_delta =
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
587 float border = kSoonBorderDistanceInScreenPixels / content_to_screen_scale_; 553 float border = kSoonBorderDistanceInScreenPixels / content_to_screen_scale_;
588 soon_border_rect.Inset(-border, -border, -border, -border); 554 soon_border_rect.Inset(-border, -border, -border, -border);
589 555
590 // Update the tiling state. 556 // Update the tiling state.
591 SetLiveTilesRect(eventually_rect); 557 SetLiveTilesRect(eventually_rect);
592 558
593 last_impl_frame_time_in_seconds_ = current_frame_time_in_seconds; 559 last_impl_frame_time_in_seconds_ = current_frame_time_in_seconds;
594 last_viewport_in_layer_space_ = viewport_in_layer_space; 560 last_viewport_in_layer_space_ = viewport_in_layer_space;
595 last_visible_rect_in_content_space_ = visible_rect_in_content_space; 561 last_visible_rect_in_content_space_ = visible_rect_in_content_space;
596 562
597 eviction_tiles_cache_valid_ = false;
598
599 current_visible_rect_ = visible_rect_in_content_space; 563 current_visible_rect_ = visible_rect_in_content_space;
600 current_skewport_rect_ = skewport; 564 current_skewport_rect_ = skewport;
601 current_soon_border_rect_ = soon_border_rect; 565 current_soon_border_rect_ = soon_border_rect;
602 current_eventually_rect_ = eventually_rect; 566 current_eventually_rect_ = eventually_rect;
603 current_occlusion_in_layer_space_ = occlusion_in_layer_space; 567 current_occlusion_in_layer_space_ = occlusion_in_layer_space;
604 568
605 // Update has_*_tiles state. 569 // Update has_*_tiles state.
606 gfx::Rect tiling_rect(tiling_size()); 570 gfx::Rect tiling_rect(tiling_size());
607 571
608 has_visible_rect_tiles_ = tiling_rect.Intersects(current_visible_rect_); 572 has_visible_rect_tiles_ = tiling_rect.Intersects(current_visible_rect_);
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after
991 if (delta < event.distance) 955 if (delta < event.distance)
992 break; 956 break;
993 } 957 }
994 958
995 gfx::Rect result(origin_x, origin_y, width, height); 959 gfx::Rect result(origin_x, origin_y, width, height);
996 if (cache) 960 if (cache)
997 cache->previous_result = result; 961 cache->previous_result = result;
998 return result; 962 return result;
999 } 963 }
1000 964
1001 void PictureLayerTiling::UpdateEvictionCacheIfNeeded(
1002 TreePriority tree_priority) {
1003 if (eviction_tiles_cache_valid_ &&
1004 eviction_cache_tree_priority_ == tree_priority)
1005 return;
1006
1007 eviction_tiles_now_.clear();
1008 eviction_tiles_now_and_required_for_activation_.clear();
1009 eviction_tiles_soon_.clear();
1010 eviction_tiles_soon_and_required_for_activation_.clear();
1011 eviction_tiles_eventually_.clear();
1012 eviction_tiles_eventually_and_required_for_activation_.clear();
1013
1014 for (TileMap::iterator it = tiles_.begin(); it != tiles_.end(); ++it) {
1015 Tile* tile = it->second.get();
1016 UpdateTileAndTwinPriority(tile);
1017 const TilePriority& priority =
1018 tile->priority_for_tree_priority(tree_priority);
1019 switch (priority.priority_bin) {
1020 case TilePriority::EVENTUALLY:
1021 if (tile->required_for_activation())
1022 eviction_tiles_eventually_and_required_for_activation_.push_back(
1023 tile);
1024 else
1025 eviction_tiles_eventually_.push_back(tile);
1026 break;
1027 case TilePriority::SOON:
1028 if (tile->required_for_activation())
1029 eviction_tiles_soon_and_required_for_activation_.push_back(tile);
1030 else
1031 eviction_tiles_soon_.push_back(tile);
1032 break;
1033 case TilePriority::NOW:
1034 if (tile->required_for_activation())
1035 eviction_tiles_now_and_required_for_activation_.push_back(tile);
1036 else
1037 eviction_tiles_now_.push_back(tile);
1038 break;
1039 }
1040 }
1041
1042 // TODO(vmpstr): Do this lazily. One option is to have a "sorted" flag that
1043 // can be updated for each of the queues.
1044 TileEvictionOrder sort_order(tree_priority);
1045 std::sort(eviction_tiles_now_.begin(), eviction_tiles_now_.end(), sort_order);
1046 std::sort(eviction_tiles_now_and_required_for_activation_.begin(),
1047 eviction_tiles_now_and_required_for_activation_.end(),
1048 sort_order);
1049 std::sort(
1050 eviction_tiles_soon_.begin(), eviction_tiles_soon_.end(), sort_order);
1051 std::sort(eviction_tiles_soon_and_required_for_activation_.begin(),
1052 eviction_tiles_soon_and_required_for_activation_.end(),
1053 sort_order);
1054 std::sort(eviction_tiles_eventually_.begin(),
1055 eviction_tiles_eventually_.end(),
1056 sort_order);
1057 std::sort(eviction_tiles_eventually_and_required_for_activation_.begin(),
1058 eviction_tiles_eventually_and_required_for_activation_.end(),
1059 sort_order);
1060
1061 eviction_tiles_cache_valid_ = true;
1062 eviction_cache_tree_priority_ = tree_priority;
1063 }
1064
1065 const std::vector<Tile*>* PictureLayerTiling::GetEvictionTiles(
1066 TreePriority tree_priority,
1067 EvictionCategory category) {
1068 UpdateEvictionCacheIfNeeded(tree_priority);
1069 switch (category) {
1070 case EVENTUALLY:
1071 return &eviction_tiles_eventually_;
1072 case EVENTUALLY_AND_REQUIRED_FOR_ACTIVATION:
1073 return &eviction_tiles_eventually_and_required_for_activation_;
1074 case SOON:
1075 return &eviction_tiles_soon_;
1076 case SOON_AND_REQUIRED_FOR_ACTIVATION:
1077 return &eviction_tiles_soon_and_required_for_activation_;
1078 case NOW:
1079 return &eviction_tiles_now_;
1080 case NOW_AND_REQUIRED_FOR_ACTIVATION:
1081 return &eviction_tiles_now_and_required_for_activation_;
1082 }
1083 NOTREACHED();
1084 return &eviction_tiles_eventually_;
1085 }
1086
1087 PictureLayerTiling::TilingRasterTileIterator::TilingRasterTileIterator() 965 PictureLayerTiling::TilingRasterTileIterator::TilingRasterTileIterator()
1088 : tiling_(NULL), current_tile_(NULL) {} 966 : tiling_(NULL), current_tile_(NULL) {}
1089 967
1090 PictureLayerTiling::TilingRasterTileIterator::TilingRasterTileIterator( 968 PictureLayerTiling::TilingRasterTileIterator::TilingRasterTileIterator(
1091 PictureLayerTiling* tiling) 969 PictureLayerTiling* tiling)
1092 : tiling_(tiling), phase_(VISIBLE_RECT), current_tile_(NULL) { 970 : tiling_(tiling), phase_(VISIBLE_RECT), current_tile_(NULL) {
1093 if (!tiling_->has_visible_rect_tiles_) { 971 if (!tiling_->has_visible_rect_tiles_) {
1094 AdvancePhase(); 972 AdvancePhase();
1095 return; 973 return;
1096 } 974 }
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
1210 } 1088 }
1211 current_tile_ = tiling_->TileAt(next_index.first, next_index.second); 1089 current_tile_ = tiling_->TileAt(next_index.first, next_index.second);
1212 } 1090 }
1213 1091
1214 if (current_tile_) 1092 if (current_tile_)
1215 tiling_->UpdateTileAndTwinPriority(current_tile_); 1093 tiling_->UpdateTileAndTwinPriority(current_tile_);
1216 return *this; 1094 return *this;
1217 } 1095 }
1218 1096
1219 } // namespace cc 1097 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698