| Index: src/core/SkBitmapProcState.cpp
|
| diff --git a/src/core/SkBitmapProcState.cpp b/src/core/SkBitmapProcState.cpp
|
| index 0b50fbc32dc8f4d160a78bc54e4b46de300ff14b..720a30f05c4a72b77365237c929755e0c1a4cf17 100644
|
| --- a/src/core/SkBitmapProcState.cpp
|
| +++ b/src/core/SkBitmapProcState.cpp
|
| @@ -98,6 +98,12 @@
|
| return (dimension & ~0x3FFF) == 0;
|
| }
|
|
|
| +static SkScalar effective_matrix_scale(const SkMatrix& mat) {
|
| + SkScalar dx = SkVector::Length(mat.getScaleX(), mat.getSkewY());
|
| + SkScalar dy = SkVector::Length(mat.getSkewX(), mat.getScaleY());
|
| + return SkScalarSqrt(dx * dy);
|
| +}
|
| +
|
| // Check to see that the size of the bitmap that would be produced by
|
| // scaling by the given inverted matrix is less than the maximum allowed.
|
| static inline bool cache_size_okay(const SkBitmap& bm, const SkMatrix& invMat) {
|
| @@ -113,6 +119,22 @@
|
| }
|
|
|
| /*
|
| + * Extract the "best" scale factors from a matrix.
|
| + */
|
| +static bool extract_scale(const SkMatrix& matrix, SkVector* scale) {
|
| + SkASSERT(!matrix.hasPerspective());
|
| + SkScalar sx = SkPoint::Length(matrix[SkMatrix::kMScaleX], matrix[SkMatrix::kMSkewY]);
|
| + SkScalar sy = SkPoint::Length(matrix[SkMatrix::kMSkewX], matrix[SkMatrix::kMScaleY]);
|
| + if (!SkScalarIsFinite(sx) || !SkScalarIsFinite(sy) ||
|
| + SkScalarNearlyZero(sx) || SkScalarNearlyZero(sy))
|
| + {
|
| + return false;
|
| + }
|
| + scale->set(sx, sy);
|
| + return true;
|
| +}
|
| +
|
| +/*
|
| * High quality is implemented by performing up-right scale-only filtering and then
|
| * using bilerp for any remaining transformations.
|
| */
|
| @@ -132,12 +154,12 @@
|
| SkScalar invScaleX = fInvMatrix.getScaleX();
|
| SkScalar invScaleY = fInvMatrix.getScaleY();
|
| if (fInvMatrix.getType() & SkMatrix::kAffine_Mask) {
|
| - SkSize scale;
|
| - if (!fInvMatrix.decomposeScale(&scale)) {
|
| - return;
|
| - }
|
| - invScaleX = scale.width();
|
| - invScaleY = scale.height();
|
| + SkVector scale;
|
| + if (!extract_scale(fInvMatrix, &scale)) {
|
| + return; // can't find suitable scale factors
|
| + }
|
| + invScaleX = scale.x();
|
| + invScaleY = scale.y();
|
| }
|
| if (SkScalarNearlyEqual(invScaleX, 1) && SkScalarNearlyEqual(invScaleY, 1)) {
|
| return; // no need for HQ
|
| @@ -182,11 +204,7 @@
|
| // to a valid bitmap.
|
| fFilterLevel = kLow_SkFilterQuality;
|
|
|
| - SkSize invScaleSize;
|
| - if (!fInvMatrix.decomposeScale(&invScaleSize, NULL)) {
|
| - return;
|
| - }
|
| - SkScalar invScale = SkScalarSqrt(invScaleSize.width() * invScaleSize.height());
|
| + SkScalar invScale = effective_matrix_scale(fInvMatrix);
|
|
|
| if (invScale > SK_Scalar1) {
|
| fCurrMip.reset(SkMipMapCache::FindAndRef(fOrigBitmap));
|
|
|