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

Side by Side Diff: ui/gfx/transform.cc

Issue 11434027: Check for identity before doing matrix math in more places in gfx::Transform (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebased Created 8 years 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 // MSVC++ requires this to be set before any other includes to get M_PI. 5 // MSVC++ requires this to be set before any other includes to get M_PI.
6 #define _USE_MATH_DEFINES 6 #define _USE_MATH_DEFINES
7 7
8 #include "ui/gfx/transform.h" 8 #include "ui/gfx/transform.h"
9 9
10 #include <cmath> 10 #include <cmath>
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
199 if (matrix_.isIdentity()) 199 if (matrix_.isIdentity())
200 matrix_.setDouble(3, 2, -1.0 / depth); 200 matrix_.setDouble(3, 2, -1.0 / depth);
201 else { 201 else {
202 SkMatrix44 m; 202 SkMatrix44 m;
203 m.setDouble(3, 2, -1.0 / depth); 203 m.setDouble(3, 2, -1.0 / depth);
204 matrix_.preConcat(m); 204 matrix_.preConcat(m);
205 } 205 }
206 } 206 }
207 207
208 void Transform::PreconcatTransform(const Transform& transform) { 208 void Transform::PreconcatTransform(const Transform& transform) {
209 if (!transform.matrix_.isIdentity()) { 209 if (matrix_.isIdentity()) {
210 matrix_ = transform.matrix_;
211 } else if (!transform.matrix_.isIdentity()) {
210 matrix_.preConcat(transform.matrix_); 212 matrix_.preConcat(transform.matrix_);
211 } 213 }
212 } 214 }
213 215
214 void Transform::ConcatTransform(const Transform& transform) { 216 void Transform::ConcatTransform(const Transform& transform) {
215 if (!transform.matrix_.isIdentity()) { 217 if (matrix_.isIdentity()) {
218 matrix_ = transform.matrix_;
219 } else if (!transform.matrix_.isIdentity()) {
216 matrix_.postConcat(transform.matrix_); 220 matrix_.postConcat(transform.matrix_);
217 } 221 }
218 } 222 }
219 223
220 bool Transform::IsIdentity() const { 224 bool Transform::IsIdentity() const {
221 return matrix_.isIdentity(); 225 return matrix_.isIdentity();
222 } 226 }
223 227
224 bool Transform::IsIdentityOrTranslation() const { 228 bool Transform::IsIdentityOrTranslation() const {
229 if (matrix_.isIdentity())
230 return true;
231
225 bool has_no_perspective = !matrix_.getDouble(3, 0) && 232 bool has_no_perspective = !matrix_.getDouble(3, 0) &&
226 !matrix_.getDouble(3, 1) && 233 !matrix_.getDouble(3, 1) &&
227 !matrix_.getDouble(3, 2) && 234 !matrix_.getDouble(3, 2) &&
228 (matrix_.getDouble(3, 3) == 1); 235 (matrix_.getDouble(3, 3) == 1);
229 236
230 bool has_no_rotation_or_skew = !matrix_.getDouble(0, 1) && 237 bool has_no_rotation_or_skew = !matrix_.getDouble(0, 1) &&
231 !matrix_.getDouble(0, 2) && 238 !matrix_.getDouble(0, 2) &&
232 !matrix_.getDouble(1, 0) && 239 !matrix_.getDouble(1, 0) &&
233 !matrix_.getDouble(1, 2) && 240 !matrix_.getDouble(1, 2) &&
234 !matrix_.getDouble(2, 0) && 241 !matrix_.getDouble(2, 0) &&
235 !matrix_.getDouble(2, 1); 242 !matrix_.getDouble(2, 1);
236 243
237 bool has_no_scale = matrix_.getDouble(0, 0) == 1 && 244 bool has_no_scale = matrix_.getDouble(0, 0) == 1 &&
238 matrix_.getDouble(1, 1) == 1 && 245 matrix_.getDouble(1, 1) == 1 &&
239 matrix_.getDouble(2, 2) == 1; 246 matrix_.getDouble(2, 2) == 1;
240 247
241 return has_no_perspective && has_no_rotation_or_skew && has_no_scale; 248 return has_no_perspective && has_no_rotation_or_skew && has_no_scale;
242 } 249 }
243 250
244 bool Transform::IsScaleOrTranslation() const { 251 bool Transform::IsScaleOrTranslation() const {
252 if (matrix_.isIdentity())
253 return true;
254
245 bool has_no_perspective = !matrix_.getDouble(3, 0) && 255 bool has_no_perspective = !matrix_.getDouble(3, 0) &&
246 !matrix_.getDouble(3, 1) && 256 !matrix_.getDouble(3, 1) &&
247 !matrix_.getDouble(3, 2) && 257 !matrix_.getDouble(3, 2) &&
248 (matrix_.getDouble(3, 3) == 1); 258 (matrix_.getDouble(3, 3) == 1);
249 259
250 bool has_no_rotation_or_skew = !matrix_.getDouble(0, 1) && 260 bool has_no_rotation_or_skew = !matrix_.getDouble(0, 1) &&
251 !matrix_.getDouble(0, 2) && 261 !matrix_.getDouble(0, 2) &&
252 !matrix_.getDouble(1, 0) && 262 !matrix_.getDouble(1, 0) &&
253 !matrix_.getDouble(1, 2) && 263 !matrix_.getDouble(1, 2) &&
254 !matrix_.getDouble(2, 0) && 264 !matrix_.getDouble(2, 0) &&
255 !matrix_.getDouble(2, 1); 265 !matrix_.getDouble(2, 1);
256 266
257 return has_no_perspective && has_no_rotation_or_skew; 267 return has_no_perspective && has_no_rotation_or_skew;
258 } 268 }
259 269
260 bool Transform::HasPerspective() const { 270 bool Transform::HasPerspective() const {
261 return matrix_.getDouble(3, 0) || 271 return !matrix_.isIdentity() &&
262 matrix_.getDouble(3, 1) || 272 (matrix_.getDouble(3, 0) ||
263 matrix_.getDouble(3, 2) || 273 matrix_.getDouble(3, 1) ||
264 (matrix_.getDouble(3, 3) != 1); 274 matrix_.getDouble(3, 2) ||
275 (matrix_.getDouble(3, 3) != 1));
265 } 276 }
266 277
267 bool Transform::IsInvertible() const { 278 bool Transform::IsInvertible() const {
268 return std::abs(matrix_.determinant()) > kTooSmallForDeterminant; 279 return std::abs(matrix_.determinant()) > kTooSmallForDeterminant;
269 } 280 }
270 281
271 bool Transform::IsBackFaceVisible() const { 282 bool Transform::IsBackFaceVisible() const {
272 // Compute whether a layer with a forward-facing normal of (0, 0, 1, 0) 283 // Compute whether a layer with a forward-facing normal of (0, 0, 1, 0)
273 // would have its back face visible after applying the transform. 284 // would have its back face visible after applying the transform.
274 // 285 if (matrix_.isIdentity())
286 return false;
287
275 // This is done by transforming the normal and seeing if the resulting z 288 // This is done by transforming the normal and seeing if the resulting z
276 // value is positive or negative. However, note that transforming a normal 289 // value is positive or negative. However, note that transforming a normal
277 // actually requires using the inverse-transpose of the original transform. 290 // actually requires using the inverse-transpose of the original transform.
278 // 291 //
279 // We can avoid inverting and transposing the matrix since we know we want 292 // We can avoid inverting and transposing the matrix since we know we want
280 // to transform only the specific normal vector (0, 0, 1, 0). In this case, 293 // to transform only the specific normal vector (0, 0, 1, 0). In this case,
281 // we only need the 3rd row, 3rd column of the inverse-transpose. We can 294 // we only need the 3rd row, 3rd column of the inverse-transpose. We can
282 // calculate only the 3rd row 3rd column element of the inverse, skipping 295 // calculate only the 3rd row 3rd column element of the inverse, skipping
283 // everything else. 296 // everything else.
284 // 297 //
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
367 // TODO(sad): Try to avoid trying to invert the matrix. 380 // TODO(sad): Try to avoid trying to invert the matrix.
368 SkMatrix44 inverse; 381 SkMatrix44 inverse;
369 if (!matrix_.invert(&inverse)) 382 if (!matrix_.invert(&inverse))
370 return false; 383 return false;
371 384
372 TransformPointInternal(inverse, point); 385 TransformPointInternal(inverse, point);
373 return true; 386 return true;
374 } 387 }
375 388
376 void Transform::TransformRect(RectF* rect) const { 389 void Transform::TransformRect(RectF* rect) const {
390 if (matrix_.isIdentity())
391 return;
392
377 SkRect src = RectFToSkRect(*rect); 393 SkRect src = RectFToSkRect(*rect);
378 const SkMatrix& matrix = matrix_; 394 const SkMatrix& matrix = matrix_;
379 matrix.mapRect(&src); 395 matrix.mapRect(&src);
380 *rect = SkRectToRectF(src); 396 *rect = SkRectToRectF(src);
381 } 397 }
382 398
383 bool Transform::TransformRectReverse(RectF* rect) const { 399 bool Transform::TransformRectReverse(RectF* rect) const {
400 if (matrix_.isIdentity())
401 return true;
402
384 SkMatrix44 inverse; 403 SkMatrix44 inverse;
385 if (!matrix_.invert(&inverse)) 404 if (!matrix_.invert(&inverse))
386 return false; 405 return false;
406
387 const SkMatrix& matrix = inverse; 407 const SkMatrix& matrix = inverse;
388 SkRect src = RectFToSkRect(*rect); 408 SkRect src = RectFToSkRect(*rect);
389 matrix.mapRect(&src); 409 matrix.mapRect(&src);
390 *rect = SkRectToRectF(src); 410 *rect = SkRectToRectF(src);
391 return true; 411 return true;
392 } 412 }
393 413
394 bool Transform::Blend(const Transform& from, double progress) { 414 bool Transform::Blend(const Transform& from, double progress) {
395 if (progress <= 0.0) { 415 if (progress <= 0.0) {
396 *this = from; 416 *this = from;
(...skipping 10 matching lines...) Expand all
407 return false; 427 return false;
408 428
409 if (!BlendDecomposedTransforms(&to_decomp, to_decomp, from_decomp, progress)) 429 if (!BlendDecomposedTransforms(&to_decomp, to_decomp, from_decomp, progress))
410 return false; 430 return false;
411 431
412 matrix_ = ComposeTransform(to_decomp).matrix(); 432 matrix_ = ComposeTransform(to_decomp).matrix();
413 return true; 433 return true;
414 } 434 }
415 435
416 Transform Transform::operator*(const Transform& other) const { 436 Transform Transform::operator*(const Transform& other) const {
437 if (matrix_.isIdentity())
438 return other;
439 if (other.matrix_.isIdentity())
440 return *this;
417 Transform to_return; 441 Transform to_return;
418 to_return.matrix_.setConcat(matrix_, other.matrix_); 442 to_return.matrix_.setConcat(matrix_, other.matrix_);
419 return to_return; 443 return to_return;
420 } 444 }
421 445
422 Transform& Transform::operator*=(const Transform& other) { 446 Transform& Transform::operator*=(const Transform& other) {
423 matrix_.preConcat(other.matrix_); 447 PreconcatTransform(other);
424 return *this; 448 return *this;
425 } 449 }
426 450
427 void Transform::TransformPointInternal(const SkMatrix44& xform, 451 void Transform::TransformPointInternal(const SkMatrix44& xform,
428 Point3F& point) const { 452 Point3F& point) const {
453 if (xform.isIdentity())
454 return;
455
429 SkMScalar p[4] = { 456 SkMScalar p[4] = {
430 SkDoubleToMScalar(point.x()), 457 SkDoubleToMScalar(point.x()),
431 SkDoubleToMScalar(point.y()), 458 SkDoubleToMScalar(point.y()),
432 SkDoubleToMScalar(point.z()), 459 SkDoubleToMScalar(point.z()),
433 SkDoubleToMScalar(1) 460 SkDoubleToMScalar(1)
434 }; 461 };
435 462
436 xform.mapMScalars(p); 463 xform.mapMScalars(p);
437 464
438 if (p[3] != 1 && abs(p[3]) > 0) { 465 if (p[3] != 1 && abs(p[3]) > 0) {
439 point.SetPoint(p[0] / p[3], p[1] / p[3], p[2]/ p[3]); 466 point.SetPoint(p[0] / p[3], p[1] / p[3], p[2]/ p[3]);
440 } else { 467 } else {
441 point.SetPoint(p[0], p[1], p[2]); 468 point.SetPoint(p[0], p[1], p[2]);
442 } 469 }
443 } 470 }
444 471
445 void Transform::TransformPointInternal(const SkMatrix44& xform, 472 void Transform::TransformPointInternal(const SkMatrix44& xform,
446 Point& point) const { 473 Point& point) const {
474 if (xform.isIdentity())
475 return;
476
447 SkMScalar p[4] = { 477 SkMScalar p[4] = {
448 SkDoubleToMScalar(point.x()), 478 SkDoubleToMScalar(point.x()),
449 SkDoubleToMScalar(point.y()), 479 SkDoubleToMScalar(point.y()),
450 SkDoubleToMScalar(0), 480 SkDoubleToMScalar(0),
451 SkDoubleToMScalar(1) 481 SkDoubleToMScalar(1)
452 }; 482 };
453 483
454 xform.mapMScalars(p); 484 xform.mapMScalars(p);
455 485
456 point.SetPoint(ToRoundedInt(p[0]), ToRoundedInt(p[1])); 486 point.SetPoint(ToRoundedInt(p[0]), ToRoundedInt(p[1]));
457 } 487 }
458 488
459 } // namespace gfx 489 } // namespace gfx
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698