summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorweiliangc <weiliangc@chromium.org>2015-12-08 19:39:26 -0800
committerCommit bot <commit-bot@chromium.org>2015-12-09 03:40:25 +0000
commitc154ce2efa59dbaecb3cb038adb247426f7c6988 (patch)
treeadc06272fccf970cb021180efa52e6f67c236236
parentd2dc9a29ec062b23a18bca4f69d56901634b5545 (diff)
downloadchromium_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}
-rw-r--r--cc/layers/delegated_renderer_layer_impl_unittest.cc32
-rw-r--r--cc/layers/layer.cc4
-rw-r--r--cc/layers/layer.h8
-rw-r--r--cc/layers/layer_impl.cc24
-rw-r--r--cc/layers/layer_impl.h7
-rw-r--r--cc/layers/layer_impl_unittest.cc14
-rw-r--r--cc/layers/layer_iterator_unittest.cc9
-rw-r--r--cc/layers/nine_patch_layer_impl_unittest.cc2
-rw-r--r--cc/layers/picture_layer_impl_perftest.cc2
-rw-r--r--cc/layers/picture_layer_impl_unittest.cc6
-rw-r--r--cc/layers/render_surface_impl_unittest.cc2
-rw-r--r--cc/layers/solid_color_layer_impl_unittest.cc6
-rw-r--r--cc/layers/ui_resource_layer_impl_unittest.cc2
-rw-r--r--cc/layers/video_layer_impl_unittest.cc2
-rw-r--r--cc/test/layer_test_common.h9
-rw-r--r--cc/test/layer_tree_host_common_test.cc28
-rw-r--r--cc/test/layer_tree_host_common_test.h19
-rw-r--r--cc/tiles/tile_manager_perftest.cc2
-rw-r--r--cc/trees/damage_tracker_unittest.cc29
-rw-r--r--cc/trees/draw_property_utils.cc67
-rw-r--r--cc/trees/layer_tree_host.cc6
-rw-r--r--cc/trees/layer_tree_host_common.cc213
-rw-r--r--cc/trees/layer_tree_host_common.h8
-rw-r--r--cc/trees/layer_tree_host_common_unittest.cc289
-rw-r--r--cc/trees/layer_tree_host_impl.cc7
-rw-r--r--cc/trees/layer_tree_host_impl.h1
-rw-r--r--cc/trees/layer_tree_host_impl_unittest.cc91
-rw-r--r--cc/trees/layer_tree_impl.cc8
-rw-r--r--cc/trees/layer_tree_impl.h1
-rw-r--r--cc/trees/layer_tree_impl_unittest.cc13
-rw-r--r--cc/trees/occlusion_tracker_perftest.cc2
-rw-r--r--cc/trees/occlusion_tracker_unittest.cc29
-rw-r--r--cc/trees/property_tree_builder.cc159
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);