diff options
author | weiliangc <weiliangc@chromium.org> | 2015-12-08 19:39:26 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-12-09 03:40:25 +0000 |
commit | c154ce2efa59dbaecb3cb038adb247426f7c6988 (patch) | |
tree | adc06272fccf970cb021180efa52e6f67c236236 | |
parent | d2dc9a29ec062b23a18bca4f69d56901634b5545 (diff) | |
download | chromium_src-c154ce2efa59dbaecb3cb038adb247426f7c6988.zip chromium_src-c154ce2efa59dbaecb3cb038adb247426f7c6988.tar.gz chromium_src-c154ce2efa59dbaecb3cb038adb247426f7c6988.tar.bz2 |
Create RenderSurface on Effect Tree
Move RenderSurface creation reason to effect tree. Update LayerImpl's
API to include SetForceRenderSurface. Update unittests.
R=enne
BUG=557160
CQ_INCLUDE_TRYBOTS=tryserver.blink:linux_blink_rel
Committed: https://crrev.com/4374c2cc231a7e5b6ae65d0e0814b5dccf445200
Cr-Commit-Position: refs/heads/master@{#363544}
Review URL: https://codereview.chromium.org/1491033002
Cr-Commit-Position: refs/heads/master@{#363967}
33 files changed, 615 insertions, 486 deletions
diff --git a/cc/layers/delegated_renderer_layer_impl_unittest.cc b/cc/layers/delegated_renderer_layer_impl_unittest.cc index 4093a08d..725fb79 100644 --- a/cc/layers/delegated_renderer_layer_impl_unittest.cc +++ b/cc/layers/delegated_renderer_layer_impl_unittest.cc @@ -76,17 +76,17 @@ class DelegatedRendererLayerImplTestSimple host_impl_->SetViewportSize(gfx::Size(100, 100)); root_layer->SetBounds(gfx::Size(100, 100)); - root_layer->SetHasRenderSurface(true); + root_layer->SetForceRenderSurface(true); layer_before->SetPosition(gfx::PointF(20.f, 20.f)); layer_before->SetBounds(gfx::Size(14, 14)); layer_before->SetDrawsContent(true); - layer_before->SetHasRenderSurface(true); + layer_before->SetForceRenderSurface(true); layer_after->SetPosition(gfx::PointF(5.f, 5.f)); layer_after->SetBounds(gfx::Size(15, 15)); layer_after->SetDrawsContent(true); - layer_after->SetHasRenderSurface(true); + layer_after->SetForceRenderSurface(true); delegated_renderer_layer->SetPosition(gfx::PointF(3.f, 3.f)); delegated_renderer_layer->SetBounds(gfx::Size(10, 10)); @@ -146,12 +146,12 @@ TEST_F(DelegatedRendererLayerImplTest, host_impl_->SetViewportSize(gfx::Size(100, 100)); root_layer->SetBounds(gfx::Size(100, 100)); - root_layer->SetHasRenderSurface(true); + root_layer->SetForceRenderSurface(true); delegated_renderer_layer->SetPosition(gfx::PointF(3.f, 3.f)); delegated_renderer_layer->SetBounds(gfx::Size(10, 10)); delegated_renderer_layer->SetDrawsContent(true); - delegated_renderer_layer->SetHasRenderSurface(true); + delegated_renderer_layer->SetForceRenderSurface(true); gfx::Transform transform; transform.Translate(1.0, 1.0); delegated_renderer_layer->SetTransform(transform); @@ -225,12 +225,12 @@ TEST_F(DelegatedRendererLayerImplTest, host_impl_->SetViewportSize(gfx::Size(100, 100)); root_layer->SetBounds(gfx::Size(100, 100)); - root_layer->SetHasRenderSurface(true); + root_layer->SetForceRenderSurface(true); delegated_renderer_layer->SetPosition(gfx::PointF(3.f, 3.f)); delegated_renderer_layer->SetBounds(gfx::Size(10, 10)); delegated_renderer_layer->SetDrawsContent(true); - delegated_renderer_layer->SetHasRenderSurface(true); + delegated_renderer_layer->SetForceRenderSurface(true); gfx::Transform transform; transform.Translate(1.0, 1.0); delegated_renderer_layer->SetTransform(transform); @@ -469,7 +469,7 @@ class DelegatedRendererLayerImplTestOwnSurface public: DelegatedRendererLayerImplTestOwnSurface() : DelegatedRendererLayerImplTestSimple() { - delegated_renderer_layer_->SetHasRenderSurface(true); + delegated_renderer_layer_->SetForceRenderSurface(true); } }; @@ -629,7 +629,7 @@ class DelegatedRendererLayerImplTestTransform host_impl_->SetViewportSize(gfx::Size(200, 200)); root_layer->SetBounds(gfx::Size(100, 100)); - root_layer->SetHasRenderSurface(true); + root_layer->SetForceRenderSurface(true); delegated_renderer_layer->SetPosition(gfx::PointF(20.f, 20.f)); delegated_renderer_layer->SetBounds(gfx::Size(75, 75)); @@ -910,7 +910,7 @@ TEST_F(DelegatedRendererLayerImplTestTransform, QuadsUnclipped_Surface) { root_delegated_render_pass_is_clipped_ = false; SetUpTest(); - delegated_renderer_layer_->SetHasRenderSurface(true); + delegated_renderer_layer_->SetForceRenderSurface(true); LayerTreeHostImpl::FrameData frame; EXPECT_EQ(DRAW_SUCCESS, PrepareToDrawFrame(&frame)); @@ -958,7 +958,7 @@ TEST_F(DelegatedRendererLayerImplTestTransform, QuadsClipped_Surface) { root_delegated_render_pass_is_clipped_ = true; SetUpTest(); - delegated_renderer_layer_->SetHasRenderSurface(true); + delegated_renderer_layer_->SetForceRenderSurface(true); LayerTreeHostImpl::FrameData frame; EXPECT_EQ(DRAW_SUCCESS, PrepareToDrawFrame(&frame)); @@ -1055,7 +1055,7 @@ class DelegatedRendererLayerImplTestClip host_impl_->SetViewportSize(gfx::Size(100, 100)); root_layer->SetBounds(gfx::Size(100, 100)); - root_layer->SetHasRenderSurface(true); + root_layer->SetForceRenderSurface(true); delegated_renderer_layer->SetPosition(gfx::PointF(20.f, 20.f)); delegated_renderer_layer->SetBounds(gfx::Size(50, 50)); @@ -1312,7 +1312,7 @@ TEST_F(DelegatedRendererLayerImplTestClip, clip_delegated_renderer_layer_ = false; SetUpTest(); - delegated_renderer_layer_->SetHasRenderSurface(true); + delegated_renderer_layer_->SetForceRenderSurface(true); LayerTreeHostImpl::FrameData frame; EXPECT_EQ(DRAW_SUCCESS, PrepareToDrawFrame(&frame)); @@ -1341,7 +1341,7 @@ TEST_F(DelegatedRendererLayerImplTestClip, clip_delegated_renderer_layer_ = false; SetUpTest(); - delegated_renderer_layer_->SetHasRenderSurface(true); + delegated_renderer_layer_->SetForceRenderSurface(true); LayerTreeHostImpl::FrameData frame; EXPECT_EQ(DRAW_SUCCESS, PrepareToDrawFrame(&frame)); @@ -1371,7 +1371,7 @@ TEST_F(DelegatedRendererLayerImplTestClip, clip_delegated_renderer_layer_ = true; SetUpTest(); - delegated_renderer_layer_->SetHasRenderSurface(true); + delegated_renderer_layer_->SetForceRenderSurface(true); LayerTreeHostImpl::FrameData frame; host_impl_->active_tree()->BuildPropertyTreesForTesting(); @@ -1400,7 +1400,7 @@ TEST_F(DelegatedRendererLayerImplTestClip, QuadsClipped_LayerClipped_Surface) { clip_delegated_renderer_layer_ = true; SetUpTest(); - delegated_renderer_layer_->SetHasRenderSurface(true); + delegated_renderer_layer_->SetForceRenderSurface(true); LayerTreeHostImpl::FrameData frame; host_impl_->active_tree()->BuildPropertyTreesForTesting(); diff --git a/cc/layers/layer.cc b/cc/layers/layer.cc index 80cac38..41fdd00 100644 --- a/cc/layers/layer.cc +++ b/cc/layers/layer.cc @@ -1206,6 +1206,7 @@ void Layer::PushPropertiesTo(LayerImpl* layer) { layer->SetDrawsContent(DrawsContent()); layer->SetHideLayerAndSubtree(hide_layer_and_subtree_); layer->SetHasRenderSurface(has_render_surface_); + layer->SetForceRenderSurface(force_render_surface_); if (!layer->FilterIsAnimatingOnImplOnly() && !FilterIsAnimating()) layer->SetFilters(filters_); DCHECK(!(FilterIsAnimating() && layer->FilterIsAnimatingOnImplOnly())); @@ -1546,9 +1547,8 @@ void Layer::SetHasRenderSurface(bool has_render_surface) { return; has_render_surface_ = has_render_surface; // We do not need SetNeedsCommit here, since this is only ever called - // during a commit, from CalculateDrawProperties. + // during a commit, from CalculateDrawProperties using property trees. SetNeedsPushProperties(); - layer_tree_host_->property_trees()->needs_rebuild = true; } gfx::ScrollOffset Layer::ScrollOffsetForAnimation() const { diff --git a/cc/layers/layer.h b/cc/layers/layer.h index b65c71b..f87d18d 100644 --- a/cc/layers/layer.h +++ b/cc/layers/layer.h @@ -521,6 +521,10 @@ class CC_EXPORT Layer : public base::RefCounted<Layer>, const gfx::Rect& clip_rect() const { return clip_rect_; } void set_clip_rect(const gfx::Rect& rect) { clip_rect_ = rect; } + // This should only be called during BeginMainFrame since it does not trigger + // a Commit. This is called right after property tree being built and should + // not trigger property tree rebuild. + void SetHasRenderSurface(bool has_render_surface); bool has_render_surface() const { return has_render_surface_; } @@ -669,10 +673,6 @@ class CC_EXPORT Layer : public base::RefCounted<Layer>, void SetParent(Layer* layer); bool DescendantIsFixedToContainerLayer() const; - // This should only be called during BeginMainFrame since it does not - // trigger a Commit. - void SetHasRenderSurface(bool has_render_surface); - // This should only be called from RemoveFromParent(). void RemoveChildOrDependent(Layer* child); diff --git a/cc/layers/layer_impl.cc b/cc/layers/layer_impl.cc index b20cb3d..6892f39 100644 --- a/cc/layers/layer_impl.cc +++ b/cc/layers/layer_impl.cc @@ -88,6 +88,7 @@ LayerImpl::LayerImpl(LayerTreeImpl* tree_impl, current_draw_mode_(DRAW_MODE_NONE), element_id_(0), mutable_properties_(kMutablePropertyNone), + force_render_surface_(false), num_layer_or_descendants_with_copy_request_(0), frame_timing_requests_dirty_(false), visited_(false), @@ -280,7 +281,6 @@ void LayerImpl::PassCopyRequests( if (requests->empty()) return; - DCHECK(render_surface()); bool was_empty = copy_requests_.empty(); for (auto& request : *requests) copy_requests_.push_back(std::move(request)); @@ -573,7 +573,14 @@ void LayerImpl::PushPropertiesTo(LayerImpl* layer) { layer->SetDoubleSided(double_sided_); layer->SetDrawsContent(DrawsContent()); layer->SetHideLayerAndSubtree(hide_layer_and_subtree_); + // If whether layer has render surface changes, we need to update draw + // properties. + // TODO(weiliangc): Should be safely removed after impl side is able to + // update render surfaces without rebuilding property trees. + if (layer->has_render_surface() != has_render_surface()) + layer->layer_tree_impl()->set_needs_update_draw_properties(); layer->SetHasRenderSurface(!!render_surface()); + layer->SetForceRenderSurface(force_render_surface_); layer->SetFilters(filters()); layer->SetBackgroundFilters(background_filters()); layer->SetMasksToBounds(masks_to_bounds_); @@ -1355,6 +1362,12 @@ bool LayerImpl::HasOnlyTranslationTransforms() const { observer_type); } +bool LayerImpl::AnimationsPreserveAxisAlignment() const { + return layer_animation_controller_ + ? layer_animation_controller_->AnimationsPreserveAxisAlignment() + : layer_tree_impl_->AnimationsPreserveAxisAlignment(this); +} + bool LayerImpl::MaximumTargetScale(float* max_scale) const { if (!layer_animation_controller_) return layer_tree_impl_->MaximumTargetScale(this, max_scale); @@ -1799,7 +1812,6 @@ void LayerImpl::SetHasRenderSurface(bool should_have_render_surface) { return; SetNeedsPushProperties(); - layer_tree_impl()->set_needs_update_draw_properties(); if (should_have_render_surface) { render_surface_ = make_scoped_ptr(new RenderSurfaceImpl(this)); return; @@ -1836,6 +1848,14 @@ gfx::Transform LayerImpl::ScreenSpaceTransform() const { return draw_properties().screen_space_transform; } +void LayerImpl::SetForceRenderSurface(bool force_render_surface) { + if (force_render_surface == force_render_surface_) + return; + + force_render_surface_ = force_render_surface; + NoteLayerPropertyChanged(); +} + Region LayerImpl::GetInvalidationRegion() { return Region(update_rect_); } diff --git a/cc/layers/layer_impl.h b/cc/layers/layer_impl.h index 04a70ef..3939b99 100644 --- a/cc/layers/layer_impl.h +++ b/cc/layers/layer_impl.h @@ -202,7 +202,7 @@ class CC_EXPORT LayerImpl : public LayerAnimationValueObserver, // For compatibility with Layer. bool has_render_surface() const { return !!render_surface(); } - + bool force_render_surface() const { return force_render_surface_; } void SetNumDescendantsThatDrawContent(int num_descendants); void SetClipParent(LayerImpl* ancestor); @@ -386,6 +386,8 @@ class CC_EXPORT LayerImpl : public LayerAnimationValueObserver, void ClearRenderSurfaceLayerList(); void SetHasRenderSurface(bool has_render_surface); + void SetForceRenderSurface(bool has_render_surface); + RenderSurfaceImpl* render_surface() const { return render_surface_.get(); } DrawProperties& draw_properties() { return draw_properties_; } @@ -534,6 +536,7 @@ class CC_EXPORT LayerImpl : public LayerAnimationValueObserver, bool HasPotentiallyRunningTransformAnimation() const; bool TransformIsAnimatingOnImplOnly() const; bool HasOnlyTranslationTransforms() const; + bool AnimationsPreserveAxisAlignment() const; void SetTransformAndInvertibility(const gfx::Transform& transform, bool transform_is_invertible); bool transform_is_invertible() const { return transform_is_invertible_; } @@ -873,6 +876,8 @@ class CC_EXPORT LayerImpl : public LayerAnimationValueObserver, scoped_refptr<base::trace_event::ConvertableToTraceFormat> debug_info_; scoped_ptr<RenderSurfaceImpl> render_surface_; + bool force_render_surface_; + std::vector<FrameTimingRequest> frame_timing_requests_; int num_layer_or_descendants_with_copy_request_; bool frame_timing_requests_dirty_; diff --git a/cc/layers/layer_impl_unittest.cc b/cc/layers/layer_impl_unittest.cc index 98e6386..7666794 100644 --- a/cc/layers/layer_impl_unittest.cc +++ b/cc/layers/layer_impl_unittest.cc @@ -9,6 +9,7 @@ #include "cc/layers/solid_color_scrollbar_layer_impl.h" #include "cc/output/filter_operation.h" #include "cc/output/filter_operations.h" +#include "cc/test/animation_test_common.h" #include "cc/test/fake_impl_task_runner_provider.h" #include "cc/test/fake_layer_tree_host_impl.h" #include "cc/test/fake_output_surface.h" @@ -297,13 +298,18 @@ TEST(LayerImplTest, VerifyNeedsUpdateDrawProperties) { // verified. VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetDrawsContent(true)); VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer2->SetDrawsContent(true)); - // Render surface functions. - VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetHasRenderSurface(true)); + // Render surface functions should not trigger update draw properties, because + // creating render surface is part of update draw properties. VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetHasRenderSurface(true)); - VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetHasRenderSurface(false)); + VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetHasRenderSurface(false)); // Create a render surface, because we must have a render surface if we have // filters. - VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetHasRenderSurface(true)); + VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetHasRenderSurface(true)); + + VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetForceRenderSurface(true)); + VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetForceRenderSurface(true)); + VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetForceRenderSurface(false)); + VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetForceRenderSurface(false)); // Related filter functions. VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetFilters(arbitrary_filters)); diff --git a/cc/layers/layer_iterator_unittest.cc b/cc/layers/layer_iterator_unittest.cc index 48a8635..b9b3cf3 100644 --- a/cc/layers/layer_iterator_unittest.cc +++ b/cc/layers/layer_iterator_unittest.cc @@ -135,7 +135,6 @@ TEST_F(LayerIteratorTest, SimpleTree) { root_layer->AddChild(std::move(third)); root_layer->AddChild(std::move(fourth)); - root_layer->SetHasRenderSurface(true); host_impl_.active_tree()->SetRootLayer(std::move(root_layer)); LayerImplList render_surface_layer_list; @@ -183,7 +182,6 @@ TEST_F(LayerIteratorTest, ComplexTree) { root_layer->AddChild(std::move(root2)); root_layer->AddChild(std::move(root3)); - root_layer->SetHasRenderSurface(true); host_impl_.active_tree()->SetRootLayer(std::move(root_layer)); LayerImplList render_surface_layer_list; @@ -226,12 +224,12 @@ TEST_F(LayerIteratorTest, ComplexTreeMultiSurface) { TestLayerImpl* root221_ptr = root221.get(); TestLayerImpl* root231_ptr = root231.get(); - root22->SetHasRenderSurface(true); + root22->SetForceRenderSurface(true); + root23->SetForceRenderSurface(true); + root2->SetForceRenderSurface(true); root22->AddChild(std::move(root221)); - root23->SetHasRenderSurface(true); root23->AddChild(std::move(root231)); root2->SetDrawsContent(false); - root2->SetHasRenderSurface(true); root2->AddChild(std::move(root21)); root2->AddChild(std::move(root22)); root2->AddChild(std::move(root23)); @@ -239,7 +237,6 @@ TEST_F(LayerIteratorTest, ComplexTreeMultiSurface) { root_layer->AddChild(std::move(root2)); root_layer->AddChild(std::move(root3)); - root_layer->SetHasRenderSurface(true); host_impl_.active_tree()->SetRootLayer(std::move(root_layer)); LayerImplList render_surface_layer_list; diff --git a/cc/layers/nine_patch_layer_impl_unittest.cc b/cc/layers/nine_patch_layer_impl_unittest.cc index bed02d0..e4c779a 100644 --- a/cc/layers/nine_patch_layer_impl_unittest.cc +++ b/cc/layers/nine_patch_layer_impl_unittest.cc @@ -56,7 +56,7 @@ void NinePatchLayerLayoutTest(const gfx::Size& bitmap_size, NinePatchLayerImpl::Create(host_impl.active_tree(), 1); layer->draw_properties().visible_layer_rect = visible_layer_rect; layer->SetBounds(layer_size); - layer->SetHasRenderSurface(true); + layer->SetForceRenderSurface(true); layer->draw_properties().render_target = layer.get(); UIResourceId uid = 1; diff --git a/cc/layers/picture_layer_impl_perftest.cc b/cc/layers/picture_layer_impl_perftest.cc index 6521e1c..5088df4 100644 --- a/cc/layers/picture_layer_impl_perftest.cc +++ b/cc/layers/picture_layer_impl_perftest.cc @@ -66,7 +66,7 @@ class PictureLayerImplPerfTest : public testing::Test { FakePictureLayerImpl::CreateWithRasterSource(pending_tree, 7, raster_source); pending_layer->SetDrawsContent(true); - pending_layer->SetHasRenderSurface(true); + pending_layer->SetForceRenderSurface(true); pending_tree->SetRootLayer(std::move(pending_layer)); pending_tree->BuildPropertyTreesForTesting(); diff --git a/cc/layers/picture_layer_impl_unittest.cc b/cc/layers/picture_layer_impl_unittest.cc index 87ef961..1839690c 100644 --- a/cc/layers/picture_layer_impl_unittest.cc +++ b/cc/layers/picture_layer_impl_unittest.cc @@ -254,7 +254,7 @@ class PictureLayerImplTest : public testing::Test { if (!tile_size.IsEmpty()) pending_layer->set_fixed_tile_size(tile_size); } - pending_root->SetHasRenderSurface(true); + pending_root->SetForceRenderSurface(true); // The bounds() just mirror the raster source size. pending_layer->SetBounds(raster_source->GetSize()); pending_layer->SetRasterSourceOnPending(raster_source, invalidation); @@ -1400,7 +1400,7 @@ TEST_F(PictureLayerImplTest, HugeMasksGetScaledDown) { mask_ptr->SetBounds(layer_bounds); mask_ptr->SetDrawsContent(true); pending_layer_->SetMaskLayer(std::move(mask_ptr)); - pending_layer_->SetHasRenderSurface(true); + pending_layer_->SetForceRenderSurface(true); RebuildPropertyTreesOnPendingTree(); host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); @@ -1529,7 +1529,7 @@ TEST_F(PictureLayerImplTest, ScaledMaskLayer) { mask_ptr->SetBounds(layer_bounds); mask_ptr->SetDrawsContent(true); pending_layer_->SetMaskLayer(std::move(mask_ptr)); - pending_layer_->SetHasRenderSurface(true); + pending_layer_->SetForceRenderSurface(true); RebuildPropertyTreesOnPendingTree(); host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); diff --git a/cc/layers/render_surface_impl_unittest.cc b/cc/layers/render_surface_impl_unittest.cc index 7d026e6..96ca40b 100644 --- a/cc/layers/render_surface_impl_unittest.cc +++ b/cc/layers/render_surface_impl_unittest.cc @@ -22,7 +22,7 @@ TEST(RenderSurfaceLayerImplTest, Occlusion) { LayerImpl* owning_layer_impl = impl.AddChildToRoot<LayerImpl>(); owning_layer_impl->SetBounds(layer_size); owning_layer_impl->SetDrawsContent(true); - owning_layer_impl->SetHasRenderSurface(true); + owning_layer_impl->SetForceRenderSurface(true); impl.CalcDrawProps(viewport_size); diff --git a/cc/layers/solid_color_layer_impl_unittest.cc b/cc/layers/solid_color_layer_impl_unittest.cc index 3118114..a7317ec 100644 --- a/cc/layers/solid_color_layer_impl_unittest.cc +++ b/cc/layers/solid_color_layer_impl_unittest.cc @@ -35,7 +35,7 @@ TEST(SolidColorLayerImplTest, VerifyTilingCompleteAndNoOverlap) { SolidColorLayerImpl::Create(host_impl.active_tree(), 1); layer->draw_properties().visible_layer_rect = visible_layer_rect; layer->SetBounds(layer_size); - layer->SetHasRenderSurface(true); + layer->SetForceRenderSurface(true); layer->draw_properties().render_target = layer.get(); AppendQuadsData data; @@ -62,7 +62,7 @@ TEST(SolidColorLayerImplTest, VerifyCorrectBackgroundColorInQuad) { layer->draw_properties().visible_layer_rect = visible_layer_rect; layer->SetBounds(layer_size); layer->SetBackgroundColor(test_color); - layer->SetHasRenderSurface(true); + layer->SetForceRenderSurface(true); layer->draw_properties().render_target = layer.get(); AppendQuadsData data; @@ -91,7 +91,7 @@ TEST(SolidColorLayerImplTest, VerifyCorrectOpacityInQuad) { layer->draw_properties().visible_layer_rect = visible_layer_rect; layer->SetBounds(layer_size); layer->draw_properties().opacity = opacity; - layer->SetHasRenderSurface(true); + layer->SetForceRenderSurface(true); layer->draw_properties().render_target = layer.get(); AppendQuadsData data; diff --git a/cc/layers/ui_resource_layer_impl_unittest.cc b/cc/layers/ui_resource_layer_impl_unittest.cc index c1f9a2e..c184dd6 100644 --- a/cc/layers/ui_resource_layer_impl_unittest.cc +++ b/cc/layers/ui_resource_layer_impl_unittest.cc @@ -33,7 +33,7 @@ scoped_ptr<UIResourceLayerImpl> GenerateUIResourceLayer( UIResourceLayerImpl::Create(host_impl->active_tree(), 1); layer->draw_properties().visible_layer_rect = visible_layer_rect; layer->SetBounds(layer_size); - layer->SetHasRenderSurface(true); + layer->SetForceRenderSurface(true); layer->draw_properties().render_target = layer.get(); UIResourceBitmap bitmap(bitmap_size, opaque); diff --git a/cc/layers/video_layer_impl_unittest.cc b/cc/layers/video_layer_impl_unittest.cc index f8458d9..48c574b 100644 --- a/cc/layers/video_layer_impl_unittest.cc +++ b/cc/layers/video_layer_impl_unittest.cc @@ -93,7 +93,7 @@ TEST(VideoLayerImplTest, OccludesOtherLayers) { // Create a video layer with no frame on top of another layer. scoped_ptr<LayerImpl> layer_impl = LayerImpl::Create(active_tree, 3); - layer_impl->SetHasRenderSurface(true); + layer_impl->SetForceRenderSurface(true); layer_impl->SetBounds(layer_size); layer_impl->SetDrawsContent(true); const auto& draw_properties = layer_impl->draw_properties(); diff --git a/cc/test/layer_test_common.h b/cc/test/layer_test_common.h index 85f2f8a..4301a30 100644 --- a/cc/test/layer_test_common.h +++ b/cc/test/layer_test_common.h @@ -70,6 +70,15 @@ class LayerTestCommon { return ptr; } + template <typename T> + T* AddReplicaLayer(LayerImpl* origin) { + scoped_ptr<T> layer = + T::Create(host_->host_impl()->active_tree(), layer_impl_id_++); + T* ptr = layer.get(); + origin->SetReplicaLayer(layer.Pass()); + return ptr; + } + template <typename T, typename A> T* AddChildToRoot(const A& a) { scoped_ptr<T> layer = diff --git a/cc/test/layer_tree_host_common_test.cc b/cc/test/layer_tree_host_common_test.cc index c05716d..02b66ac 100644 --- a/cc/test/layer_tree_host_common_test.cc +++ b/cc/test/layer_tree_host_common_test.cc @@ -11,7 +11,6 @@ #include "cc/trees/layer_tree_host_common.h" namespace cc { - LayerTreeHostCommonTestBase::LayerTreeHostCommonTestBase( const LayerTreeSettings& settings) : LayerTestCommon::LayerImplTest(settings), @@ -41,13 +40,26 @@ void LayerTreeHostCommonTestBase::SetLayerPropertiesForTesting( const gfx::PointF& position, const gfx::Size& bounds, bool flatten_transform, + bool is_3d_sorted) { + SetLayerPropertiesForTestingInternal(layer, transform, transform_origin, + position, bounds, flatten_transform, + is_3d_sorted); +} + +void LayerTreeHostCommonTestBase::SetLayerPropertiesForTesting( + LayerImpl* layer, + const gfx::Transform& transform, + const gfx::Point3F& transform_origin, + const gfx::PointF& position, + const gfx::Size& bounds, + bool flatten_transform, bool is_3d_sorted, bool create_render_surface) { SetLayerPropertiesForTestingInternal(layer, transform, transform_origin, position, bounds, flatten_transform, is_3d_sorted); if (create_render_surface) { - layer->SetHasRenderSurface(true); + layer->SetForceRenderSurface(true); } } @@ -83,11 +95,8 @@ void LayerTreeHostCommonTestBase:: LayerTreeHostCommon::PreCalculateMetaInformation(root_layer); gfx::Transform identity_transform; - bool preserves_2d_axis_alignment = false; + bool can_render_to_separate_surface = true; - LayerTreeHostCommon::UpdateRenderSurfaces( - root_layer, can_render_to_separate_surface, identity_transform, - preserves_2d_axis_alignment); Layer* page_scale_layer = nullptr; Layer* inner_viewport_scroll_layer = @@ -118,7 +127,9 @@ void LayerTreeHostCommonTestBase:: LayerTreeHostCommon::PreCalculateMetaInformationForTesting(root_layer); gfx::Transform identity_transform; + bool can_render_to_separate_surface = true; + LayerImpl* page_scale_layer = nullptr; LayerImpl* inner_viewport_scroll_layer = root_layer->layer_tree_impl()->InnerViewportScrollLayer(); @@ -134,14 +145,15 @@ void LayerTreeHostCommonTestBase:: gfx::Size device_viewport_size = gfx::Size(root_layer->bounds().width() * device_scale_factor, root_layer->bounds().height() * device_scale_factor); - std::vector<LayerImpl*> update_layer_list; + update_layer_list_impl_.reset(new LayerImplList); BuildPropertyTreesAndComputeVisibleRects( root_layer, page_scale_layer, inner_viewport_scroll_layer, outer_viewport_scroll_layer, overscroll_elasticity_layer, elastic_overscroll, page_scale_factor, device_scale_factor, gfx::Rect(device_viewport_size), identity_transform, can_render_to_separate_surface, - root_layer->layer_tree_impl()->property_trees(), &update_layer_list); + root_layer->layer_tree_impl()->property_trees(), + update_layer_list_impl_.get()); } void LayerTreeHostCommonTestBase::ExecuteCalculateDrawProperties( diff --git a/cc/test/layer_tree_host_common_test.h b/cc/test/layer_tree_host_common_test.h index f8f1a02..2a66715 100644 --- a/cc/test/layer_tree_host_common_test.h +++ b/cc/test/layer_tree_host_common_test.h @@ -5,6 +5,7 @@ #ifndef CC_TEST_LAYER_TREE_HOST_COMMON_TEST_H_ #define CC_TEST_LAYER_TREE_HOST_COMMON_TEST_H_ +#include <algorithm> #include <vector> #include "base/memory/scoped_ptr.h" @@ -66,6 +67,14 @@ class LayerTreeHostCommonTestBase : public LayerTestCommon::LayerImplTest { const gfx::PointF& position, const gfx::Size& bounds, bool flatten_transform, + bool is_3d_sorted); + + void SetLayerPropertiesForTesting(LayerImpl* layer, + const gfx::Transform& transform, + const gfx::Point3F& transform_origin, + const gfx::PointF& position, + const gfx::Size& bounds, + bool flatten_transform, bool is_3d_sorted, bool create_render_surface); @@ -118,6 +127,15 @@ class LayerTreeHostCommonTestBase : public LayerTestCommon::LayerImplTest { return render_surface_layer_list_impl_.get(); } + LayerImplList* update_layer_list_impl() const { + return update_layer_list_impl_.get(); + } + bool UpdateLayerListImplContains(int id) const { + return std::count_if( + update_layer_list_impl_->begin(), update_layer_list_impl_->end(), + [id](LayerImpl* layer) { return layer->id() == id; }) != 0; + } + const LayerList& update_layer_list() const { return update_layer_list_; } bool UpdateLayerListContains(int id) const; @@ -130,6 +148,7 @@ class LayerTreeHostCommonTestBase : public LayerTestCommon::LayerImplTest { private: scoped_ptr<std::vector<LayerImpl*>> render_surface_layer_list_impl_; LayerList update_layer_list_; + scoped_ptr<LayerImplList> update_layer_list_impl_; LayerSettings layer_settings_; int render_surface_layer_list_count_; diff --git a/cc/tiles/tile_manager_perftest.cc b/cc/tiles/tile_manager_perftest.cc index e28f35a..87709f4 100644 --- a/cc/tiles/tile_manager_perftest.cc +++ b/cc/tiles/tile_manager_perftest.cc @@ -169,7 +169,7 @@ class TileManagerPerfTest : public testing::Test { FakePictureLayerImpl::CreateWithRasterSource(pending_tree, id_, raster_source); pending_layer->SetDrawsContent(true); - pending_layer->SetHasRenderSurface(true); + pending_layer->SetForceRenderSurface(true); pending_tree->SetRootLayer(std::move(pending_layer)); pending_tree->BuildPropertyTreesForTesting(); diff --git a/cc/trees/damage_tracker_unittest.cc b/cc/trees/damage_tracker_unittest.cc index 6fd2929..9a00403 100644 --- a/cc/trees/damage_tracker_unittest.cc +++ b/cc/trees/damage_tracker_unittest.cc @@ -29,7 +29,6 @@ void ExecuteCalculateDrawProperties(LayerImpl* root, // Sanity check: The test itself should create the root layer's render // surface, so that the surface (and its damage tracker) can // persist across multiple calls to this function. - ASSERT_TRUE(root->render_surface()); ASSERT_FALSE(render_surface_layer_list->size()); FakeLayerTreeHostImpl::RecursiveUpdateNumChildren(root); @@ -38,6 +37,7 @@ void ExecuteCalculateDrawProperties(LayerImpl* root, root, root->bounds(), render_surface_layer_list, root->layer_tree_impl()->current_render_surface_list_id()); LayerTreeHostCommon::CalculateDrawProperties(&inputs); + ASSERT_TRUE(root->render_surface()); } void ClearDamageForAllSurfaces(LayerImpl* layer) { @@ -94,8 +94,7 @@ class DamageTrackerTest : public testing::Test { root->SetPosition(gfx::PointF()); root->SetBounds(gfx::Size(500, 500)); root->SetDrawsContent(true); - root->SetHasRenderSurface(true); - root->render_surface()->SetContentRect(gfx::Rect(0, 0, 500, 500)); + root->SetForceRenderSurface(true); child->SetPosition(gfx::PointF(100.f, 100.f)); child->SetBounds(gfx::Size(30, 30)); @@ -124,8 +123,7 @@ class DamageTrackerTest : public testing::Test { root->SetPosition(gfx::PointF()); root->SetBounds(gfx::Size(500, 500)); root->SetDrawsContent(true); - root->SetHasRenderSurface(true); - root->render_surface()->SetContentRect(gfx::Rect(0, 0, 500, 500)); + root->SetForceRenderSurface(true); child1->SetPosition(gfx::PointF(100.f, 100.f)); child1->SetBounds(gfx::Size(30, 30)); @@ -133,7 +131,7 @@ class DamageTrackerTest : public testing::Test { // its own RenderSurface. This layer does not draw, but is intended to // create its own RenderSurface. child1->SetDrawsContent(false); - child1->SetHasRenderSurface(true); + child1->SetForceRenderSurface(true); child2->SetPosition(gfx::PointF(11.f, 11.f)); child2->SetBounds(gfx::Size(18, 18)); @@ -544,7 +542,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForImageFilter) { // Setting the filter will damage the whole surface. ClearDamageForAllSurfaces(root.get()); - child->SetHasRenderSurface(true); + child->SetForceRenderSurface(true); child->SetFilters(filters); EmulateDrawingOneFrame(root.get()); root_damage_rect = @@ -937,7 +935,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForAddingAndRemovingRenderSurfaces) { // CASE 1: If a descendant surface disappears, its entire old area becomes // exposed. ClearDamageForAllSurfaces(root.get()); - child1->SetHasRenderSurface(false); + child1->SetForceRenderSurface(false); EmulateDrawingOneFrame(root.get()); // Sanity check that there is only one surface now. @@ -962,7 +960,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForAddingAndRemovingRenderSurfaces) { // Then change the tree so that the render surface is added back. ClearDamageForAllSurfaces(root.get()); - child1->SetHasRenderSurface(true); + child1->SetForceRenderSurface(true); EmulateDrawingOneFrame(root.get()); @@ -1065,7 +1063,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForReplica) { reflection.Scale3d(-1.0, 1.0, 1.0); grand_child1_replica->SetTransform(reflection); grand_child1->SetReplicaLayer(std::move(grand_child1_replica)); - grand_child1->SetHasRenderSurface(true); + grand_child1->SetForceRenderSurface(true); } EmulateDrawingOneFrame(root.get()); @@ -1116,7 +1114,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForReplica) { // reflection to damage the target surface. ClearDamageForAllSurfaces(root.get()); grand_child1->SetReplicaLayer(nullptr); - grand_child1->SetHasRenderSurface(false); + grand_child1->SetForceRenderSurface(false); EmulateDrawingOneFrame(root.get()); ASSERT_EQ(old_content_rect.width(), child1->render_surface()->content_rect().width()); @@ -1150,7 +1148,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForMask) { mask_layer->SetPosition(child->position()); mask_layer->SetBounds(child->bounds()); child->SetMaskLayer(std::move(mask_layer)); - child->SetHasRenderSurface(true); + child->SetForceRenderSurface(true); } LayerImpl* mask_layer = child->mask_layer(); @@ -1239,7 +1237,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForReplicaMask) { reflection.Scale3d(-1.0, 1.0, 1.0); grand_child1_replica->SetTransform(reflection); grand_child1->SetReplicaLayer(std::move(grand_child1_replica)); - grand_child1->SetHasRenderSurface(true); + grand_child1->SetForceRenderSurface(true); } LayerImpl* grand_child1_replica = grand_child1->replica_layer(); @@ -1316,7 +1314,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForReplicaMaskWithTransformOrigin) { reflection.Scale3d(-1.0, 1.0, 1.0); grand_child1_replica->SetTransform(reflection); grand_child1->SetReplicaLayer(std::move(grand_child1_replica)); - grand_child1->SetHasRenderSurface(true); + grand_child1->SetForceRenderSurface(true); } LayerImpl* grand_child1_replica = grand_child1->replica_layer(); @@ -1383,7 +1381,8 @@ TEST_F(DamageTrackerTest, VerifyDamageForEmptyLayerList) { // tracker does not crash when it receives an empty layer_list. scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_.active_tree(), 1); - root->SetHasRenderSurface(true); + root->SetForceRenderSurface(true); + EmulateDrawingOneFrame(root.get()); root->draw_properties().render_target = root.get(); ASSERT_EQ(root.get(), root->render_target()); diff --git a/cc/trees/draw_property_utils.cc b/cc/trees/draw_property_utils.cc index 971888d..a5243e8 100644 --- a/cc/trees/draw_property_utils.cc +++ b/cc/trees/draw_property_utils.cc @@ -21,6 +21,28 @@ namespace cc { namespace { template <typename LayerType> +static void ValidateRenderSurfaces(LayerType* layer) { + for (size_t i = 0; i < layer->children().size(); ++i) { + ValidateRenderSurfaces(layer->child_at(i)); + } + + // This test verifies that there are no cases where a LayerImpl needs + // a render surface, but doesn't have one. + if (layer->has_render_surface()) + return; + + DCHECK(layer->filters().IsEmpty()) << "layer: " << layer->id(); + DCHECK(layer->background_filters().IsEmpty()) << "layer: " << layer->id(); + DCHECK(layer->parent()) << "layer: " << layer->id(); + if (layer->parent()->replica_layer() == layer) + return; + DCHECK(!layer->mask_layer()) << "layer: " << layer->id(); + DCHECK(!layer->replica_layer()) << "layer: " << layer->id(); + DCHECK(!layer->is_root_for_isolated_group()) << "layer: " << layer->id(); + DCHECK(!layer->HasCopyRequest()) << "layer: " << layer->id(); +} + +template <typename LayerType> void CalculateVisibleRects(const std::vector<LayerType*>& visible_layer_list, const ClipTree& clip_tree, const TransformTree& transform_tree, @@ -438,6 +460,43 @@ void FindLayersThatNeedUpdates( } } +template <typename LayerType> +void UpdateRenderSurfacesWithEffectTreeInternal(EffectTree* effect_tree, + LayerType* layer) { + EffectNode* node = effect_tree->Node(layer->effect_tree_index()); + + if (node->owner_id == layer->id() && node->data.has_render_surface) + layer->SetHasRenderSurface(true); + else + layer->SetHasRenderSurface(false); + + for (size_t i = 0; i < layer->children().size(); ++i) { + UpdateRenderSurfacesWithEffectTreeInternal<LayerType>(effect_tree, + layer->child_at(i)); + } +} + +void UpdateRenderSurfacesWithEffectTree(EffectTree* effect_tree, Layer* layer) { + UpdateRenderSurfacesWithEffectTreeInternal<Layer>(effect_tree, layer); +} + +void UpdateRenderSurfacesNonRootSurfacesDisabled(LayerImpl* layer) { + // Only root layer has render surface, all other layers don't. + layer->SetHasRenderSurface(!layer->parent()); + + for (size_t i = 0; i < layer->children().size(); ++i) + UpdateRenderSurfacesNonRootSurfacesDisabled(layer->child_at(i)); +} + +void UpdateRenderSurfacesWithEffectTree(EffectTree* effect_tree, + bool non_root_surfaces_enabled, + LayerImpl* layer) { + if (!non_root_surfaces_enabled) + UpdateRenderSurfacesNonRootSurfacesDisabled(layer); + else + UpdateRenderSurfacesWithEffectTreeInternal<LayerImpl>(effect_tree, layer); +} + } // namespace static void ResetIfHasNanCoordinate(gfx::RectF* rect) { @@ -500,7 +559,6 @@ void ComputeClips(ClipTree* clip_tree, parent_to_current, parent_clip_node->data.combined_clip_in_target_space); } - // Only nodes affected by ancestor clips will have their clip adjusted due // to intersecting with an ancestor clip. But, we still need to propagate // the combined clip to our children because if they are clipped, they may @@ -523,7 +581,6 @@ void ComputeClips(ClipTree* clip_tree, ResetIfHasNanCoordinate(&clip_node->data.combined_clip_in_target_space); continue; } - bool use_only_parent_clip = !clip_node->data.applies_local_clip; if (use_only_parent_clip) { clip_node->data.combined_clip_in_target_space = @@ -648,6 +705,8 @@ void BuildPropertyTreesAndComputeVisibleRects( outer_viewport_scroll_layer, overscroll_elasticity_layer, elastic_overscroll, page_scale_factor, device_scale_factor, viewport, device_transform, property_trees); + UpdateRenderSurfacesWithEffectTree(&property_trees->effect_tree, root_layer); + ValidateRenderSurfaces(root_layer); ComputeVisibleRectsUsingPropertyTrees(root_layer, property_trees, can_render_to_separate_surface, update_layer_list); @@ -691,6 +750,10 @@ void ComputeVisibleRectsUsingPropertyTrees(LayerImpl* root_layer, PropertyTrees* property_trees, bool can_render_to_separate_surface, LayerImplList* visible_layer_list) { + UpdateRenderSurfacesWithEffectTree( + &property_trees->effect_tree, can_render_to_separate_surface, root_layer); + if (can_render_to_separate_surface) + ValidateRenderSurfaces(root_layer); LayerImplList update_layer_list; ComputeVisibleRectsUsingPropertyTreesInternal( root_layer, property_trees, can_render_to_separate_surface, diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc index 5acc333..b5f0231 100644 --- a/cc/trees/layer_tree_host.cc +++ b/cc/trees/layer_tree_host.cc @@ -779,22 +779,18 @@ bool LayerTreeHost::DoUpdateLayers(Layer* root_layer) { device_scale_factor_); } - bool can_render_to_separate_surface = true; TRACE_EVENT0("cc", "LayerTreeHost::UpdateLayers::CalcDrawProps"); LayerTreeHostCommon::PreCalculateMetaInformation(root_layer); - bool preserves_2d_axis_alignment = false; gfx::Transform identity_transform; LayerList update_layer_list; - LayerTreeHostCommon::UpdateRenderSurfaces( - root_layer, can_render_to_separate_surface, identity_transform, - preserves_2d_axis_alignment); { TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug.cdp-perf"), "LayerTreeHostCommon::ComputeVisibleRectsWithPropertyTrees"); + bool can_render_to_separate_surface = true; BuildPropertyTreesAndComputeVisibleRects( root_layer, page_scale_layer, inner_viewport_scroll_layer_.get(), outer_viewport_scroll_layer_.get(), overscroll_elasticity_layer_.get(), diff --git a/cc/trees/layer_tree_host_common.cc b/cc/trees/layer_tree_host_common.cc index 5e62f09..3ea2a2d 100644 --- a/cc/trees/layer_tree_host_common.cc +++ b/cc/trees/layer_tree_host_common.cc @@ -625,141 +625,6 @@ static inline bool SubtreeShouldBeSkipped(LayerImpl* layer, static inline void SavePaintPropertiesLayer(LayerImpl* layer) {} -static bool SubtreeShouldRenderToSeparateSurface( - Layer* layer, - bool axis_aligned_with_respect_to_parent) { - // - // A layer and its descendants should render onto a new RenderSurfaceImpl if - // any of these rules hold: - // - - // The root layer owns a render surface, but it never acts as a contributing - // surface to another render target. Compositor features that are applied via - // a contributing surface can not be applied to the root layer. In order to - // use these effects, another child of the root would need to be introduced - // in order to act as a contributing surface to the root layer's surface. - bool is_root = IsRootLayer(layer); - - // If the layer uses a mask. - if (layer->mask_layer()) { - DCHECK(!is_root); - return true; - } - - // If the layer has a reflection. - if (layer->replica_layer()) { - DCHECK(!is_root); - return true; - } - - // If the layer uses a CSS filter. - if (!layer->filters().IsEmpty() || !layer->background_filters().IsEmpty()) { - DCHECK(!is_root); - return true; - } - - // If the layer will use a CSS filter. In this case, the animation - // will start and add a filter to this layer, so it needs a surface. - if (layer->HasPotentiallyRunningFilterAnimation()) { - DCHECK(!is_root); - return true; - } - - int num_descendants_that_draw_content = - layer->NumDescendantsThatDrawContent(); - - // If the layer flattens its subtree, but it is treated as a 3D object by its - // parent (i.e. parent participates in a 3D rendering context). - if (LayerIsInExisting3DRenderingContext(layer) && - layer->should_flatten_transform() && - num_descendants_that_draw_content > 0) { - TRACE_EVENT_INSTANT0( - "cc", - "LayerTreeHostCommon::SubtreeShouldRenderToSeparateSurface flattening", - TRACE_EVENT_SCOPE_THREAD); - DCHECK(!is_root); - return true; - } - - // If the layer has blending. - // TODO(rosca): this is temporary, until blending is implemented for other - // types of quads than RenderPassDrawQuad. Layers having descendants that draw - // content will still create a separate rendering surface. - if (!layer->uses_default_blend_mode()) { - TRACE_EVENT_INSTANT0( - "cc", - "LayerTreeHostCommon::SubtreeShouldRenderToSeparateSurface blending", - TRACE_EVENT_SCOPE_THREAD); - DCHECK(!is_root); - return true; - } - - // If the layer clips its descendants but it is not axis-aligned with respect - // to its parent. - bool layer_clips_external_content = - LayerClipsSubtree(layer) || layer->HasDelegatedContent(); - if (layer_clips_external_content && !axis_aligned_with_respect_to_parent && - num_descendants_that_draw_content > 0) { - TRACE_EVENT_INSTANT0( - "cc", - "LayerTreeHostCommon::SubtreeShouldRenderToSeparateSurface clipping", - TRACE_EVENT_SCOPE_THREAD); - DCHECK(!is_root); - return true; - } - - // If the layer has some translucency and does not have a preserves-3d - // transform style. This condition only needs a render surface if two or more - // layers in the subtree overlap. But checking layer overlaps is unnecessarily - // costly so instead we conservatively create a surface whenever at least two - // layers draw content for this subtree. - bool at_least_two_layers_in_subtree_draw_content = - num_descendants_that_draw_content > 0 && - (layer->DrawsContent() || num_descendants_that_draw_content > 1); - - if (layer->opacity() != 1.f && layer->should_flatten_transform() && - at_least_two_layers_in_subtree_draw_content) { - TRACE_EVENT_INSTANT0( - "cc", - "LayerTreeHostCommon::SubtreeShouldRenderToSeparateSurface opacity", - TRACE_EVENT_SCOPE_THREAD); - DCHECK(!is_root); - return true; - } - - // The root layer should always have a render_surface. - if (is_root) - return true; - - // - // These are allowed on the root surface, as they don't require the surface to - // be used as a contributing surface in order to apply correctly. - // - - // If the layer has isolation. - // TODO(rosca): to be optimized - create separate rendering surface only when - // the blending descendants might have access to the content behind this layer - // (layer has transparent background or descendants overflow). - // https://code.google.com/p/chromium/issues/detail?id=301738 - if (layer->is_root_for_isolated_group()) { - TRACE_EVENT_INSTANT0( - "cc", - "LayerTreeHostCommon::SubtreeShouldRenderToSeparateSurface isolation", - TRACE_EVENT_SCOPE_THREAD); - return true; - } - - // If we force it. - if (layer->force_render_surface()) - return true; - - // If we'll make a copy of the layer's contents. - if (layer->HasCopyRequest()) - return true; - - return false; -} - // This function returns a translation matrix that can be applied on a vector // that's in the layer's target surface coordinate, while the position offset is // specified in some ancestor layer's coordinate. @@ -1146,11 +1011,13 @@ struct PreCalculateMetaInformationRecursiveData { size_t num_unclipped_descendants; int num_layer_or_descendants_with_copy_request; int num_layer_or_descendants_with_input_handler; + int num_descendants_that_draw_content; PreCalculateMetaInformationRecursiveData() : num_unclipped_descendants(0), num_layer_or_descendants_with_copy_request(0), - num_layer_or_descendants_with_input_handler(0) {} + num_layer_or_descendants_with_input_handler(0), + num_descendants_that_draw_content(0) {} void Merge(const PreCalculateMetaInformationRecursiveData& data) { num_layer_or_descendants_with_copy_request += @@ -1158,26 +1025,10 @@ struct PreCalculateMetaInformationRecursiveData { num_layer_or_descendants_with_input_handler += data.num_layer_or_descendants_with_input_handler; num_unclipped_descendants += data.num_unclipped_descendants; + num_descendants_that_draw_content += data.num_descendants_that_draw_content; } }; -static void ValidateRenderSurface(LayerImpl* layer) { - // This test verifies that there are no cases where a LayerImpl needs - // a render surface, but doesn't have one. - if (layer->render_surface()) - return; - - DCHECK(layer->filters().IsEmpty()) << "layer: " << layer->id(); - DCHECK(layer->background_filters().IsEmpty()) << "layer: " << layer->id(); - DCHECK(!layer->mask_layer()) << "layer: " << layer->id(); - DCHECK(!layer->replica_layer()) << "layer: " << layer->id(); - DCHECK(!IsRootLayer(layer)) << "layer: " << layer->id(); - DCHECK(!layer->is_root_for_isolated_group()) << "layer: " << layer->id(); - DCHECK(!layer->HasCopyRequest()) << "layer: " << layer->id(); -} - -static void ValidateRenderSurface(Layer* layer) {} - static bool IsMetaInformationRecomputationNeeded(Layer* layer) { return layer->layer_tree_host()->needs_meta_info_recomputation(); } @@ -1194,8 +1045,6 @@ static void UpdateMetaInformationSequenceNumber(LayerImpl* root_layer) { static void PreCalculateMetaInformationInternal( Layer* layer, PreCalculateMetaInformationRecursiveData* recursive_data) { - ValidateRenderSurface(layer); - if (!IsMetaInformationRecomputationNeeded(layer)) { DCHECK(IsRootLayer(layer)); return; @@ -1247,8 +1096,6 @@ static void PreCalculateMetaInformationInternal( static void PreCalculateMetaInformationInternal( LayerImpl* layer, PreCalculateMetaInformationRecursiveData* recursive_data) { - ValidateRenderSurface(layer); - layer->set_sorted_for_recursion(false); layer->draw_properties().has_child_with_a_scroll_parent = false; layer->set_layer_or_descendant_is_drawn(false); @@ -1295,6 +1142,11 @@ static void PreCalculateMetaInformationInternal( // for tests constructing layers on the compositor thread. layer->set_num_layer_or_descendant_with_copy_request( recursive_data->num_layer_or_descendants_with_copy_request); + layer->SetNumDescendantsThatDrawContent( + recursive_data->num_descendants_that_draw_content); + + if (layer->DrawsContent()) + recursive_data->num_descendants_that_draw_content++; } void LayerTreeHostCommon::PreCalculateMetaInformation(Layer* root_layer) { @@ -2216,43 +2068,6 @@ static void ProcessCalcDrawPropsInputs( data_for_recursion->subtree_is_visible_from_ancestor = true; } -void LayerTreeHostCommon::UpdateRenderSurface( - Layer* layer, - bool can_render_to_separate_surface, - gfx::Transform* transform, - bool* draw_transform_is_axis_aligned) { - bool preserves_2d_axis_alignment = - transform->Preserves2dAxisAlignment() && *draw_transform_is_axis_aligned; - if (IsRootLayer(layer) || (can_render_to_separate_surface && - SubtreeShouldRenderToSeparateSurface( - layer, preserves_2d_axis_alignment))) { - // We reset the transform here so that any axis-changing transforms - // will now be relative to this RenderSurface. - transform->MakeIdentity(); - *draw_transform_is_axis_aligned = true; - layer->SetHasRenderSurface(true); - return; - } - layer->SetHasRenderSurface(false); -} - -void LayerTreeHostCommon::UpdateRenderSurfaces( - Layer* layer, - bool can_render_to_separate_surface, - const gfx::Transform& parent_transform, - bool draw_transform_is_axis_aligned) { - gfx::Transform transform_for_children = layer->transform(); - transform_for_children *= parent_transform; - draw_transform_is_axis_aligned &= layer->AnimationsPreserveAxisAlignment(); - UpdateRenderSurface(layer, can_render_to_separate_surface, - &transform_for_children, &draw_transform_is_axis_aligned); - - for (size_t i = 0; i < layer->children().size(); ++i) { - UpdateRenderSurfaces(layer->children()[i].get(), - can_render_to_separate_surface, transform_for_children, - draw_transform_is_axis_aligned); - } -} static bool ApproximatelyEqual(const gfx::Rect& r1, const gfx::Rect& r2) { // TODO(vollick): This tolerance should be lower: crbug.com/471786 @@ -2351,7 +2166,6 @@ void VerifyPropertyTreeValuesForLayer(LayerImpl* current_layer, ComputeLayerDrawPropertiesUsingPropertyTrees( current_layer, property_trees, layers_always_allowed_lcd_text, can_use_lcd_text, &draw_properties); - const bool visible_rects_match = ApproximatelyEqual( current_layer->visible_layer_rect(), draw_properties.visible_layer_rect); CHECK(visible_rects_match) @@ -2433,7 +2247,9 @@ void CalculateRenderTargetInternal(LayerImpl* layer, (can_render_to_separate_surface && layer->render_surface()); if (render_to_separate_surface) { - DCHECK(layer->render_surface()); + DCHECK(layer->render_surface()) << IsRootLayer(layer) + << can_render_to_separate_surface + << layer->has_render_surface(); layer->draw_properties().render_target = layer; if (layer->mask_layer()) @@ -2744,7 +2560,6 @@ void CalculateDrawPropertiesAndVerify( UpdateMetaInformationSequenceNumber(inputs->root_layer); PreCalculateMetaInformationRecursiveData recursive_data; PreCalculateMetaInformationInternal(inputs->root_layer, &recursive_data); - const bool should_measure_property_tree_performance = inputs->verify_property_trees && (property_tree_option == BUILD_PROPERTY_TREES_IF_NEEDED); @@ -2826,6 +2641,8 @@ void CalculateDrawPropertiesAndVerify( } std::vector<AccumulatedSurfaceState> accumulated_surface_state; + DCHECK(inputs->can_render_to_separate_surface == + inputs->property_trees->non_root_surfaces_enabled); CalculateRenderTarget(inputs); if (inputs->use_property_trees) { for (LayerImpl* layer : visible_layer_list) { @@ -2867,8 +2684,6 @@ void LayerTreeHostCommon::CalculateDrawProperties( CalcDrawPropsMainInputs* inputs) { LayerList update_layer_list; bool can_render_to_separate_surface = true; - UpdateRenderSurfaces(inputs->root_layer, can_render_to_separate_surface, - gfx::Transform(), false); PropertyTrees* property_trees = inputs->root_layer->layer_tree_host()->property_trees(); Layer* overscroll_elasticity_layer = nullptr; diff --git a/cc/trees/layer_tree_host_common.h b/cc/trees/layer_tree_host_common.h index ea75068..9265932 100644 --- a/cc/trees/layer_tree_host_common.h +++ b/cc/trees/layer_tree_host_common.h @@ -115,14 +115,6 @@ class CC_EXPORT LayerTreeHostCommon { int current_render_surface_layer_list_id); }; - static void UpdateRenderSurfaces(Layer* root_layer, - bool can_render_to_separate_surface, - const gfx::Transform& transform, - bool preserves_2d_axis_alignment); - static void UpdateRenderSurface(Layer* layer, - bool can_render_to_separate_surface, - gfx::Transform* transform, - bool* animation_preserves_axis_alignment); static void CalculateDrawProperties(CalcDrawPropsMainInputs* inputs); static void PreCalculateMetaInformation(Layer* root_layer); static void PreCalculateMetaInformationForTesting(LayerImpl* root_layer); diff --git a/cc/trees/layer_tree_host_common_unittest.cc b/cc/trees/layer_tree_host_common_unittest.cc index 4328371..4f620c2 100644 --- a/cc/trees/layer_tree_host_common_unittest.cc +++ b/cc/trees/layer_tree_host_common_unittest.cc @@ -152,25 +152,27 @@ TEST_F(LayerTreeHostCommonTest, DoNotSkipLayersWithHandlers) { gfx::Transform identity_matrix; SetLayerPropertiesForTesting(parent, identity_matrix, gfx::Point3F(), - gfx::PointF(), gfx::Size(100, 100), true, false, - true); + gfx::PointF(), gfx::Size(100, 100), true, false); SetLayerPropertiesForTesting(child, identity_matrix, gfx::Point3F(), gfx::PointF(10, 10), gfx::Size(100, 100), true, - false, false); + false); // This would have previously caused us to skip our subtree, but this would be // wrong; we need up-to-date draw properties to do hit testing on the layers // with handlers. child->SetOpacity(0.f); SetLayerPropertiesForTesting(grand_child, identity_matrix, gfx::Point3F(), gfx::PointF(10, 10), gfx::Size(100, 100), true, - false, false); + false); grand_child->SetTouchEventHandlerRegion(gfx::Rect(0, 0, 100, 100)); ExecuteCalculateDrawProperties(parent); + EXPECT_TRUE(child->has_render_surface()); + EXPECT_FALSE(grand_child->has_render_surface()); // Check that we've computed draw properties for the subtree rooted at // |child|. - EXPECT_FALSE(child->draw_properties().target_space_transform.IsIdentity()); + EXPECT_TRUE(child->draw_properties().target_space_transform.IsIdentity()); + EXPECT_FALSE(child->render_surface()->draw_transform().IsIdentity()); EXPECT_FALSE( grand_child->draw_properties().target_space_transform.IsIdentity()); } @@ -1396,34 +1398,23 @@ TEST_F(LayerTreeHostCommonTest, DrawOpacityWhenCannotRenderToSeparateSurface) { } TEST_F(LayerTreeHostCommonTest, ForceRenderSurface) { - scoped_refptr<Layer> parent = Layer::Create(layer_settings()); - scoped_refptr<Layer> render_surface1 = Layer::Create(layer_settings()); - scoped_refptr<LayerWithForcedDrawsContent> child = - make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings())); - render_surface1->SetForceRenderSurface(true); - - host()->SetRootLayer(parent); + LayerImpl* parent = root_layer(); + LayerImpl* render_surface1 = AddChildToRoot<LayerImpl>(); + LayerImpl* child = AddChild<LayerImpl>(render_surface1); const gfx::Transform identity_matrix; - SetLayerPropertiesForTesting(parent.get(), identity_matrix, gfx::Point3F(), + SetLayerPropertiesForTesting(parent, identity_matrix, gfx::Point3F(), gfx::PointF(), gfx::Size(10, 10), true, false); - SetLayerPropertiesForTesting(render_surface1.get(), identity_matrix, - gfx::Point3F(), gfx::PointF(), gfx::Size(10, 10), - true, false); - SetLayerPropertiesForTesting(child.get(), identity_matrix, gfx::Point3F(), + SetLayerPropertiesForTesting(render_surface1, identity_matrix, gfx::Point3F(), + gfx::PointF(), gfx::Size(10, 10), true, false); + SetLayerPropertiesForTesting(child, identity_matrix, gfx::Point3F(), gfx::PointF(), gfx::Size(10, 10), true, false); - parent->AddChild(render_surface1); - render_surface1->AddChild(child); - - // Sanity check before the actual test - EXPECT_FALSE(parent->has_render_surface()); - EXPECT_FALSE(render_surface1->has_render_surface()); + child->SetDrawsContent(true); + render_surface1->SetForceRenderSurface(true); { - LayerTreeHostCommon::CalcDrawPropsMainInputs inputs(parent.get(), - parent->bounds()); - LayerTreeHostCommon::CalculateDrawProperties(&inputs); + ExecuteCalculateDrawPropertiesWithPropertyTrees(parent); // The root layer always creates a render surface EXPECT_TRUE(parent->has_render_surface()); @@ -1432,9 +1423,8 @@ TEST_F(LayerTreeHostCommonTest, ForceRenderSurface) { { render_surface1->SetForceRenderSurface(false); - LayerTreeHostCommon::CalcDrawPropsMainInputs inputs(parent.get(), - parent->bounds()); - LayerTreeHostCommon::CalculateDrawProperties(&inputs); + render_surface1->layer_tree_impl()->property_trees()->needs_rebuild = true; + ExecuteCalculateDrawPropertiesWithPropertyTrees(parent); EXPECT_TRUE(parent->has_render_surface()); EXPECT_FALSE(render_surface1->has_render_surface()); } @@ -1780,6 +1770,9 @@ TEST_F(LayerTreeHostCommonTest, IsClippedWhenCannotRenderToSeparateSurface) { // Case 1: Nothing is clipped. In this case, is_clipped is always false, with // or without surfaces. + root->SetHasRenderSurface(true); + child1->SetHasRenderSurface(true); + grand_child->SetHasRenderSurface(true); ExecuteCalculateDrawProperties(root); EXPECT_FALSE(root->is_clipped()); EXPECT_FALSE(parent->is_clipped()); @@ -1802,6 +1795,9 @@ TEST_F(LayerTreeHostCommonTest, IsClippedWhenCannotRenderToSeparateSurface) { // next render surface. Without surfaces, the entire tree is clipped. root->SetMasksToBounds(true); host_impl()->active_tree()->property_trees()->needs_rebuild = true; + root->SetHasRenderSurface(true); + child1->SetHasRenderSurface(true); + grand_child->SetHasRenderSurface(true); ExecuteCalculateDrawProperties(root); EXPECT_TRUE(root->is_clipped()); EXPECT_TRUE(parent->is_clipped()); @@ -1827,6 +1823,9 @@ TEST_F(LayerTreeHostCommonTest, IsClippedWhenCannotRenderToSeparateSurface) { // clipped. parent->SetMasksToBounds(true); host_impl()->active_tree()->property_trees()->needs_rebuild = true; + root->SetHasRenderSurface(true); + child1->SetHasRenderSurface(true); + grand_child->SetHasRenderSurface(true); ExecuteCalculateDrawProperties(root); EXPECT_FALSE(root->is_clipped()); EXPECT_TRUE(parent->is_clipped()); @@ -1852,6 +1851,9 @@ TEST_F(LayerTreeHostCommonTest, IsClippedWhenCannotRenderToSeparateSurface) { // clipped. child1->SetMasksToBounds(true); host_impl()->active_tree()->property_trees()->needs_rebuild = true; + root->SetHasRenderSurface(true); + child1->SetHasRenderSurface(true); + grand_child->SetHasRenderSurface(true); ExecuteCalculateDrawProperties(root); EXPECT_FALSE(root->is_clipped()); EXPECT_FALSE(parent->is_clipped()); @@ -1877,6 +1879,9 @@ TEST_F(LayerTreeHostCommonTest, IsClippedWhenCannotRenderToSeparateSurface) { leaf_node1->SetMasksToBounds(true); leaf_node2->SetMasksToBounds(true); host_impl()->active_tree()->property_trees()->needs_rebuild = true; + root->SetHasRenderSurface(true); + child1->SetHasRenderSurface(true); + grand_child->SetHasRenderSurface(true); ExecuteCalculateDrawProperties(root); EXPECT_FALSE(root->is_clipped()); EXPECT_FALSE(parent->is_clipped()); @@ -2065,31 +2070,40 @@ TEST_F(LayerTreeHostCommonTest, ClipRectWhenCannotRenderToSeparateSurface) { // child1 and grand_child get render surfaces when surfaces are enabled. SetLayerPropertiesForTesting(root, identity_matrix, gfx::Point3F(), - gfx::PointF(), gfx::Size(100, 100), true, false, - true); + gfx::PointF(), gfx::Size(100, 100), true, false); SetLayerPropertiesForTesting(parent, identity_matrix, gfx::Point3F(), gfx::PointF(2.f, 2.f), gfx::Size(400, 400), true, - false, false); + false); SetLayerPropertiesForTesting(child1, identity_matrix, gfx::Point3F(), gfx::PointF(4.f, 4.f), gfx::Size(800, 800), true, - false, true); + false); SetLayerPropertiesForTesting(child2, identity_matrix, gfx::Point3F(), gfx::PointF(3.f, 3.f), gfx::Size(800, 800), true, - false, false); + false); SetLayerPropertiesForTesting(grand_child, identity_matrix, gfx::Point3F(), gfx::PointF(8.f, 8.f), gfx::Size(1500, 1500), - true, false, true); + true, false); SetLayerPropertiesForTesting(leaf_node1, identity_matrix, gfx::Point3F(), gfx::PointF(16.f, 16.f), gfx::Size(2000, 2000), - true, false, false); + true, false); SetLayerPropertiesForTesting(leaf_node2, identity_matrix, gfx::Point3F(), gfx::PointF(9.f, 9.f), gfx::Size(2000, 2000), - true, false, false); + true, false); // Case 1: Nothing is clipped. In this case, each layer's clip rect is its // bounds in target space. The only thing that changes when surfaces are // disabled is that target space is always screen space. + root->SetForceRenderSurface(true); + child1->SetForceRenderSurface(true); + grand_child->SetForceRenderSurface(true); ExecuteCalculateDrawProperties(root); + EXPECT_TRUE(root->has_render_surface()); + EXPECT_FALSE(parent->has_render_surface()); + EXPECT_TRUE(child1->has_render_surface()); + EXPECT_FALSE(child2->has_render_surface()); + EXPECT_TRUE(grand_child->has_render_surface()); + EXPECT_FALSE(leaf_node1->has_render_surface()); + EXPECT_FALSE(leaf_node2->has_render_surface()); EXPECT_EQ(gfx::Rect(100, 100), root->clip_rect()); EXPECT_EQ(gfx::Rect(2, 2, 400, 400), parent->clip_rect()); EXPECT_EQ(gfx::Rect(800, 800), child1->clip_rect()); @@ -2111,7 +2125,17 @@ TEST_F(LayerTreeHostCommonTest, ClipRectWhenCannotRenderToSeparateSurface) { // render surface are clipped by the root's bounds. root->SetMasksToBounds(true); host_impl()->active_tree()->property_trees()->needs_rebuild = true; + root->SetForceRenderSurface(true); + child1->SetForceRenderSurface(true); + grand_child->SetForceRenderSurface(true); ExecuteCalculateDrawProperties(root); + EXPECT_TRUE(root->has_render_surface()); + EXPECT_FALSE(parent->has_render_surface()); + EXPECT_TRUE(child1->has_render_surface()); + EXPECT_FALSE(child2->has_render_surface()); + EXPECT_TRUE(grand_child->has_render_surface()); + EXPECT_FALSE(leaf_node1->has_render_surface()); + EXPECT_FALSE(leaf_node2->has_render_surface()); EXPECT_EQ(gfx::Rect(100, 100), root->clip_rect()); EXPECT_EQ(gfx::Rect(100, 100), parent->clip_rect()); EXPECT_EQ(gfx::Rect(800, 800), child1->clip_rect()); @@ -2140,7 +2164,17 @@ TEST_F(LayerTreeHostCommonTest, ClipRectWhenCannotRenderToSeparateSurface) { parent->SetMasksToBounds(true); child1->SetMasksToBounds(true); host_impl()->active_tree()->property_trees()->needs_rebuild = true; + root->SetForceRenderSurface(true); + child1->SetForceRenderSurface(true); + grand_child->SetForceRenderSurface(true); ExecuteCalculateDrawProperties(root); + EXPECT_TRUE(root->has_render_surface()); + EXPECT_FALSE(parent->has_render_surface()); + EXPECT_TRUE(child1->has_render_surface()); + EXPECT_FALSE(child2->has_render_surface()); + EXPECT_TRUE(grand_child->has_render_surface()); + EXPECT_FALSE(leaf_node1->has_render_surface()); + EXPECT_FALSE(leaf_node2->has_render_surface()); EXPECT_EQ(gfx::Rect(100, 100), root->clip_rect()); EXPECT_EQ(gfx::Rect(2, 2, 400, 400), parent->clip_rect()); EXPECT_EQ(gfx::Rect(800, 800), child1->clip_rect()); @@ -2196,6 +2230,10 @@ TEST_F(LayerTreeHostCommonTest, SurfacesDisabledAndReEnabled) { parent->SetMasksToBounds(true); child->SetMasksToBounds(true); + root->SetHasRenderSurface(true); + child->SetHasRenderSurface(true); + grand_child->SetHasRenderSurface(true); + gfx::Transform expected_leaf_draw_transform_with_surfaces; expected_leaf_draw_transform_with_surfaces.Translate(16.0, 16.0); @@ -2208,12 +2246,20 @@ TEST_F(LayerTreeHostCommonTest, SurfacesDisabledAndReEnabled) { EXPECT_EQ(expected_leaf_draw_transform_with_surfaces, leaf_node->DrawTransform()); + root->SetHasRenderSurface(true); + child->SetHasRenderSurface(true); + grand_child->SetHasRenderSurface(true); + ExecuteCalculateDrawPropertiesWithoutSeparateSurfaces(root); EXPECT_EQ(gfx::Rect(6, 6, 396, 396), leaf_node->clip_rect()); EXPECT_EQ(gfx::Rect(30, 30, 372, 372), leaf_node->drawable_content_rect()); EXPECT_EQ(expected_leaf_draw_transform_without_surfaces, leaf_node->DrawTransform()); + root->SetHasRenderSurface(true); + child->SetHasRenderSurface(true); + grand_child->SetHasRenderSurface(true); + ExecuteCalculateDrawProperties(root); EXPECT_EQ(gfx::Rect(16, 16, 2000, 2000), leaf_node->clip_rect()); EXPECT_EQ(gfx::Rect(16, 16, 2000, 2000), leaf_node->drawable_content_rect()); @@ -2962,6 +3008,9 @@ TEST_F(LayerTreeHostCommonTest, // Each layer's drawable content rect is its bounds in target space; the only // thing that changes with surfaces disabled is that target space is always // screen space. + root->SetHasRenderSurface(true); + child1->SetHasRenderSurface(true); + child2->SetHasRenderSurface(true); ExecuteCalculateDrawProperties(root); EXPECT_EQ(gfx::Rect(100, 100), root->visible_layer_rect()); EXPECT_EQ(gfx::Rect(0, 0, 98, 98), parent->visible_layer_rect()); @@ -3010,6 +3059,9 @@ TEST_F(LayerTreeHostCommonTest, // surfaces are disabled. parent->SetMasksToBounds(true); host_impl()->active_tree()->property_trees()->needs_rebuild = true; + root->SetHasRenderSurface(true); + child1->SetHasRenderSurface(true); + child2->SetHasRenderSurface(true); ExecuteCalculateDrawProperties(root); EXPECT_EQ(gfx::Rect(100, 100), root->visible_layer_rect()); EXPECT_EQ(gfx::Rect(98, 98), parent->visible_layer_rect()); @@ -3057,6 +3109,9 @@ TEST_F(LayerTreeHostCommonTest, child1->SetMasksToBounds(true); grand_child2->SetMasksToBounds(true); host_impl()->active_tree()->property_trees()->needs_rebuild = true; + root->SetHasRenderSurface(true); + child1->SetHasRenderSurface(true); + child2->SetHasRenderSurface(true); ExecuteCalculateDrawProperties(root); EXPECT_EQ(gfx::Rect(100, 100), root->visible_layer_rect()); EXPECT_EQ(gfx::Rect(98, 98), parent->visible_layer_rect()); @@ -4073,42 +4128,26 @@ TEST_F(LayerTreeHostCommonTest, BackFaceCullingWithPreserves3d) { // is used. const gfx::Transform identity_matrix; - scoped_refptr<Layer> parent = Layer::Create(layer_settings()); - scoped_refptr<LayerWithForcedDrawsContent> front_facing_child = - make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings())); - scoped_refptr<LayerWithForcedDrawsContent> back_facing_child = - make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings())); - scoped_refptr<LayerWithForcedDrawsContent> front_facing_surface = - make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings())); - scoped_refptr<LayerWithForcedDrawsContent> back_facing_surface = - make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings())); - scoped_refptr<LayerWithForcedDrawsContent> - front_facing_child_of_front_facing_surface = - make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings())); - scoped_refptr<LayerWithForcedDrawsContent> - back_facing_child_of_front_facing_surface = - make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings())); - scoped_refptr<LayerWithForcedDrawsContent> - front_facing_child_of_back_facing_surface = - make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings())); - scoped_refptr<LayerWithForcedDrawsContent> - back_facing_child_of_back_facing_surface = - make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings())); - scoped_refptr<LayerWithForcedDrawsContent> dummy_replica_layer1 = - make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings())); - scoped_refptr<LayerWithForcedDrawsContent> dummy_replica_layer2 = - make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings())); - - parent->AddChild(front_facing_child); - parent->AddChild(back_facing_child); - parent->AddChild(front_facing_surface); - parent->AddChild(back_facing_surface); - front_facing_surface->AddChild(front_facing_child_of_front_facing_surface); - front_facing_surface->AddChild(back_facing_child_of_front_facing_surface); - back_facing_surface->AddChild(front_facing_child_of_back_facing_surface); - back_facing_surface->AddChild(back_facing_child_of_back_facing_surface); - - host()->SetRootLayer(parent); + LayerImpl* parent = root_layer(); + LayerImpl* front_facing_child = AddChildToRoot<LayerImpl>(); + LayerImpl* back_facing_child = AddChildToRoot<LayerImpl>(); + LayerImpl* front_facing_surface = AddChildToRoot<LayerImpl>(); + LayerImpl* back_facing_surface = AddChildToRoot<LayerImpl>(); + LayerImpl* front_facing_child_of_front_facing_surface = + AddChild<LayerImpl>(front_facing_surface); + LayerImpl* back_facing_child_of_front_facing_surface = + AddChild<LayerImpl>(front_facing_surface); + LayerImpl* front_facing_child_of_back_facing_surface = + AddChild<LayerImpl>(back_facing_surface); + LayerImpl* back_facing_child_of_back_facing_surface = + AddChild<LayerImpl>(back_facing_surface); + // Opacity will not force creation of render surfaces in this case because of + // the preserve-3d transform style. Instead, an example of when a surface + // would be created with preserve-3d is when there is a replica layer. + LayerImpl* dummy_replica_layer1 = + AddReplicaLayer<LayerImpl>(front_facing_surface); + LayerImpl* dummy_replica_layer2 = + AddReplicaLayer<LayerImpl>(back_facing_surface); // Nothing is double-sided front_facing_child->SetDoubleSided(false); @@ -4120,53 +4159,59 @@ TEST_F(LayerTreeHostCommonTest, BackFaceCullingWithPreserves3d) { front_facing_child_of_back_facing_surface->SetDoubleSided(false); back_facing_child_of_back_facing_surface->SetDoubleSided(false); + // Everything draws content. + front_facing_child->SetDrawsContent(true); + back_facing_child->SetDrawsContent(true); + front_facing_surface->SetDrawsContent(true); + back_facing_surface->SetDrawsContent(true); + front_facing_child_of_front_facing_surface->SetDrawsContent(true); + back_facing_child_of_front_facing_surface->SetDrawsContent(true); + front_facing_child_of_back_facing_surface->SetDrawsContent(true); + back_facing_child_of_back_facing_surface->SetDrawsContent(true); + dummy_replica_layer1->SetDrawsContent(true); + dummy_replica_layer2->SetDrawsContent(true); + gfx::Transform backface_matrix; backface_matrix.Translate(50.0, 50.0); backface_matrix.RotateAboutYAxis(180.0); backface_matrix.Translate(-50.0, -50.0); - // Opacity will not force creation of render surfaces in this case because of - // the preserve-3d transform style. Instead, an example of when a surface - // would be created with preserve-3d is when there is a replica layer. - front_facing_surface->SetReplicaLayer(dummy_replica_layer1.get()); - back_facing_surface->SetReplicaLayer(dummy_replica_layer2.get()); - // Each surface creates its own new 3d rendering context (as defined by W3C // spec). According to current W3C CSS gfx::Transforms spec, layers in a 3d // rendering context should use the transform with respect to that context. // This 3d rendering context occurs when (a) parent's transform style is flat // and (b) the layer's transform style is preserve-3d. - SetLayerPropertiesForTesting(parent.get(), identity_matrix, gfx::Point3F(), + SetLayerPropertiesForTesting(parent, identity_matrix, gfx::Point3F(), gfx::PointF(), gfx::Size(100, 100), true, false); // parent transform style is flat. - SetLayerPropertiesForTesting(front_facing_child.get(), identity_matrix, + SetLayerPropertiesForTesting(front_facing_child, identity_matrix, gfx::Point3F(), gfx::PointF(), gfx::Size(100, 100), true, false); - SetLayerPropertiesForTesting(back_facing_child.get(), backface_matrix, + SetLayerPropertiesForTesting(back_facing_child, backface_matrix, gfx::Point3F(), gfx::PointF(), gfx::Size(100, 100), true, false); // surface transform style is preserve-3d. - SetLayerPropertiesForTesting(front_facing_surface.get(), identity_matrix, + SetLayerPropertiesForTesting(front_facing_surface, identity_matrix, gfx::Point3F(), gfx::PointF(), gfx::Size(100, 100), false, true); // surface transform style is preserve-3d. - SetLayerPropertiesForTesting(back_facing_surface.get(), backface_matrix, + SetLayerPropertiesForTesting(back_facing_surface, backface_matrix, gfx::Point3F(), gfx::PointF(), gfx::Size(100, 100), false, true); - SetLayerPropertiesForTesting(front_facing_child_of_front_facing_surface.get(), + SetLayerPropertiesForTesting(front_facing_child_of_front_facing_surface, identity_matrix, gfx::Point3F(), gfx::PointF(), gfx::Size(100, 100), true, true); - SetLayerPropertiesForTesting(back_facing_child_of_front_facing_surface.get(), + SetLayerPropertiesForTesting(back_facing_child_of_front_facing_surface, backface_matrix, gfx::Point3F(), gfx::PointF(), gfx::Size(100, 100), true, true); - SetLayerPropertiesForTesting(front_facing_child_of_back_facing_surface.get(), + SetLayerPropertiesForTesting(front_facing_child_of_back_facing_surface, identity_matrix, gfx::Point3F(), gfx::PointF(), gfx::Size(100, 100), true, true); - SetLayerPropertiesForTesting(back_facing_child_of_back_facing_surface.get(), + SetLayerPropertiesForTesting(back_facing_child_of_back_facing_surface, backface_matrix, gfx::Point3F(), gfx::PointF(), gfx::Size(100, 100), true, true); - ExecuteCalculateDrawPropertiesWithPropertyTrees(parent.get()); + ExecuteCalculateDrawPropertiesWithPropertyTrees(parent); // Verify which render surfaces were created and used. EXPECT_FALSE(front_facing_child->has_render_surface()); @@ -4180,11 +4225,11 @@ TEST_F(LayerTreeHostCommonTest, BackFaceCullingWithPreserves3d) { EXPECT_FALSE(front_facing_child_of_back_facing_surface->has_render_surface()); EXPECT_FALSE(back_facing_child_of_back_facing_surface->has_render_surface()); - EXPECT_EQ(3u, update_layer_list().size()); + EXPECT_EQ(3u, update_layer_list_impl()->size()); - EXPECT_TRUE(UpdateLayerListContains(front_facing_child->id())); - EXPECT_TRUE(UpdateLayerListContains(front_facing_surface->id())); - EXPECT_TRUE(UpdateLayerListContains( + EXPECT_TRUE(UpdateLayerListImplContains(front_facing_child->id())); + EXPECT_TRUE(UpdateLayerListImplContains(front_facing_surface->id())); + EXPECT_TRUE(UpdateLayerListImplContains( front_facing_child_of_front_facing_surface->id())); } @@ -5932,24 +5977,11 @@ TEST_F(LayerTreeHostCommonTest, CreateRenderSurfaceWhenFlattenInsideRenderingContext) { // Verifies that Render Surfaces are created at the edge of rendering context. - scoped_refptr<LayerWithForcedDrawsContent> parent = - make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings())); - Layer* root = parent.get(); - scoped_refptr<LayerWithForcedDrawsContent> child_1 = - make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings())); - Layer* child1 = child_1.get(); - scoped_refptr<LayerWithForcedDrawsContent> child_2 = - make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings())); - Layer* child2 = child_2.get(); - scoped_refptr<LayerWithForcedDrawsContent> child_3 = - make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings())); - Layer* child3 = child_3.get(); - - parent->AddChild(std::move(child_1)); - child1->AddChild(std::move(child_2)); - child2->AddChild(std::move(child_3)); - - host()->SetRootLayer(root); + LayerImpl* root = root_layer(); + LayerImpl* child1 = AddChildToRoot<LayerImpl>(); + LayerImpl* child2 = AddChild<LayerImpl>(child1); + LayerImpl* child3 = AddChild<LayerImpl>(child2); + root->SetDrawsContent(true); const gfx::Transform identity_matrix; gfx::Point3F transform_origin; @@ -5960,15 +5992,18 @@ TEST_F(LayerTreeHostCommonTest, position, bounds, true, false); SetLayerPropertiesForTesting(child1, identity_matrix, transform_origin, position, bounds, false, true); + child1->SetDrawsContent(true); SetLayerPropertiesForTesting(child2, identity_matrix, transform_origin, position, bounds, true, false); + child2->SetDrawsContent(true); SetLayerPropertiesForTesting(child3, identity_matrix, transform_origin, position, bounds, true, false); + child3->SetDrawsContent(true); child2->Set3dSortingContextId(1); child3->Set3dSortingContextId(1); - ExecuteCalculateDrawPropertiesWithPropertyTrees(parent.get()); + ExecuteCalculateDrawPropertiesWithPropertyTrees(root); // Verify which render surfaces were created. EXPECT_TRUE(root->has_render_surface()); @@ -5983,6 +6018,7 @@ TEST_F(LayerTreeHostCommonTest, CanRenderToSeparateSurface) { TestTaskGraphRunner task_graph_runner; FakeLayerTreeHostImpl host_impl(&task_runner_provider, &shared_bitmap_manager, &task_graph_runner); + scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl.active_tree(), 12345); scoped_ptr<LayerImpl> child1 = @@ -7477,7 +7513,7 @@ TEST_F(LayerTreeHostCommonTest, DrawPropertyScales) { root->AddChild(std::move(child1)); root->AddChild(std::move(child2)); - root->SetHasRenderSurface(true); + root->SetForceRenderSurface(true); root->SetDrawsContent(true); gfx::Transform identity_matrix, scale_transform_child1, @@ -7497,7 +7533,6 @@ TEST_F(LayerTreeHostCommonTest, DrawPropertyScales) { scoped_ptr<LayerImpl> replica_layer = LayerImpl::Create(host_impl.active_tree(), 5); - replica_layer->SetHasRenderSurface(true); replica_layer->SetMaskLayer(LayerImpl::Create(host_impl.active_tree(), 6)); child1_layer->SetReplicaLayer(std::move(replica_layer)); child1_layer->SetHasRenderSurface(true); @@ -8712,21 +8747,23 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceClipsSubtree) { test_layer->SetDrawsContent(true); SetLayerPropertiesForTesting(root, identity_matrix, gfx::Point3F(), - gfx::PointF(), gfx::Size(30, 30), true, false, - true); + gfx::PointF(), gfx::Size(30, 30), true, false); SetLayerPropertiesForTesting(significant_transform, transform1, gfx::Point3F(), gfx::PointF(), gfx::Size(30, 30), - true, false, false); + true, false); SetLayerPropertiesForTesting(layer_clips_subtree, identity_matrix, gfx::Point3F(), gfx::PointF(), gfx::Size(30, 30), - true, false, false); + true, false); SetLayerPropertiesForTesting(render_surface, transform2, gfx::Point3F(), - gfx::PointF(), gfx::Size(30, 30), true, false, - true); + gfx::PointF(), gfx::Size(30, 30), true, false); SetLayerPropertiesForTesting(test_layer, identity_matrix, gfx::Point3F(), - gfx::PointF(), gfx::Size(30, 30), true, false, - false); + gfx::PointF(), gfx::Size(30, 30), true, false); + root->SetForceRenderSurface(true); + significant_transform->SetForceRenderSurface(false); + layer_clips_subtree->SetForceRenderSurface(true); + render_surface->SetForceRenderSurface(true); + test_layer->SetForceRenderSurface(false); ExecuteCalculateDrawProperties(root); TransformTree transform_tree = @@ -8735,10 +8772,16 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceClipsSubtree) { transform_tree.Node(significant_transform->transform_tree_index()); EXPECT_EQ(transform_node->owner_id, significant_transform->id()); + EXPECT_TRUE(root->has_render_surface()); + EXPECT_FALSE(significant_transform->has_render_surface()); + EXPECT_TRUE(layer_clips_subtree->has_render_surface()); + EXPECT_TRUE(render_surface->has_render_surface()); + EXPECT_FALSE(test_layer->has_render_surface()); + ClipTree clip_tree = root->layer_tree_impl()->property_trees()->clip_tree; ClipNode* clip_node = clip_tree.Node(render_surface->clip_tree_index()); EXPECT_FALSE(clip_node->data.applies_local_clip); - EXPECT_EQ(gfx::Rect(30, 21), test_layer->visible_rect_from_property_trees()); + EXPECT_EQ(gfx::Rect(22, 21), test_layer->visible_rect_from_property_trees()); } TEST_F(LayerTreeHostCommonTest, TransformOfParentClipNodeAncestorOfTarget) { diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc index 43ad959..9524e41 100644 --- a/cc/trees/layer_tree_host_impl.cc +++ b/cc/trees/layer_tree_host_impl.cc @@ -3671,6 +3671,13 @@ void LayerTreeHostImpl::TreeLayerTransformIsPotentiallyAnimatingChanged( layer->OnTransformIsPotentiallyAnimatingChanged(is_animating); } +bool LayerTreeHostImpl::AnimationsPreserveAxisAlignment( + const LayerImpl* layer) const { + return animation_host_ + ? animation_host_->AnimationsPreserveAxisAlignment(layer->id()) + : true; +} + void LayerTreeHostImpl::SetLayerFilterMutated(int layer_id, LayerTreeType tree_type, const FilterOperations& filters) { diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h index 119e57e..188efaf 100644 --- a/cc/trees/layer_tree_host_impl.h +++ b/cc/trees/layer_tree_host_impl.h @@ -254,6 +254,7 @@ class CC_EXPORT LayerTreeHostImpl void TreeLayerTransformIsPotentiallyAnimatingChanged(int layer_id, LayerTreeImpl* tree, bool is_animating); + bool AnimationsPreserveAxisAlignment(const LayerImpl* layer) const; // LayerTreeMutatorsClient implementation. bool IsLayerInTree(int layer_id, LayerTreeType tree_type) const override; diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc index 0f58bfa..3dd4fb9 100644 --- a/cc/trees/layer_tree_host_impl_unittest.cc +++ b/cc/trees/layer_tree_host_impl_unittest.cc @@ -195,7 +195,7 @@ class LayerTreeHostImplTest : public testing::Test, root->SetBounds(gfx::Size(10, 10)); root->SetDrawsContent(true); root->draw_properties().visible_layer_rect = gfx::Rect(0, 0, 10, 10); - root->SetHasRenderSurface(true); + root->SetForceRenderSurface(true); host_impl_->active_tree()->SetRootLayer(std::move(root)); } @@ -256,7 +256,7 @@ class LayerTreeHostImplTest : public testing::Test, LayerImpl::Create(layer_tree_impl, 1); root->SetBounds(content_size); root->SetPosition(gfx::PointF()); - root->SetHasRenderSurface(true); + root->SetForceRenderSurface(true); scoped_ptr<LayerImpl> inner_scroll = LayerImpl::Create(layer_tree_impl, kInnerViewportScrollLayerId); @@ -1109,7 +1109,7 @@ TEST_F(LayerTreeHostImplTest, AnimationSchedulingPendingTree) { LayerImpl::Create(host_impl_->pending_tree(), 1)); LayerImpl* root = host_impl_->pending_tree()->root_layer(); root->SetBounds(gfx::Size(50, 50)); - root->SetHasRenderSurface(true); + root->SetForceRenderSurface(true); root->AddChild(LayerImpl::Create(host_impl_->pending_tree(), 2)); LayerImpl* child = root->children()[0].get(); @@ -1159,7 +1159,7 @@ TEST_F(LayerTreeHostImplTest, AnimationSchedulingActiveTree) { LayerImpl::Create(host_impl_->active_tree(), 1)); LayerImpl* root = host_impl_->active_tree()->root_layer(); root->SetBounds(gfx::Size(50, 50)); - root->SetHasRenderSurface(true); + root->SetForceRenderSurface(true); root->AddChild(LayerImpl::Create(host_impl_->active_tree(), 2)); LayerImpl* child = root->children()[0].get(); @@ -2991,7 +2991,7 @@ class DidDrawCheckLayer : public LayerImpl { std::vector<scoped_ptr<CopyOutputRequest>> requests; requests.push_back( CopyOutputRequest::CreateRequest(base::Bind(&IgnoreResult))); - SetHasRenderSurface(true); + SetForceRenderSurface(true); PassCopyRequests(&requests); } @@ -3023,7 +3023,7 @@ TEST_F(LayerTreeHostImplTest, WillDrawReturningFalseDoesNotCall) { host_impl_->active_tree()->root_layer()); root->AddChild(DidDrawCheckLayer::Create(host_impl_->active_tree(), 2)); - root->SetHasRenderSurface(true); + root->SetForceRenderSurface(true); DidDrawCheckLayer* layer = static_cast<DidDrawCheckLayer*>(root->children()[0].get()); @@ -3064,7 +3064,7 @@ TEST_F(LayerTreeHostImplTest, DidDrawNotCalledOnHiddenLayer) { DidDrawCheckLayer* root = static_cast<DidDrawCheckLayer*>( host_impl_->active_tree()->root_layer()); root->SetMasksToBounds(true); - root->SetHasRenderSurface(true); + root->SetForceRenderSurface(true); root->AddChild(DidDrawCheckLayer::Create(host_impl_->active_tree(), 2)); DidDrawCheckLayer* layer = static_cast<DidDrawCheckLayer*>(root->children()[0].get()); @@ -3117,7 +3117,7 @@ TEST_F(LayerTreeHostImplTest, WillDrawNotCalledOnOccludedLayer) { static_cast<DidDrawCheckLayer*>(root->children()[0].get()); root->AddChild(DidDrawCheckLayer::Create(host_impl_->active_tree(), 3)); - root->SetHasRenderSurface(true); + root->SetForceRenderSurface(true); DidDrawCheckLayer* top_layer = static_cast<DidDrawCheckLayer*>(root->children()[1].get()); // This layer covers the occluded_layer above. Make this layer large so it can @@ -3149,7 +3149,7 @@ TEST_F(LayerTreeHostImplTest, DidDrawCalledOnAllLayers) { static_cast<DidDrawCheckLayer*>(host_impl_->active_tree()->root_layer()); root->AddChild(DidDrawCheckLayer::Create(host_impl_->active_tree(), 2)); - root->SetHasRenderSurface(true); + root->SetForceRenderSurface(true); DidDrawCheckLayer* layer1 = static_cast<DidDrawCheckLayer*>(root->children()[0].get()); @@ -3157,7 +3157,7 @@ TEST_F(LayerTreeHostImplTest, DidDrawCalledOnAllLayers) { DidDrawCheckLayer* layer2 = static_cast<DidDrawCheckLayer*>(layer1->children()[0].get()); - layer1->SetHasRenderSurface(true); + layer1->SetForceRenderSurface(true); layer1->SetShouldFlattenTransform(true); EXPECT_FALSE(root->did_draw_called()); @@ -3314,7 +3314,7 @@ TEST_F(LayerTreeHostImplTest, PrepareToDrawSucceedsAndFails) { DidDrawCheckLayer::Create(host_impl_->active_tree(), 1)); DidDrawCheckLayer* root = static_cast<DidDrawCheckLayer*>(host_impl_->active_tree()->root_layer()); - root->SetHasRenderSurface(true); + root->SetForceRenderSurface(true); LayerTreeHostImpl::FrameData frame; EXPECT_EQ(DRAW_SUCCESS, PrepareToDrawFrame(&frame)); @@ -3407,7 +3407,7 @@ TEST_F(LayerTreeHostImplTest, DidDrawCheckLayer::Create(host_impl_->active_tree(), 1)); DidDrawCheckLayer* root = static_cast<DidDrawCheckLayer*>(host_impl_->active_tree()->root_layer()); - root->SetHasRenderSurface(true); + root->SetForceRenderSurface(true); LayerTreeHostImpl::FrameData frame; EXPECT_EQ(DRAW_SUCCESS, PrepareToDrawFrame(&frame)); @@ -3468,7 +3468,7 @@ TEST_F(LayerTreeHostImplTest, TEST_F(LayerTreeHostImplTest, ScrollRootIgnored) { scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1); root->SetScrollClipLayer(Layer::INVALID_ID); - root->SetHasRenderSurface(true); + root->SetForceRenderSurface(true); host_impl_->active_tree()->SetRootLayer(std::move(root)); DrawFrame(); @@ -3551,7 +3551,7 @@ class LayerTreeHostImplTopControlsTest : public LayerTreeHostImplTest { root->SetPosition(gfx::PointF()); root->SetDrawsContent(false); root->SetIsContainerForFixedPositionLayers(true); - root_clip->SetHasRenderSurface(true); + root_clip->SetForceRenderSurface(true); outer_clip->SetBounds(outer_viewport_size); outer_scroll->SetScrollClipLayer(outer_clip->id()); outer_scroll->SetBounds(scroll_layer_size); @@ -4235,7 +4235,7 @@ TEST_F(LayerTreeHostImplTest, ScrollNonCompositedRoot) { scroll_layer->AddChild(std::move(content_layer)); scroll_clip_layer->AddChild(std::move(scroll_layer)); - scroll_clip_layer->SetHasRenderSurface(true); + scroll_clip_layer->SetForceRenderSurface(true); host_impl_->active_tree()->SetRootLayer(std::move(scroll_clip_layer)); host_impl_->SetViewportSize(surface_size); DrawFrame(); @@ -4254,7 +4254,7 @@ TEST_F(LayerTreeHostImplTest, ScrollChildCallsCommitAndRedraw) { scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1); root->SetBounds(surface_size); root->AddChild(CreateScrollableLayer(2, contents_size, root.get())); - root->SetHasRenderSurface(true); + root->SetForceRenderSurface(true); host_impl_->active_tree()->SetRootLayer(std::move(root)); host_impl_->SetViewportSize(surface_size); DrawFrame(); @@ -4271,7 +4271,7 @@ TEST_F(LayerTreeHostImplTest, ScrollMissesChild) { gfx::Size surface_size(10, 10); scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1); root->AddChild(CreateScrollableLayer(2, surface_size, root.get())); - root->SetHasRenderSurface(true); + root->SetForceRenderSurface(true); host_impl_->active_tree()->SetRootLayer(std::move(root)); host_impl_->SetViewportSize(surface_size); DrawFrame(); @@ -4287,7 +4287,7 @@ TEST_F(LayerTreeHostImplTest, ScrollMissesChild) { TEST_F(LayerTreeHostImplTest, ScrollMissesBackfacingChild) { gfx::Size surface_size(10, 10); scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1); - root->SetHasRenderSurface(true); + root->SetForceRenderSurface(true); scoped_ptr<LayerImpl> child = CreateScrollableLayer(2, surface_size, root.get()); host_impl_->SetViewportSize(surface_size); @@ -4324,7 +4324,7 @@ TEST_F(LayerTreeHostImplTest, ScrollBlockedByContentLayer) { CreateScrollableLayer(2, surface_size, clip_layer.get()); scroll_layer->AddChild(std::move(content_layer)); clip_layer->AddChild(std::move(scroll_layer)); - clip_layer->SetHasRenderSurface(true); + clip_layer->SetForceRenderSurface(true); host_impl_->active_tree()->SetRootLayer(std::move(clip_layer)); host_impl_->SetViewportSize(surface_size); @@ -4526,7 +4526,7 @@ TEST_F(LayerTreeHostImplTest, ScrollChildBeyondLimit) { gfx::Size content_size(20, 20); scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1); root->SetBounds(surface_size); - root->SetHasRenderSurface(true); + root->SetForceRenderSurface(true); scoped_ptr<LayerImpl> grand_child = CreateScrollableLayer(3, content_size, root.get()); @@ -4572,7 +4572,7 @@ TEST_F(LayerTreeHostImplTest, ScrollWithoutBubbling) { gfx::Size surface_size(20, 20); gfx::Size viewport_size(10, 10); scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1); - root->SetHasRenderSurface(true); + root->SetForceRenderSurface(true); scoped_ptr<LayerImpl> root_scrolling = CreateScrollableLayer(2, surface_size, root.get()); root_scrolling->SetIsContainerForFixedPositionLayers(true); @@ -4688,7 +4688,7 @@ TEST_F(LayerTreeHostImplTest, ScrollEventBubbling) { gfx::Size content_size(20, 20); scoped_ptr<LayerImpl> root_clip = LayerImpl::Create(host_impl_->active_tree(), 3); - root_clip->SetHasRenderSurface(true); + root_clip->SetForceRenderSurface(true); scoped_ptr<LayerImpl> root = CreateScrollableLayer(1, content_size, root_clip.get()); // Make 'root' the clip layer for child: since they have the same sizes the @@ -4732,7 +4732,7 @@ TEST_F(LayerTreeHostImplTest, ScrollBeforeRedraw) { scoped_ptr<LayerImpl> root_scroll = CreateScrollableLayer(2, surface_size, root_clip.get()); root_scroll->SetIsContainerForFixedPositionLayers(true); - root_clip->SetHasRenderSurface(true); + root_clip->SetForceRenderSurface(true); root_clip->AddChild(std::move(root_scroll)); host_impl_->active_tree()->SetRootLayer(std::move(root_clip)); host_impl_->active_tree()->SetViewportLayersFromIds(Layer::INVALID_ID, 1, 2, @@ -4750,7 +4750,7 @@ TEST_F(LayerTreeHostImplTest, ScrollBeforeRedraw) { CreateScrollableLayer(4, surface_size, root_clip2.get()); root_scroll2->SetIsContainerForFixedPositionLayers(true); root_clip2->AddChild(std::move(root_scroll2)); - root_clip2->SetHasRenderSurface(true); + root_clip2->SetForceRenderSurface(true); host_impl_->active_tree()->SetRootLayer(std::move(root_clip2)); host_impl_->active_tree()->SetViewportLayersFromIds(Layer::INVALID_ID, 3, 4, Layer::INVALID_ID); @@ -5321,7 +5321,7 @@ TEST_F(LayerTreeHostImplTest, OverscrollChildWithoutBubbling) { gfx::Size surface_size(10, 10); scoped_ptr<LayerImpl> root_clip = LayerImpl::Create(host_impl_->active_tree(), 4); - root_clip->SetHasRenderSurface(true); + root_clip->SetForceRenderSurface(true); scoped_ptr<LayerImpl> root = CreateScrollableLayer(1, surface_size, root_clip.get()); @@ -5578,7 +5578,7 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { LayerImpl::Create(host_impl_->active_tree(), 1); root->SetBounds(gfx::Size(10, 10)); root->SetDrawsContent(false); - root->SetHasRenderSurface(true); + root->SetForceRenderSurface(true); host_impl_->active_tree()->SetRootLayer(std::move(root)); } LayerImpl* root = host_impl_->active_tree()->root_layer(); @@ -5688,7 +5688,7 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { // carries the inherited opacity). layer1->SetContentsOpaque(true); layer1->SetOpacity(0.5f); - layer1->SetHasRenderSurface(true); + layer1->SetForceRenderSurface(true); layer1->SetExpectation(false, true); layer1->SetUpdateRect(gfx::Rect(layer1->bounds())); layer2->SetExpectation(false, false); @@ -5700,7 +5700,7 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { EXPECT_TRUE(layer1->quads_appended()); EXPECT_TRUE(layer2->quads_appended()); host_impl_->DidDrawAllLayers(frame); - layer1->SetHasRenderSurface(false); + layer1->SetForceRenderSurface(false); // Draw again, but with child non-opaque, to make sure // layer1 not culled. @@ -5818,7 +5818,7 @@ class LayerTreeHostImplViewportCoveredTest : public LayerTreeHostImplTest { host_impl_->active_tree()->set_background_color(SK_ColorGRAY); host_impl_->active_tree()->SetRootLayer( LayerImpl::Create(host_impl_->active_tree(), 1)); - host_impl_->active_tree()->root_layer()->SetHasRenderSurface(true); + host_impl_->active_tree()->root_layer()->SetForceRenderSurface(true); host_impl_->active_tree()->root_layer()->AddChild( BlendStateCheckLayer::Create(host_impl_->active_tree(), 2, @@ -6074,7 +6074,7 @@ TEST_F(LayerTreeHostImplTest, ReshapeNotCalledUntilDraw) { FakeDrawableLayerImpl::Create(host_impl_->active_tree(), 1); root->SetBounds(gfx::Size(10, 10)); root->SetDrawsContent(true); - root->SetHasRenderSurface(true); + root->SetForceRenderSurface(true); host_impl_->active_tree()->SetRootLayer(std::move(root)); EXPECT_FALSE(provider->TestContext3d()->reshape_called()); provider->TestContext3d()->clear_reshape_called(); @@ -6140,7 +6140,7 @@ TEST_F(LayerTreeHostImplTest, PartialSwapReceivesDamageRect) { scoped_ptr<LayerImpl> root = FakeDrawableLayerImpl::Create(layer_tree_host_impl->active_tree(), 1); - root->SetHasRenderSurface(true); + root->SetForceRenderSurface(true); scoped_ptr<LayerImpl> child = FakeDrawableLayerImpl::Create(layer_tree_host_impl->active_tree(), 2); child->SetPosition(gfx::PointF(12.f, 13.f)); @@ -6206,7 +6206,7 @@ TEST_F(LayerTreeHostImplTest, RootLayerDoesntCreateExtraSurface) { child->SetDrawsContent(true); root->SetBounds(gfx::Size(10, 10)); root->SetDrawsContent(true); - root->SetHasRenderSurface(true); + root->SetForceRenderSurface(true); root->AddChild(std::move(child)); host_impl_->active_tree()->SetRootLayer(std::move(root)); @@ -6455,19 +6455,18 @@ static scoped_ptr<LayerTreeHostImpl> SetupLayersForOpacity( gfx::Rect child_rect(10, 10, 50, 50); gfx::Rect grand_child_rect(5, 5, 150, 150); - root->SetHasRenderSurface(true); + root->SetForceRenderSurface(true); root->SetPosition(gfx::PointF(root_rect.origin())); root->SetBounds(root_rect.size()); root->draw_properties().visible_layer_rect = root_rect; root->SetDrawsContent(false); - root->render_surface()->SetContentRect(gfx::Rect(root_rect.size())); child->SetPosition(gfx::PointF(child_rect.x(), child_rect.y())); child->SetOpacity(0.5f); child->SetBounds(gfx::Size(child_rect.width(), child_rect.height())); child->draw_properties().visible_layer_rect = child_rect; child->SetDrawsContent(false); - child->SetHasRenderSurface(true); + child->SetForceRenderSurface(true); grand_child->SetPosition(gfx::PointF(grand_child_rect.origin())); grand_child->SetBounds(grand_child_rect.size()); @@ -6553,7 +6552,7 @@ TEST_F(LayerTreeHostImplTest, LayersFreeTextures) { scoped_ptr<LayerImpl> root_layer = LayerImpl::Create(host_impl_->active_tree(), 1); root_layer->SetBounds(gfx::Size(10, 10)); - root_layer->SetHasRenderSurface(true); + root_layer->SetForceRenderSurface(true); scoped_refptr<VideoFrame> softwareFrame = media::VideoFrame::CreateColorFrame( @@ -6686,7 +6685,7 @@ TEST_F(LayerTreeHostImplTestWithDelegatingRenderer, FrameIncludesDamageRect) { root->SetPosition(gfx::PointF()); root->SetBounds(gfx::Size(10, 10)); root->SetDrawsContent(true); - root->SetHasRenderSurface(true); + root->SetForceRenderSurface(true); // Child layer is in the bottom right corner. scoped_ptr<SolidColorLayerImpl> child = @@ -6743,7 +6742,7 @@ TEST_F(LayerTreeHostImplTest, FarAwayQuadsDontNeedAA) { scoped_ptr<LayerImpl> scoped_root = LayerImpl::Create(host_impl_->pending_tree(), 1); LayerImpl* root = scoped_root.get(); - root->SetHasRenderSurface(true); + root->SetForceRenderSurface(true); host_impl_->pending_tree()->SetRootLayer(std::move(scoped_root)); @@ -7121,7 +7120,7 @@ TEST_F(LayerTreeHostImplTest, TouchFlingShouldNotBubble) { gfx::Size content_size(20, 20); scoped_ptr<LayerImpl> root_clip = LayerImpl::Create(host_impl_->active_tree(), 3); - root_clip->SetHasRenderSurface(true); + root_clip->SetForceRenderSurface(true); scoped_ptr<LayerImpl> root = CreateScrollableLayer(1, content_size, root_clip.get()); @@ -7165,7 +7164,7 @@ TEST_F(LayerTreeHostImplTest, TouchFlingShouldContinueScrollingCurrentLayer) { // the scroll doesn't bubble up to the parent layer. gfx::Size surface_size(10, 10); scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1); - root->SetHasRenderSurface(true); + root->SetForceRenderSurface(true); scoped_ptr<LayerImpl> root_scrolling = CreateScrollableLayer(2, surface_size, root.get()); @@ -7236,7 +7235,7 @@ TEST_F(LayerTreeHostImplTest, WheelFlingShouldntBubble) { gfx::Size content_size(20, 20); scoped_ptr<LayerImpl> root_clip = LayerImpl::Create(host_impl_->active_tree(), 3); - root_clip->SetHasRenderSurface(true); + root_clip->SetForceRenderSurface(true); scoped_ptr<LayerImpl> root_scroll = CreateScrollableLayer(1, content_size, root_clip.get()); int root_scroll_id = root_scroll->id(); @@ -7468,7 +7467,7 @@ TEST_F(LayerTreeHostImplTest, LatencyInfoPassedToCompositorFrameMetadata) { root->SetPosition(gfx::PointF()); root->SetBounds(gfx::Size(10, 10)); root->SetDrawsContent(true); - root->SetHasRenderSurface(true); + root->SetForceRenderSurface(true); host_impl_->active_tree()->SetRootLayer(std::move(root)); @@ -7508,7 +7507,7 @@ TEST_F(LayerTreeHostImplTest, SelectionBoundsPassedToCompositorFrameMetadata) { root->SetPosition(gfx::PointF()); root->SetBounds(gfx::Size(10, 10)); root->SetDrawsContent(true); - root->SetHasRenderSurface(true); + root->SetForceRenderSurface(true); host_impl_->active_tree()->SetRootLayer(std::move(root)); @@ -8143,7 +8142,7 @@ class LayerTreeHostImplVirtualViewportTest : public LayerTreeHostImplTest { page_scale->AddChild(std::move(inner_scroll)); inner_clip->AddChild(std::move(page_scale)); - inner_clip->SetHasRenderSurface(true); + inner_clip->SetForceRenderSurface(true); layer_tree_impl->SetRootLayer(std::move(inner_clip)); layer_tree_impl->SetViewportLayersFromIds( Layer::INVALID_ID, kPageScaleLayerId, kInnerViewportScrollLayerId, @@ -8610,7 +8609,7 @@ TEST_F(LayerTreeHostImplTest, ExternalTransformAffectsSublayerScaleFactor) { .get(); content_layer->AddChild(LayerImpl::Create(host_impl_->active_tree(), 100)); LayerImpl* test_layer = host_impl_->active_tree()->LayerById(100); - test_layer->SetHasRenderSurface(true); + test_layer->SetForceRenderSurface(true); test_layer->SetDrawsContent(true); test_layer->SetBounds(layer_size); gfx::Transform perspective_transform; @@ -9267,7 +9266,7 @@ TEST_F(LayerTreeHostImplTest, SubLayerScaleForNodeInSubtreeOfPageScaleLayer) { LayerImpl* in_subtree_of_page_scale_layer = host_impl_->active_tree()->LayerById(100); - in_subtree_of_page_scale_layer->SetHasRenderSurface(true); + in_subtree_of_page_scale_layer->SetForceRenderSurface(true); host_impl_->active_tree()->BuildPropertyTreesForTesting(); DrawFrame(); TransformNode* node = diff --git a/cc/trees/layer_tree_impl.cc b/cc/trees/layer_tree_impl.cc index 6a25beb..9fbd118 100644 --- a/cc/trees/layer_tree_impl.cc +++ b/cc/trees/layer_tree_impl.cc @@ -1857,6 +1857,14 @@ bool LayerTreeImpl::TransformIsAnimatingOnImplOnly( : false; } +bool LayerTreeImpl::AnimationsPreserveAxisAlignment( + const LayerImpl* layer) const { + return layer_tree_host_impl_->animation_host() + ? layer_tree_host_impl_->animation_host() + ->AnimationsPreserveAxisAlignment(layer->id()) + : true; +} + bool LayerTreeImpl::HasOnlyTranslationTransforms(const LayerImpl* layer) const { LayerTreeType tree_type = IsActiveTree() ? LayerTreeType::ACTIVE : LayerTreeType::PENDING; diff --git a/cc/trees/layer_tree_impl.h b/cc/trees/layer_tree_impl.h index 044e957..2b6ad61 100644 --- a/cc/trees/layer_tree_impl.h +++ b/cc/trees/layer_tree_impl.h @@ -397,6 +397,7 @@ class CC_EXPORT LayerTreeImpl { bool OpacityIsAnimatingOnImplOnly(const LayerImpl* layer) const; bool TransformIsAnimatingOnImplOnly(const LayerImpl* layer) const; + bool AnimationsPreserveAxisAlignment(const LayerImpl* layer) const; bool HasOnlyTranslationTransforms(const LayerImpl* layer) const; bool MaximumTargetScale(const LayerImpl* layer, float* max_scale) const; diff --git a/cc/trees/layer_tree_impl_unittest.cc b/cc/trees/layer_tree_impl_unittest.cc index 0e82324..b6cf7f2 100644 --- a/cc/trees/layer_tree_impl_unittest.cc +++ b/cc/trees/layer_tree_impl_unittest.cc @@ -577,12 +577,13 @@ TEST_F(LayerTreeImplTest, HitTestingForMultiClippedRotatedLayer) { grand_child->AddChild(std::move(rotated_leaf)); child->AddChild(std::move(grand_child)); root->AddChild(std::move(child)); + + ExecuteCalculateDrawProperties(root.get()); } host_impl().SetViewportSize(root->bounds()); host_impl().active_tree()->SetRootLayer(std::move(root)); host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); - // (11, 89) is close to the the bottom left corner within the clip, but it is // not inside the layer. gfx::PointF test_point(11.f, 89.f); @@ -753,6 +754,8 @@ TEST_F(LayerTreeImplTest, HitTestingForMultipleLayers) { child1->AddChild(std::move(grand_child1)); root->AddChild(std::move(child1)); root->AddChild(std::move(child2)); + + ExecuteCalculateDrawProperties(root.get()); } LayerImpl* child1 = root->children()[0].get(); @@ -1189,7 +1192,7 @@ TEST_F(LayerTreeImplTest, HitTestingForMultipleLayerLists) { transform_origin, position, bounds, true, false, false); child1->SetDrawsContent(true); - child1->SetHasRenderSurface(true); + child1->SetForceRenderSurface(true); position = gfx::PointF(50.f, 10.f); bounds = gfx::Size(50, 50); @@ -1197,7 +1200,7 @@ TEST_F(LayerTreeImplTest, HitTestingForMultipleLayerLists) { transform_origin, position, bounds, true, false, false); child2->SetDrawsContent(true); - child2->SetHasRenderSurface(true); + child2->SetForceRenderSurface(true); // Remember that grand_child is positioned with respect to its parent (i.e. // child1). In screen space, the intended position is (10, 50), with size @@ -1208,11 +1211,13 @@ TEST_F(LayerTreeImplTest, HitTestingForMultipleLayerLists) { transform_origin, position, bounds, true, false, false); grand_child1->SetDrawsContent(true); - grand_child1->SetHasRenderSurface(true); + grand_child1->SetForceRenderSurface(true); child1->AddChild(std::move(grand_child1)); root->AddChild(std::move(child1)); root->AddChild(std::move(child2)); + + ExecuteCalculateDrawProperties(root.get()); } LayerImpl* child1 = root->children()[0].get(); diff --git a/cc/trees/occlusion_tracker_perftest.cc b/cc/trees/occlusion_tracker_perftest.cc index 0df01e1..3ae39e6 100644 --- a/cc/trees/occlusion_tracker_perftest.cc +++ b/cc/trees/occlusion_tracker_perftest.cc @@ -45,7 +45,7 @@ class OcclusionTrackerPerfTest : public testing::Test { host_impl_->InitializeRenderer(output_surface_.get()); scoped_ptr<LayerImpl> root_layer = LayerImpl::Create(active_tree(), 1); - root_layer->SetHasRenderSurface(true); + root_layer->SetForceRenderSurface(true); active_tree()->SetRootLayer(std::move(root_layer)); } diff --git a/cc/trees/occlusion_tracker_unittest.cc b/cc/trees/occlusion_tracker_unittest.cc index bda7b98..5c658c3 100644 --- a/cc/trees/occlusion_tracker_unittest.cc +++ b/cc/trees/occlusion_tracker_unittest.cc @@ -106,7 +106,7 @@ class OcclusionTrackerTest : public testing::Test { DCHECK(!root_.get()); root_ = std::move(layer); - layer_ptr->SetHasRenderSurface(true); + layer_ptr->SetForceRenderSurface(true); SetRootLayerOnMainThread(layer_ptr); return layer_ptr; @@ -130,7 +130,7 @@ class OcclusionTrackerTest : public testing::Test { const gfx::PointF& position, const gfx::Size& bounds) { LayerImpl* layer = CreateLayer(parent, transform, position, bounds); - layer->SetHasRenderSurface(true); + layer->SetForceRenderSurface(true); return layer; } @@ -189,7 +189,7 @@ class OcclusionTrackerTest : public testing::Test { bool opaque) { TestContentLayerImpl* layer = CreateDrawingLayer(parent, transform, position, bounds, opaque); - layer->SetHasRenderSurface(true); + layer->SetForceRenderSurface(true); return layer; } @@ -213,7 +213,6 @@ class OcclusionTrackerTest : public testing::Test { std::vector<scoped_ptr<CopyOutputRequest>> requests; requests.push_back(CopyOutputRequest::CreateBitmapRequest(base::Bind( &OcclusionTrackerTest::CopyOutputCallback, base::Unretained(this)))); - layer->SetHasRenderSurface(true); layer->PassCopyRequests(&requests); } @@ -536,7 +535,7 @@ class OcclusionTrackerTestScaledRenderSurface : public OcclusionTrackerTest { layer1_matrix.Scale(2.0, 2.0); TestContentLayerImpl* layer1 = this->CreateDrawingLayer( parent, layer1_matrix, gfx::PointF(), gfx::Size(100, 100), true); - layer1->SetHasRenderSurface(true); + layer1->SetForceRenderSurface(true); gfx::Transform layer2_matrix; layer2_matrix.Translate(25.0, 25.0); @@ -917,17 +916,17 @@ class OcclusionTrackerTestFilters : public OcclusionTrackerTest { parent, layer_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500), true); - blur_layer->SetHasRenderSurface(true); + blur_layer->SetForceRenderSurface(true); FilterOperations filters; filters.Append(FilterOperation::CreateBlurFilter(10.f)); blur_layer->SetFilters(filters); - opaque_layer->SetHasRenderSurface(true); + opaque_layer->SetForceRenderSurface(true); filters.Clear(); filters.Append(FilterOperation::CreateGrayscaleFilter(0.5f)); opaque_layer->SetFilters(filters); - opacity_layer->SetHasRenderSurface(true); + opacity_layer->SetForceRenderSurface(true); filters.Clear(); filters.Append(FilterOperation::CreateOpacityFilter(0.5f)); opacity_layer->SetFilters(filters); @@ -1459,7 +1458,6 @@ class OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter LayerImpl* filtered_surface = this->CreateDrawingLayer( parent, scale_by_half, gfx::PointF(50.f, 50.f), gfx::Size(100, 100), false); - filtered_surface->SetHasRenderSurface(true); filtered_surface->SetBackgroundFilters(filters); gfx::Rect occlusion_rect; switch (i) { @@ -1480,6 +1478,7 @@ class OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter LayerImpl* occluding_layer = this->CreateDrawingLayer( parent, this->identity_matrix, gfx::PointF(occlusion_rect.origin()), occlusion_rect.size(), true); + occluding_layer->SetForceRenderSurface(false); this->CalcDrawEtc(parent); TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 200, 200)); @@ -1563,8 +1562,8 @@ class OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice gfx::Size(50, 50), true); // Filters make the layers own surfaces. - filtered_surface1->SetHasRenderSurface(true); - filtered_surface2->SetHasRenderSurface(true); + filtered_surface1->SetForceRenderSurface(true); + filtered_surface2->SetForceRenderSurface(true); FilterOperations filters; filters.Append(FilterOperation::CreateBlurFilter(1.f)); filtered_surface1->SetBackgroundFilters(filters); @@ -1640,7 +1639,7 @@ class OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter gfx::Size()); // Filters make the layer own a surface. - filtered_surface->SetHasRenderSurface(true); + filtered_surface->SetForceRenderSurface(true); FilterOperations filters; filters.Append(FilterOperation::CreateBlurFilter(3.f)); filtered_surface->SetBackgroundFilters(filters); @@ -1707,7 +1706,7 @@ class OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded gfx::Size(50, 50), true); // Filters make the layer own a surface. - filtered_surface->SetHasRenderSurface(true); + filtered_surface->SetForceRenderSurface(true); FilterOperations filters; filters.Append(FilterOperation::CreateBlurFilter(3.f)); filtered_surface->SetBackgroundFilters(filters); @@ -1786,7 +1785,7 @@ class OcclusionTrackerTestReduceOcclusionWhenBkgdFilterIsPartiallyOccluded gfx::Size(10, 10), true); // Filters make the layer own a surface. - filtered_surface->SetHasRenderSurface(true); + filtered_surface->SetForceRenderSurface(true); FilterOperations filters; filters.Append(FilterOperation::CreateBlurFilter(3.f)); filtered_surface->SetBackgroundFilters(filters); @@ -1861,7 +1860,7 @@ class OcclusionTrackerTestBlendModeDoesNotOcclude gfx::Size(20, 22), true); // Blend mode makes the layer own a surface. - blend_mode_layer->SetHasRenderSurface(true); + blend_mode_layer->SetForceRenderSurface(true); blend_mode_layer->SetBlendMode(SkXfermode::kMultiply_Mode); this->CalcDrawEtc(parent); diff --git a/cc/trees/property_tree_builder.cc b/cc/trees/property_tree_builder.cc index 8763b91..a770bd6 100644 --- a/cc/trees/property_tree_builder.cc +++ b/cc/trees/property_tree_builder.cc @@ -47,6 +47,8 @@ struct DataForRecursion { bool target_is_clipped; const gfx::Transform* device_transform; gfx::Vector2dF scroll_compensation_adjustment; + gfx::Transform compound_transform_since_render_target; + bool axis_align_since_render_target; int sequence_number; }; @@ -70,11 +72,11 @@ static ClipNode* GetClipParent(const DataForRecursion<LayerType>& data, template <typename LayerType> static bool AppliesClip(LayerType* layer, const DataForRecursion<LayerType>& data, + bool created_render_surface, bool is_clipped) { - const bool render_surface_applies_clip = - layer->has_render_surface() && is_clipped; + const bool render_surface_applies_clip = created_render_surface && is_clipped; const bool render_surface_may_grow_due_to_clip_children = - layer->has_render_surface() && layer->num_unclipped_descendants() > 0; + created_render_surface && layer->num_unclipped_descendants() > 0; if (layer->masks_to_bounds() || layer->mask_layer() || render_surface_may_grow_due_to_clip_children) @@ -108,7 +110,7 @@ void AddClipNodeIfNeeded(const DataForRecursion<LayerType>& data_from_ancestor, bool layers_are_clipped = false; bool has_unclipped_surface = false; - if (layer->has_render_surface()) { + if (created_render_surface) { // Clips can usually be applied to a surface's descendants simply by // clipping the surface (or applied implicitly by the surface's bounds). // However, if the surface has unclipped descendants (layers that aren't @@ -147,7 +149,8 @@ void AddClipNodeIfNeeded(const DataForRecursion<LayerType>& data_from_ancestor, parent->data.layers_are_clipped_when_surfaces_disabled; bool applies_clip = - AppliesClip(layer, data_from_ancestor, ancestor_clips_subtree); + AppliesClip(layer, data_from_ancestor, created_render_surface, + ancestor_clips_subtree); bool parent_applies_clip = !parent->data.resets_clip; // When we have an unclipped surface, all ancestor clips no longer apply. @@ -182,7 +185,7 @@ void AddClipNodeIfNeeded(const DataForRecursion<LayerType>& data_from_ancestor, // Surfaces reset the rect used for layer clipping. At other nodes, layer // clipping state from ancestors must continue to get propagated. node.data.layer_clipping_uses_only_local_clip = - layer->has_render_surface() || !ancestor_clips_subtree; + created_render_surface || !ancestor_clips_subtree; } else { // Otherwise, we're either unclipped, or exist only in order to apply our // parent's clips in our space. @@ -201,7 +204,6 @@ void AddClipNodeIfNeeded(const DataForRecursion<LayerType>& data_from_ancestor, } layer->SetClipTreeIndex(data_for_children->clip_tree_parent); - // TODO(awoloszyn): Right now when we hit a node with a replica, we reset the // clip for all children since we may need to draw. We need to figure out a // better way, since we will need both the clipped and unclipped versions. @@ -233,7 +235,7 @@ bool AddTransformNodeIfNeeded( const bool has_any_transform_animation = layer->HasAnyAnimationTargetingProperty(Animation::TRANSFORM); - const bool has_surface = layer->has_render_surface(); + const bool has_surface = created_render_surface; bool requires_node = is_root || is_scrollable || has_significant_transform || has_any_transform_animation || has_surface || is_fixed || @@ -431,6 +433,122 @@ bool IsAnimatingOpacity(LayerImpl* layer) { } template <typename LayerType> +static inline bool LayerIsInExisting3DRenderingContext(LayerType* layer) { + return layer->Is3dSorted() && layer->parent() && + layer->parent()->Is3dSorted() && + (layer->parent()->sorting_context_id() == layer->sorting_context_id()); +} + +template <typename LayerType> +bool ShouldCreateRenderSurface(LayerType* layer, + gfx::Transform current_transform, + bool axis_aligned) { + const bool preserves_2d_axis_alignment = + (current_transform * layer->transform()).Preserves2dAxisAlignment() && + axis_aligned && layer->AnimationsPreserveAxisAlignment(); + const bool is_root = !layer->parent(); + if (is_root) + return true; + + // If the layer uses a mask and the layer is not a replica layer. + // TODO(weiliangc): After slimming paint there won't be replica layers. + if (layer->mask_layer() && layer->parent()->replica_layer() != layer) { + return true; + } + + // If the layer has a reflection. + if (layer->replica_layer()) { + return true; + } + + // If the layer uses a CSS filter. + if (!layer->filters().IsEmpty() || !layer->background_filters().IsEmpty()) { + return true; + } + + // If the layer will use a CSS filter. In this case, the animation + // will start and add a filter to this layer, so it needs a surface. + if (layer->HasPotentiallyRunningFilterAnimation()) { + return true; + } + + int num_descendants_that_draw_content = + layer->NumDescendantsThatDrawContent(); + + // If the layer flattens its subtree, but it is treated as a 3D object by its + // parent (i.e. parent participates in a 3D rendering context). + if (LayerIsInExisting3DRenderingContext(layer) && + layer->should_flatten_transform() && + num_descendants_that_draw_content > 0) { + TRACE_EVENT_INSTANT0( + "cc", "PropertyTreeBuilder::ShouldCreateRenderSurface flattening", + TRACE_EVENT_SCOPE_THREAD); + return true; + } + + // If the layer has blending. + // TODO(rosca): this is temporary, until blending is implemented for other + // types of quads than RenderPassDrawQuad. Layers having descendants that draw + // content will still create a separate rendering surface. + if (!layer->uses_default_blend_mode()) { + TRACE_EVENT_INSTANT0( + "cc", "PropertyTreeBuilder::ShouldCreateRenderSurface blending", + TRACE_EVENT_SCOPE_THREAD); + return true; + } + // If the layer clips its descendants but it is not axis-aligned with respect + // to its parent. + bool layer_clips_external_content = + LayerClipsSubtree(layer) || layer->HasDelegatedContent(); + if (layer_clips_external_content && !preserves_2d_axis_alignment && + num_descendants_that_draw_content > 0) { + TRACE_EVENT_INSTANT0( + "cc", "PropertyTreeBuilder::ShouldCreateRenderSurface clipping", + TRACE_EVENT_SCOPE_THREAD); + return true; + } + + // If the layer has some translucency and does not have a preserves-3d + // transform style. This condition only needs a render surface if two or more + // layers in the subtree overlap. But checking layer overlaps is unnecessarily + // costly so instead we conservatively create a surface whenever at least two + // layers draw content for this subtree. + bool at_least_two_layers_in_subtree_draw_content = + num_descendants_that_draw_content > 0 && + (layer->DrawsContent() || num_descendants_that_draw_content > 1); + + if (layer->opacity() != 1.f && layer->should_flatten_transform() && + at_least_two_layers_in_subtree_draw_content) { + TRACE_EVENT_INSTANT0( + "cc", "PropertyTreeBuilder::ShouldCreateRenderSurface opacity", + TRACE_EVENT_SCOPE_THREAD); + DCHECK(!is_root); + return true; + } + // If the layer has isolation. + // TODO(rosca): to be optimized - create separate rendering surface only when + // the blending descendants might have access to the content behind this layer + // (layer has transparent background or descendants overflow). + // https://code.google.com/p/chromium/issues/detail?id=301738 + if (layer->is_root_for_isolated_group()) { + TRACE_EVENT_INSTANT0( + "cc", "PropertyTreeBuilder::ShouldCreateRenderSurface isolation", + TRACE_EVENT_SCOPE_THREAD); + return true; + } + + // If we force it. + if (layer->force_render_surface()) + return true; + + // If we'll make a copy of the layer's contents. + if (layer->HasCopyRequest()) + return true; + + return false; +} + +template <typename LayerType> bool AddEffectNodeIfNeeded( const DataForRecursion<LayerType>& data_from_ancestor, LayerType* layer, @@ -438,15 +556,22 @@ bool AddEffectNodeIfNeeded( const bool is_root = !layer->parent(); const bool has_transparency = layer->opacity() != 1.f; const bool has_animated_opacity = IsAnimatingOpacity(layer); - const bool has_render_surface = layer->has_render_surface(); - bool requires_node = - is_root || has_transparency || has_animated_opacity || has_render_surface; + const bool should_create_render_surface = ShouldCreateRenderSurface( + layer, data_from_ancestor.compound_transform_since_render_target, + data_from_ancestor.axis_align_since_render_target); + data_for_children->axis_align_since_render_target &= + layer->AnimationsPreserveAxisAlignment(); + + bool requires_node = is_root || has_transparency || has_animated_opacity || + should_create_render_surface; int parent_id = data_from_ancestor.effect_tree_parent; if (!requires_node) { layer->SetEffectTreeIndex(parent_id); data_for_children->effect_tree_parent = parent_id; + data_for_children->compound_transform_since_render_target *= + layer->transform(); return false; } @@ -454,7 +579,8 @@ bool AddEffectNodeIfNeeded( node.owner_id = layer->id(); node.data.opacity = layer->opacity(); node.data.screen_space_opacity = layer->opacity(); - node.data.has_render_surface = has_render_surface; + node.data.has_render_surface = should_create_render_surface; + if (!is_root) { // For every effect node, we create a transform node, so it's safe to use // the next available id from the transform tree as this effect node's @@ -477,7 +603,12 @@ bool AddEffectNodeIfNeeded( data_for_children->effect_tree_parent = data_for_children->effect_tree->Insert(node, parent_id); layer->SetEffectTreeIndex(data_for_children->effect_tree_parent); - return has_render_surface; + if (should_create_render_surface) { + data_for_children->compound_transform_since_render_target = + gfx::Transform(); + data_for_children->axis_align_since_render_target = true; + } + return should_create_render_surface; } template <typename LayerType> @@ -581,6 +712,8 @@ void BuildPropertyTreesTopLevelInternal( data_for_recursion.transform_tree->clear(); data_for_recursion.clip_tree->clear(); data_for_recursion.effect_tree->clear(); + data_for_recursion.compound_transform_since_render_target = gfx::Transform(); + data_for_recursion.axis_align_since_render_target = true; data_for_recursion.sequence_number = property_trees->sequence_number; data_for_recursion.transform_tree->set_device_scale_factor( device_scale_factor); |