summaryrefslogtreecommitdiffstats
path: root/cc/layers
diff options
context:
space:
mode:
authoravallee@chromium.org <avallee@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-01-24 01:33:11 +0000
committeravallee@chromium.org <avallee@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-01-24 01:33:11 +0000
commit3d86dd7a4ebd896a46f4c07cd7a2fbb6df726217 (patch)
tree54751d98283fefa47e68978a6a0218e1966b53b5 /cc/layers
parent938023f551e85235e39ec7a9ebbb4cd94764d9f0 (diff)
downloadchromium_src-3d86dd7a4ebd896a46f4c07cd7a2fbb6df726217.zip
chromium_src-3d86dd7a4ebd896a46f4c07cd7a2fbb6df726217.tar.gz
chromium_src-3d86dd7a4ebd896a46f4c07cd7a2fbb6df726217.tar.bz2
Compute accurate screen space bounds for animated layers.
This walks up the layer tree transforming a layer's bounds as a box through the different layer transforms and uses the LayerAnimationController::AnimationBoundsForBox to transform the box at layers which are animated. Expansion of the box is included for filters which change the bounds, however, the LayerAnimationController implementation is currently stubbed. + Added computation of animation bounds of layers in the screen space. - Removed invalid assertion in LayerAnimationControllerTest.AnimatedBounds. ~ Renamed methods to use the uniform naming AnimationBounds. ~ Extracted LTHC::ApplySublayerTransformAboutAnchor from LTHC::CalculateDrawPropertiesInternal. ~ Fixed LayerImpl::AsValueInto to correctly calculate bounds. ! Did not substitute implementation of ApplySublayerTransformAboutAnchor inside CalculateDrawPropertiesInternal due to performance regression. BUG=280375 Review URL: https://codereview.chromium.org/109193002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@246767 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc/layers')
-rw-r--r--cc/layers/layer.h4
-rw-r--r--cc/layers/layer_impl.cc16
-rw-r--r--cc/layers/layer_impl.h10
-rw-r--r--cc/layers/layer_utils.cc160
-rw-r--r--cc/layers/layer_utils.h29
-rw-r--r--cc/layers/layer_utils_unittest.cc258
6 files changed, 460 insertions, 17 deletions
diff --git a/cc/layers/layer.h b/cc/layers/layer.h
index 5f9caf6..df358f2 100644
--- a/cc/layers/layer.h
+++ b/cc/layers/layer.h
@@ -397,10 +397,6 @@ class CC_EXPORT Layer : public base::RefCounted<Layer>,
void PauseAnimation(int animation_id, double time_offset);
void RemoveAnimation(int animation_id);
- bool AnimatedBoundsForBox(const gfx::BoxF& box, gfx::BoxF* bounds) {
- return layer_animation_controller_->AnimatedBoundsForBox(box, bounds);
- }
-
LayerAnimationController* layer_animation_controller() {
return layer_animation_controller_.get();
}
diff --git a/cc/layers/layer_impl.cc b/cc/layers/layer_impl.cc
index 7444b77..beb282d 100644
--- a/cc/layers/layer_impl.cc
+++ b/cc/layers/layer_impl.cc
@@ -17,10 +17,12 @@
#include "cc/debug/micro_benchmark_impl.h"
#include "cc/debug/traced_value.h"
#include "cc/input/layer_scroll_offset_delegate.h"
+#include "cc/layers/layer_utils.h"
#include "cc/layers/painted_scrollbar_layer_impl.h"
#include "cc/layers/quad_sink.h"
#include "cc/output/copy_output_request.h"
#include "cc/quads/debug_border_draw_quad.h"
+#include "cc/trees/layer_tree_host_common.h"
#include "cc/trees/layer_tree_impl.h"
#include "cc/trees/layer_tree_settings.h"
#include "cc/trees/proxy.h"
@@ -1305,13 +1307,13 @@ void LayerImpl::AsValueInto(base::DictionaryValue* state) const {
state->SetBoolean("can_use_lcd_text", can_use_lcd_text());
state->SetBoolean("contents_opaque", contents_opaque());
- if (layer_animation_controller_->IsAnimatingProperty(Animation::Transform) ||
- layer_animation_controller_->IsAnimatingProperty(Animation::Filter)) {
- gfx::BoxF box(bounds().width(), bounds().height(), 0.f);
- gfx::BoxF inflated;
- if (layer_animation_controller_->AnimatedBoundsForBox(box, &inflated))
- state->Set("animated_bounds", MathUtil::AsValue(inflated).release());
- }
+ state->SetBoolean(
+ "has_animation_bounds",
+ layer_animation_controller()->HasAnimationThatInflatesBounds());
+
+ gfx::BoxF box;
+ if (LayerUtils::GetAnimationBounds(*this, &box))
+ state->Set("animation_bounds", MathUtil::AsValue(box).release());
if (debug_info_.get()) {
std::string str;
diff --git a/cc/layers/layer_impl.h b/cc/layers/layer_impl.h
index 75f02ec..66fa84b 100644
--- a/cc/layers/layer_impl.h
+++ b/cc/layers/layer_impl.h
@@ -350,12 +350,6 @@ class CC_EXPORT LayerImpl : public LayerAnimationValueObserver,
float contents_scale_y() const { return draw_properties_.contents_scale_y; }
void SetContentsScale(float contents_scale_x, float contents_scale_y);
- // Computes a box in screen space that should entirely contain the layer's
- // bounds through the entirety of the layer's current animation. Returns true
- // and sets |out| to the inflation if there are animations that can inflate
- // bounds in the path to the root layer. Returns false otherwise.
- bool GetAnimationBounds(gfx::BoxF* out) const { return false; }
-
virtual void CalculateContentsScale(float ideal_contents_scale,
float device_scale_factor,
float page_scale_factor,
@@ -465,6 +459,10 @@ class CC_EXPORT LayerImpl : public LayerAnimationValueObserver,
return layer_animation_controller_.get();
}
+ const LayerAnimationController* layer_animation_controller() const {
+ return layer_animation_controller_.get();
+ }
+
virtual Region VisibleContentOpaqueRegion() const;
virtual void DidBecomeActive();
diff --git a/cc/layers/layer_utils.cc b/cc/layers/layer_utils.cc
new file mode 100644
index 0000000..7da41a3
--- /dev/null
+++ b/cc/layers/layer_utils.cc
@@ -0,0 +1,160 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/layers/layer_utils.h"
+
+#include "cc/layers/layer_impl.h"
+#include "cc/trees/layer_tree_host_common.h"
+#include "ui/gfx/box_f.h"
+
+namespace cc {
+
+namespace {
+
+bool HasAnimationThatInflatesBounds(const LayerImpl& layer) {
+ return layer.layer_animation_controller()->HasAnimationThatInflatesBounds();
+}
+
+bool HasFilterAnimationThatInflatesBounds(const LayerImpl& layer) {
+ return layer.layer_animation_controller()
+ ->HasFilterAnimationThatInflatesBounds();
+}
+
+bool HasTransformAnimationThatInflatesBounds(const LayerImpl& layer) {
+ return layer.layer_animation_controller()
+ ->HasTransformAnimationThatInflatesBounds();
+}
+
+inline bool HasAncestorTransformAnimation(const LayerImpl& layer) {
+ return layer.screen_space_transform_is_animating();
+}
+
+inline bool HasAncestorFilterAnimation(const LayerImpl& layer) {
+ for (const LayerImpl* current = &layer; current;
+ current = current->parent()) {
+ if (HasFilterAnimationThatInflatesBounds(*current))
+ return true;
+ }
+
+ return false;
+}
+
+} // namespace
+
+bool LayerUtils::GetAnimationBounds(const LayerImpl& layer_in, gfx::BoxF* out) {
+ // We don't care about animated bounds for invisible layers.
+ if (!layer_in.DrawsContent())
+ return false;
+
+ // We also don't care for layers that are not animated or a child of an
+ // animated layer.
+ if (!HasAncestorTransformAnimation(layer_in) &&
+ !HasAncestorFilterAnimation(layer_in))
+ return false;
+
+ // To compute the inflated bounds for a layer, we start by taking its bounds
+ // and converting it to a 3d box, and then we transform or inflate it
+ // repeatedly as we walk up the layer tree to the root.
+ //
+ // At each layer we apply the following transformations to the box:
+ // 1) We translate so that the anchor point is the origin.
+ // 2) We either apply the layer's transform or inflate if the layer's
+ // transform is animated.
+ // 3) We undo the translation from step 1 and apply a second translation
+ // to account for the layer's position.
+ // 4) We apply the sublayer transform from our parent (about the parent's
+ // anchor point).
+ //
+ gfx::BoxF box(layer_in.bounds().width(), layer_in.bounds().height(), 0.f);
+
+ // We want to inflate/transform the box as few times as possible. Each time
+ // we do this, we have to make the box axis aligned again, so if we make many
+ // small adjustments to the box by transforming it repeatedly rather than
+ // once by the product of all these matrices, we will accumulate a bunch of
+ // unnecessary inflation because of the the many axis-alignment fixes. This
+ // matrix stores said product.
+ gfx::Transform coalesced_transform;
+
+ for (const LayerImpl* layer = &layer_in; layer; layer = layer->parent()) {
+ int anchor_x = layer->anchor_point().x() * layer->bounds().width();
+ int anchor_y = layer->anchor_point().y() * layer->bounds().height();
+ gfx::PointF position = layer->position();
+ if (layer->parent() && !HasAnimationThatInflatesBounds(*layer)) {
+ // |composite_layer_transform| contains 1 - 4 mentioned above. We compute
+ // it separately and apply afterwards because it's a bit more efficient
+ // because post-multiplication appears a bit more expensive, so we want
+ // to do it only once.
+ gfx::Transform composite_layer_transform;
+
+ if (!layer->parent()->sublayer_transform().IsIdentity()) {
+ LayerTreeHostCommon::ApplySublayerTransformAboutAnchor(
+ *layer->parent(),
+ layer->parent()->bounds(),
+ &composite_layer_transform);
+ }
+
+ composite_layer_transform.Translate3d(anchor_x + position.x(),
+ anchor_y + position.y(),
+ layer->anchor_point_z());
+ composite_layer_transform.PreconcatTransform(layer->transform());
+ composite_layer_transform.Translate3d(
+ -anchor_x, -anchor_y, -layer->anchor_point_z());
+
+ // Add this layer's contributions to the |coalesced_transform|.
+ coalesced_transform.ConcatTransform(composite_layer_transform);
+ continue;
+ }
+
+ // First, apply coalesced transform we've been building and reset it.
+ coalesced_transform.TransformBox(&box);
+ coalesced_transform.MakeIdentity();
+
+ // We need to apply the inflation about the layer's anchor point. Rather
+ // than doing this via transforms, we'll just shift the box directly.
+ box.set_origin(box.origin() + gfx::Vector3dF(-anchor_x,
+ -anchor_y,
+ -layer->anchor_point_z()));
+
+ // Perform the inflation
+ if (HasFilterAnimationThatInflatesBounds(*layer)) {
+ gfx::BoxF inflated;
+ if (!layer->layer_animation_controller()->FilterAnimationBoundsForBox(
+ box, &inflated))
+ return false;
+ box = inflated;
+ }
+
+ if (HasTransformAnimationThatInflatesBounds(*layer)) {
+ gfx::BoxF inflated;
+ if (!layer->layer_animation_controller()->TransformAnimationBoundsForBox(
+ box, &inflated))
+ return false;
+ box = inflated;
+ }
+
+ // Apply step 3) mentioned above.
+ box.set_origin(box.origin() + gfx::Vector3dF(anchor_x + position.x(),
+ anchor_y + position.y(),
+ layer->anchor_point_z()));
+
+ // Even for layers with animations, we have to tack in the sublayer
+ // transform of our parent. *Every* layer is repsonsible for including the
+ // sublayer transform of its parent (see step 4 above).
+ if (layer->parent()) {
+ LayerTreeHostCommon::ApplySublayerTransformAboutAnchor(
+ *layer->parent(), layer->parent()->bounds(), &coalesced_transform);
+ }
+ }
+
+ // If we've got an unapplied coalesced transform at this point, it must still
+ // be applied.
+ if (!coalesced_transform.IsIdentity())
+ coalesced_transform.TransformBox(&box);
+
+ *out = box;
+
+ return true;
+}
+
+} // namespace cc
diff --git a/cc/layers/layer_utils.h b/cc/layers/layer_utils.h
new file mode 100644
index 0000000..396f070
--- /dev/null
+++ b/cc/layers/layer_utils.h
@@ -0,0 +1,29 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CC_LAYERS_LAYER_UTILS_H_
+#define CC_LAYERS_LAYER_UTILS_H_
+
+#include "cc/base/cc_export.h"
+
+namespace gfx {
+ class BoxF;
+} // namespace gfx
+
+namespace cc {
+ class LayerImpl;
+
+ class CC_EXPORT LayerUtils {
+ public:
+ // Computes a box in screen space that should entirely contain the layer's
+ // bounds through the entirety of the layer's current animation. Returns
+ // true and sets |out| to the inflation if there are animations that can
+ // inflate bounds in the path to the root layer and that it was able to
+ // inflate correctly. Returns false otherwise.
+ static bool GetAnimationBounds(const LayerImpl& layer, gfx::BoxF* out);
+ };
+
+} // namespace cc
+
+#endif // CC_LAYERS_LAYER_UTILS_H_
diff --git a/cc/layers/layer_utils_unittest.cc b/cc/layers/layer_utils_unittest.cc
new file mode 100644
index 0000000..9738f60
--- /dev/null
+++ b/cc/layers/layer_utils_unittest.cc
@@ -0,0 +1,258 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/layers/layer_utils.h"
+
+#include "cc/animation/transform_operations.h"
+#include "cc/layers/layer_impl.h"
+#include "cc/test/animation_test_common.h"
+#include "cc/test/fake_impl_proxy.h"
+#include "cc/test/fake_layer_tree_host_impl.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/gfx/box_f.h"
+#include "ui/gfx/test/gfx_util.h"
+
+namespace cc {
+namespace {
+
+float diagonal(float width, float height) {
+ return std::sqrt(width * width + height * height);
+}
+
+class LayerUtilsGetAnimationBoundsTest : public testing::Test {
+ public:
+ LayerUtilsGetAnimationBoundsTest()
+ : host_impl_(&proxy_),
+ root_(CreateThreeNodeTree(host_impl_)),
+ parent_(root_->children()[0]),
+ child_(parent_->children()[0]) {}
+
+ LayerImpl* root() { return root_.get(); }
+ LayerImpl* parent() { return parent_; }
+ LayerImpl* child() { return child_; }
+
+ private:
+ static scoped_ptr<LayerImpl> CreateThreeNodeTree(
+ LayerTreeHostImpl& host_impl) {
+ scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl.active_tree(), 1);
+ root->AddChild(LayerImpl::Create(host_impl.active_tree(), 2));
+ root->children()[0]
+ ->AddChild(LayerImpl::Create(host_impl.active_tree(), 3));
+ return root.Pass();
+ }
+
+ FakeImplProxy proxy_;
+ FakeLayerTreeHostImpl host_impl_;
+ scoped_ptr<LayerImpl> root_;
+ LayerImpl* parent_;
+ LayerImpl* child_;
+};
+
+TEST_F(LayerUtilsGetAnimationBoundsTest, ScaleRoot) {
+ double duration = 1.0;
+
+ TransformOperations start;
+ start.AppendScale(1.f, 1.f, 1.f);
+ TransformOperations end;
+ end.AppendScale(2.f, 2.f, 1.f);
+ AddAnimatedTransformToLayer(root(), duration, start, end);
+
+ root()->SetPosition(gfx::PointF());
+ parent()->SetPosition(gfx::PointF());
+ parent()->SetBounds(gfx::Size(350, 200));
+
+ child()->SetDrawsContent(true);
+ child()->draw_properties().screen_space_transform_is_animating = true;
+ child()->SetPosition(gfx::PointF(150.f, 50.f));
+ child()->SetBounds(gfx::Size(100, 200));
+
+ gfx::BoxF box;
+ bool success = LayerUtils::GetAnimationBounds(*child(), &box);
+ EXPECT_TRUE(success);
+ gfx::BoxF expected(150.f, 50.f, 0.f, 350.f, 450.f, 0.f);
+ EXPECT_BOXF_EQ(expected, box);
+}
+
+TEST_F(LayerUtilsGetAnimationBoundsTest, TranslateParentLayer) {
+ double duration = 1.0;
+
+ TransformOperations start;
+ start.AppendTranslate(0.f, 0.f, 0.f);
+ TransformOperations end;
+ end.AppendTranslate(50.f, 50.f, 0.f);
+ AddAnimatedTransformToLayer(parent(), duration, start, end);
+
+ parent()->SetBounds(gfx::Size(350, 200));
+
+ child()->SetDrawsContent(true);
+ child()->draw_properties().screen_space_transform_is_animating = true;
+ child()->SetPosition(gfx::PointF(150.f, 50.f));
+ child()->SetBounds(gfx::Size(100, 200));
+
+ gfx::BoxF box;
+ bool success = LayerUtils::GetAnimationBounds(*child(), &box);
+ EXPECT_TRUE(success);
+ gfx::BoxF expected(150.f, 50.f, 0.f, 150.f, 250.f, 0.f);
+ EXPECT_BOXF_EQ(expected, box);
+}
+
+TEST_F(LayerUtilsGetAnimationBoundsTest, TranslateChildLayer) {
+ double duration = 1.0;
+
+ TransformOperations start;
+ start.AppendTranslate(0.f, 0.f, 0.f);
+ TransformOperations end;
+ end.AppendTranslate(50.f, 50.f, 0.f);
+ AddAnimatedTransformToLayer(child(), duration, start, end);
+
+ parent()->SetBounds(gfx::Size(350, 200));
+
+ child()->SetDrawsContent(true);
+ child()->draw_properties().screen_space_transform_is_animating = true;
+ child()->SetPosition(gfx::PointF(150.f, 50.f));
+ child()->SetBounds(gfx::Size(100, 200));
+
+ gfx::BoxF box;
+ bool success = LayerUtils::GetAnimationBounds(*child(), &box);
+ EXPECT_TRUE(success);
+ gfx::BoxF expected(150.f, 50.f, 0.f, 150.f, 250.f, 0.f);
+ EXPECT_BOXF_EQ(expected, box);
+}
+
+TEST_F(LayerUtilsGetAnimationBoundsTest, TranslateBothLayers) {
+ double duration = 1.0;
+
+ TransformOperations start;
+ start.AppendTranslate(0.f, 0.f, 0.f);
+ TransformOperations child_end;
+ child_end.AppendTranslate(50.f, 0.f, 0.f);
+ AddAnimatedTransformToLayer(parent(), duration, start, child_end);
+
+ TransformOperations grand_child_end;
+ grand_child_end.AppendTranslate(0.f, 50.f, 0.f);
+ AddAnimatedTransformToLayer(child(), duration, start, grand_child_end);
+
+ parent()->SetBounds(gfx::Size(350, 200));
+
+ child()->SetDrawsContent(true);
+ child()->draw_properties().screen_space_transform_is_animating = true;
+ child()->SetPosition(gfx::PointF(150.f, 50.f));
+ child()->SetBounds(gfx::Size(100, 200));
+
+ gfx::BoxF box;
+ bool success = LayerUtils::GetAnimationBounds(*child(), &box);
+ EXPECT_TRUE(success);
+ gfx::BoxF expected(150.f, 50.f, 0.f, 150.f, 250.f, 0.f);
+ EXPECT_BOXF_EQ(expected, box);
+}
+
+TEST_F(LayerUtilsGetAnimationBoundsTest, RotateXNoPerspective) {
+ double duration = 1.0;
+
+ TransformOperations start;
+ start.AppendRotate(1.f, 0.f, 0.f, 0.f);
+ TransformOperations end;
+ end.AppendRotate(1.f, 0.f, 0.f, 90.f);
+ AddAnimatedTransformToLayer(child(), duration, start, end);
+
+ parent()->SetBounds(gfx::Size(350, 200));
+
+ gfx::Size bounds(100, 100);
+ child()->SetDrawsContent(true);
+ child()->draw_properties().screen_space_transform_is_animating = true;
+ child()->SetPosition(gfx::PointF(150.f, 50.f));
+ child()->SetBounds(bounds);
+
+ gfx::BoxF box;
+ bool success = LayerUtils::GetAnimationBounds(*child(), &box);
+ EXPECT_TRUE(success);
+ gfx::BoxF expected(150.f, 50.f, -50.f, 100.f, 100.f, 100.f);
+ EXPECT_BOXF_EQ(expected, box);
+}
+
+TEST_F(LayerUtilsGetAnimationBoundsTest, RotateXWithPerspective) {
+ double duration = 1.0;
+
+ TransformOperations start;
+ start.AppendRotate(1.f, 0.f, 0.f, 0.f);
+ TransformOperations end;
+ end.AppendRotate(1.f, 0.f, 0.f, 90.f);
+ AddAnimatedTransformToLayer(child(), duration, start, end);
+
+ // Make the anchor point not the default 0.5 value and line up with the
+ // child center to make the math easier.
+ parent()->SetAnchorPoint(gfx::PointF(0.375f, 0.375f));
+ parent()->SetBounds(gfx::Size(400, 400));
+
+ gfx::Transform perspective;
+ perspective.ApplyPerspectiveDepth(100.f);
+ parent()->SetSublayerTransform(perspective);
+
+ gfx::Size bounds(100, 100);
+ child()->SetDrawsContent(true);
+ child()->draw_properties().screen_space_transform_is_animating = true;
+ child()->SetPosition(gfx::PointF(100.f, 100.f));
+ child()->SetBounds(bounds);
+
+ gfx::BoxF box;
+ bool success = LayerUtils::GetAnimationBounds(*child(), &box);
+ EXPECT_TRUE(success);
+ gfx::BoxF expected(50.f, 50.f, -33.333336f, 200.f, 200.f, 133.333344f);
+ EXPECT_BOXF_EQ(expected, box);
+}
+
+TEST_F(LayerUtilsGetAnimationBoundsTest, RotateZ) {
+ double duration = 1.0;
+
+ TransformOperations start;
+ start.AppendRotate(0.f, 0.f, 1.f, 0.f);
+ TransformOperations end;
+ end.AppendRotate(0.f, 0.f, 1.f, 90.f);
+ AddAnimatedTransformToLayer(child(), duration, start, end);
+
+ parent()->SetBounds(gfx::Size(350, 200));
+
+ gfx::Size bounds(100, 100);
+ child()->SetDrawsContent(true);
+ child()->draw_properties().screen_space_transform_is_animating = true;
+ child()->SetPosition(gfx::PointF(150.f, 50.f));
+ child()->SetBounds(bounds);
+
+ gfx::BoxF box;
+ bool success = LayerUtils::GetAnimationBounds(*child(), &box);
+ EXPECT_TRUE(success);
+ float diag = diagonal(bounds.width(), bounds.height());
+ gfx::BoxF expected(150.f + 0.5f * (bounds.width() - diag),
+ 50.f + 0.5f * (bounds.height() - diag),
+ 0.f,
+ diag,
+ diag,
+ 0.f);
+ EXPECT_BOXF_EQ(expected, box);
+}
+
+TEST_F(LayerUtilsGetAnimationBoundsTest, MismatchedTransforms) {
+ double duration = 1.0;
+
+ TransformOperations start;
+ start.AppendTranslate(5, 6, 7);
+ TransformOperations end;
+ end.AppendRotate(0.f, 0.f, 1.f, 90.f);
+ AddAnimatedTransformToLayer(child(), duration, start, end);
+
+ parent()->SetBounds(gfx::Size(350, 200));
+
+ gfx::Size bounds(100, 100);
+ child()->SetDrawsContent(true);
+ child()->draw_properties().screen_space_transform_is_animating = true;
+ child()->SetPosition(gfx::PointF(150.f, 50.f));
+ child()->SetBounds(bounds);
+
+ gfx::BoxF box;
+ bool success = LayerUtils::GetAnimationBounds(*child(), &box);
+ EXPECT_FALSE(success);
+}
+
+} // namespace
+} // namespace cc