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

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

Issue 505913003: cc: Remove and Create the correct tiles when resizing live tiles rect (Closed) Base URL: http://chromium.googlesource.com/chromium/src.git@master
Patch Set: livetiles: rebase Created 6 years, 3 months 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
« no previous file with comments | « cc/resources/picture_layer_tiling.h ('k') | cc/resources/picture_layer_tiling_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "cc/base/math_util.h" 15 #include "cc/base/math_util.h"
15 #include "cc/resources/tile.h" 16 #include "cc/resources/tile.h"
16 #include "cc/resources/tile_priority.h" 17 #include "cc/resources/tile_priority.h"
17 #include "cc/trees/occlusion_tracker.h" 18 #include "cc/trees/occlusion_tracker.h"
18 #include "ui/gfx/point_conversions.h" 19 #include "ui/gfx/point_conversions.h"
19 #include "ui/gfx/rect_conversions.h" 20 #include "ui/gfx/rect_conversions.h"
20 #include "ui/gfx/safe_integer_conversions.h" 21 #include "ui/gfx/safe_integer_conversions.h"
21 #include "ui/gfx/size_conversions.h" 22 #include "ui/gfx/size_conversions.h"
22 23
23 namespace cc { 24 namespace cc {
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
140 scoped_refptr<Tile> tile = client_->CreateTile(this, tile_rect); 141 scoped_refptr<Tile> tile = client_->CreateTile(this, tile_rect);
141 if (tile.get()) { 142 if (tile.get()) {
142 DCHECK(!tile->is_shared()); 143 DCHECK(!tile->is_shared());
143 tiles_[key] = tile; 144 tiles_[key] = tile;
144 } 145 }
145 return tile.get(); 146 return tile.get();
146 } 147 }
147 148
148 void PictureLayerTiling::CreateMissingTilesInLiveTilesRect() { 149 void PictureLayerTiling::CreateMissingTilesInLiveTilesRect() {
149 const PictureLayerTiling* twin_tiling = client_->GetTwinTiling(this); 150 const PictureLayerTiling* twin_tiling = client_->GetTwinTiling(this);
150 bool include_borders = true; 151 bool include_borders = false;
151 for (TilingData::Iterator iter( 152 for (TilingData::Iterator iter(
152 &tiling_data_, live_tiles_rect_, include_borders); 153 &tiling_data_, live_tiles_rect_, include_borders);
153 iter; 154 iter;
154 ++iter) { 155 ++iter) {
155 TileMapKey key = iter.index(); 156 TileMapKey key = iter.index();
156 TileMap::iterator find = tiles_.find(key); 157 TileMap::iterator find = tiles_.find(key);
157 if (find != tiles_.end()) 158 if (find != tiles_.end())
158 continue; 159 continue;
159 CreateTile(key.first, key.second, twin_tiling); 160 CreateTile(key.first, key.second, twin_tiling);
160 } 161 }
162
163 VerifyLiveTilesRect();
161 } 164 }
162 165
163 void PictureLayerTiling::UpdateTilesToCurrentPile( 166 void PictureLayerTiling::UpdateTilesToCurrentPile(
164 const Region& layer_invalidation, 167 const Region& layer_invalidation,
165 const gfx::Size& new_layer_bounds) { 168 const gfx::Size& new_layer_bounds) {
166 DCHECK(!new_layer_bounds.IsEmpty()); 169 DCHECK(!new_layer_bounds.IsEmpty());
167 170
168 gfx::Size old_layer_bounds = layer_bounds_; 171 gfx::Size old_layer_bounds = layer_bounds_;
169 layer_bounds_ = new_layer_bounds; 172 layer_bounds_ = new_layer_bounds;
170 173
171 gfx::Size content_bounds = 174 gfx::Size content_bounds =
172 gfx::ToCeiledSize(gfx::ScaleSize(layer_bounds_, contents_scale_)); 175 gfx::ToCeiledSize(gfx::ScaleSize(layer_bounds_, contents_scale_));
173 gfx::Size tile_size = tiling_data_.max_texture_size(); 176 gfx::Size tile_size = tiling_data_.max_texture_size();
174 177
175 if (layer_bounds_ != old_layer_bounds) { 178 if (layer_bounds_ != old_layer_bounds) {
179 // The SetLiveTilesRect() method would drop tiles outside the new bounds,
180 // but may do so incorrectly if resizing the tiling causes the number of
181 // tiles in the tiling_data_ to change.
182 gfx::Rect content_rect(content_bounds);
183 int before_left = tiling_data_.TileXIndexFromSrcCoord(live_tiles_rect_.x());
184 int before_top = tiling_data_.TileYIndexFromSrcCoord(live_tiles_rect_.y());
185 int before_right =
186 tiling_data_.TileXIndexFromSrcCoord(live_tiles_rect_.right() - 1);
187 int before_bottom =
188 tiling_data_.TileYIndexFromSrcCoord(live_tiles_rect_.bottom() - 1);
189
190 // The live_tiles_rect_ is clamped to stay within the tiling size as we
191 // change it.
192 live_tiles_rect_.Intersect(content_rect);
193 tiling_data_.SetTilingSize(content_bounds);
194
195 int after_right = -1;
196 int after_bottom = -1;
197 if (!live_tiles_rect_.IsEmpty()) {
198 after_right =
199 tiling_data_.TileXIndexFromSrcCoord(live_tiles_rect_.right() - 1);
200 after_bottom =
201 tiling_data_.TileYIndexFromSrcCoord(live_tiles_rect_.bottom() - 1);
202 }
203
204 // There is no recycled twin since this is run on the pending tiling.
205 PictureLayerTiling* recycled_twin = NULL;
206 DCHECK_EQ(recycled_twin, client_->GetRecycledTwinTiling(this));
207 DCHECK_EQ(PENDING_TREE, client_->GetTree());
208
176 // Drop tiles outside the new layer bounds if the layer shrank. 209 // Drop tiles outside the new layer bounds if the layer shrank.
177 SetLiveTilesRect( 210 for (int i = after_right + 1; i <= before_right; ++i) {
178 gfx::IntersectRects(live_tiles_rect_, gfx::Rect(content_bounds))); 211 for (int j = before_top; j <= before_bottom; ++j)
179 tiling_data_.SetTilingSize(content_bounds); 212 RemoveTileAt(i, j, recycled_twin);
213 }
214 for (int i = before_left; i <= after_right; ++i) {
215 for (int j = after_bottom + 1; j <= before_bottom; ++j)
216 RemoveTileAt(i, j, recycled_twin);
217 }
218
219 // If the layer grew, the live_tiles_rect_ is not changed, but a new row
220 // and/or column of tiles may now exist inside the same live_tiles_rect_.
221 const PictureLayerTiling* twin_tiling = client_->GetTwinTiling(this);
222 if (after_right > before_right) {
223 DCHECK_EQ(after_right, before_right + 1);
224 for (int j = before_top; j <= after_bottom; ++j)
225 CreateTile(after_right, j, twin_tiling);
226 }
227 if (after_bottom > before_bottom) {
228 DCHECK_EQ(after_bottom, before_bottom + 1);
229 for (int i = before_left; i <= before_right; ++i)
230 CreateTile(i, after_bottom, twin_tiling);
231 }
232
180 tile_size = client_->CalculateTileSize(content_bounds); 233 tile_size = client_->CalculateTileSize(content_bounds);
181 } 234 }
182 235
183 if (tile_size != tiling_data_.max_texture_size()) { 236 if (tile_size != tiling_data_.max_texture_size()) {
184 tiling_data_.SetMaxTextureSize(tile_size); 237 tiling_data_.SetMaxTextureSize(tile_size);
185 // When the tile size changes, the TilingData positions no longer work 238 // When the tile size changes, the TilingData positions no longer work
186 // as valid keys to the TileMap, so just drop all tiles. 239 // as valid keys to the TileMap, so just drop all tiles.
187 Reset(); 240 Reset();
188 } else { 241 } else {
189 Invalidate(layer_invalidation); 242 Invalidate(layer_invalidation);
190 } 243 }
191 244
192 PicturePileImpl* pile = client_->GetPile(); 245 PicturePileImpl* pile = client_->GetPile();
193 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) 246 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it)
194 it->second->set_picture_pile(pile); 247 it->second->set_picture_pile(pile);
248 VerifyLiveTilesRect();
195 } 249 }
196 250
197 void PictureLayerTiling::RemoveTilesInRegion(const Region& layer_region) { 251 void PictureLayerTiling::RemoveTilesInRegion(const Region& layer_region) {
198 bool recreate_invalidated_tiles = false; 252 bool recreate_invalidated_tiles = false;
199 DoInvalidate(layer_region, recreate_invalidated_tiles); 253 DoInvalidate(layer_region, recreate_invalidated_tiles);
200 } 254 }
201 255
202 void PictureLayerTiling::Invalidate(const Region& layer_region) { 256 void PictureLayerTiling::Invalidate(const Region& layer_region) {
203 bool recreate_invalidated_tiles = true; 257 bool recreate_invalidated_tiles = true;
204 DoInvalidate(layer_region, recreate_invalidated_tiles); 258 DoInvalidate(layer_region, recreate_invalidated_tiles);
205 } 259 }
206 260
207 void PictureLayerTiling::DoInvalidate(const Region& layer_region, 261 void PictureLayerTiling::DoInvalidate(const Region& layer_region,
208 bool recreate_invalidated_tiles) { 262 bool recreate_invalidated_tiles) {
209 std::vector<TileMapKey> new_tile_keys; 263 std::vector<TileMapKey> new_tile_keys;
210 gfx::Rect expanded_live_tiles_rect = 264 gfx::Rect expanded_live_tiles_rect =
211 tiling_data_.ExpandRectIgnoringBordersToTileBoundsWithBorders( 265 tiling_data_.ExpandRectIgnoringBordersToTileBounds(live_tiles_rect_);
212 live_tiles_rect_);
213 for (Region::Iterator iter(layer_region); iter.has_rect(); iter.next()) { 266 for (Region::Iterator iter(layer_region); iter.has_rect(); iter.next()) {
214 gfx::Rect layer_rect = iter.rect(); 267 gfx::Rect layer_rect = iter.rect();
215 gfx::Rect content_rect = 268 gfx::Rect content_rect =
216 gfx::ScaleToEnclosingRect(layer_rect, contents_scale_); 269 gfx::ScaleToEnclosingRect(layer_rect, contents_scale_);
270 // Consider tiles inside the live tiles rect even if only their border
271 // pixels intersect the invalidation. But don't consider tiles outside
272 // the live tiles rect with the same conditions, as they won't exist.
273 int border_pixels = tiling_data_.border_texels();
274 content_rect.Inset(-border_pixels, -border_pixels);
217 // Avoid needless work by not bothering to invalidate where there aren't 275 // Avoid needless work by not bothering to invalidate where there aren't
218 // tiles. 276 // tiles.
219 content_rect.Intersect(expanded_live_tiles_rect); 277 content_rect.Intersect(expanded_live_tiles_rect);
220 if (content_rect.IsEmpty()) 278 if (content_rect.IsEmpty())
221 continue; 279 continue;
222 bool include_borders = true; 280 // Since the content_rect includes border pixels already, don't include
281 // borders when iterating to avoid double counting them.
282 bool include_borders = false;
223 for (TilingData::Iterator iter( 283 for (TilingData::Iterator iter(
224 &tiling_data_, content_rect, include_borders); 284 &tiling_data_, content_rect, include_borders);
225 iter; 285 iter;
226 ++iter) { 286 ++iter) {
227 // There is no recycled twin since this is run on the pending tiling. 287 // There is no recycled twin since this is run on the pending tiling.
228 PictureLayerTiling* recycled_twin = NULL; 288 PictureLayerTiling* recycled_twin = NULL;
229 DCHECK_EQ(recycled_twin, client_->GetRecycledTwinTiling(this)); 289 DCHECK_EQ(recycled_twin, client_->GetRecycledTwinTiling(this));
230 DCHECK_EQ(PENDING_TREE, client_->GetTree()); 290 DCHECK_EQ(PENDING_TREE, client_->GetTree());
231 if (RemoveTileAt(iter.index_x(), iter.index_y(), recycled_twin)) 291 if (RemoveTileAt(iter.index_x(), iter.index_y(), recycled_twin))
232 new_tile_keys.push_back(iter.index()); 292 new_tile_keys.push_back(iter.index());
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after
515 575
516 last_impl_frame_time_in_seconds_ = current_frame_time_in_seconds; 576 last_impl_frame_time_in_seconds_ = current_frame_time_in_seconds;
517 last_visible_rect_in_content_space_ = visible_rect_in_content_space; 577 last_visible_rect_in_content_space_ = visible_rect_in_content_space;
518 578
519 eviction_tiles_cache_valid_ = false; 579 eviction_tiles_cache_valid_ = false;
520 580
521 TilePriority now_priority(resolution_, TilePriority::NOW, 0); 581 TilePriority now_priority(resolution_, TilePriority::NOW, 0);
522 float content_to_screen_scale = ideal_contents_scale / contents_scale_; 582 float content_to_screen_scale = ideal_contents_scale / contents_scale_;
523 583
524 // Assign now priority to all visible tiles. 584 // Assign now priority to all visible tiles.
525 bool include_borders = true; 585 bool include_borders = false;
526 has_visible_rect_tiles_ = false; 586 has_visible_rect_tiles_ = false;
527 for (TilingData::Iterator iter( 587 for (TilingData::Iterator iter(
528 &tiling_data_, visible_rect_in_content_space, include_borders); 588 &tiling_data_, visible_rect_in_content_space, include_borders);
529 iter; 589 iter;
530 ++iter) { 590 ++iter) {
531 TileMap::iterator find = tiles_.find(iter.index()); 591 TileMap::iterator find = tiles_.find(iter.index());
532 if (find == tiles_.end()) 592 if (find == tiles_.end())
533 continue; 593 continue;
534 has_visible_rect_tiles_ = true; 594 has_visible_rect_tiles_ = true;
535 Tile* tile = find->second.get(); 595 Tile* tile = find->second.get();
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
649 for (TilingData::DifferenceIterator iter(&tiling_data_, 709 for (TilingData::DifferenceIterator iter(&tiling_data_,
650 new_live_tiles_rect, 710 new_live_tiles_rect,
651 live_tiles_rect_); 711 live_tiles_rect_);
652 iter; 712 iter;
653 ++iter) { 713 ++iter) {
654 TileMapKey key(iter.index()); 714 TileMapKey key(iter.index());
655 CreateTile(key.first, key.second, twin_tiling); 715 CreateTile(key.first, key.second, twin_tiling);
656 } 716 }
657 717
658 live_tiles_rect_ = new_live_tiles_rect; 718 live_tiles_rect_ = new_live_tiles_rect;
719 VerifyLiveTilesRect();
720 }
721
722 void PictureLayerTiling::VerifyLiveTilesRect() {
723 #if DCHECK_IS_ON
724 for (TileMap::iterator it = tiles_.begin(); it != tiles_.end(); ++it) {
725 if (!it->second.get())
726 continue;
727 DCHECK(it->first.first < tiling_data_.num_tiles_x())
728 << this << " " << it->first.first << "," << it->first.second
729 << " num_tiles_x " << tiling_data_.num_tiles_x() << " live_tiles_rect "
730 << live_tiles_rect_.ToString();
731 DCHECK(it->first.second < tiling_data_.num_tiles_y())
732 << this << " " << it->first.first << "," << it->first.second
733 << " num_tiles_y " << tiling_data_.num_tiles_y() << " live_tiles_rect "
734 << live_tiles_rect_.ToString();
735 DCHECK(tiling_data_.TileBounds(it->first.first, it->first.second)
736 .Intersects(live_tiles_rect_))
737 << this << " " << it->first.first << "," << it->first.second
738 << " tile bounds "
739 << tiling_data_.TileBounds(it->first.first, it->first.second).ToString()
740 << " live_tiles_rect " << live_tiles_rect_.ToString();
741 }
742 #endif
659 } 743 }
660 744
661 void PictureLayerTiling::DidBecomeRecycled() { 745 void PictureLayerTiling::DidBecomeRecycled() {
662 // DidBecomeActive below will set the active priority for tiles that are 746 // DidBecomeActive below will set the active priority for tiles that are
663 // still in the tree. Calling this first on an active tiling that is becoming 747 // still in the tree. Calling this first on an active tiling that is becoming
664 // recycled takes care of tiles that are no longer in the active tree (eg. 748 // recycled takes care of tiles that are no longer in the active tree (eg.
665 // due to a pending invalidation). 749 // due to a pending invalidation).
666 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) { 750 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) {
667 it->second->SetPriority(ACTIVE_TREE, TilePriority()); 751 it->second->SetPriority(ACTIVE_TREE, TilePriority());
668 } 752 }
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after
949 PictureLayerTiling* tiling, 1033 PictureLayerTiling* tiling,
950 WhichTree tree) 1034 WhichTree tree)
951 : tiling_(tiling), phase_(VISIBLE_RECT), tree_(tree), current_tile_(NULL) { 1035 : tiling_(tiling), phase_(VISIBLE_RECT), tree_(tree), current_tile_(NULL) {
952 if (!tiling_->has_visible_rect_tiles_) { 1036 if (!tiling_->has_visible_rect_tiles_) {
953 AdvancePhase(); 1037 AdvancePhase();
954 return; 1038 return;
955 } 1039 }
956 1040
957 visible_iterator_ = TilingData::Iterator(&tiling_->tiling_data_, 1041 visible_iterator_ = TilingData::Iterator(&tiling_->tiling_data_,
958 tiling_->current_visible_rect_, 1042 tiling_->current_visible_rect_,
959 true /* include_borders */); 1043 false /* include_borders */);
960 if (!visible_iterator_) { 1044 if (!visible_iterator_) {
961 AdvancePhase(); 1045 AdvancePhase();
962 return; 1046 return;
963 } 1047 }
964 1048
965 current_tile_ = 1049 current_tile_ =
966 tiling_->TileAt(visible_iterator_.index_x(), visible_iterator_.index_y()); 1050 tiling_->TileAt(visible_iterator_.index_x(), visible_iterator_.index_y());
967 if (!current_tile_ || !TileNeedsRaster(current_tile_)) 1051 if (!current_tile_ || !TileNeedsRaster(current_tile_))
968 ++(*this); 1052 ++(*this);
969 } 1053 }
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
1106 DCHECK(*this); 1190 DCHECK(*this);
1107 do { 1191 do {
1108 ++current_eviction_tiles_index_; 1192 ++current_eviction_tiles_index_;
1109 } while (current_eviction_tiles_index_ != eviction_tiles_->size() && 1193 } while (current_eviction_tiles_index_ != eviction_tiles_->size() &&
1110 !(*eviction_tiles_)[current_eviction_tiles_index_]->HasResources()); 1194 !(*eviction_tiles_)[current_eviction_tiles_index_]->HasResources());
1111 1195
1112 return *this; 1196 return *this;
1113 } 1197 }
1114 1198
1115 } // namespace cc 1199 } // namespace cc
OLDNEW
« no previous file with comments | « cc/resources/picture_layer_tiling.h ('k') | cc/resources/picture_layer_tiling_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698