OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |