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

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

Issue 375923005: cc: Explicitly invalidate all dropped recordings on the main thread. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: invalid-resize: resizedeletestiles Created 6 years, 5 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 | Annotate | Revision Log
« no previous file with comments | « cc/resources/picture_pile.h ('k') | cc/resources/picture_pile_base.h » ('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_pile.h" 5 #include "cc/resources/picture_pile.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <limits> 8 #include <limits>
9 #include <vector> 9 #include <vector>
10 10
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 150
151 PicturePile::~PicturePile() { 151 PicturePile::~PicturePile() {
152 } 152 }
153 153
154 bool PicturePile::UpdateAndExpandInvalidation( 154 bool PicturePile::UpdateAndExpandInvalidation(
155 ContentLayerClient* painter, 155 ContentLayerClient* painter,
156 Region* invalidation, 156 Region* invalidation,
157 SkColor background_color, 157 SkColor background_color,
158 bool contents_opaque, 158 bool contents_opaque,
159 bool contents_fill_bounds_completely, 159 bool contents_fill_bounds_completely,
160 const gfx::Rect& layer_bounds_rect,
160 const gfx::Rect& visible_layer_rect, 161 const gfx::Rect& visible_layer_rect,
161 int frame_number, 162 int frame_number,
162 Picture::RecordingMode recording_mode, 163 Picture::RecordingMode recording_mode,
163 RenderingStatsInstrumentation* stats_instrumentation) { 164 RenderingStatsInstrumentation* stats_instrumentation) {
164 background_color_ = background_color; 165 background_color_ = background_color;
165 contents_opaque_ = contents_opaque; 166 contents_opaque_ = contents_opaque;
166 contents_fill_bounds_completely_ = contents_fill_bounds_completely; 167 contents_fill_bounds_completely_ = contents_fill_bounds_completely;
167 168
169 bool updated = false;
170
171 Region resize_invalidation;
172 gfx::Rect old_tiling_rect = tiling_rect();
173 if (old_tiling_rect != layer_bounds_rect) {
174 tiling_.SetTilingRect(layer_bounds_rect);
175 updated = true;
176 }
177
168 gfx::Rect interest_rect = visible_layer_rect; 178 gfx::Rect interest_rect = visible_layer_rect;
169 interest_rect.Inset( 179 interest_rect.Inset(
170 -kPixelDistanceToRecord, 180 -kPixelDistanceToRecord,
171 -kPixelDistanceToRecord, 181 -kPixelDistanceToRecord,
172 -kPixelDistanceToRecord, 182 -kPixelDistanceToRecord,
173 -kPixelDistanceToRecord); 183 -kPixelDistanceToRecord);
174 recorded_viewport_ = interest_rect; 184 recorded_viewport_ = interest_rect;
175 recorded_viewport_.Intersect(tiling_rect()); 185 recorded_viewport_.Intersect(tiling_rect());
176 186
177 gfx::Rect interest_rect_over_tiles = 187 gfx::Rect interest_rect_over_tiles =
178 tiling_.ExpandRectToTileBounds(interest_rect); 188 tiling_.ExpandRectToTileBounds(interest_rect);
179 189
190 if (old_tiling_rect != layer_bounds_rect) {
191 has_any_recordings_ = false;
192
193 if (tiling_rect().origin() != old_tiling_rect.origin()) {
194 // If the origin changes we just do something simple.
195 picture_map_.clear();
196 invalidation->Union(old_tiling_rect);
197 invalidation->Union(tiling_rect());
198 } else {
199 // Drop recordings that are outside the new layer bounds or that changed
200 // size.
201 std::vector<PictureMapKey> to_erase;
202 int min_toss_x = tiling_.num_tiles_x();
203 if (tiling_rect().right() > old_tiling_rect.right()) {
204 min_toss_x =
205 tiling_.FirstBorderTileXIndexFromSrcCoord(old_tiling_rect.right());
206 }
207 int min_toss_y = tiling_.num_tiles_y();
208 if (tiling_rect().bottom() > old_tiling_rect.bottom()) {
209 min_toss_y =
210 tiling_.FirstBorderTileYIndexFromSrcCoord(old_tiling_rect.bottom());
211 }
212 for (PictureMap::const_iterator it = picture_map_.begin();
213 it != picture_map_.end();
214 ++it) {
215 const PictureMapKey& key = it->first;
216 if (key.first < min_toss_x && key.second < min_toss_y) {
217 has_any_recordings_ |= !!it->second.GetPicture();
218 continue;
219 }
220 to_erase.push_back(key);
221 }
222
223 for (size_t i = 0; i < to_erase.size(); ++i)
224 picture_map_.erase(to_erase[i]);
225
226 // If a recording is dropped and not re-recorded below, invalidate that
227 // full recording to cause any raster tiles that would use it to be
228 // dropped.
229 // If the recording will be replaced below, just invalidate newly exposed
230 // areas to force raster tiles that include the old recording to know
231 // there is new recording to display.
232 gfx::Rect old_tiling_rect_over_tiles =
233 tiling_.ExpandRectToTileBounds(old_tiling_rect);
234 if (min_toss_x < tiling_.num_tiles_x()) {
235 int unrecorded_left = std::max(tiling_.TilePositionX(min_toss_x),
236 interest_rect_over_tiles.right());
237 int exposed_left = old_tiling_rect.right();
238 int left = std::min(unrecorded_left, exposed_left);
239 int tile_right =
240 tiling_.TilePositionX(min_toss_x) + tiling_.TileSizeX(min_toss_x);
241 int exposed_right = tiling_rect().right();
242 int right = std::min(tile_right, exposed_right);
243 gfx::Rect right_side(left,
244 old_tiling_rect_over_tiles.y(),
245 right - left,
246 old_tiling_rect_over_tiles.height());
247 resize_invalidation.Union(right_side);
248 }
249 if (min_toss_y < tiling_.num_tiles_y()) {
250 int unrecorded_top = std::max(tiling_.TilePositionY(min_toss_y),
251 interest_rect_over_tiles.bottom());
252 int exposed_top = old_tiling_rect.bottom();
253 int top = std::min(unrecorded_top, exposed_top);
254 int tile_bottom =
255 tiling_.TilePositionY(min_toss_y) + tiling_.TileSizeY(min_toss_y);
256 int exposed_bottom = tiling_rect().bottom();
257 int bottom = std::min(tile_bottom, exposed_bottom);
258 gfx::Rect bottom_side(old_tiling_rect_over_tiles.x(),
259 top,
260 old_tiling_rect_over_tiles.width(),
261 bottom - top);
262 resize_invalidation.Union(bottom_side);
263 }
264 }
265 }
266
180 Region invalidation_expanded_to_full_tiles; 267 Region invalidation_expanded_to_full_tiles;
181
182 bool invalidated = false;
183 for (Region::Iterator i(*invalidation); i.has_rect(); i.next()) { 268 for (Region::Iterator i(*invalidation); i.has_rect(); i.next()) {
184 gfx::Rect invalid_rect = i.rect(); 269 gfx::Rect invalid_rect = i.rect();
270
271 // Expand invalidation that is outside tiles that intersect the interest
272 // rect. These tiles are no longer valid and should be considerered fully
273 // invalid, so we can know to not keep around raster tiles that intersect
274 // with these recording tiles.
275 gfx::Rect invalid_rect_outside_interest_rect_tiles = invalid_rect;
276 // TODO(danakj): We should have a Rect-subtract-Rect-to-2-rects operator
277 // instead of using Rect::Subtract which gives you the bounding box of the
278 // subtraction.
279 invalid_rect_outside_interest_rect_tiles.Subtract(interest_rect_over_tiles);
280 invalidation_expanded_to_full_tiles.Union(tiling_.ExpandRectToTileBounds(
281 invalid_rect_outside_interest_rect_tiles));
282
185 // Split this inflated invalidation across tile boundaries and apply it 283 // Split this inflated invalidation across tile boundaries and apply it
186 // to all tiles that it touches. 284 // to all tiles that it touches.
187 bool include_borders = true; 285 bool include_borders = true;
188 for (TilingData::Iterator iter(&tiling_, invalid_rect, include_borders); 286 for (TilingData::Iterator iter(&tiling_, invalid_rect, include_borders);
189 iter; 287 iter;
190 ++iter) { 288 ++iter) {
191 const PictureMapKey& key = iter.index(); 289 const PictureMapKey& key = iter.index();
192 290
193 PictureMap::iterator picture_it = picture_map_.find(key); 291 PictureMap::iterator picture_it = picture_map_.find(key);
194 if (picture_it == picture_map_.end()) 292 if (picture_it == picture_map_.end())
195 continue; 293 continue;
196 294
197 // Inform the grid cell that it has been invalidated in this frame. 295 // Inform the grid cell that it has been invalidated in this frame.
198 invalidated = picture_it->second.Invalidate(frame_number) || invalidated; 296 updated = picture_it->second.Invalidate(frame_number) || updated;
297 // Invalidate drops the picture so the whole tile better be invalidated if
298 // it won't be re-recorded below.
299 DCHECK(
300 tiling_.TileBounds(key.first, key.second).Intersects(interest_rect) ||
301 invalidation_expanded_to_full_tiles.Contains(
302 tiling_.TileBounds(key.first, key.second)));
199 } 303 }
200
201 // Expand invalidation that is outside tiles that intersect the interest
202 // rect. These tiles are no longer valid and should be considerered fully
203 // invalid, so we can know to not keep around raster tiles that intersect
204 // with these recording tiles.
205 gfx::Rect invalid_rect_outside_interest_rect_tiles = invalid_rect;
206 // TODO(danakj): We should have a Rect-subtract-Rect-to-2-rects operator
207 // instead of using Rect::Subtract which gives you the bounding box of the
208 // subtraction.
209 invalid_rect_outside_interest_rect_tiles.Subtract(interest_rect_over_tiles);
210 invalidation_expanded_to_full_tiles.Union(tiling_.ExpandRectToTileBounds(
211 invalid_rect_outside_interest_rect_tiles));
212 } 304 }
213 305
214 invalidation->Union(invalidation_expanded_to_full_tiles); 306 invalidation->Union(invalidation_expanded_to_full_tiles);
307 invalidation->Union(resize_invalidation);
215 308
216 // Make a list of all invalid tiles; we will attempt to 309 // Make a list of all invalid tiles; we will attempt to
217 // cluster these into multiple invalidation regions. 310 // cluster these into multiple invalidation regions.
218 std::vector<gfx::Rect> invalid_tiles; 311 std::vector<gfx::Rect> invalid_tiles;
219 bool include_borders = true; 312 bool include_borders = true;
220 for (TilingData::Iterator it(&tiling_, interest_rect, include_borders); it; 313 for (TilingData::Iterator it(&tiling_, interest_rect, include_borders); it;
221 ++it) { 314 ++it) {
222 const PictureMapKey& key = it.index(); 315 const PictureMapKey& key = it.index();
223 PictureInfo& info = picture_map_[key]; 316 PictureInfo& info = picture_map_[key];
224 317
(...skipping 17 matching lines...) Expand all
242 // to be considered invalid, so that we know not to keep around raster 335 // to be considered invalid, so that we know not to keep around raster
243 // tiles that intersect this recording tile. 336 // tiles that intersect this recording tile.
244 invalidation->Union(tiling_.TileBounds(it.index_x(), it.index_y())); 337 invalidation->Union(tiling_.TileBounds(it.index_x(), it.index_y()));
245 } 338 }
246 } 339 }
247 340
248 std::vector<gfx::Rect> record_rects; 341 std::vector<gfx::Rect> record_rects;
249 ClusterTiles(invalid_tiles, &record_rects); 342 ClusterTiles(invalid_tiles, &record_rects);
250 343
251 if (record_rects.empty()) 344 if (record_rects.empty())
252 return invalidated; 345 return updated;
253 346
254 for (std::vector<gfx::Rect>::iterator it = record_rects.begin(); 347 for (std::vector<gfx::Rect>::iterator it = record_rects.begin();
255 it != record_rects.end(); 348 it != record_rects.end();
256 it++) { 349 it++) {
257 gfx::Rect record_rect = *it; 350 gfx::Rect record_rect = *it;
258 record_rect = PadRect(record_rect); 351 record_rect = PadRect(record_rect);
259 352
260 int repeat_count = std::max(1, slow_down_raster_scale_factor_for_debug_); 353 int repeat_count = std::max(1, slow_down_raster_scale_factor_for_debug_);
261 scoped_refptr<Picture> picture; 354 scoped_refptr<Picture> picture;
262 int num_raster_threads = RasterWorkerPool::GetNumRasterThreads(); 355 int num_raster_threads = RasterWorkerPool::GetNumRasterThreads();
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
308 } 401 }
309 } 402 }
310 DCHECK(found_tile_for_recorded_picture); 403 DCHECK(found_tile_for_recorded_picture);
311 } 404 }
312 405
313 has_any_recordings_ = true; 406 has_any_recordings_ = true;
314 DCHECK(CanRasterSlowTileCheck(recorded_viewport_)); 407 DCHECK(CanRasterSlowTileCheck(recorded_viewport_));
315 return true; 408 return true;
316 } 409 }
317 410
411 void PicturePile::SetEmptyBounds() {
412 tiling_.SetTilingRect(gfx::Rect());
413 picture_map_.clear();
414 has_any_recordings_ = false;
415 recorded_viewport_ = gfx::Rect();
416 }
417
318 } // namespace cc 418 } // namespace cc
OLDNEW
« no previous file with comments | « cc/resources/picture_pile.h ('k') | cc/resources/picture_pile_base.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698