Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(188)

Side by Side Diff: cc/animation/transform_operation.cc

Issue 23043011: cc: Use SkMScalar instead of doubles everywhere in cc (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: danakj review Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <algorithm> 5 #include <algorithm>
6 #include <cmath> 6 #include <cmath>
7 #include <limits> 7 #include <limits>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "cc/animation/transform_operation.h" 10 #include "cc/animation/transform_operation.h"
11 #include "ui/gfx/box_f.h" 11 #include "ui/gfx/box_f.h"
12 #include "ui/gfx/vector3d_f.h" 12 #include "ui/gfx/vector3d_f.h"
13 13
14 namespace { 14 namespace {
15 const double kAngleEpsilon = 1e-4; 15 const SkMScalar kAngleEpsilon = 1e-4;
16 } 16 }
17 17
18 namespace cc { 18 namespace cc {
19 19
20 bool TransformOperation::IsIdentity() const { 20 bool TransformOperation::IsIdentity() const {
21 return matrix.IsIdentity(); 21 return matrix.IsIdentity();
22 } 22 }
23 23
24 static bool IsOperationIdentity(const TransformOperation* operation) { 24 static bool IsOperationIdentity(const TransformOperation* operation) {
25 return !operation || operation->IsIdentity(); 25 return !operation || operation->IsIdentity();
26 } 26 }
27 27
28 static bool ShareSameAxis(const TransformOperation* from, 28 static bool ShareSameAxis(const TransformOperation* from,
29 const TransformOperation* to, 29 const TransformOperation* to,
30 double* axis_x, 30 SkMScalar* axis_x,
31 double* axis_y, 31 SkMScalar* axis_y,
32 double* axis_z, 32 SkMScalar* axis_z,
33 double* angle_from) { 33 SkMScalar* angle_from) {
34 if (IsOperationIdentity(from) && IsOperationIdentity(to)) 34 if (IsOperationIdentity(from) && IsOperationIdentity(to))
35 return false; 35 return false;
36 36
37 if (IsOperationIdentity(from) && !IsOperationIdentity(to)) { 37 if (IsOperationIdentity(from) && !IsOperationIdentity(to)) {
38 *axis_x = to->rotate.axis.x; 38 *axis_x = to->rotate.axis.x;
39 *axis_y = to->rotate.axis.y; 39 *axis_y = to->rotate.axis.y;
40 *axis_z = to->rotate.axis.z; 40 *axis_z = to->rotate.axis.z;
41 *angle_from = 0; 41 *angle_from = 0;
42 return true; 42 return true;
43 } 43 }
44 44
45 if (!IsOperationIdentity(from) && IsOperationIdentity(to)) { 45 if (!IsOperationIdentity(from) && IsOperationIdentity(to)) {
46 *axis_x = from->rotate.axis.x; 46 *axis_x = from->rotate.axis.x;
47 *axis_y = from->rotate.axis.y; 47 *axis_y = from->rotate.axis.y;
48 *axis_z = from->rotate.axis.z; 48 *axis_z = from->rotate.axis.z;
49 *angle_from = from->rotate.angle; 49 *angle_from = from->rotate.angle;
50 return true; 50 return true;
51 } 51 }
52 52
53 double length_2 = from->rotate.axis.x * from->rotate.axis.x + 53 SkMScalar length_2 = from->rotate.axis.x * from->rotate.axis.x +
54 from->rotate.axis.y * from->rotate.axis.y + 54 from->rotate.axis.y * from->rotate.axis.y +
55 from->rotate.axis.z * from->rotate.axis.z; 55 from->rotate.axis.z * from->rotate.axis.z;
56 double other_length_2 = to->rotate.axis.x * to->rotate.axis.x + 56 SkMScalar other_length_2 = to->rotate.axis.x * to->rotate.axis.x +
57 to->rotate.axis.y * to->rotate.axis.y + 57 to->rotate.axis.y * to->rotate.axis.y +
58 to->rotate.axis.z * to->rotate.axis.z; 58 to->rotate.axis.z * to->rotate.axis.z;
59 59
60 if (length_2 <= kAngleEpsilon || other_length_2 <= kAngleEpsilon) 60 if (length_2 <= kAngleEpsilon || other_length_2 <= kAngleEpsilon)
61 return false; 61 return false;
62 62
63 double dot = to->rotate.axis.x * from->rotate.axis.x + 63 SkMScalar dot = to->rotate.axis.x * from->rotate.axis.x +
64 to->rotate.axis.y * from->rotate.axis.y + 64 to->rotate.axis.y * from->rotate.axis.y +
65 to->rotate.axis.z * from->rotate.axis.z; 65 to->rotate.axis.z * from->rotate.axis.z;
66 double error = std::abs(1.0 - (dot * dot) / (length_2 * other_length_2)); 66 SkMScalar error =
67 std::abs(SK_MScalar1 - (dot * dot) / (length_2 * other_length_2));
danakj 2013/09/11 18:53:46 based on our discussions, i guess 1.f would also b
67 bool result = error < kAngleEpsilon; 68 bool result = error < kAngleEpsilon;
68 if (result) { 69 if (result) {
69 *axis_x = to->rotate.axis.x; 70 *axis_x = to->rotate.axis.x;
70 *axis_y = to->rotate.axis.y; 71 *axis_y = to->rotate.axis.y;
71 *axis_z = to->rotate.axis.z; 72 *axis_z = to->rotate.axis.z;
72 // If the axes are pointing in opposite directions, we need to reverse 73 // If the axes are pointing in opposite directions, we need to reverse
73 // the angle. 74 // the angle.
74 *angle_from = dot > 0 ? from->rotate.angle : -from->rotate.angle; 75 *angle_from = dot > 0 ? from->rotate.angle : -from->rotate.angle;
75 } 76 }
76 return result; 77 return result;
77 } 78 }
78 79
79 static double BlendDoubles(double from, double to, double progress) { 80 static SkMScalar BlendSkMScalars(SkMScalar from,
81 SkMScalar to,
82 SkMScalar progress) {
80 return from * (1 - progress) + to * progress; 83 return from * (1 - progress) + to * progress;
81 } 84 }
82 85
83 bool TransformOperation::BlendTransformOperations( 86 bool TransformOperation::BlendTransformOperations(
84 const TransformOperation* from, 87 const TransformOperation* from,
85 const TransformOperation* to, 88 const TransformOperation* to,
86 double progress, 89 SkMScalar progress,
87 gfx::Transform* result) { 90 gfx::Transform* result) {
88 if (IsOperationIdentity(from) && IsOperationIdentity(to)) 91 if (IsOperationIdentity(from) && IsOperationIdentity(to))
89 return true; 92 return true;
90 93
91 TransformOperation::Type interpolation_type = 94 TransformOperation::Type interpolation_type =
92 TransformOperation::TransformOperationIdentity; 95 TransformOperation::TransformOperationIdentity;
93 if (IsOperationIdentity(to)) 96 if (IsOperationIdentity(to))
94 interpolation_type = from->type; 97 interpolation_type = from->type;
95 else 98 else
96 interpolation_type = to->type; 99 interpolation_type = to->type;
97 100
98 switch (interpolation_type) { 101 switch (interpolation_type) {
99 case TransformOperation::TransformOperationTranslate: { 102 case TransformOperation::TransformOperationTranslate: {
100 double from_x = IsOperationIdentity(from) ? 0 : from->translate.x; 103 SkMScalar from_x = IsOperationIdentity(from) ? 0 : from->translate.x;
101 double from_y = IsOperationIdentity(from) ? 0 : from->translate.y; 104 SkMScalar from_y = IsOperationIdentity(from) ? 0 : from->translate.y;
102 double from_z = IsOperationIdentity(from) ? 0 : from->translate.z; 105 SkMScalar from_z = IsOperationIdentity(from) ? 0 : from->translate.z;
103 double to_x = IsOperationIdentity(to) ? 0 : to->translate.x; 106 SkMScalar to_x = IsOperationIdentity(to) ? 0 : to->translate.x;
104 double to_y = IsOperationIdentity(to) ? 0 : to->translate.y; 107 SkMScalar to_y = IsOperationIdentity(to) ? 0 : to->translate.y;
105 double to_z = IsOperationIdentity(to) ? 0 : to->translate.z; 108 SkMScalar to_z = IsOperationIdentity(to) ? 0 : to->translate.z;
106 result->Translate3d(BlendDoubles(from_x, to_x, progress), 109 result->Translate3d(BlendSkMScalars(from_x, to_x, progress),
107 BlendDoubles(from_y, to_y, progress), 110 BlendSkMScalars(from_y, to_y, progress),
108 BlendDoubles(from_z, to_z, progress)); 111 BlendSkMScalars(from_z, to_z, progress));
109 break; 112 break;
110 } 113 }
111 case TransformOperation::TransformOperationRotate: { 114 case TransformOperation::TransformOperationRotate: {
112 double axis_x = 0; 115 SkMScalar axis_x = 0;
113 double axis_y = 0; 116 SkMScalar axis_y = 0;
114 double axis_z = 1; 117 SkMScalar axis_z = 1;
115 double from_angle = 0; 118 SkMScalar from_angle = 0;
116 double to_angle = IsOperationIdentity(to) ? 0 : to->rotate.angle; 119 SkMScalar to_angle = IsOperationIdentity(to) ? 0 : to->rotate.angle;
117 if (ShareSameAxis(from, to, &axis_x, &axis_y, &axis_z, &from_angle)) { 120 if (ShareSameAxis(from, to, &axis_x, &axis_y, &axis_z, &from_angle)) {
118 result->RotateAbout(gfx::Vector3dF(axis_x, axis_y, axis_z), 121 result->RotateAbout(gfx::Vector3dF(axis_x, axis_y, axis_z),
119 BlendDoubles(from_angle, to_angle, progress)); 122 BlendSkMScalars(from_angle, to_angle, progress));
120 } else { 123 } else {
121 gfx::Transform to_matrix; 124 gfx::Transform to_matrix;
122 if (!IsOperationIdentity(to)) 125 if (!IsOperationIdentity(to))
123 to_matrix = to->matrix; 126 to_matrix = to->matrix;
124 gfx::Transform from_matrix; 127 gfx::Transform from_matrix;
125 if (!IsOperationIdentity(from)) 128 if (!IsOperationIdentity(from))
126 from_matrix = from->matrix; 129 from_matrix = from->matrix;
127 *result = to_matrix; 130 *result = to_matrix;
128 if (!result->Blend(from_matrix, progress)) 131 if (!result->Blend(from_matrix, progress))
129 return false; 132 return false;
130 } 133 }
131 break; 134 break;
132 } 135 }
133 case TransformOperation::TransformOperationScale: { 136 case TransformOperation::TransformOperationScale: {
134 double from_x = IsOperationIdentity(from) ? 1 : from->scale.x; 137 SkMScalar from_x = IsOperationIdentity(from) ? 1 : from->scale.x;
135 double from_y = IsOperationIdentity(from) ? 1 : from->scale.y; 138 SkMScalar from_y = IsOperationIdentity(from) ? 1 : from->scale.y;
136 double from_z = IsOperationIdentity(from) ? 1 : from->scale.z; 139 SkMScalar from_z = IsOperationIdentity(from) ? 1 : from->scale.z;
137 double to_x = IsOperationIdentity(to) ? 1 : to->scale.x; 140 SkMScalar to_x = IsOperationIdentity(to) ? 1 : to->scale.x;
138 double to_y = IsOperationIdentity(to) ? 1 : to->scale.y; 141 SkMScalar to_y = IsOperationIdentity(to) ? 1 : to->scale.y;
139 double to_z = IsOperationIdentity(to) ? 1 : to->scale.z; 142 SkMScalar to_z = IsOperationIdentity(to) ? 1 : to->scale.z;
140 result->Scale3d(BlendDoubles(from_x, to_x, progress), 143 result->Scale3d(BlendSkMScalars(from_x, to_x, progress),
141 BlendDoubles(from_y, to_y, progress), 144 BlendSkMScalars(from_y, to_y, progress),
142 BlendDoubles(from_z, to_z, progress)); 145 BlendSkMScalars(from_z, to_z, progress));
143 break; 146 break;
144 } 147 }
145 case TransformOperation::TransformOperationSkew: { 148 case TransformOperation::TransformOperationSkew: {
146 double from_x = IsOperationIdentity(from) ? 0 : from->skew.x; 149 SkMScalar from_x = IsOperationIdentity(from) ? 0 : from->skew.x;
147 double from_y = IsOperationIdentity(from) ? 0 : from->skew.y; 150 SkMScalar from_y = IsOperationIdentity(from) ? 0 : from->skew.y;
148 double to_x = IsOperationIdentity(to) ? 0 : to->skew.x; 151 SkMScalar to_x = IsOperationIdentity(to) ? 0 : to->skew.x;
149 double to_y = IsOperationIdentity(to) ? 0 : to->skew.y; 152 SkMScalar to_y = IsOperationIdentity(to) ? 0 : to->skew.y;
150 result->SkewX(BlendDoubles(from_x, to_x, progress)); 153 result->SkewX(BlendSkMScalars(from_x, to_x, progress));
151 result->SkewY(BlendDoubles(from_y, to_y, progress)); 154 result->SkewY(BlendSkMScalars(from_y, to_y, progress));
152 break; 155 break;
153 } 156 }
154 case TransformOperation::TransformOperationPerspective: { 157 case TransformOperation::TransformOperationPerspective: {
155 double from_perspective_depth = IsOperationIdentity(from) ? 158 SkMScalar from_perspective_depth =
156 std::numeric_limits<double>::max() : from->perspective_depth; 159 IsOperationIdentity(from) ? std::numeric_limits<SkMScalar>::max()
157 double to_perspective_depth = IsOperationIdentity(to) ? 160 : from->perspective_depth;
158 std::numeric_limits<double>::max() : to->perspective_depth; 161 SkMScalar to_perspective_depth = IsOperationIdentity(to)
159 result->ApplyPerspectiveDepth( 162 ? std::numeric_limits<SkMScalar>::max()
danakj 2013/09/11 18:53:46 i thought clang-format lines up the ? with the = a
enne (OOO) 2013/09/11 19:58:30 I think you're mis-remembering. It lines up ? and
160 BlendDoubles(from_perspective_depth, to_perspective_depth, progress)); 163 : to->perspective_depth;
164 result->ApplyPerspectiveDepth(BlendSkMScalars(
165 from_perspective_depth, to_perspective_depth, progress));
161 break; 166 break;
162 } 167 }
163 case TransformOperation::TransformOperationMatrix: { 168 case TransformOperation::TransformOperationMatrix: {
164 gfx::Transform to_matrix; 169 gfx::Transform to_matrix;
165 if (!IsOperationIdentity(to)) 170 if (!IsOperationIdentity(to))
166 to_matrix = to->matrix; 171 to_matrix = to->matrix;
167 gfx::Transform from_matrix; 172 gfx::Transform from_matrix;
168 if (!IsOperationIdentity(from)) 173 if (!IsOperationIdentity(from))
169 from_matrix = from->matrix; 174 from_matrix = from->matrix;
170 *result = to_matrix; 175 *result = to_matrix;
(...skipping 29 matching lines...) Expand all
200 float max_x = std::max(box->right(), 0.f); 205 float max_x = std::max(box->right(), 0.f);
201 float max_y = std::max(box->bottom(), 0.f); 206 float max_y = std::max(box->bottom(), 0.f);
202 float max_z = std::max(box->front(), 0.f); 207 float max_z = std::max(box->front(), 0.f);
203 *box = gfx::BoxF( 208 *box = gfx::BoxF(
204 min_x, min_y, min_z, max_x - min_x, max_y - min_y, max_z - min_z); 209 min_x, min_y, min_z, max_x - min_x, max_y - min_y, max_z - min_z);
205 } 210 }
206 211
207 bool TransformOperation::BlendedBoundsForBox(const gfx::BoxF& box, 212 bool TransformOperation::BlendedBoundsForBox(const gfx::BoxF& box,
208 const TransformOperation* from, 213 const TransformOperation* from,
209 const TransformOperation* to, 214 const TransformOperation* to,
210 double min_progress, 215 SkMScalar min_progress,
211 double max_progress, 216 SkMScalar max_progress,
212 gfx::BoxF* bounds) { 217 gfx::BoxF* bounds) {
213 bool is_identity_from = IsOperationIdentity(from); 218 bool is_identity_from = IsOperationIdentity(from);
214 bool is_identity_to = IsOperationIdentity(to); 219 bool is_identity_to = IsOperationIdentity(to);
215 if (is_identity_from && is_identity_to) { 220 if (is_identity_from && is_identity_to) {
216 *bounds = box; 221 *bounds = box;
217 return true; 222 return true;
218 } 223 }
219 224
220 TransformOperation::Type interpolation_type = 225 TransformOperation::Type interpolation_type =
221 TransformOperation::TransformOperationIdentity; 226 TransformOperation::TransformOperationIdentity;
222 if (is_identity_to) 227 if (is_identity_to)
223 interpolation_type = from->type; 228 interpolation_type = from->type;
224 else 229 else
225 interpolation_type = to->type; 230 interpolation_type = to->type;
226 231
227 switch (interpolation_type) { 232 switch (interpolation_type) {
228 case TransformOperation::TransformOperationTranslate: { 233 case TransformOperation::TransformOperationTranslate: {
229 double from_x, from_y, from_z; 234 SkMScalar from_x, from_y, from_z;
230 if (is_identity_from) { 235 if (is_identity_from) {
231 from_x = from_y = from_z = 0.0; 236 from_x = from_y = from_z = 0.0;
232 } else { 237 } else {
233 from_x = from->translate.x; 238 from_x = from->translate.x;
234 from_y = from->translate.y; 239 from_y = from->translate.y;
235 from_z = from->translate.z; 240 from_z = from->translate.z;
236 } 241 }
237 double to_x, to_y, to_z; 242 SkMScalar to_x, to_y, to_z;
238 if (is_identity_to) { 243 if (is_identity_to) {
239 to_x = to_y = to_z = 0.0; 244 to_x = to_y = to_z = 0.0;
240 } else { 245 } else {
241 to_x = to->translate.x; 246 to_x = to->translate.x;
242 to_y = to->translate.y; 247 to_y = to->translate.y;
243 to_z = to->translate.z; 248 to_z = to->translate.z;
244 } 249 }
245 *bounds = box; 250 *bounds = box;
246 *bounds += gfx::Vector3dF(BlendDoubles(from_x, to_x, min_progress), 251 *bounds += gfx::Vector3dF(BlendSkMScalars(from_x, to_x, min_progress),
247 BlendDoubles(from_y, to_y, min_progress), 252 BlendSkMScalars(from_y, to_y, min_progress),
248 BlendDoubles(from_z, to_z, min_progress)); 253 BlendSkMScalars(from_z, to_z, min_progress));
249 gfx::BoxF bounds_max = box; 254 gfx::BoxF bounds_max = box;
250 bounds_max += gfx::Vector3dF(BlendDoubles(from_x, to_x, max_progress), 255 bounds_max += gfx::Vector3dF(BlendSkMScalars(from_x, to_x, max_progress),
251 BlendDoubles(from_y, to_y, max_progress), 256 BlendSkMScalars(from_y, to_y, max_progress),
252 BlendDoubles(from_z, to_z, max_progress)); 257 BlendSkMScalars(from_z, to_z, max_progress));
253 bounds->Union(bounds_max); 258 bounds->Union(bounds_max);
254 return true; 259 return true;
255 } 260 }
256 case TransformOperation::TransformOperationScale: { 261 case TransformOperation::TransformOperationScale: {
257 double from_x, from_y, from_z; 262 SkMScalar from_x, from_y, from_z;
258 if (is_identity_from) { 263 if (is_identity_from) {
259 from_x = from_y = from_z = 1.0; 264 from_x = from_y = from_z = 1.0;
260 } else { 265 } else {
261 from_x = from->scale.x; 266 from_x = from->scale.x;
262 from_y = from->scale.y; 267 from_y = from->scale.y;
263 from_z = from->scale.z; 268 from_z = from->scale.z;
264 } 269 }
265 double to_x, to_y, to_z; 270 SkMScalar to_x, to_y, to_z;
266 if (is_identity_to) { 271 if (is_identity_to) {
267 to_x = to_y = to_z = 1.0; 272 to_x = to_y = to_z = 1.0;
268 } else { 273 } else {
269 to_x = to->scale.x; 274 to_x = to->scale.x;
270 to_y = to->scale.y; 275 to_y = to->scale.y;
271 to_z = to->scale.z; 276 to_z = to->scale.z;
272 } 277 }
273 *bounds = box; 278 *bounds = box;
274 ApplyScaleToBox(BlendDoubles(from_x, to_x, min_progress), 279 ApplyScaleToBox(
275 BlendDoubles(from_y, to_y, min_progress), 280 SkMScalarToFloat(BlendSkMScalars(from_x, to_x, min_progress)),
276 BlendDoubles(from_z, to_z, min_progress), 281 SkMScalarToFloat(BlendSkMScalars(from_y, to_y, min_progress)),
277 bounds); 282 SkMScalarToFloat(BlendSkMScalars(from_z, to_z, min_progress)),
283 bounds);
278 gfx::BoxF bounds_max = box; 284 gfx::BoxF bounds_max = box;
279 ApplyScaleToBox(BlendDoubles(from_x, to_x, max_progress), 285 ApplyScaleToBox(
280 BlendDoubles(from_y, to_y, max_progress), 286 SkMScalarToFloat(BlendSkMScalars(from_x, to_x, max_progress)),
281 BlendDoubles(from_z, to_z, max_progress), 287 SkMScalarToFloat(BlendSkMScalars(from_y, to_y, max_progress)),
282 &bounds_max); 288 SkMScalarToFloat(BlendSkMScalars(from_z, to_z, max_progress)),
289 &bounds_max);
283 if (!bounds->IsEmpty() && !bounds_max.IsEmpty()) { 290 if (!bounds->IsEmpty() && !bounds_max.IsEmpty()) {
284 bounds->Union(bounds_max); 291 bounds->Union(bounds_max);
285 } else if (!bounds->IsEmpty()) { 292 } else if (!bounds->IsEmpty()) {
286 UnionBoxWithZeroScale(bounds); 293 UnionBoxWithZeroScale(bounds);
287 } else if (!bounds_max.IsEmpty()) { 294 } else if (!bounds_max.IsEmpty()) {
288 UnionBoxWithZeroScale(&bounds_max); 295 UnionBoxWithZeroScale(&bounds_max);
289 *bounds = bounds_max; 296 *bounds = bounds_max;
290 } 297 }
291 298
292 return true; 299 return true;
293 } 300 }
294 case TransformOperation::TransformOperationIdentity: 301 case TransformOperation::TransformOperationIdentity:
295 *bounds = box; 302 *bounds = box;
296 return true; 303 return true;
297 case TransformOperation::TransformOperationRotate: 304 case TransformOperation::TransformOperationRotate:
298 case TransformOperation::TransformOperationSkew: 305 case TransformOperation::TransformOperationSkew:
299 case TransformOperation::TransformOperationPerspective: 306 case TransformOperation::TransformOperationPerspective:
300 case TransformOperation::TransformOperationMatrix: 307 case TransformOperation::TransformOperationMatrix:
301 return false; 308 return false;
302 } 309 }
303 NOTREACHED(); 310 NOTREACHED();
304 return false; 311 return false;
305 } 312 }
306 313
307 } // namespace cc 314 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698