From acd5661350286666f1ca0d513bef340a743ca651 Mon Sep 17 00:00:00 2001 From: vmpstr Date: Thu, 6 Nov 2014 17:44:08 -0800 Subject: [PATCH] cc: Remove PicturePileBase as a base class of PicturePileImpl. This patch removes PicturePileBase from being a base class of PicturePileImpl. This is meant to serve as a first step in a cleanup that eliminates PicturePileBase and instead provides an explicit passing of values from PicturePile to PicturePileImpl. This, in turn, would hopefully expose some opportunities for cleanups, since it feels that PicturePileBase has become a bit of a catch-all for passing settings from PictureLayer to PictureLayerImpl/RasterWorkerPool. R=danakj BUG=430260 Review URL: https://codereview.chromium.org/689423003 Cr-Commit-Position: refs/heads/master@{#303158} --- cc/layers/picture_layer_impl.cc | 2 +- cc/layers/picture_layer_impl_unittest.cc | 31 +++--- cc/output/renderer_pixeltest.cc | 118 ++++++----------------- cc/resources/picture_pile.cc | 13 +++ cc/resources/picture_pile.h | 5 + cc/resources/picture_pile_base.cc | 52 ---------- cc/resources/picture_pile_base.h | 20 ++-- cc/resources/picture_pile_impl.cc | 81 +++++++++++++++- cc/resources/picture_pile_impl.h | 38 +++++++- cc/resources/picture_pile_unittest.cc | 9 +- cc/test/fake_picture_pile_impl.cc | 115 ++++++++++++++++------ cc/test/fake_picture_pile_impl.h | 12 +++ 12 files changed, 294 insertions(+), 202 deletions(-) diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc index f9678cc24275..822fcf3dc218 100644 --- a/cc/layers/picture_layer_impl.cc +++ b/cc/layers/picture_layer_impl.cc @@ -629,7 +629,7 @@ skia::RefPtr PictureLayerImpl::GetPicture() { scoped_refptr PictureLayerImpl::CreateTile(PictureLayerTiling* tiling, const gfx::Rect& content_rect) { DCHECK(!pile_->is_solid_color()); - if (!pile_->CanRaster(tiling->contents_scale(), content_rect)) + if (!pile_->CoversRect(content_rect, tiling->contents_scale())) return scoped_refptr(); int flags = 0; diff --git a/cc/layers/picture_layer_impl_unittest.cc b/cc/layers/picture_layer_impl_unittest.cc index a46386cf5585..4b42eca413fb 100644 --- a/cc/layers/picture_layer_impl_unittest.cc +++ b/cc/layers/picture_layer_impl_unittest.cc @@ -658,10 +658,10 @@ TEST_F(PictureLayerImplTest, AddTilesFromNewRecording) { ++iter) { EXPECT_FALSE(iter.full_tile_geometry_rect().IsEmpty()); // Ensure there is a recording for this tile. - bool in_pending = pending_pile->CanRaster(tiling->contents_scale(), - iter.full_tile_geometry_rect()); - bool in_active = active_pile->CanRaster(tiling->contents_scale(), - iter.full_tile_geometry_rect()); + bool in_pending = pending_pile->CoversRect(iter.full_tile_geometry_rect(), + tiling->contents_scale()); + bool in_active = active_pile->CoversRect(iter.full_tile_geometry_rect(), + tiling->contents_scale()); if (in_pending && !in_active) EXPECT_EQ(pending_pile.get(), iter->raster_source()); @@ -1132,8 +1132,15 @@ TEST_F(PictureLayerImplTest, DontAddLowResDuringAnimation) { } TEST_F(PictureLayerImplTest, DontAddLowResForSmallLayers) { - gfx::Size tile_size(host_impl_.settings().default_tile_size); - SetupDefaultTrees(tile_size); + gfx::Size layer_bounds(host_impl_.settings().default_tile_size); + gfx::Size tile_size(100, 100); + + scoped_refptr pending_pile = + FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds); + scoped_refptr active_pile = + FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds); + + SetupTrees(pending_pile, active_pile); float low_res_factor = host_impl_.settings().low_res_contents_scale_factor; float device_scale = 1.f; @@ -1181,8 +1188,8 @@ TEST_F(PictureLayerImplTest, DontAddLowResForSmallLayers) { ResetTilingsAndRasterScales(); // Mask layers dont create low res since they always fit on one tile. - pending_layer_->pile()->set_is_mask(true); - active_layer_->pile()->set_is_mask(true); + pending_pile->SetIsMask(true); + active_pile->SetIsMask(true); SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale, @@ -1197,7 +1204,7 @@ TEST_F(PictureLayerImplTest, HugeMasksDontGetTiles) { scoped_refptr valid_pile = FakePicturePileImpl::CreateFilledPile(tile_size, gfx::Size(1000, 1000)); - valid_pile->set_is_mask(true); + valid_pile->SetIsMask(true); SetupPendingTree(valid_pile); SetupDrawPropertiesAndUpdateTiles(pending_layer_, 1.f, 1.f, 1.f, 1.f, false); @@ -1224,7 +1231,7 @@ TEST_F(PictureLayerImplTest, HugeMasksDontGetTiles) { scoped_refptr huge_pile = FakePicturePileImpl::CreateFilledPile( tile_size, gfx::Size(max_texture_size + 1, 10)); - huge_pile->set_is_mask(true); + huge_pile->SetIsMask(true); SetupPendingTree(huge_pile); SetupDrawPropertiesAndUpdateTiles(pending_layer_, 1.f, 1.f, 1.f, 1.f, false); @@ -1249,7 +1256,7 @@ TEST_F(PictureLayerImplTest, ScaledMaskLayer) { scoped_refptr valid_pile = FakePicturePileImpl::CreateFilledPile(tile_size, gfx::Size(1000, 1000)); - valid_pile->set_is_mask(true); + valid_pile->SetIsMask(true); SetupPendingTree(valid_pile); float ideal_contents_scale = 1.3f; @@ -3708,7 +3715,7 @@ TEST_F(PictureLayerImplTest, UpdateTilesForMasksWithNoVisibleContent) { scoped_refptr pending_pile = FakePicturePileImpl::CreateFilledPile(tile_size, bounds); - pending_pile->set_is_mask(true); + pending_pile->SetIsMask(true); scoped_ptr mask = FakePictureLayerImpl::CreateWithPile( host_impl_.pending_tree(), 3, pending_pile); diff --git a/cc/output/renderer_pixeltest.cc b/cc/output/renderer_pixeltest.cc index c1728698badb..bdb030f06314 100644 --- a/cc/output/renderer_pixeltest.cc +++ b/cc/output/renderer_pixeltest.cc @@ -1759,14 +1759,9 @@ TYPED_TEST(RendererPixelTest, PictureDrawQuadIdentityScale) { blue_quad->SetNew(blue_shared_state, viewport, // Intentionally bigger than clip. - gfx::Rect(), - viewport, - gfx::RectF(viewport), - viewport.size(), - texture_format, - viewport, - 1.f, - PicturePileImpl::CreateFromOther(blue_pile.get())); + gfx::Rect(), viewport, gfx::RectF(viewport), + viewport.size(), texture_format, viewport, 1.f, + blue_pile.get()); // One viewport-filling green quad. scoped_refptr green_pile = @@ -1782,16 +1777,9 @@ TYPED_TEST(RendererPixelTest, PictureDrawQuadIdentityScale) { PictureDrawQuad* green_quad = pass->CreateAndAppendDrawQuad(); - green_quad->SetNew(green_shared_state, - viewport, - gfx::Rect(), - viewport, - gfx::RectF(0.f, 0.f, 1.f, 1.f), - viewport.size(), - texture_format, - viewport, - 1.f, - PicturePileImpl::CreateFromOther(green_pile.get())); + green_quad->SetNew(green_shared_state, viewport, gfx::Rect(), viewport, + gfx::RectF(0.f, 0.f, 1.f, 1.f), viewport.size(), + texture_format, viewport, 1.f, green_pile.get()); RenderPassList pass_list; pass_list.push_back(pass.Pass()); @@ -1828,16 +1816,9 @@ TYPED_TEST(RendererPixelTest, PictureDrawQuadOpacity) { PictureDrawQuad* green_quad = pass->CreateAndAppendDrawQuad(); - green_quad->SetNew(green_shared_state, - viewport, - gfx::Rect(), - viewport, - gfx::RectF(0, 0, 1, 1), - viewport.size(), - texture_format, - viewport, - 1.f, - PicturePileImpl::CreateFromOther(green_pile.get())); + green_quad->SetNew(green_shared_state, viewport, gfx::Rect(), viewport, + gfx::RectF(0, 0, 1, 1), viewport.size(), texture_format, + viewport, 1.f, green_pile.get()); // One viewport-filling white quad. scoped_refptr white_pile = @@ -1853,16 +1834,9 @@ TYPED_TEST(RendererPixelTest, PictureDrawQuadOpacity) { PictureDrawQuad* white_quad = pass->CreateAndAppendDrawQuad(); - white_quad->SetNew(white_shared_state, - viewport, - gfx::Rect(), - viewport, - gfx::RectF(0, 0, 1, 1), - viewport.size(), - texture_format, - viewport, - 1.f, - PicturePileImpl::CreateFromOther(white_pile.get())); + white_quad->SetNew(white_shared_state, viewport, gfx::Rect(), viewport, + gfx::RectF(0, 0, 1, 1), viewport.size(), texture_format, + viewport, 1.f, white_pile.get()); RenderPassList pass_list; pass_list.push_back(pass.Pass()); @@ -1927,16 +1901,9 @@ TYPED_TEST(RendererPixelTest, PictureDrawQuadDisableImageFiltering) { content_to_target_transform, viewport, pass.get()); PictureDrawQuad* quad = pass->CreateAndAppendDrawQuad(); - quad->SetNew(shared_state, - viewport, - gfx::Rect(), - viewport, - gfx::RectF(0, 0, 2, 2), - viewport.size(), - texture_format, - viewport, - 1.f, - PicturePileImpl::CreateFromOther(pile.get())); + quad->SetNew(shared_state, viewport, gfx::Rect(), viewport, + gfx::RectF(0, 0, 2, 2), viewport.size(), texture_format, + viewport, 1.f, pile.get()); RenderPassList pass_list; pass_list.push_back(pass.Pass()); @@ -1984,29 +1951,17 @@ TYPED_TEST(RendererPixelTest, PictureDrawQuadNonIdentityScale) { PictureDrawQuad* green_quad1 = pass->CreateAndAppendDrawQuad(); - green_quad1->SetNew(top_right_green_shared_quad_state, - green_rect1, - gfx::Rect(), - green_rect1, - gfx::RectF(green_rect1.size()), - green_rect1.size(), - texture_format, - green_rect1, - 1.f, - PicturePileImpl::CreateFromOther(green_pile.get())); + green_quad1->SetNew(top_right_green_shared_quad_state, green_rect1, + gfx::Rect(), green_rect1, gfx::RectF(green_rect1.size()), + green_rect1.size(), texture_format, green_rect1, 1.f, + green_pile.get()); PictureDrawQuad* green_quad2 = pass->CreateAndAppendDrawQuad(); - green_quad2->SetNew(top_right_green_shared_quad_state, - green_rect2, - gfx::Rect(), - green_rect2, - gfx::RectF(green_rect2.size()), - green_rect2.size(), - texture_format, - green_rect2, - 1.f, - PicturePileImpl::CreateFromOther(green_pile.get())); + green_quad2->SetNew(top_right_green_shared_quad_state, green_rect2, + gfx::Rect(), green_rect2, gfx::RectF(green_rect2.size()), + green_rect2.size(), texture_format, green_rect2, 1.f, + green_pile.get()); // Add a green clipped checkerboard in the bottom right to help test // interleaving picture quad content and solid color content. @@ -2072,16 +2027,10 @@ TYPED_TEST(RendererPixelTest, PictureDrawQuadNonIdentityScale) { content_to_target_transform, quad_content_rect, pass.get()); PictureDrawQuad* blue_quad = pass->CreateAndAppendDrawQuad(); - blue_quad->SetNew(blue_shared_state, - quad_content_rect, - gfx::Rect(), - quad_content_rect, - gfx::RectF(quad_content_rect), - content_union_rect.size(), - texture_format, - content_union_rect, - contents_scale, - PicturePileImpl::CreateFromOther(pile.get())); + blue_quad->SetNew(blue_shared_state, quad_content_rect, gfx::Rect(), + quad_content_rect, gfx::RectF(quad_content_rect), + content_union_rect.size(), texture_format, + content_union_rect, contents_scale, pile.get()); // Fill left half of viewport with green. gfx::Transform half_green_content_to_target_transform; @@ -2284,16 +2233,9 @@ TEST_F(GLRendererPixelTest, PictureDrawQuadTexture4444) { blue_content_to_target_transform, viewport, pass.get()); PictureDrawQuad* blue_quad = pass->CreateAndAppendDrawQuad(); - blue_quad->SetNew(blue_shared_state, - viewport, - gfx::Rect(), - viewport, - gfx::RectF(0.f, 0.f, 1.f, 1.f), - viewport.size(), - texture_format, - viewport, - 1.f, - PicturePileImpl::CreateFromOther(blue_pile.get())); + blue_quad->SetNew(blue_shared_state, viewport, gfx::Rect(), viewport, + gfx::RectF(0.f, 0.f, 1.f, 1.f), viewport.size(), + texture_format, viewport, 1.f, blue_pile.get()); RenderPassList pass_list; pass_list.push_back(pass.Pass()); diff --git a/cc/resources/picture_pile.cc b/cc/resources/picture_pile.cc index 1ad673b7222b..1ebb1cff15d3 100644 --- a/cc/resources/picture_pile.cc +++ b/cc/resources/picture_pile.cc @@ -541,6 +541,19 @@ void PicturePile::SetEmptyBounds() { Clear(); } +bool PicturePile::CanRasterSlowTileCheck(const gfx::Rect& layer_rect) const { + bool include_borders = false; + for (TilingData::Iterator tile_iter(&tiling_, layer_rect, include_borders); + tile_iter; ++tile_iter) { + PictureMap::const_iterator map_iter = picture_map_.find(tile_iter.index()); + if (map_iter == picture_map_.end()) + return false; + if (!map_iter->second.GetPicture()) + return false; + } + return true; +} + void PicturePile::DetermineIfSolidColor() { is_solid_color_ = false; solid_color_ = SK_ColorTRANSPARENT; diff --git a/cc/resources/picture_pile.h b/cc/resources/picture_pile.h index 7cd22296c5f2..18e1e5273aa7 100644 --- a/cc/resources/picture_pile.h +++ b/cc/resources/picture_pile.h @@ -55,6 +55,11 @@ class CC_EXPORT PicturePile : public PicturePileBase { void SetPixelRecordDistanceForTesting(int d) { pixel_record_distance_ = d; } + protected: + // An internal CanRaster check that goes to the picture_map rather than + // using the recorded_viewport hint. + bool CanRasterSlowTileCheck(const gfx::Rect& layer_rect) const; + private: friend class PicturePileImpl; diff --git a/cc/resources/picture_pile_base.cc b/cc/resources/picture_pile_base.cc index a145b6c1c525..1184cf1e2a69 100644 --- a/cc/resources/picture_pile_base.cc +++ b/cc/resources/picture_pile_base.cc @@ -141,39 +141,6 @@ bool PicturePileBase::HasRecordingAt(int x, int y) { return !!found->second.GetPicture(); } -bool PicturePileBase::CanRaster(float contents_scale, - const gfx::Rect& content_rect) const { - if (tiling_.tiling_size().IsEmpty()) - return false; - gfx::Rect layer_rect = gfx::ScaleToEnclosingRect( - content_rect, 1.f / contents_scale); - layer_rect.Intersect(gfx::Rect(tiling_.tiling_size())); - - // Common case inside of viewport to avoid the slower map lookups. - if (recorded_viewport_.Contains(layer_rect)) { - // Sanity check that there are no false positives in recorded_viewport_. - DCHECK(CanRasterSlowTileCheck(layer_rect)); - return true; - } - - return CanRasterSlowTileCheck(layer_rect); -} - -bool PicturePileBase::CanRasterSlowTileCheck( - const gfx::Rect& layer_rect) const { - bool include_borders = false; - for (TilingData::Iterator tile_iter(&tiling_, layer_rect, include_borders); - tile_iter; - ++tile_iter) { - PictureMap::const_iterator map_iter = picture_map_.find(tile_iter.index()); - if (map_iter == picture_map_.end()) - return false; - if (!map_iter->second.GetPicture()) - return false; - } - return true; -} - gfx::Rect PicturePileBase::PaddedRect(const PictureMapKey& key) const { gfx::Rect tile = tiling_.TileBounds(key.first, key.second); return PadRect(tile); @@ -186,25 +153,6 @@ gfx::Rect PicturePileBase::PadRect(const gfx::Rect& rect) const { return padded_rect; } -void PicturePileBase::AsValueInto(base::debug::TracedValue* pictures) const { - gfx::Rect tiling_rect(tiling_.tiling_size()); - std::set appended_pictures; - bool include_borders = true; - for (TilingData::Iterator tile_iter(&tiling_, tiling_rect, include_borders); - tile_iter; - ++tile_iter) { - PictureMap::const_iterator map_iter = picture_map_.find(tile_iter.index()); - if (map_iter == picture_map_.end()) - continue; - - const Picture* picture = map_iter->second.GetPicture(); - if (picture && (appended_pictures.count(picture) == 0)) { - appended_pictures.insert(picture); - TracedValue::AppendIDRef(picture, pictures); - } - } -} - PicturePileBase::PictureInfo::PictureInfo() : last_frame_number_(0) {} PicturePileBase::PictureInfo::~PictureInfo() {} diff --git a/cc/resources/picture_pile_base.h b/cc/resources/picture_pile_base.h index 71e5bad18518..66d37d81b888 100644 --- a/cc/resources/picture_pile_base.h +++ b/cc/resources/picture_pile_base.h @@ -42,16 +42,11 @@ class CC_EXPORT PicturePileBase { int num_tiles_y() const { return tiling_.num_tiles_y(); } gfx::Rect tile_bounds(int x, int y) const { return tiling_.TileBounds(x, y); } bool HasRecordingAt(int x, int y); - bool CanRaster(float contents_scale, const gfx::Rect& content_rect) const; - - // If this pile contains any valid recordings. May have false positives. - bool HasRecordings() const { return has_any_recordings_; } bool is_solid_color() const { return is_solid_color_; } SkColor solid_color() const { return solid_color_; } void set_is_mask(bool is_mask) { is_mask_ = is_mask; } - bool is_mask() const { return is_mask_; } static void ComputeTileGridInfo(const gfx::Size& tile_grid_size, SkTileGridFactory::TileGridInfo* info); @@ -59,12 +54,17 @@ class CC_EXPORT PicturePileBase { void SetTileGridSize(const gfx::Size& tile_grid_size); TilingData& tiling() { return tiling_; } - void AsValueInto(base::debug::TracedValue* array) const; - SkTileGridFactory::TileGridInfo GetTileGridInfoForTesting() const { return tile_grid_info_; } + void SetRecordedViewportForTesting(const gfx::Rect& viewport) { + recorded_viewport_ = viewport; + } + void SetHasAnyRecordingsForTesting(bool has_recordings) { + has_any_recordings_ = has_recordings; + } + protected: class CC_EXPORT PictureInfo { public: @@ -104,10 +104,6 @@ class CC_EXPORT PicturePileBase { gfx::Rect PaddedRect(const PictureMapKey& key) const; gfx::Rect PadRect(const gfx::Rect& rect) const; - // An internal CanRaster check that goes to the picture_map rather than - // using the recorded_viewport hint. - bool CanRasterSlowTileCheck(const gfx::Rect& layer_rect) const; - // A picture pile is a tiled set of pictures. The picture map is a map of tile // indices to picture infos. PictureMap picture_map_; @@ -129,6 +125,8 @@ class CC_EXPORT PicturePileBase { SkColor solid_color_; private: + friend class PicturePileImpl; + void SetBufferPixels(int buffer_pixels); DISALLOW_COPY_AND_ASSIGN(PicturePileBase); diff --git a/cc/resources/picture_pile_impl.cc b/cc/resources/picture_pile_impl.cc index 0ad746c85389..de25c04721be 100644 --- a/cc/resources/picture_pile_impl.cc +++ b/cc/resources/picture_pile_impl.cc @@ -26,11 +26,34 @@ scoped_refptr PicturePileImpl::CreateFromOther( } PicturePileImpl::PicturePileImpl() - : likely_to_be_used_for_transform_animation_(false) { + : background_color_(SK_ColorTRANSPARENT), + contents_opaque_(false), + contents_fill_bounds_completely_(false), + is_solid_color_(false), + solid_color_(SK_ColorTRANSPARENT), + has_any_recordings_(false), + is_mask_(false), + clear_canvas_with_debug_color_(false), + min_contents_scale_(0.f), + slow_down_raster_scale_factor_for_debug_(0), + likely_to_be_used_for_transform_animation_(false) { } PicturePileImpl::PicturePileImpl(const PicturePileBase* other) - : PicturePileBase(other), + : picture_map_(other->picture_map_), + tiling_(other->tiling_), + background_color_(other->background_color_), + contents_opaque_(other->contents_opaque_), + contents_fill_bounds_completely_(other->contents_fill_bounds_completely_), + is_solid_color_(other->is_solid_color_), + solid_color_(other->solid_color_), + recorded_viewport_(other->recorded_viewport_), + has_any_recordings_(other->has_any_recordings_), + is_mask_(other->is_mask_), + clear_canvas_with_debug_color_(other->clear_canvas_with_debug_color_), + min_contents_scale_(other->min_contents_scale_), + slow_down_raster_scale_factor_for_debug_( + other->slow_down_raster_scale_factor_for_debug_), likely_to_be_used_for_transform_animation_(false) { } @@ -320,13 +343,65 @@ void PicturePileImpl::GatherPixelRefs( bool PicturePileImpl::CoversRect(const gfx::Rect& content_rect, float contents_scale) const { - return CanRaster(contents_scale, content_rect); + if (tiling_.tiling_size().IsEmpty()) + return false; + gfx::Rect layer_rect = + gfx::ScaleToEnclosingRect(content_rect, 1.f / contents_scale); + layer_rect.Intersect(gfx::Rect(tiling_.tiling_size())); + + // Common case inside of viewport to avoid the slower map lookups. + if (recorded_viewport_.Contains(layer_rect)) { + // Sanity check that there are no false positives in recorded_viewport_. + DCHECK(CanRasterSlowTileCheck(layer_rect)); + return true; + } + + return CanRasterSlowTileCheck(layer_rect); +} + +gfx::Rect PicturePileImpl::PaddedRect(const PictureMapKey& key) const { + gfx::Rect padded_rect = tiling_.TileBounds(key.first, key.second); + padded_rect.Inset(-buffer_pixels(), -buffer_pixels(), -buffer_pixels(), + -buffer_pixels()); + return padded_rect; +} + +bool PicturePileImpl::CanRasterSlowTileCheck( + const gfx::Rect& layer_rect) const { + bool include_borders = false; + for (TilingData::Iterator tile_iter(&tiling_, layer_rect, include_borders); + tile_iter; ++tile_iter) { + PictureMap::const_iterator map_iter = picture_map_.find(tile_iter.index()); + if (map_iter == picture_map_.end()) + return false; + if (!map_iter->second.GetPicture()) + return false; + } + return true; } bool PicturePileImpl::SuitableForDistanceFieldText() const { return likely_to_be_used_for_transform_animation_; } +void PicturePileImpl::AsValueInto(base::debug::TracedValue* pictures) const { + gfx::Rect tiling_rect(tiling_.tiling_size()); + std::set appended_pictures; + bool include_borders = true; + for (TilingData::Iterator tile_iter(&tiling_, tiling_rect, include_borders); + tile_iter; ++tile_iter) { + PictureMap::const_iterator map_iter = picture_map_.find(tile_iter.index()); + if (map_iter == picture_map_.end()) + continue; + + const Picture* picture = map_iter->second.GetPicture(); + if (picture && (appended_pictures.count(picture) == 0)) { + appended_pictures.insert(picture); + TracedValue::AppendIDRef(picture, pictures); + } + } +} + PicturePileImpl::PixelRefIterator::PixelRefIterator( const gfx::Rect& content_rect, float contents_scale, diff --git a/cc/resources/picture_pile_impl.h b/cc/resources/picture_pile_impl.h index 9f350a9933c0..479846bb0ffa 100644 --- a/cc/resources/picture_pile_impl.h +++ b/cc/resources/picture_pile_impl.h @@ -22,7 +22,7 @@ namespace cc { // TODO(vmpstr): Clean up PicturePileBase and make it a member. -class CC_EXPORT PicturePileImpl : public PicturePileBase, public RasterSource { +class CC_EXPORT PicturePileImpl : public RasterSource { public: static scoped_refptr Create(); static scoped_refptr CreateFromOther( @@ -59,6 +59,14 @@ class CC_EXPORT PicturePileImpl : public PicturePileBase, public RasterSource { likely_to_be_used_for_transform_animation_ = true; } + gfx::Size tiling_size() const { return tiling_.tiling_size(); } + bool is_solid_color() const { return is_solid_color_; } + SkColor solid_color() const { return solid_color_; } + // If this pile contains any valid recordings. May have false positives. + bool HasRecordings() const { return has_any_recordings_; } + void AsValueInto(base::debug::TracedValue* array) const; + bool is_mask() const { return is_mask_; } + // Iterator used to return SkPixelRefs from this picture pile. // Public for testing. class CC_EXPORT PixelRefIterator { @@ -87,10 +95,32 @@ class CC_EXPORT PicturePileImpl : public PicturePileBase, public RasterSource { friend class PicturePile; friend class PixelRefIterator; + // TODO(vmpstr): Change this when pictures are split from invalidation info, + // and when PicturePileBase goes away. + using PictureMapKey = PicturePileBase::PictureMapKey; + using PictureMap = PicturePileBase::PictureMap; + using PictureInfo = PicturePileBase::PictureInfo; + PicturePileImpl(); explicit PicturePileImpl(const PicturePileBase* other); ~PicturePileImpl() override; + int buffer_pixels() const { return tiling_.border_texels(); } + + PictureMap picture_map_; + TilingData tiling_; + SkColor background_color_; + bool contents_opaque_; + bool contents_fill_bounds_completely_; + bool is_solid_color_; + SkColor solid_color_; + gfx::Rect recorded_viewport_; + bool has_any_recordings_; + bool is_mask_; + bool clear_canvas_with_debug_color_; + float min_contents_scale_; + int slow_down_raster_scale_factor_for_debug_; + private: typedef std::map PictureRegionMap; @@ -112,6 +142,12 @@ class CC_EXPORT PicturePileImpl : public PicturePileBase, public RasterSource { float contents_scale, bool is_analysis) const; + // An internal CanRaster check that goes to the picture_map rather than + // using the recorded_viewport hint. + bool CanRasterSlowTileCheck(const gfx::Rect& layer_rect) const; + + gfx::Rect PaddedRect(const PictureMapKey& key) const; + bool likely_to_be_used_for_transform_animation_; DISALLOW_COPY_AND_ASSIGN(PicturePileImpl); diff --git a/cc/resources/picture_pile_unittest.cc b/cc/resources/picture_pile_unittest.cc index 24bed3e64c03..60a1f0b71a76 100644 --- a/cc/resources/picture_pile_unittest.cc +++ b/cc/resources/picture_pile_unittest.cc @@ -26,10 +26,15 @@ class TestPicturePile : public PicturePile { PictureMap& picture_map() { return picture_map_; } const gfx::Rect& recorded_viewport() const { return recorded_viewport_; } - bool CanRasterLayerRect(const gfx::Rect& layer_rect) { - return CanRaster(1.f, layer_rect); + bool CanRasterLayerRect(gfx::Rect layer_rect) { + layer_rect.Intersect(gfx::Rect(tiling_.tiling_size())); + if (recorded_viewport_.Contains(layer_rect)) + return true; + return CanRasterSlowTileCheck(layer_rect); } + bool HasRecordings() const { return has_any_recordings_; } + typedef PicturePile::PictureInfo PictureInfo; typedef PicturePile::PictureMapKey PictureMapKey; typedef PicturePile::PictureMap PictureMap; diff --git a/cc/test/fake_picture_pile_impl.cc b/cc/test/fake_picture_pile_impl.cc index 32a6589ee967..e688d22020b9 100644 --- a/cc/test/fake_picture_pile_impl.cc +++ b/cc/test/fake_picture_pile_impl.cc @@ -4,9 +4,11 @@ #include "cc/test/fake_picture_pile_impl.h" +#include #include #include +#include "cc/resources/picture_pile.h" #include "cc/test/impl_side_painting_settings.h" #include "testing/gtest/include/gtest/gtest.h" @@ -14,62 +16,71 @@ namespace cc { FakePicturePileImpl::FakePicturePileImpl() {} +FakePicturePileImpl::FakePicturePileImpl(const PicturePileBase* other) + : PicturePileImpl(other), + tile_grid_info_(other->GetTileGridInfoForTesting()) { +} + FakePicturePileImpl::~FakePicturePileImpl() {} scoped_refptr FakePicturePileImpl::CreateFilledPile( const gfx::Size& tile_size, const gfx::Size& layer_bounds) { - scoped_refptr pile(new FakePicturePileImpl()); - pile->tiling().SetTilingSize(layer_bounds); - pile->tiling().SetMaxTextureSize(tile_size); - pile->SetTileGridSize(ImplSidePaintingSettings().default_tile_grid_size); - pile->recorded_viewport_ = gfx::Rect(layer_bounds); - pile->has_any_recordings_ = true; - for (int x = 0; x < pile->tiling().num_tiles_x(); ++x) { - for (int y = 0; y < pile->tiling().num_tiles_y(); ++y) - pile->AddRecordingAt(x, y); + PicturePile pile; + pile.tiling().SetTilingSize(layer_bounds); + pile.tiling().SetMaxTextureSize(tile_size); + pile.SetTileGridSize(ImplSidePaintingSettings().default_tile_grid_size); + pile.SetRecordedViewportForTesting(gfx::Rect(layer_bounds)); + pile.SetHasAnyRecordingsForTesting(true); + + auto pile_impl = make_scoped_refptr(new FakePicturePileImpl(&pile)); + for (int x = 0; x < pile_impl->tiling().num_tiles_x(); ++x) { + for (int y = 0; y < pile_impl->tiling().num_tiles_y(); ++y) + pile_impl->AddRecordingAt(x, y); } - return pile; + return pile_impl; } scoped_refptr FakePicturePileImpl::CreateEmptyPile( const gfx::Size& tile_size, const gfx::Size& layer_bounds) { - scoped_refptr pile(new FakePicturePileImpl()); - pile->tiling().SetTilingSize(layer_bounds); - pile->tiling().SetMaxTextureSize(tile_size); - pile->SetTileGridSize(ImplSidePaintingSettings().default_tile_grid_size); - pile->recorded_viewport_ = gfx::Rect(); - pile->has_any_recordings_ = false; - return pile; + PicturePile pile; + pile.tiling().SetTilingSize(layer_bounds); + pile.tiling().SetMaxTextureSize(tile_size); + pile.SetTileGridSize(ImplSidePaintingSettings().default_tile_grid_size); + pile.SetRecordedViewportForTesting(gfx::Rect()); + pile.SetHasAnyRecordingsForTesting(false); + return make_scoped_refptr(new FakePicturePileImpl(&pile)); } scoped_refptr FakePicturePileImpl::CreateEmptyPileThatThinksItHasRecordings( const gfx::Size& tile_size, const gfx::Size& layer_bounds) { - scoped_refptr pile(new FakePicturePileImpl()); - pile->tiling().SetTilingSize(layer_bounds); - pile->tiling().SetMaxTextureSize(tile_size); - pile->SetTileGridSize(ImplSidePaintingSettings().default_tile_grid_size); + PicturePile pile; + pile.tiling().SetTilingSize(layer_bounds); + pile.tiling().SetMaxTextureSize(tile_size); + pile.SetTileGridSize(ImplSidePaintingSettings().default_tile_grid_size); // This simulates a false positive for this flag. - pile->recorded_viewport_ = gfx::Rect(); - pile->has_any_recordings_ = true; - return pile; + pile.SetRecordedViewportForTesting(gfx::Rect()); + pile.SetHasAnyRecordingsForTesting(true); + return make_scoped_refptr(new FakePicturePileImpl(&pile)); } scoped_refptr FakePicturePileImpl::CreateInfiniteFilledPile() { - scoped_refptr pile(new FakePicturePileImpl()); + PicturePile pile; gfx::Size size(std::numeric_limits::max(), std::numeric_limits::max()); - pile->tiling().SetTilingSize(size); - pile->tiling().SetMaxTextureSize(size); - pile->SetTileGridSize(size); - pile->recorded_viewport_ = gfx::Rect(size); - pile->has_any_recordings_ = true; - pile->AddRecordingAt(0, 0); - return pile; + pile.tiling().SetTilingSize(size); + pile.tiling().SetMaxTextureSize(size); + pile.SetTileGridSize(size); + pile.SetRecordedViewportForTesting(gfx::Rect(size)); + pile.SetHasAnyRecordingsForTesting(true); + + auto pile_impl = make_scoped_refptr(new FakePicturePileImpl(&pile)); + pile_impl->AddRecordingAt(0, 0); + return pile_impl; } void FakePicturePileImpl::AddRecordingAt(int x, int y) { @@ -103,6 +114,13 @@ void FakePicturePileImpl::RemoveRecordingAt(int x, int y) { EXPECT_FALSE(HasRecordingAt(x, y)); } +bool FakePicturePileImpl::HasRecordingAt(int x, int y) const { + PictureMap::const_iterator found = picture_map_.find(PictureMapKey(x, y)); + if (found == picture_map_.end()) + return false; + return !!found->second.GetPicture(); +} + void FakePicturePileImpl::RerecordPile() { for (int y = 0; y < num_tiles_y(); ++y) { for (int x = 0; x < num_tiles_x(); ++x) { @@ -112,4 +130,37 @@ void FakePicturePileImpl::RerecordPile() { } } +void FakePicturePileImpl::SetMinContentsScale(float min_contents_scale) { + if (min_contents_scale_ == min_contents_scale) + return; + + // Picture contents are played back scaled. When the final contents scale is + // less than 1 (i.e. low res), then multiple recorded pixels will be used + // to raster one final pixel. To avoid splitting a final pixel across + // pictures (which would result in incorrect rasterization due to blending), a + // buffer margin is added so that any picture can be snapped to integral + // final pixels. + // + // For example, if a 1/4 contents scale is used, then that would be 3 buffer + // pixels, since that's the minimum number of pixels to add so that resulting + // content can be snapped to a four pixel aligned grid. + int buffer_pixels = static_cast(ceil(1 / min_contents_scale) - 1); + buffer_pixels = std::max(0, buffer_pixels); + SetBufferPixels(buffer_pixels); + min_contents_scale_ = min_contents_scale; +} + +void FakePicturePileImpl::SetBufferPixels(int new_buffer_pixels) { + if (new_buffer_pixels == buffer_pixels()) + return; + + Clear(); + tiling_.SetBorderTexels(new_buffer_pixels); +} + +void FakePicturePileImpl::Clear() { + picture_map_.clear(); + recorded_viewport_ = gfx::Rect(); +} + } // namespace cc diff --git a/cc/test/fake_picture_pile_impl.h b/cc/test/fake_picture_pile_impl.h index 10c769aefa6f..ab27238bc7f1 100644 --- a/cc/test/fake_picture_pile_impl.h +++ b/cc/test/fake_picture_pile_impl.h @@ -72,12 +72,24 @@ class FakePicturePileImpl : public PicturePileImpl { is_solid_color_ = is_solid_color; } + bool HasRecordingAt(int x, int y) const; + void SetIsMask(bool mask) { is_mask_ = mask; } + + int num_tiles_x() const { return tiling_.num_tiles_x(); } + int num_tiles_y() const { return tiling_.num_tiles_y(); } + + void SetMinContentsScale(float scale); + void SetBufferPixels(int new_buffer_pixels); + void Clear(); + protected: FakePicturePileImpl(); + explicit FakePicturePileImpl(const PicturePileBase* other); ~FakePicturePileImpl() override; FakeContentLayerClient client_; SkPaint default_paint_; + SkTileGridFactory::TileGridInfo tile_grid_info_; }; } // namespace cc