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

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

Issue 714203006: cc: Remove PicturePileBase (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix build.gn 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
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
11 #include "cc/base/region.h" 11 #include "cc/base/region.h"
12 #include "cc/resources/picture_pile_impl.h" 12 #include "cc/resources/picture_pile_impl.h"
13 #include "cc/resources/raster_worker_pool.h" 13 #include "cc/resources/raster_worker_pool.h"
14 #include "skia/ext/analysis_canvas.h" 14 #include "skia/ext/analysis_canvas.h"
15 15
16 namespace { 16 namespace {
17 // Layout pixel buffer around the visible layer rect to record. Any base 17 // Layout pixel buffer around the visible layer rect to record. Any base
18 // picture that intersects the visible layer rect expanded by this distance 18 // picture that intersects the visible layer rect expanded by this distance
19 // will be recorded. 19 // will be recorded.
20 const int kPixelDistanceToRecord = 8000; 20 const int kPixelDistanceToRecord = 8000;
21 // We don't perform solid color analysis on images that have more than 10 skia 21 // We don't perform solid color analysis on images that have more than 10 skia
22 // operations. 22 // operations.
23 const int kOpCountThatIsOkToAnalyze = 10; 23 const int kOpCountThatIsOkToAnalyze = 10;
24 24
25 // Dimensions of the tiles in this picture pile as well as the dimensions of
26 // the base picture in each tile.
27 const int kBasePictureSize = 512;
28 const int kTileGridBorderPixels = 1;
29 #ifdef NDEBUG
30 const bool kDefaultClearCanvasSetting = false;
31 #else
32 const bool kDefaultClearCanvasSetting = true;
33 #endif
34
35 // Invalidation frequency settings. kInvalidationFrequencyThreshold is a value
36 // between 0 and 1 meaning invalidation frequency between 0% and 100% that
37 // indicates when to stop invalidating offscreen regions.
38 // kFrequentInvalidationDistanceThreshold defines what it means to be
39 // "offscreen" in terms of distance to visible in css pixels.
40 const float kInvalidationFrequencyThreshold = 0.75f;
41 const int kFrequentInvalidationDistanceThreshold = 512;
42
25 // TODO(humper): The density threshold here is somewhat arbitrary; need a 43 // TODO(humper): The density threshold here is somewhat arbitrary; need a
26 // way to set // this from the command line so we can write a benchmark 44 // way to set // this from the command line so we can write a benchmark
27 // script and find a sweet spot. 45 // script and find a sweet spot.
28 const float kDensityThreshold = 0.5f; 46 const float kDensityThreshold = 0.5f;
29 47
30 bool rect_sort_y(const gfx::Rect& r1, const gfx::Rect& r2) { 48 bool rect_sort_y(const gfx::Rect& r1, const gfx::Rect& r2) {
31 return r1.y() < r2.y() || (r1.y() == r2.y() && r1.x() < r2.x()); 49 return r1.y() < r2.y() || (r1.y() == r2.y() && r1.x() < r2.x());
32 } 50 }
33 51
34 bool rect_sort_x(const gfx::Rect& r1, const gfx::Rect& r2) { 52 bool rect_sort_x(const gfx::Rect& r1, const gfx::Rect& r2) {
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
142 160
143 *record_rects = vertical_clustering; 161 *record_rects = vertical_clustering;
144 return vertical_density; 162 return vertical_density;
145 } 163 }
146 164
147 } // namespace 165 } // namespace
148 166
149 namespace cc { 167 namespace cc {
150 168
151 PicturePile::PicturePile() 169 PicturePile::PicturePile()
152 : is_suitable_for_gpu_rasterization_(true), 170 : min_contents_scale_(0),
153 pixel_record_distance_(kPixelDistanceToRecord) { 171 slow_down_raster_scale_factor_for_debug_(0),
172 contents_opaque_(false),
173 contents_fill_bounds_completely_(false),
174 clear_canvas_with_debug_color_(kDefaultClearCanvasSetting),
175 has_any_recordings_(false),
176 is_mask_(false),
177 is_solid_color_(false),
178 solid_color_(SK_ColorTRANSPARENT),
179 pixel_record_distance_(kPixelDistanceToRecord),
180 is_suitable_for_gpu_rasterization_(true) {
181 tiling_.SetMaxTextureSize(gfx::Size(kBasePictureSize, kBasePictureSize));
182 tile_grid_info_.fTileInterval.setEmpty();
183 tile_grid_info_.fMargin.setEmpty();
184 tile_grid_info_.fOffset.setZero();
154 } 185 }
155 186
156 PicturePile::~PicturePile() { 187 PicturePile::~PicturePile() {
157 } 188 }
158 189
159 bool PicturePile::UpdateAndExpandInvalidation( 190 bool PicturePile::UpdateAndExpandInvalidation(
160 ContentLayerClient* painter, 191 ContentLayerClient* painter,
161 Region* invalidation, 192 Region* invalidation,
162 SkColor background_color, 193 SkColor background_color,
163 bool contents_opaque, 194 bool contents_opaque,
164 bool contents_fill_bounds_completely, 195 bool contents_fill_bounds_completely,
165 const gfx::Size& layer_size, 196 const gfx::Size& layer_size,
166 const gfx::Rect& visible_layer_rect, 197 const gfx::Rect& visible_layer_rect,
167 int frame_number, 198 int frame_number,
168 Picture::RecordingMode recording_mode) { 199 Picture::RecordingMode recording_mode) {
169 background_color_ = background_color; 200 background_color_ = background_color;
170 contents_opaque_ = contents_opaque; 201 contents_opaque_ = contents_opaque;
171 contents_fill_bounds_completely_ = contents_fill_bounds_completely; 202 contents_fill_bounds_completely_ = contents_fill_bounds_completely;
172 203
173 bool updated = false; 204 bool updated = false;
174 205
175 Region resize_invalidation; 206 Region resize_invalidation;
176 gfx::Size old_tiling_size = tiling_size(); 207 gfx::Size old_tiling_size = GetSize();
177 if (old_tiling_size != layer_size) { 208 if (old_tiling_size != layer_size) {
178 tiling_.SetTilingSize(layer_size); 209 tiling_.SetTilingSize(layer_size);
179 updated = true; 210 updated = true;
180 } 211 }
181 212
182 gfx::Rect interest_rect = visible_layer_rect; 213 gfx::Rect interest_rect = visible_layer_rect;
183 interest_rect.Inset(-pixel_record_distance_, -pixel_record_distance_); 214 interest_rect.Inset(-pixel_record_distance_, -pixel_record_distance_);
184 recorded_viewport_ = interest_rect; 215 recorded_viewport_ = interest_rect;
185 recorded_viewport_.Intersect(gfx::Rect(tiling_size())); 216 recorded_viewport_.Intersect(gfx::Rect(GetSize()));
186 217
187 gfx::Rect interest_rect_over_tiles = 218 gfx::Rect interest_rect_over_tiles =
188 tiling_.ExpandRectToTileBounds(interest_rect); 219 tiling_.ExpandRectToTileBounds(interest_rect);
189 220
190 gfx::Size min_tiling_size( 221 gfx::Size min_tiling_size(
191 std::min(tiling_size().width(), old_tiling_size.width()), 222 std::min(GetSize().width(), old_tiling_size.width()),
192 std::min(tiling_size().height(), old_tiling_size.height())); 223 std::min(GetSize().height(), old_tiling_size.height()));
193 gfx::Size max_tiling_size( 224 gfx::Size max_tiling_size(
194 std::max(tiling_size().width(), old_tiling_size.width()), 225 std::max(GetSize().width(), old_tiling_size.width()),
195 std::max(tiling_size().height(), old_tiling_size.height())); 226 std::max(GetSize().height(), old_tiling_size.height()));
196 227
197 if (old_tiling_size != layer_size) { 228 if (old_tiling_size != layer_size) {
198 has_any_recordings_ = false; 229 has_any_recordings_ = false;
199 230
200 // Drop recordings that are outside the new or old layer bounds or that 231 // Drop recordings that are outside the new or old layer bounds or that
201 // changed size. Newly exposed areas are considered invalidated. 232 // changed size. Newly exposed areas are considered invalidated.
202 // Previously exposed areas that are now outside of bounds also need to 233 // Previously exposed areas that are now outside of bounds also need to
203 // be invalidated, as they may become part of raster when scale < 1. 234 // be invalidated, as they may become part of raster when scale < 1.
204 std::vector<PictureMapKey> to_erase; 235 std::vector<PictureMapKey> to_erase;
205 int min_toss_x = tiling_.num_tiles_x(); 236 int min_toss_x = tiling_.num_tiles_x();
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
381 resize_invalidation.Union(right_rect); 412 resize_invalidation.Union(right_rect);
382 resize_invalidation.Union(top_rect); 413 resize_invalidation.Union(top_rect);
383 resize_invalidation.Union(bottom_rect); 414 resize_invalidation.Union(bottom_rect);
384 resize_invalidation.Union(exposed_rect); 415 resize_invalidation.Union(exposed_rect);
385 } 416 }
386 } 417 }
387 418
388 // Detect cases where the full pile is invalidated, in this situation we 419 // Detect cases where the full pile is invalidated, in this situation we
389 // can just drop/invalidate everything. 420 // can just drop/invalidate everything.
390 if (invalidation->Contains(gfx::Rect(old_tiling_size)) || 421 if (invalidation->Contains(gfx::Rect(old_tiling_size)) ||
391 invalidation->Contains(gfx::Rect(tiling_size()))) { 422 invalidation->Contains(gfx::Rect(GetSize()))) {
392 for (auto& it : picture_map_) 423 for (auto& it : picture_map_)
393 updated = it.second.Invalidate(frame_number) || updated; 424 updated = it.second.Invalidate(frame_number) || updated;
394 } else { 425 } else {
395 // Expand invalidation that is on tiles that aren't in the interest rect and 426 // Expand invalidation that is on tiles that aren't in the interest rect and
396 // will not be re-recorded below. These tiles are no longer valid and should 427 // will not be re-recorded below. These tiles are no longer valid and should
397 // be considerered fully invalid, so we can know to not keep around raster 428 // be considerered fully invalid, so we can know to not keep around raster
398 // tiles that intersect with these recording tiles. 429 // tiles that intersect with these recording tiles.
399 Region invalidation_expanded_to_full_tiles; 430 Region invalidation_expanded_to_full_tiles;
400 431
401 for (Region::Iterator i(*invalidation); i.has_rect(); i.next()) { 432 for (Region::Iterator i(*invalidation); i.has_rect(); i.next()) {
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
532 DetermineIfSolidColor(); 563 DetermineIfSolidColor();
533 DCHECK(found_tile_for_recorded_picture); 564 DCHECK(found_tile_for_recorded_picture);
534 } 565 }
535 566
536 has_any_recordings_ = true; 567 has_any_recordings_ = true;
537 DCHECK(CanRasterSlowTileCheck(recorded_viewport_)); 568 DCHECK(CanRasterSlowTileCheck(recorded_viewport_));
538 return true; 569 return true;
539 } 570 }
540 571
541 gfx::Size PicturePile::GetSize() const { 572 gfx::Size PicturePile::GetSize() const {
542 return tiling_size(); 573 return tiling_.tiling_size();
543 } 574 }
544 575
545 void PicturePile::SetEmptyBounds() { 576 void PicturePile::SetEmptyBounds() {
546 tiling_.SetTilingSize(gfx::Size()); 577 tiling_.SetTilingSize(gfx::Size());
547 Clear(); 578 Clear();
548 } 579 }
549 580
550 void PicturePile::SetMinContentsScale(float min_contents_scale) { 581 void PicturePile::SetMinContentsScale(float min_contents_scale) {
551 PicturePileBase::SetMinContentsScale(min_contents_scale); 582 DCHECK(min_contents_scale);
583 if (min_contents_scale_ == min_contents_scale)
584 return;
585
586 // Picture contents are played back scaled. When the final contents scale is
587 // less than 1 (i.e. low res), then multiple recorded pixels will be used
588 // to raster one final pixel. To avoid splitting a final pixel across
589 // pictures (which would result in incorrect rasterization due to blending), a
590 // buffer margin is added so that any picture can be snapped to integral
591 // final pixels.
592 //
593 // For example, if a 1/4 contents scale is used, then that would be 3 buffer
594 // pixels, since that's the minimum number of pixels to add so that resulting
595 // content can be snapped to a four pixel aligned grid.
596 int buffer_pixels = static_cast<int>(ceil(1 / min_contents_scale) - 1);
597 buffer_pixels = std::max(0, buffer_pixels);
598 SetBufferPixels(buffer_pixels);
599 min_contents_scale_ = min_contents_scale;
600 }
601
602 // static
603 void PicturePile::ComputeTileGridInfo(const gfx::Size& tile_grid_size,
604 SkTileGridFactory::TileGridInfo* info) {
605 DCHECK(info);
606 info->fTileInterval.set(tile_grid_size.width() - 2 * kTileGridBorderPixels,
607 tile_grid_size.height() - 2 * kTileGridBorderPixels);
608 DCHECK_GT(info->fTileInterval.width(), 0);
609 DCHECK_GT(info->fTileInterval.height(), 0);
610 info->fMargin.set(kTileGridBorderPixels, kTileGridBorderPixels);
611 // Offset the tile grid coordinate space to take into account the fact
612 // that the top-most and left-most tiles do not have top and left borders
613 // respectively.
614 info->fOffset.set(-kTileGridBorderPixels, -kTileGridBorderPixels);
552 } 615 }
553 616
554 void PicturePile::SetTileGridSize(const gfx::Size& tile_grid_size) { 617 void PicturePile::SetTileGridSize(const gfx::Size& tile_grid_size) {
555 PicturePileBase::SetTileGridSize(tile_grid_size); 618 ComputeTileGridInfo(tile_grid_size, &tile_grid_info_);
556 } 619 }
557 620
558 void PicturePile::SetSlowdownRasterScaleFactor(int factor) { 621 void PicturePile::SetSlowdownRasterScaleFactor(int factor) {
559 slow_down_raster_scale_factor_for_debug_ = factor; 622 slow_down_raster_scale_factor_for_debug_ = factor;
560 } 623 }
561 624
562 void PicturePile::SetShowDebugPictureBorders(bool show) {
563 show_debug_picture_borders_ = show;
564 }
565
566 void PicturePile::SetIsMask(bool is_mask) { 625 void PicturePile::SetIsMask(bool is_mask) {
567 set_is_mask(is_mask); 626 is_mask_ = is_mask;
568 } 627 }
569 628
570 void PicturePile::SetUnsuitableForGpuRasterizationForTesting() { 629 void PicturePile::SetUnsuitableForGpuRasterizationForTesting() {
571 is_suitable_for_gpu_rasterization_ = false; 630 is_suitable_for_gpu_rasterization_ = false;
572 } 631 }
573 632
574 bool PicturePile::IsSuitableForGpuRasterization() const { 633 bool PicturePile::IsSuitableForGpuRasterization() const {
575 return is_suitable_for_gpu_rasterization_; 634 return is_suitable_for_gpu_rasterization_;
576 } 635 }
577 636
578 scoped_refptr<RasterSource> PicturePile::CreateRasterSource() const { 637 scoped_refptr<RasterSource> PicturePile::CreateRasterSource() const {
579 return PicturePileImpl::CreateFromOther(this); 638 return scoped_refptr<RasterSource>(PicturePileImpl::CreateFromOther(this));
danakj 2014/11/12 20:33:37 I don't think that you need to cast it like this?
580 } 639 }
581 640
582 SkTileGridFactory::TileGridInfo PicturePile::GetTileGridInfoForTesting() const { 641 SkTileGridFactory::TileGridInfo PicturePile::GetTileGridInfoForTesting() const {
583 return PicturePileBase::GetTileGridInfoForTesting(); 642 return tile_grid_info_;
584 } 643 }
585 644
586 bool PicturePile::CanRasterSlowTileCheck(const gfx::Rect& layer_rect) const { 645 bool PicturePile::CanRasterSlowTileCheck(const gfx::Rect& layer_rect) const {
587 bool include_borders = false; 646 bool include_borders = false;
588 for (TilingData::Iterator tile_iter(&tiling_, layer_rect, include_borders); 647 for (TilingData::Iterator tile_iter(&tiling_, layer_rect, include_borders);
589 tile_iter; ++tile_iter) { 648 tile_iter; ++tile_iter) {
590 PictureMap::const_iterator map_iter = picture_map_.find(tile_iter.index()); 649 PictureMap::const_iterator map_iter = picture_map_.find(tile_iter.index());
591 if (map_iter == picture_map_.end()) 650 if (map_iter == picture_map_.end())
592 return false; 651 return false;
593 if (!map_iter->second.GetPicture()) 652 if (!map_iter->second.GetPicture())
(...skipping 27 matching lines...) Expand all
621 if (it->second.GetPicture() != picture) 680 if (it->second.GetPicture() != picture)
622 return; 681 return;
623 } 682 }
624 skia::AnalysisCanvas canvas(recorded_viewport_.width(), 683 skia::AnalysisCanvas canvas(recorded_viewport_.width(),
625 recorded_viewport_.height()); 684 recorded_viewport_.height());
626 canvas.translate(-recorded_viewport_.x(), -recorded_viewport_.y()); 685 canvas.translate(-recorded_viewport_.x(), -recorded_viewport_.y());
627 picture->Raster(&canvas, nullptr, Region(), 1.0f); 686 picture->Raster(&canvas, nullptr, Region(), 1.0f);
628 is_solid_color_ = canvas.GetColorIfSolid(&solid_color_); 687 is_solid_color_ = canvas.GetColorIfSolid(&solid_color_);
629 } 688 }
630 689
690 gfx::Rect PicturePile::PaddedRect(const PictureMapKey& key) const {
691 gfx::Rect tile = tiling_.TileBounds(key.first, key.second);
692 return PadRect(tile);
693 }
694
695 gfx::Rect PicturePile::PadRect(const gfx::Rect& rect) const {
696 gfx::Rect padded_rect = rect;
697 padded_rect.Inset(-buffer_pixels(), -buffer_pixels(), -buffer_pixels(),
698 -buffer_pixels());
699 return padded_rect;
700 }
701
702 void PicturePile::Clear() {
703 picture_map_.clear();
704 recorded_viewport_ = gfx::Rect();
705 has_any_recordings_ = false;
706 is_solid_color_ = false;
707 }
708
709 PicturePile::PictureInfo::PictureInfo() : last_frame_number_(0) {
710 }
711
712 PicturePile::PictureInfo::~PictureInfo() {
713 }
714
715 void PicturePile::PictureInfo::AdvanceInvalidationHistory(int frame_number) {
716 DCHECK_GE(frame_number, last_frame_number_);
717 if (frame_number == last_frame_number_)
718 return;
719
720 invalidation_history_ <<= (frame_number - last_frame_number_);
721 last_frame_number_ = frame_number;
722 }
723
724 bool PicturePile::PictureInfo::Invalidate(int frame_number) {
725 AdvanceInvalidationHistory(frame_number);
726 invalidation_history_.set(0);
727
728 bool did_invalidate = !!picture_.get();
729 picture_ = NULL;
730 return did_invalidate;
731 }
732
733 bool PicturePile::PictureInfo::NeedsRecording(int frame_number,
734 int distance_to_visible) {
735 AdvanceInvalidationHistory(frame_number);
736
737 // We only need recording if we don't have a picture. Furthermore, we only
738 // need a recording if we're within frequent invalidation distance threshold
739 // or the invalidation is not frequent enough (below invalidation frequency
740 // threshold).
741 return !picture_.get() &&
742 ((distance_to_visible <= kFrequentInvalidationDistanceThreshold) ||
743 (GetInvalidationFrequency() < kInvalidationFrequencyThreshold));
744 }
745
746 void PicturePile::SetBufferPixels(int new_buffer_pixels) {
747 if (new_buffer_pixels == buffer_pixels())
748 return;
749
750 Clear();
751 tiling_.SetBorderTexels(new_buffer_pixels);
752 }
753
754 void PicturePile::PictureInfo::SetPicture(scoped_refptr<Picture> picture) {
755 picture_ = picture;
756 }
757
758 const Picture* PicturePile::PictureInfo::GetPicture() const {
759 return picture_.get();
760 }
761
762 float PicturePile::PictureInfo::GetInvalidationFrequency() const {
763 return invalidation_history_.count() /
764 static_cast<float>(INVALIDATION_FRAMES_TRACKED);
765 }
766
631 } // namespace cc 767 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698