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

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

Issue 754433003: Update from https://crrev.com/305340 (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 6 years, 1 month 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_pile.h ('k') | cc/resources/resource_provider.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 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
99 DCHECK(!cur_record_rect.IsEmpty()); 99 DCHECK(!cur_record_rect.IsEmpty());
100 clustered_rects->push_back(cur_record_rect); 100 clustered_rects->push_back(cur_record_rect);
101 total_record_area += cluster_record_area;; 101 total_record_area += cluster_record_area;;
102 102
103 DCHECK_NE(total_record_area, 0); 103 DCHECK_NE(total_record_area, 0);
104 104
105 return static_cast<float>(total_invalid_area) / 105 return static_cast<float>(total_invalid_area) /
106 static_cast<float>(total_record_area); 106 static_cast<float>(total_record_area);
107 } 107 }
108 108
109 float ClusterTiles(const std::vector<gfx::Rect>& invalid_tiles, 109 void ClusterTiles(const std::vector<gfx::Rect>& invalid_tiles,
110 std::vector<gfx::Rect>* record_rects) { 110 std::vector<gfx::Rect>* record_rects) {
111 TRACE_EVENT1("cc", "ClusterTiles", 111 TRACE_EVENT1("cc", "ClusterTiles",
112 "count", 112 "count",
113 invalid_tiles.size()); 113 invalid_tiles.size());
114
115 if (invalid_tiles.size() <= 1) { 114 if (invalid_tiles.size() <= 1) {
116 // Quickly handle the special case for common 115 // Quickly handle the special case for common
117 // single-invalidation update, and also the less common 116 // single-invalidation update, and also the less common
118 // case of no tiles passed in. 117 // case of no tiles passed in.
119 *record_rects = invalid_tiles; 118 *record_rects = invalid_tiles;
120 return 1; 119 return;
121 } 120 }
122 121
123 // Sort the invalid tiles by y coordinate. 122 // Sort the invalid tiles by y coordinate.
124 std::vector<gfx::Rect> invalid_tiles_vertical = invalid_tiles; 123 std::vector<gfx::Rect> invalid_tiles_vertical = invalid_tiles;
125 std::sort(invalid_tiles_vertical.begin(), 124 std::sort(invalid_tiles_vertical.begin(),
126 invalid_tiles_vertical.end(), 125 invalid_tiles_vertical.end(),
127 rect_sort_y); 126 rect_sort_y);
128 127
129 float vertical_density;
130 std::vector<gfx::Rect> vertical_clustering; 128 std::vector<gfx::Rect> vertical_clustering;
131 vertical_density = PerformClustering(invalid_tiles_vertical, 129 float vertical_density =
132 &vertical_clustering); 130 PerformClustering(invalid_tiles_vertical, &vertical_clustering);
133 131
134 // If vertical density is optimal, then we can return early. 132 // If vertical density is optimal, then we can return early.
135 if (vertical_density == 1.f) { 133 if (vertical_density == 1.f) {
136 *record_rects = vertical_clustering; 134 *record_rects = vertical_clustering;
137 return vertical_density; 135 return;
138 } 136 }
139 137
140 // Now try again with a horizontal sort, see which one is best 138 // Now try again with a horizontal sort, see which one is best
141 std::vector<gfx::Rect> invalid_tiles_horizontal = invalid_tiles; 139 std::vector<gfx::Rect> invalid_tiles_horizontal = invalid_tiles;
142 std::sort(invalid_tiles_horizontal.begin(), 140 std::sort(invalid_tiles_horizontal.begin(),
143 invalid_tiles_horizontal.end(), 141 invalid_tiles_horizontal.end(),
144 rect_sort_x); 142 rect_sort_x);
145 143
146 float horizontal_density;
147 std::vector<gfx::Rect> horizontal_clustering; 144 std::vector<gfx::Rect> horizontal_clustering;
148 horizontal_density = PerformClustering(invalid_tiles_horizontal, 145 float horizontal_density =
149 &horizontal_clustering); 146 PerformClustering(invalid_tiles_horizontal, &horizontal_clustering);
150 147
151 if (vertical_density < horizontal_density) { 148 if (vertical_density < horizontal_density) {
152 *record_rects = horizontal_clustering; 149 *record_rects = horizontal_clustering;
153 return horizontal_density; 150 return;
154 } 151 }
155 152
156 *record_rects = vertical_clustering; 153 *record_rects = vertical_clustering;
157 return vertical_density;
158 } 154 }
159 155
160 } // namespace 156 } // namespace
161 157
162 namespace cc { 158 namespace cc {
163 159
164 PicturePile::PicturePile() 160 PicturePile::PicturePile()
165 : min_contents_scale_(0), 161 : min_contents_scale_(0),
166 slow_down_raster_scale_factor_for_debug_(0), 162 slow_down_raster_scale_factor_for_debug_(0),
167 can_use_lcd_text_(true), 163 can_use_lcd_text_(true),
(...skipping 15 matching lines...) Expand all
183 ContentLayerClient* painter, 179 ContentLayerClient* painter,
184 Region* invalidation, 180 Region* invalidation,
185 bool can_use_lcd_text, 181 bool can_use_lcd_text,
186 const gfx::Size& layer_size, 182 const gfx::Size& layer_size,
187 const gfx::Rect& visible_layer_rect, 183 const gfx::Rect& visible_layer_rect,
188 int frame_number, 184 int frame_number,
189 Picture::RecordingMode recording_mode) { 185 Picture::RecordingMode recording_mode) {
190 bool can_use_lcd_text_changed = can_use_lcd_text_ != can_use_lcd_text; 186 bool can_use_lcd_text_changed = can_use_lcd_text_ != can_use_lcd_text;
191 can_use_lcd_text_ = can_use_lcd_text; 187 can_use_lcd_text_ = can_use_lcd_text;
192 188
189 gfx::Rect interest_rect = visible_layer_rect;
190 interest_rect.Inset(-pixel_record_distance_, -pixel_record_distance_);
191 recorded_viewport_ = interest_rect;
192 recorded_viewport_.Intersect(gfx::Rect(layer_size));
193
194 bool updated =
195 ApplyInvalidationAndResize(interest_rect, invalidation, layer_size,
196 frame_number, can_use_lcd_text_changed);
197 std::vector<gfx::Rect> invalid_tiles;
198 GetInvalidTileRects(interest_rect, invalidation, visible_layer_rect,
199 frame_number, &invalid_tiles);
200 std::vector<gfx::Rect> record_rects;
201 ClusterTiles(invalid_tiles, &record_rects);
202
203 if (record_rects.empty())
204 return updated;
205
206 CreatePictures(painter, recording_mode, record_rects);
207
208 DetermineIfSolidColor();
209
210 has_any_recordings_ = true;
211 DCHECK(CanRasterSlowTileCheck(recorded_viewport_));
212 return true;
213 }
214
215 bool PicturePile::ApplyInvalidationAndResize(const gfx::Rect& interest_rect,
216 Region* invalidation,
217 const gfx::Size& layer_size,
218 int frame_number,
219 bool can_use_lcd_text_changed) {
193 bool updated = false; 220 bool updated = false;
194 221
195 Region synthetic_invalidation; 222 Region synthetic_invalidation;
196 gfx::Size old_tiling_size = GetSize(); 223 gfx::Size old_tiling_size = GetSize();
197 if (old_tiling_size != layer_size) { 224 if (old_tiling_size != layer_size) {
198 tiling_.SetTilingSize(layer_size); 225 tiling_.SetTilingSize(layer_size);
199 updated = true; 226 updated = true;
200 } 227 }
201 if (can_use_lcd_text_changed) { 228 if (can_use_lcd_text_changed) {
202 // When LCD text is enabled/disabled, we must drop any raster tiles for 229 // When LCD text is enabled/disabled, we must drop any raster tiles for
203 // the pile, so they can be recreated in a manner consistent with the new 230 // the pile, so they can be recreated in a manner consistent with the new
204 // setting. We do this with |synthetic_invalidation| since we don't need to 231 // setting. We do this with |synthetic_invalidation| since we don't need to
205 // do a new recording, just invalidate rastered content. 232 // do a new recording, just invalidate rastered content.
206 synthetic_invalidation.Union(gfx::Rect(GetSize())); 233 synthetic_invalidation.Union(gfx::Rect(GetSize()));
207 updated = true; 234 updated = true;
208 } 235 }
209 236
210 gfx::Rect interest_rect = visible_layer_rect;
211 interest_rect.Inset(-pixel_record_distance_, -pixel_record_distance_);
212 recorded_viewport_ = interest_rect;
213 recorded_viewport_.Intersect(gfx::Rect(GetSize()));
214
215 gfx::Rect interest_rect_over_tiles = 237 gfx::Rect interest_rect_over_tiles =
216 tiling_.ExpandRectToTileBounds(interest_rect); 238 tiling_.ExpandRectToTileBounds(interest_rect);
217 239
218 gfx::Size min_tiling_size( 240 if (old_tiling_size != layer_size) {
219 std::min(GetSize().width(), old_tiling_size.width()), 241 gfx::Size min_tiling_size(
220 std::min(GetSize().height(), old_tiling_size.height())); 242 std::min(GetSize().width(), old_tiling_size.width()),
221 gfx::Size max_tiling_size( 243 std::min(GetSize().height(), old_tiling_size.height()));
222 std::max(GetSize().width(), old_tiling_size.width()), 244 gfx::Size max_tiling_size(
223 std::max(GetSize().height(), old_tiling_size.height())); 245 std::max(GetSize().width(), old_tiling_size.width()),
246 std::max(GetSize().height(), old_tiling_size.height()));
224 247
225 if (old_tiling_size != layer_size) {
226 has_any_recordings_ = false; 248 has_any_recordings_ = false;
227 249
228 // Drop recordings that are outside the new or old layer bounds or that 250 // Drop recordings that are outside the new or old layer bounds or that
229 // changed size. Newly exposed areas are considered invalidated. 251 // changed size. Newly exposed areas are considered invalidated.
230 // Previously exposed areas that are now outside of bounds also need to 252 // Previously exposed areas that are now outside of bounds also need to
231 // be invalidated, as they may become part of raster when scale < 1. 253 // be invalidated, as they may become part of raster when scale < 1.
232 std::vector<PictureMapKey> to_erase; 254 std::vector<PictureMapKey> to_erase;
233 int min_toss_x = tiling_.num_tiles_x(); 255 int min_toss_x = tiling_.num_tiles_x();
234 if (max_tiling_size.width() > min_tiling_size.width()) { 256 if (max_tiling_size.width() > min_tiling_size.width()) {
235 min_toss_x = 257 min_toss_x =
236 tiling_.FirstBorderTileXIndexFromSrcCoord(min_tiling_size.width()); 258 tiling_.FirstBorderTileXIndexFromSrcCoord(min_tiling_size.width());
237 } 259 }
238 int min_toss_y = tiling_.num_tiles_y(); 260 int min_toss_y = tiling_.num_tiles_y();
239 if (max_tiling_size.height() > min_tiling_size.height()) { 261 if (max_tiling_size.height() > min_tiling_size.height()) {
240 min_toss_y = 262 min_toss_y =
241 tiling_.FirstBorderTileYIndexFromSrcCoord(min_tiling_size.height()); 263 tiling_.FirstBorderTileYIndexFromSrcCoord(min_tiling_size.height());
242 } 264 }
243 for (PictureMap::const_iterator it = picture_map_.begin(); 265 for (const auto& key_picture_pair : picture_map_) {
244 it != picture_map_.end(); 266 const PictureMapKey& key = key_picture_pair.first;
245 ++it) {
246 const PictureMapKey& key = it->first;
247 if (key.first < min_toss_x && key.second < min_toss_y) { 267 if (key.first < min_toss_x && key.second < min_toss_y) {
248 has_any_recordings_ |= !!it->second.GetPicture(); 268 has_any_recordings_ |= !!key_picture_pair.second.GetPicture();
249 continue; 269 continue;
250 } 270 }
251 to_erase.push_back(key); 271 to_erase.push_back(key);
252 } 272 }
253 273
254 for (size_t i = 0; i < to_erase.size(); ++i) 274 for (size_t i = 0; i < to_erase.size(); ++i)
255 picture_map_.erase(to_erase[i]); 275 picture_map_.erase(to_erase[i]);
256 276
257 // If a recording is dropped and not re-recorded below, invalidate that 277 // If a recording is dropped and not re-recorded below, invalidate that
258 // full recording to cause any raster tiles that would use it to be 278 // full recording to cause any raster tiles that would use it to be
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
465 DCHECK_IMPLIES(!tiling_.TileBounds(key.first, key.second) 485 DCHECK_IMPLIES(!tiling_.TileBounds(key.first, key.second)
466 .Intersects(interest_rect_over_tiles), 486 .Intersects(interest_rect_over_tiles),
467 invalidation_expanded_to_full_tiles.Contains( 487 invalidation_expanded_to_full_tiles.Contains(
468 tiling_.TileBounds(key.first, key.second))); 488 tiling_.TileBounds(key.first, key.second)));
469 } 489 }
470 } 490 }
471 invalidation->Union(invalidation_expanded_to_full_tiles); 491 invalidation->Union(invalidation_expanded_to_full_tiles);
472 } 492 }
473 493
474 invalidation->Union(synthetic_invalidation); 494 invalidation->Union(synthetic_invalidation);
495 return updated;
496 }
475 497
498 void PicturePile::GetInvalidTileRects(const gfx::Rect& interest_rect,
499 Region* invalidation,
500 const gfx::Rect& visible_layer_rect,
501 int frame_number,
502 std::vector<gfx::Rect>* invalid_tiles) {
476 // Make a list of all invalid tiles; we will attempt to 503 // Make a list of all invalid tiles; we will attempt to
477 // cluster these into multiple invalidation regions. 504 // cluster these into multiple invalidation regions.
478 std::vector<gfx::Rect> invalid_tiles;
479 bool include_borders = true; 505 bool include_borders = true;
480 for (TilingData::Iterator it(&tiling_, interest_rect, include_borders); it; 506 for (TilingData::Iterator it(&tiling_, interest_rect, include_borders); it;
481 ++it) { 507 ++it) {
482 const PictureMapKey& key = it.index(); 508 const PictureMapKey& key = it.index();
483 PictureInfo& info = picture_map_[key]; 509 PictureInfo& info = picture_map_[key];
484 510
485 gfx::Rect rect = PaddedRect(key); 511 gfx::Rect rect = PaddedRect(key);
486 int distance_to_visible = 512 int distance_to_visible =
487 rect.ManhattanInternalDistance(visible_layer_rect); 513 rect.ManhattanInternalDistance(visible_layer_rect);
488 514
489 if (info.NeedsRecording(frame_number, distance_to_visible)) { 515 if (info.NeedsRecording(frame_number, distance_to_visible)) {
490 gfx::Rect tile = tiling_.TileBounds(key.first, key.second); 516 gfx::Rect tile = tiling_.TileBounds(key.first, key.second);
491 invalid_tiles.push_back(tile); 517 invalid_tiles->push_back(tile);
492 } else if (!info.GetPicture()) { 518 } else if (!info.GetPicture()) {
493 if (recorded_viewport_.Intersects(rect)) { 519 if (recorded_viewport_.Intersects(rect)) {
494 // Recorded viewport is just an optimization for a fully recorded 520 // Recorded viewport is just an optimization for a fully recorded
495 // interest rect. In this case, a tile in that rect has declined 521 // interest rect. In this case, a tile in that rect has declined
496 // to be recorded (probably due to frequent invalidations). 522 // to be recorded (probably due to frequent invalidations).
497 // TODO(enne): Shrink the recorded_viewport_ rather than clearing. 523 // TODO(enne): Shrink the recorded_viewport_ rather than clearing.
498 recorded_viewport_ = gfx::Rect(); 524 recorded_viewport_ = gfx::Rect();
499 } 525 }
500 526
501 // If a tile in the interest rect is not recorded, the entire tile needs 527 // If a tile in the interest rect is not recorded, the entire tile needs
502 // to be considered invalid, so that we know not to keep around raster 528 // to be considered invalid, so that we know not to keep around raster
503 // tiles that intersect this recording tile. 529 // tiles that intersect this recording tile.
504 invalidation->Union(tiling_.TileBounds(it.index_x(), it.index_y())); 530 invalidation->Union(tiling_.TileBounds(it.index_x(), it.index_y()));
505 } 531 }
506 } 532 }
533 }
507 534
508 std::vector<gfx::Rect> record_rects; 535 void PicturePile::CreatePictures(ContentLayerClient* painter,
509 ClusterTiles(invalid_tiles, &record_rects); 536 Picture::RecordingMode recording_mode,
510 537 const std::vector<gfx::Rect>& record_rects) {
511 if (record_rects.empty()) 538 for (const auto& record_rect : record_rects) {
512 return updated; 539 gfx::Rect padded_record_rect = PadRect(record_rect);
513
514 for (std::vector<gfx::Rect>::iterator it = record_rects.begin();
515 it != record_rects.end();
516 it++) {
517 gfx::Rect record_rect = *it;
518 record_rect = PadRect(record_rect);
519 540
520 int repeat_count = std::max(1, slow_down_raster_scale_factor_for_debug_); 541 int repeat_count = std::max(1, slow_down_raster_scale_factor_for_debug_);
521 scoped_refptr<Picture> picture; 542 scoped_refptr<Picture> picture;
522 543
523 // Note: Currently, gathering of pixel refs when using a single 544 // Note: Currently, gathering of pixel refs when using a single
524 // raster thread doesn't provide any benefit. This might change 545 // raster thread doesn't provide any benefit. This might change
525 // in the future but we avoid it for now to reduce the cost of 546 // in the future but we avoid it for now to reduce the cost of
526 // Picture::Create. 547 // Picture::Create.
527 bool gather_pixel_refs = RasterWorkerPool::GetNumRasterThreads() > 1; 548 bool gather_pixel_refs = RasterWorkerPool::GetNumRasterThreads() > 1;
528 549
529 { 550 for (int i = 0; i < repeat_count; i++) {
530 for (int i = 0; i < repeat_count; i++) { 551 picture = Picture::Create(padded_record_rect, painter, tile_grid_info_,
531 picture = Picture::Create(record_rect, 552 gather_pixel_refs, recording_mode);
532 painter, 553 // Note the '&&' with previous is-suitable state.
533 tile_grid_info_, 554 // This means that once a picture-pile becomes unsuitable for gpu
534 gather_pixel_refs, 555 // rasterization due to some content, it will continue to be unsuitable
535 recording_mode); 556 // even if that content is replaced by gpu-friendly content.
536 // Note the '&&' with previous is-suitable state. 557 // This is an optimization to avoid iterating though all pictures in
537 // This means that once a picture-pile becomes unsuitable for gpu 558 // the pile after each invalidation.
538 // rasterization due to some content, it will continue to be unsuitable 559 is_suitable_for_gpu_rasterization_ &=
539 // even if that content is replaced by gpu-friendly content. 560 picture->IsSuitableForGpuRasterization();
540 // This is an optimization to avoid iterating though all pictures in
541 // the pile after each invalidation.
542 is_suitable_for_gpu_rasterization_ &=
543 picture->IsSuitableForGpuRasterization();
544 }
545 } 561 }
546 562
547 bool found_tile_for_recorded_picture = false; 563 bool found_tile_for_recorded_picture = false;
548 564
549 bool include_borders = true; 565 bool include_borders = true;
550 for (TilingData::Iterator it(&tiling_, record_rect, include_borders); it; 566 for (TilingData::Iterator it(&tiling_, padded_record_rect, include_borders);
551 ++it) { 567 it; ++it) {
552 const PictureMapKey& key = it.index(); 568 const PictureMapKey& key = it.index();
553 gfx::Rect tile = PaddedRect(key); 569 gfx::Rect tile = PaddedRect(key);
554 if (record_rect.Contains(tile)) { 570 if (padded_record_rect.Contains(tile)) {
555 PictureInfo& info = picture_map_[key]; 571 PictureInfo& info = picture_map_[key];
556 info.SetPicture(picture); 572 info.SetPicture(picture);
557 found_tile_for_recorded_picture = true; 573 found_tile_for_recorded_picture = true;
558 } 574 }
559 } 575 }
560 DetermineIfSolidColor();
561 DCHECK(found_tile_for_recorded_picture); 576 DCHECK(found_tile_for_recorded_picture);
562 } 577 }
563
564 has_any_recordings_ = true;
565 DCHECK(CanRasterSlowTileCheck(recorded_viewport_));
566 return true;
567 } 578 }
568 579
569 scoped_refptr<RasterSource> PicturePile::CreateRasterSource() const { 580 scoped_refptr<RasterSource> PicturePile::CreateRasterSource() const {
570 return scoped_refptr<RasterSource>( 581 return scoped_refptr<RasterSource>(
571 PicturePileImpl::CreateFromPicturePile(this)); 582 PicturePileImpl::CreateFromPicturePile(this));
572 } 583 }
573 584
574 gfx::Size PicturePile::GetSize() const { 585 gfx::Size PicturePile::GetSize() const {
575 return tiling_.tiling_size(); 586 return tiling_.tiling_size();
576 } 587 }
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
752 const Picture* PicturePile::PictureInfo::GetPicture() const { 763 const Picture* PicturePile::PictureInfo::GetPicture() const {
753 return picture_.get(); 764 return picture_.get();
754 } 765 }
755 766
756 float PicturePile::PictureInfo::GetInvalidationFrequency() const { 767 float PicturePile::PictureInfo::GetInvalidationFrequency() const {
757 return invalidation_history_.count() / 768 return invalidation_history_.count() /
758 static_cast<float>(INVALIDATION_FRAMES_TRACKED); 769 static_cast<float>(INVALIDATION_FRAMES_TRACKED);
759 } 770 }
760 771
761 } // namespace cc 772 } // namespace cc
OLDNEW
« no previous file with comments | « cc/resources/picture_pile.h ('k') | cc/resources/resource_provider.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698