root/cc/layers/layer_utils_unittest.cc

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. diagonal
  2. child_
  3. root
  4. parent
  5. child
  6. CreateThreeNodeTree
  7. TEST_F
  8. TEST_F
  9. TEST_F
  10. TEST_F
  11. TEST_F
  12. TEST_F
  13. TEST_F
  14. TEST_F

// 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 "cc/test/test_shared_bitmap_manager.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_, &shared_bitmap_manager_),
        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_;
  TestSharedBitmapManager shared_bitmap_manager_;
  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()->SetTransform(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

/* [<][>][^][v][top][bottom][index][help] */