FileSystem mods: Changes to snapshot file creation to remove dependencies on blobs.
[chromium-blink-merge.git] / cc / transform_operations.cc
blob22054bd174bd6667a30fac500beb82eef9e99a23
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "cc/transform_operations.h"
6 #include "ui/gfx/transform_util.h"
7 #include "ui/gfx/vector3d_f.h"
9 namespace cc {
11 TransformOperations::TransformOperations()
12 : decomposed_transform_dirty_(true) {
15 TransformOperations::TransformOperations(const TransformOperations& other) {
16 operations_ = other.operations_;
17 decomposed_transform_dirty_ = other.decomposed_transform_dirty_;
18 if (!decomposed_transform_dirty_) {
19 decomposed_transform_.reset(
20 new gfx::DecomposedTransform(*other.decomposed_transform_.get()));
24 TransformOperations::~TransformOperations() {
27 gfx::Transform TransformOperations::Apply() const {
28 gfx::Transform to_return;
29 for (size_t i = 0; i < operations_.size(); ++i)
30 to_return.PreconcatTransform(operations_[i].matrix);
31 return to_return;
34 gfx::Transform TransformOperations::Blend(
35 const TransformOperations& from, double progress) const {
36 gfx::Transform to_return;
37 BlendInternal(from, progress, &to_return);
38 return to_return;
41 bool TransformOperations::MatchesTypes(const TransformOperations& other) const {
42 if (IsIdentity() || other.IsIdentity())
43 return true;
45 if (operations_.size() != other.operations_.size())
46 return false;
48 for (size_t i = 0; i < operations_.size(); ++i) {
49 if (operations_[i].type != other.operations_[i].type
50 && !operations_[i].IsIdentity()
51 && !other.operations_[i].IsIdentity())
52 return false;
55 return true;
58 bool TransformOperations::CanBlendWith(
59 const TransformOperations& other) const {
60 gfx::Transform dummy;
61 return BlendInternal(other, 0.5, &dummy);
64 void TransformOperations::AppendTranslate(double x, double y, double z) {
65 TransformOperation to_add;
66 to_add.matrix.Translate3d(x, y, z);
67 to_add.type = TransformOperation::TransformOperationTranslate;
68 to_add.translate.x = x;
69 to_add.translate.y = y;
70 to_add.translate.z = z;
71 operations_.push_back(to_add);
72 decomposed_transform_dirty_ = true;
75 void TransformOperations::AppendRotate(double x, double y, double z,
76 double degrees) {
77 TransformOperation to_add;
78 to_add.matrix.RotateAbout(gfx::Vector3dF(x, y, z), degrees);
79 to_add.type = TransformOperation::TransformOperationRotate;
80 to_add.rotate.axis.x = x;
81 to_add.rotate.axis.y = y;
82 to_add.rotate.axis.z = z;
83 to_add.rotate.angle = degrees;
84 operations_.push_back(to_add);
85 decomposed_transform_dirty_ = true;
88 void TransformOperations::AppendScale(double x, double y, double z) {
89 TransformOperation to_add;
90 to_add.matrix.Scale3d(x, y, z);
91 to_add.type = TransformOperation::TransformOperationScale;
92 to_add.scale.x = x;
93 to_add.scale.y = y;
94 to_add.scale.z = z;
95 operations_.push_back(to_add);
96 decomposed_transform_dirty_ = true;
99 void TransformOperations::AppendSkew(double x, double y) {
100 TransformOperation to_add;
101 to_add.matrix.SkewX(x);
102 to_add.matrix.SkewY(y);
103 to_add.type = TransformOperation::TransformOperationSkew;
104 to_add.skew.x = x;
105 to_add.skew.y = y;
106 operations_.push_back(to_add);
107 decomposed_transform_dirty_ = true;
110 void TransformOperations::AppendPerspective(double depth) {
111 TransformOperation to_add;
112 to_add.matrix.ApplyPerspectiveDepth(depth);
113 to_add.type = TransformOperation::TransformOperationPerspective;
114 to_add.perspective_depth = depth;
115 operations_.push_back(to_add);
116 decomposed_transform_dirty_ = true;
119 void TransformOperations::AppendMatrix(const gfx::Transform& matrix) {
120 TransformOperation to_add;
121 to_add.matrix = matrix;
122 to_add.type = TransformOperation::TransformOperationMatrix;
123 operations_.push_back(to_add);
124 decomposed_transform_dirty_ = true;
127 void TransformOperations::AppendIdentity() {
128 operations_.push_back(TransformOperation());
131 bool TransformOperations::IsIdentity() const {
132 for (size_t i = 0; i < operations_.size(); ++i) {
133 if (!operations_[i].IsIdentity())
134 return false;
136 return true;
139 bool TransformOperations::BlendInternal(const TransformOperations& from,
140 double progress,
141 gfx::Transform* result) const {
142 bool from_identity = from.IsIdentity();
143 bool to_identity = IsIdentity();
144 if (from_identity && to_identity)
145 return true;
147 if (MatchesTypes(from)) {
148 size_t num_operations =
149 std::max(from_identity ? 0 : from.operations_.size(),
150 to_identity ? 0 : operations_.size());
151 for (size_t i = 0; i < num_operations; ++i) {
152 gfx::Transform blended;
153 if (!TransformOperation::BlendTransformOperations(
154 from_identity ? 0 : &from.operations_[i],
155 to_identity ? 0 : &operations_[i],
156 progress,
157 blended))
158 return false;
159 result->PreconcatTransform(blended);
161 return true;
164 if (progress <= 0.0) {
165 *result = from.Apply();
166 return true;
169 if (progress >= 1.0) {
170 *result = Apply();
171 return true;
174 if (!ComputeDecomposedTransform() || !from.ComputeDecomposedTransform())
175 return false;
177 gfx::DecomposedTransform to_return;
178 if (!gfx::BlendDecomposedTransforms(&to_return,
179 *decomposed_transform_.get(),
180 *from.decomposed_transform_.get(),
181 progress))
182 return false;
184 *result = ComposeTransform(to_return);
185 return true;
188 bool TransformOperations::ComputeDecomposedTransform() const {
189 if (decomposed_transform_dirty_) {
190 if (!decomposed_transform_)
191 decomposed_transform_.reset(new gfx::DecomposedTransform());
192 gfx::Transform transform = Apply();
193 if (!gfx::DecomposeTransform(decomposed_transform_.get(), transform))
194 return false;
195 decomposed_transform_dirty_ = false;
197 return true;
200 } // namespace cc