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 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
159 ContentLayerClient* painter, | 159 ContentLayerClient* painter, |
160 Region* invalidation, | 160 Region* invalidation, |
161 SkColor background_color, | 161 SkColor background_color, |
162 bool contents_opaque, | 162 bool contents_opaque, |
163 bool contents_fill_bounds_completely, | 163 bool contents_fill_bounds_completely, |
164 const gfx::Size& layer_size, | 164 const gfx::Size& layer_size, |
165 const gfx::Rect& visible_layer_rect, | 165 const gfx::Rect& visible_layer_rect, |
166 int frame_number, | 166 int frame_number, |
167 Picture::RecordingMode recording_mode, | 167 Picture::RecordingMode recording_mode, |
168 RenderingStatsInstrumentation* stats_instrumentation) { | 168 RenderingStatsInstrumentation* stats_instrumentation) { |
169 TRACE_EVENT0("cc", "PicturePile::UpdateAndExpandInvalidation"); | |
ajuma
2014/10/10 15:43:03
Did you mean to add these trace events, or is this
danakj
2014/10/10 16:07:15
Oh thanks that's from debugging the next bug, they
| |
169 background_color_ = background_color; | 170 background_color_ = background_color; |
170 contents_opaque_ = contents_opaque; | 171 contents_opaque_ = contents_opaque; |
171 contents_fill_bounds_completely_ = contents_fill_bounds_completely; | 172 contents_fill_bounds_completely_ = contents_fill_bounds_completely; |
172 | 173 |
173 bool updated = false; | 174 bool updated = false; |
174 | 175 |
175 Region resize_invalidation; | 176 Region resize_invalidation; |
176 gfx::Size old_tiling_size = tiling_size(); | 177 gfx::Size old_tiling_size = tiling_size(); |
177 if (old_tiling_size != layer_size) { | 178 if (old_tiling_size != layer_size) { |
178 tiling_.SetTilingSize(layer_size); | 179 tiling_.SetTilingSize(layer_size); |
179 updated = true; | 180 updated = true; |
180 } | 181 } |
181 | 182 |
182 gfx::Rect interest_rect = visible_layer_rect; | 183 gfx::Rect interest_rect = visible_layer_rect; |
183 interest_rect.Inset( | 184 interest_rect.Inset( |
184 -kPixelDistanceToRecord, | 185 -kPixelDistanceToRecord, |
185 -kPixelDistanceToRecord, | 186 -kPixelDistanceToRecord, |
186 -kPixelDistanceToRecord, | 187 -kPixelDistanceToRecord, |
187 -kPixelDistanceToRecord); | 188 -kPixelDistanceToRecord); |
188 recorded_viewport_ = interest_rect; | 189 recorded_viewport_ = interest_rect; |
189 recorded_viewport_.Intersect(gfx::Rect(tiling_size())); | 190 recorded_viewport_.Intersect(gfx::Rect(tiling_size())); |
190 | 191 |
191 gfx::Rect interest_rect_over_tiles = | 192 gfx::Rect interest_rect_over_tiles = |
192 tiling_.ExpandRectToTileBounds(interest_rect); | 193 tiling_.ExpandRectToTileBounds(interest_rect); |
193 | 194 |
194 if (old_tiling_size != layer_size) { | 195 if (old_tiling_size != layer_size) { |
196 TRACE_EVENT0("cc", "PicturePile::SizeChanged"); | |
195 has_any_recordings_ = false; | 197 has_any_recordings_ = false; |
196 | 198 |
197 // Drop recordings that are outside the new layer bounds or that changed | 199 // Drop recordings that are outside the new layer bounds or that changed |
198 // size. | 200 // size. |
199 std::vector<PictureMapKey> to_erase; | 201 std::vector<PictureMapKey> to_erase; |
200 int min_toss_x = tiling_.num_tiles_x(); | 202 int min_toss_x = tiling_.num_tiles_x(); |
201 if (tiling_size().width() > old_tiling_size.width()) { | 203 if (tiling_size().width() > old_tiling_size.width()) { |
202 min_toss_x = | 204 min_toss_x = |
203 tiling_.FirstBorderTileXIndexFromSrcCoord(old_tiling_size.width()); | 205 tiling_.FirstBorderTileXIndexFromSrcCoord(old_tiling_size.width()); |
204 } | 206 } |
205 int min_toss_y = tiling_.num_tiles_y(); | 207 int min_toss_y = tiling_.num_tiles_y(); |
206 if (tiling_size().height() > old_tiling_size.height()) { | 208 if (tiling_size().height() > old_tiling_size.height()) { |
207 min_toss_y = | 209 min_toss_y = |
208 tiling_.FirstBorderTileYIndexFromSrcCoord(old_tiling_size.height()); | 210 tiling_.FirstBorderTileYIndexFromSrcCoord(old_tiling_size.height()); |
209 } | 211 } |
212 { | |
213 TRACE_EVENT0("cc", "PicturePile::FindingKeys"); | |
210 for (PictureMap::const_iterator it = picture_map_.begin(); | 214 for (PictureMap::const_iterator it = picture_map_.begin(); |
211 it != picture_map_.end(); | 215 it != picture_map_.end(); |
212 ++it) { | 216 ++it) { |
213 const PictureMapKey& key = it->first; | 217 const PictureMapKey& key = it->first; |
214 if (key.first < min_toss_x && key.second < min_toss_y) { | 218 if (key.first < min_toss_x && key.second < min_toss_y) { |
215 has_any_recordings_ |= !!it->second.GetPicture(); | 219 has_any_recordings_ |= !!it->second.GetPicture(); |
216 continue; | 220 continue; |
217 } | 221 } |
218 to_erase.push_back(key); | 222 to_erase.push_back(key); |
219 } | 223 } |
224 } | |
220 | 225 |
226 { | |
227 TRACE_EVENT0("cc", "PicturePile::DeletingKeys"); | |
221 for (size_t i = 0; i < to_erase.size(); ++i) | 228 for (size_t i = 0; i < to_erase.size(); ++i) |
222 picture_map_.erase(to_erase[i]); | 229 picture_map_.erase(to_erase[i]); |
230 } | |
223 | 231 |
224 // If a recording is dropped and not re-recorded below, invalidate that | 232 // If a recording is dropped and not re-recorded below, invalidate that |
225 // full recording to cause any raster tiles that would use it to be | 233 // full recording to cause any raster tiles that would use it to be |
226 // dropped. | 234 // dropped. |
227 // If the recording will be replaced below, just invalidate newly exposed | 235 // If the recording will be replaced below, just invalidate newly exposed |
228 // areas to force raster tiles that include the old recording to know | 236 // areas to force raster tiles that include the old recording to know |
229 // there is new recording to display. | 237 // there is new recording to display. |
230 gfx::Rect old_tiling_rect_over_tiles = | 238 gfx::Rect old_tiling_rect_over_tiles = |
231 tiling_.ExpandRectToTileBounds(gfx::Rect(old_tiling_size)); | 239 tiling_.ExpandRectToTileBounds(gfx::Rect(old_tiling_size)); |
232 if (min_toss_x < tiling_.num_tiles_x()) { | 240 if (min_toss_x < tiling_.num_tiles_x()) { |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
374 resize_invalidation.Union(right_rect); | 382 resize_invalidation.Union(right_rect); |
375 resize_invalidation.Union(top_rect); | 383 resize_invalidation.Union(top_rect); |
376 resize_invalidation.Union(bottom_rect); | 384 resize_invalidation.Union(bottom_rect); |
377 resize_invalidation.Union(exposed_rect); | 385 resize_invalidation.Union(exposed_rect); |
378 } | 386 } |
379 } | 387 } |
380 | 388 |
381 Region invalidation_expanded_to_full_tiles; | 389 Region invalidation_expanded_to_full_tiles; |
382 for (Region::Iterator i(*invalidation); i.has_rect(); i.next()) { | 390 for (Region::Iterator i(*invalidation); i.has_rect(); i.next()) { |
383 gfx::Rect invalid_rect = i.rect(); | 391 gfx::Rect invalid_rect = i.rect(); |
392 TRACE_EVENT1( | |
393 "cc", "PicturePile::Invalidating", "rect", invalid_rect.ToString()); | |
384 | 394 |
385 // Expand invalidation that is outside tiles that intersect the interest | 395 // Expand invalidation that is outside tiles that intersect the interest |
386 // rect. These tiles are no longer valid and should be considerered fully | 396 // rect. These tiles are no longer valid and should be considerered fully |
387 // invalid, so we can know to not keep around raster tiles that intersect | 397 // invalid, so we can know to not keep around raster tiles that intersect |
388 // with these recording tiles. | 398 // with these recording tiles. |
389 gfx::Rect invalid_rect_outside_interest_rect_tiles = invalid_rect; | 399 gfx::Rect invalid_rect_outside_interest_rect_tiles = invalid_rect; |
390 // TODO(danakj): We should have a Rect-subtract-Rect-to-2-rects operator | 400 // TODO(danakj): We should have a Rect-subtract-Rect-to-2-rects operator |
391 // instead of using Rect::Subtract which gives you the bounding box of the | 401 // instead of using Rect::Subtract which gives you the bounding box of the |
392 // subtraction. | 402 // subtraction. |
393 invalid_rect_outside_interest_rect_tiles.Subtract(interest_rect_over_tiles); | 403 invalid_rect_outside_interest_rect_tiles.Subtract(interest_rect_over_tiles); |
394 invalidation_expanded_to_full_tiles.Union(tiling_.ExpandRectToTileBounds( | 404 invalidation_expanded_to_full_tiles.Union(tiling_.ExpandRectToTileBounds( |
395 invalid_rect_outside_interest_rect_tiles)); | 405 invalid_rect_outside_interest_rect_tiles)); |
396 | 406 |
397 // Split this inflated invalidation across tile boundaries and apply it | 407 // Split this inflated invalidation across tile boundaries and apply it |
398 // to all tiles that it touches. | 408 // to all tiles that it touches. |
399 bool include_borders = true; | 409 bool include_borders = true; |
410 int n = 0; | |
400 for (TilingData::Iterator iter(&tiling_, invalid_rect, include_borders); | 411 for (TilingData::Iterator iter(&tiling_, invalid_rect, include_borders); |
401 iter; | 412 iter; |
402 ++iter) { | 413 ++iter) { |
414 ++n; | |
403 const PictureMapKey& key = iter.index(); | 415 const PictureMapKey& key = iter.index(); |
404 | 416 |
405 PictureMap::iterator picture_it = picture_map_.find(key); | 417 PictureMap::iterator picture_it = picture_map_.find(key); |
406 if (picture_it == picture_map_.end()) | 418 if (picture_it == picture_map_.end()) |
407 continue; | 419 continue; |
408 | 420 |
409 // Inform the grid cell that it has been invalidated in this frame. | 421 // Inform the grid cell that it has been invalidated in this frame. |
410 updated = picture_it->second.Invalidate(frame_number) || updated; | 422 updated = picture_it->second.Invalidate(frame_number) || updated; |
411 // Invalidate drops the picture so the whole tile better be invalidated if | 423 // Invalidate drops the picture so the whole tile better be invalidated if |
412 // it won't be re-recorded below. | 424 // it won't be re-recorded below. |
413 DCHECK_IMPLIES(!tiling_.TileBounds(key.first, key.second) | 425 DCHECK_IMPLIES(!tiling_.TileBounds(key.first, key.second) |
414 .Intersects(interest_rect_over_tiles), | 426 .Intersects(interest_rect_over_tiles), |
415 invalidation_expanded_to_full_tiles.Contains( | 427 invalidation_expanded_to_full_tiles.Contains( |
416 tiling_.TileBounds(key.first, key.second))); | 428 tiling_.TileBounds(key.first, key.second))); |
417 } | 429 } |
430 TRACE_EVENT1("cc", "PicturePile::InvalidatingTiles", "tiles", n); | |
418 } | 431 } |
419 | 432 |
433 { | |
434 TRACE_EVENT0("cc", "PicturePile::Unioning"); | |
420 invalidation->Union(invalidation_expanded_to_full_tiles); | 435 invalidation->Union(invalidation_expanded_to_full_tiles); |
421 invalidation->Union(resize_invalidation); | 436 invalidation->Union(resize_invalidation); |
437 } | |
422 | 438 |
423 // Make a list of all invalid tiles; we will attempt to | 439 // Make a list of all invalid tiles; we will attempt to |
424 // cluster these into multiple invalidation regions. | 440 // cluster these into multiple invalidation regions. |
425 std::vector<gfx::Rect> invalid_tiles; | 441 std::vector<gfx::Rect> invalid_tiles; |
426 bool include_borders = true; | 442 bool include_borders = true; |
427 for (TilingData::Iterator it(&tiling_, interest_rect, include_borders); it; | 443 for (TilingData::Iterator it(&tiling_, interest_rect, include_borders); it; |
428 ++it) { | 444 ++it) { |
445 TRACE_EVENT0("cc", "PicturePile::ListingTiles"); | |
429 const PictureMapKey& key = it.index(); | 446 const PictureMapKey& key = it.index(); |
430 PictureInfo& info = picture_map_[key]; | 447 PictureInfo& info = picture_map_[key]; |
431 | 448 |
432 gfx::Rect rect = PaddedRect(key); | 449 gfx::Rect rect = PaddedRect(key); |
433 int distance_to_visible = | 450 int distance_to_visible = |
434 rect.ManhattanInternalDistance(visible_layer_rect); | 451 rect.ManhattanInternalDistance(visible_layer_rect); |
435 | 452 |
436 if (info.NeedsRecording(frame_number, distance_to_visible)) { | 453 if (info.NeedsRecording(frame_number, distance_to_visible)) { |
437 gfx::Rect tile = tiling_.TileBounds(key.first, key.second); | 454 gfx::Rect tile = tiling_.TileBounds(key.first, key.second); |
438 invalid_tiles.push_back(tile); | 455 invalid_tiles.push_back(tile); |
439 } else if (!info.GetPicture()) { | 456 } else if (!info.GetPicture()) { |
440 if (recorded_viewport_.Intersects(rect)) { | 457 if (recorded_viewport_.Intersects(rect)) { |
441 // Recorded viewport is just an optimization for a fully recorded | 458 // Recorded viewport is just an optimization for a fully recorded |
442 // interest rect. In this case, a tile in that rect has declined | 459 // interest rect. In this case, a tile in that rect has declined |
443 // to be recorded (probably due to frequent invalidations). | 460 // to be recorded (probably due to frequent invalidations). |
444 // TODO(enne): Shrink the recorded_viewport_ rather than clearing. | 461 // TODO(enne): Shrink the recorded_viewport_ rather than clearing. |
445 recorded_viewport_ = gfx::Rect(); | 462 recorded_viewport_ = gfx::Rect(); |
446 } | 463 } |
447 | 464 |
448 // If a tile in the interest rect is not recorded, the entire tile needs | 465 // If a tile in the interest rect is not recorded, the entire tile needs |
449 // to be considered invalid, so that we know not to keep around raster | 466 // to be considered invalid, so that we know not to keep around raster |
450 // tiles that intersect this recording tile. | 467 // tiles that intersect this recording tile. |
451 invalidation->Union(tiling_.TileBounds(it.index_x(), it.index_y())); | 468 invalidation->Union(tiling_.TileBounds(it.index_x(), it.index_y())); |
452 } | 469 } |
453 } | 470 } |
454 | 471 |
455 std::vector<gfx::Rect> record_rects; | 472 std::vector<gfx::Rect> record_rects; |
473 { | |
474 TRACE_EVENT0("cc", "PicturePile::Clustering"); | |
456 ClusterTiles(invalid_tiles, &record_rects); | 475 ClusterTiles(invalid_tiles, &record_rects); |
476 } | |
457 | 477 |
458 if (record_rects.empty()) | 478 if (record_rects.empty()) |
459 return updated; | 479 return updated; |
460 | 480 |
461 for (std::vector<gfx::Rect>::iterator it = record_rects.begin(); | 481 for (std::vector<gfx::Rect>::iterator it = record_rects.begin(); |
462 it != record_rects.end(); | 482 it != record_rects.end(); |
463 it++) { | 483 it++) { |
464 gfx::Rect record_rect = *it; | 484 gfx::Rect record_rect = *it; |
465 record_rect = PadRect(record_rect); | 485 record_rect = PadRect(record_rect); |
466 | 486 |
467 int repeat_count = std::max(1, slow_down_raster_scale_factor_for_debug_); | 487 int repeat_count = std::max(1, slow_down_raster_scale_factor_for_debug_); |
468 scoped_refptr<Picture> picture; | 488 scoped_refptr<Picture> picture; |
469 | 489 |
470 // Note: Currently, gathering of pixel refs when using a single | 490 // Note: Currently, gathering of pixel refs when using a single |
471 // raster thread doesn't provide any benefit. This might change | 491 // raster thread doesn't provide any benefit. This might change |
472 // in the future but we avoid it for now to reduce the cost of | 492 // in the future but we avoid it for now to reduce the cost of |
473 // Picture::Create. | 493 // Picture::Create. |
474 bool gather_pixel_refs = RasterWorkerPool::GetNumRasterThreads() > 1; | 494 bool gather_pixel_refs = RasterWorkerPool::GetNumRasterThreads() > 1; |
475 | 495 |
476 { | 496 { |
497 TRACE_EVENT0("cc", "PicturePile::Record"); | |
477 base::TimeDelta best_duration = base::TimeDelta::Max(); | 498 base::TimeDelta best_duration = base::TimeDelta::Max(); |
478 for (int i = 0; i < repeat_count; i++) { | 499 for (int i = 0; i < repeat_count; i++) { |
479 base::TimeTicks start_time = stats_instrumentation->StartRecording(); | 500 base::TimeTicks start_time = stats_instrumentation->StartRecording(); |
480 picture = Picture::Create(record_rect, | 501 picture = Picture::Create(record_rect, |
481 painter, | 502 painter, |
482 tile_grid_info_, | 503 tile_grid_info_, |
483 gather_pixel_refs, | 504 gather_pixel_refs, |
484 recording_mode); | 505 recording_mode); |
485 // Note the '&&' with previous is-suitable state. | 506 // Note the '&&' with previous is-suitable state. |
486 // This means that once a picture-pile becomes unsuitable for gpu | 507 // This means that once a picture-pile becomes unsuitable for gpu |
(...skipping 19 matching lines...) Expand all Loading... | |
506 for (TilingData::Iterator it(&tiling_, record_rect, include_borders); it; | 527 for (TilingData::Iterator it(&tiling_, record_rect, include_borders); it; |
507 ++it) { | 528 ++it) { |
508 const PictureMapKey& key = it.index(); | 529 const PictureMapKey& key = it.index(); |
509 gfx::Rect tile = PaddedRect(key); | 530 gfx::Rect tile = PaddedRect(key); |
510 if (record_rect.Contains(tile)) { | 531 if (record_rect.Contains(tile)) { |
511 PictureInfo& info = picture_map_[key]; | 532 PictureInfo& info = picture_map_[key]; |
512 info.SetPicture(picture); | 533 info.SetPicture(picture); |
513 found_tile_for_recorded_picture = true; | 534 found_tile_for_recorded_picture = true; |
514 } | 535 } |
515 } | 536 } |
537 TRACE_EVENT0("cc", "PicturePile::DetermineIfSolidColor"); | |
516 DetermineIfSolidColor(); | 538 DetermineIfSolidColor(); |
517 DCHECK(found_tile_for_recorded_picture); | 539 DCHECK(found_tile_for_recorded_picture); |
518 } | 540 } |
519 | 541 |
520 has_any_recordings_ = true; | 542 has_any_recordings_ = true; |
521 DCHECK(CanRasterSlowTileCheck(recorded_viewport_)); | 543 DCHECK(CanRasterSlowTileCheck(recorded_viewport_)); |
522 return true; | 544 return true; |
523 } | 545 } |
524 | 546 |
525 void PicturePile::SetEmptyBounds() { | 547 void PicturePile::SetEmptyBounds() { |
(...skipping 28 matching lines...) Expand all Loading... | |
554 if (it->second.GetPicture() != picture) | 576 if (it->second.GetPicture() != picture) |
555 return; | 577 return; |
556 } | 578 } |
557 skia::AnalysisCanvas canvas(recorded_viewport_.width(), | 579 skia::AnalysisCanvas canvas(recorded_viewport_.width(), |
558 recorded_viewport_.height()); | 580 recorded_viewport_.height()); |
559 picture->Raster(&canvas, NULL, Region(), 1.0f); | 581 picture->Raster(&canvas, NULL, Region(), 1.0f); |
560 is_solid_color_ = canvas.GetColorIfSolid(&solid_color_); | 582 is_solid_color_ = canvas.GetColorIfSolid(&solid_color_); |
561 } | 583 } |
562 | 584 |
563 } // namespace cc | 585 } // namespace cc |
OLD | NEW |