diff options
author | bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2011-05-10 13:52:42 +0000 |
---|---|---|
committer | bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2011-05-10 13:52:42 +0000 |
commit | cc4dac3dac215dc0dd56f7b30d07cc304671b033 (patch) | |
tree | df2541be704a4c8db625028013a15aa763362336 | |
parent | ee9aa304579b3d5314519372728187879456d49d (diff) |
Make GrMatrix an alias of SkMatrix. Add new methods to SkMatrix.
Review URL: http://codereview.appspot.com/4538043/
Checked in on behalf of reed@ with some additional work (remove the do-nother sk->gr matrix converter).
git-svn-id: http://skia.googlecode.com/svn/trunk@1289 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r-- | gpu/include/GrMatrix.h | 396 | ||||
-rw-r--r-- | gpu/include/GrTextContext.h | 2 | ||||
-rw-r--r-- | gpu/src/GrContext.cpp | 2 | ||||
-rw-r--r-- | gpu/src/GrGpuGLFixed.cpp | 18 | ||||
-rw-r--r-- | gpu/src/GrGpuGLShaders.cpp | 39 | ||||
-rw-r--r-- | gpu/src/GrMatrix.cpp | 3 | ||||
-rw-r--r-- | gpu/src/gr_unittests.cpp | 1 | ||||
-rw-r--r-- | include/core/SkMatrix.h | 54 | ||||
-rw-r--r-- | include/gpu/SkGr.h | 12 | ||||
-rw-r--r-- | src/core/SkMatrix.cpp | 89 | ||||
-rw-r--r-- | src/gpu/SkGpuDevice.cpp | 36 |
11 files changed, 182 insertions, 470 deletions
diff --git a/gpu/include/GrMatrix.h b/gpu/include/GrMatrix.h index 19a6644bf7..a879ed043a 100644 --- a/gpu/include/GrMatrix.h +++ b/gpu/include/GrMatrix.h @@ -19,400 +19,8 @@ #define GrMatrix_DEFINED #include "GrRect.h" +#include "SkMatrix.h" -/* - * 3x3 matrix - */ -class GrMatrix { -public: - static const GrMatrix& I() { - static const GrMatrix I = GrMatrix(GR_Scalar1, 0, 0, - 0, GR_Scalar1, 0, - 0, 0, gRESCALE); - return I; - }; - static const GrMatrix& InvalidMatrix() { - static const GrMatrix INV = - GrMatrix(GR_ScalarMax, GR_ScalarMax, GR_ScalarMax, - GR_ScalarMax, GR_ScalarMax, GR_ScalarMax, - GR_ScalarMax, GR_ScalarMax, GR_ScalarMax); - return INV; - } - /** - * Handy index constants - */ - enum { - kScaleX, - kSkewX, - kTransX, - kSkewY, - kScaleY, - kTransY, - kPersp0, - kPersp1, - kPersp2 - }; - - /** - * Create an uninitialized matrix - */ - GrMatrix() { - fTypeMask = 0; - } - - /** - * Create a matrix from an array of values - * @param values row-major array of matrix components - */ - explicit GrMatrix(const GrScalar values[]) { - setToArray(values); - } - - /** - * Create a matrix from values - * @param scaleX (0,0) matrix element - * @param skewX (0,1) matrix element - * @param transX (0,2) matrix element - * @param skewY (1,0) matrix element - * @param scaleY (1,1) matrix element - * @param transY (1,2) matrix element - * @param persp0 (2,0) matrix element - * @param persp1 (2,1) matrix element - * @param persp2 (2,2) matrix element - */ - GrMatrix(GrScalar scaleX, - GrScalar skewX, - GrScalar transX, - GrScalar skewY, - GrScalar scaleY, - GrScalar transY, - GrScalar persp0, - GrScalar persp1, - GrScalar persp2) { - setAll(scaleX, skewX, transX, - skewY, scaleY, transY, - persp0, persp1, persp2); - } - - /** - * access matrix component - * @return matrix component value - */ - const GrScalar& operator[] (int idx) const { - GrAssert((unsigned)idx < 9); - return fM[idx]; - } - - /** - * Set a matrix from an array of values - * @param values row-major array of matrix components - */ - void setToArray(const GrScalar values[]) { - for (int i = 0; i < 9; ++i) { - fM[i] = values[i]; - } - this->computeTypeMask(); - } - - /** - * Create a matrix from values - * @param scaleX (0,0) matrix element - * @param skewX (0,1) matrix element - * @param transX (0,2) matrix element - * @param skewY (1,0) matrix element - * @param scaleY (1,1) matrix element - * @param transY (1,2) matrix element - * @param persp0 (2,0) matrix element - * @param persp1 (2,1) matrix element - * @param persp2 (2,2) matrix element - */ - void setAll(GrScalar scaleX, - GrScalar skewX, - GrScalar transX, - GrScalar skewY, - GrScalar scaleY, - GrScalar transY, - GrScalar persp0, - GrScalar persp1, - GrScalar persp2) { - fM[kScaleX] = scaleX; - fM[kSkewX] = skewX; - fM[kTransX] = transX; - fM[kSkewY] = skewY; - fM[kScaleY] = scaleY; - fM[kTransY] = transY; - fM[kPersp0] = persp0; - fM[kPersp1] = persp1; - fM[kPersp2] = persp2; - - this->computeTypeMask(); - } - - /** - * set matrix component - * @param idx index of component to set - * @param value value to set component to - */ - inline void set(int idx, GrScalar value); - - /** - * make this matrix an identity matrix - */ - void setIdentity(); - - /** - * overwrite entire matrix to be a translation matrix - * @param dx amount to translate by in x - * @param dy amount to translate by in y - */ - void setTranslate(GrScalar dx, GrScalar dy); - - /** - * overwrite entire matrix to be a scaling matrix - * @param sx x scale factor - * @param sy y scale factor - */ - void setScale(GrScalar sx, GrScalar sy); - - /** - * overwrite entire matrix to be a skew matrix - * @param skx x skew factor - * @param sky y skew factor - */ - void setSkew(GrScalar skx, GrScalar sky); - - /** - * set this matrix to be a concantenation of two - * matrices (a*b). Either a, b, or both can be this matrix. - * @param a first matrix to multiply - * @param b second matrix to multiply - */ - void setConcat(const GrMatrix& a, const GrMatrix& b); - - /** - * Set this matrix to this*m - * @param m matrix to concatenate - */ - void preConcat(const GrMatrix& m); - - /** - * Set this matrix to m*this - * @param m matrix to concatenate - */ - void postConcat(const GrMatrix& m); - - /** - * Compute the inverse of this matrix, and return true if it is invertible, - * or false if not. - * - * If inverted is not null, and the matrix is invertible, then the inverse - * is written into it. If the matrix is not invertible (this method returns - * false) then inverted is left unchanged. - */ - bool invert(GrMatrix* inverted) const; - - /** - * Transforms a point by the matrix - * - * @param src the point to transform - * @return the transformed point - */ - GrPoint mapPoint(const GrPoint& src) const { - GrPoint result; - (this->*gMapProcs[fTypeMask])(&result, &src, 1); - return result; - } - - /** - * Transforms an array of points by the matrix. - * - * @param dstPts the array to write transformed points into - * @param srcPts the array of points to transform - @ @param count the number of points to transform - */ - void mapPoints(GrPoint dstPts[], - const GrPoint srcPts[], - uint32_t count) const { - (this->*gMapProcs[fTypeMask])(dstPts, srcPts, count); - } - - /** - * Transforms pts with arbitrary stride in place. - * - * @param start pointer to first point to transform - * @param stride distance in bytes between consecutive points - @ @param count the number of points to transform - */ - void mapPointsWithStride(GrPoint* start, - size_t stride, - uint32_t count) const { - for (uint32_t i = 0; i < count; ++i) { - this->mapPoints(start, start, 1); - start = (GrPoint*)((intptr_t)start + stride); - } - } - - /** - * Transforms a vector by the matrix. Doesn't handle cases when a - * homogeneous vector maps to a point (i.e. perspective transform). - * In this case the desired answer is dependent on where the tail of - * the vector is in space. - */ - void mapVec(GrVec* vec) { - GrAssert(!this->hasPerspective()); - if (!this->isIdentity()) { - GrScalar x = vec->fX; - vec->fX = (*this)[kScaleX] * x + (*this)[kSkewX] * vec->fY; - vec->fY = (*this)[kSkewY ] * x + (*this)[kScaleY] * vec->fY; - } - } - - /** - * Transform the 4 corners of the src rect, and return the bounding rect - * in the dst rect. Note: src and dst may point to the same memory. - */ - void mapRect(GrRect* dst, const GrRect& src) const; - - /** - * Transform the 4 corners of the rect, and return their bounds in the rect - */ - void mapRect(GrRect* rect) const { - this->mapRect(rect, *rect); - } - - /** - * Checks if matrix is a perspective matrix. - * @return true if third row is not (0, 0, 1) - */ - bool hasPerspective() const; - - /** - * Checks whether matrix is identity - * @return true if matrix is idenity - */ - bool isIdentity() const; - - /** - * Do axis-aligned lines stay axis aligned? May do 90 degree rotation / mirroring. - */ - bool preservesAxisAlignment() const; - - /** - * Calculates the maximum stretching factor of the matrix. Only defined if - * the matrix does not have perspective. - * - * @return maximum strecthing factor or negative if matrix has perspective. - */ - GrScalar getMaxStretch() const; - - /** - * Checks for matrix equality. Test is element-by-element equality, - * not a homogeneous test. - * @return true if matrices are equal, false otherwise - */ - bool operator == (const GrMatrix& m) const; - - /** - * Checks for matrix inequality. Test is element-by-element inequality, - * not a homogeneous test. - * @return true if matrices are not equal, false otherwise - */ - bool operator != (const GrMatrix& m) const; - - static void UnitTest(); - -private: - static const GrScalar gRESCALE; - - void computeTypeMask() { - fTypeMask = 0; - if (0 != fM[kPersp0] || 0 != fM[kPersp1] || gRESCALE != fM[kPersp2]) { - fTypeMask |= kPerspective_TypeBit; - } - if (GR_Scalar1 != fM[kScaleX] || GR_Scalar1 != fM[kScaleY]) { - fTypeMask |= kScale_TypeBit; - if (0 == fM[kScaleX] && 0 == fM[kScaleY]) { - fTypeMask |= kZeroScale_TypeBit; - } - } - if (0 != fM[kSkewX] || 0 != fM[kSkewY]) { - fTypeMask |= kSkew_TypeBit; - } - if (0 != fM[kTransX] || 0 != fM[kTransY]) { - fTypeMask |= kTranslate_TypeBit; - } - } - - - double determinant() const; - - enum TypeBits { - kScale_TypeBit = 1 << 0, // set if scales are not both 1 - kTranslate_TypeBit = 1 << 1, // set if translates are not both 0 - kSkew_TypeBit = 1 << 2, // set if skews are not both 0 - kPerspective_TypeBit = 1 << 3, // set if perspective - kZeroScale_TypeBit = 1 << 4, // set if scales are both zero - }; - - void mapIdentity(GrPoint* dst, const GrPoint* src, uint32_t count) const; - void mapScale(GrPoint* dst, const GrPoint* src, uint32_t count) const; - void mapTranslate(GrPoint* dst, const GrPoint* src, uint32_t count) const; - void mapScaleAndTranslate(GrPoint* dst, const GrPoint* src, uint32_t count) const; - void mapSkew(GrPoint* dst, const GrPoint* src, uint32_t count) const; - void mapScaleAndSkew(GrPoint* dst, const GrPoint* src, uint32_t count) const; - void mapSkewAndTranslate(GrPoint* dst, const GrPoint* src, uint32_t count) const; - void mapNonPerspective(GrPoint* dst, const GrPoint* src, uint32_t count) const; - void mapPerspective(GrPoint* dst, const GrPoint* src, uint32_t count) const; - void mapZero(GrPoint* dst, const GrPoint* src, uint32_t count) const; - void mapSetToTranslate(GrPoint* dst, const GrPoint* src, uint32_t count) const; - void mapSwappedScale(GrPoint* dst, const GrPoint* src, uint32_t count) const; - void mapSwappedScaleAndTranslate(GrPoint* dst, const GrPoint* src, uint32_t count) const; - - void mapInvalid(GrPoint* dst, const GrPoint* src, uint32_t count) const; - - typedef void (GrMatrix::*MapProc) (GrPoint* dst, const GrPoint* src, uint32_t count) const; - static const MapProc gMapProcs[]; - - int fTypeMask; - - GrScalar fM[9]; -}; - -void GrMatrix::set(int idx, GrScalar value) { - GrAssert((unsigned)idx < 9); - fM[idx] = value; - if (idx > 5) { - if (0 != fM[kPersp0] || 0 != fM[kPersp1] || - gRESCALE != fM[kPersp2]) { - fTypeMask |= kPerspective_TypeBit; - } else { - fTypeMask &= ~kPerspective_TypeBit; - } - } else if (!(idx % 4)) { - if ((GR_Scalar1 == fM[kScaleX] && GR_Scalar1 == fM[kScaleY])) { - fTypeMask &= ~kScale_TypeBit; - fTypeMask &= ~kZeroScale_TypeBit; - } else { - fTypeMask |= kScale_TypeBit; - if ((0 == fM[kScaleX] && 0 == fM[kScaleY])) { - fTypeMask |= kZeroScale_TypeBit; - } else { - fTypeMask &= ~kZeroScale_TypeBit; - } - } - } else if (2 == (idx % 3)) { - if (0 != fM[kTransX] || 0 != fM[kTransY]) { - fTypeMask |= kTranslate_TypeBit; - } else { - fTypeMask &= ~kTranslate_TypeBit; - } - } else { - if (0 != fM[kSkewX] || 0 != fM[kSkewY]) { - fTypeMask |= kSkew_TypeBit; - } else { - fTypeMask &= ~kSkew_TypeBit; - } - } -} +typedef SkMatrix GrMatrix; #endif diff --git a/gpu/include/GrTextContext.h b/gpu/include/GrTextContext.h index a5982517d2..b7a690e3fe 100644 --- a/gpu/include/GrTextContext.h +++ b/gpu/include/GrTextContext.h @@ -20,9 +20,9 @@ #include "GrGlyph.h" #include "GrPaint.h" +#include "GrMatrix.h" struct GrGpuTextVertex; -class GrMatrix; class GrContext; class GrTextStrike; class GrFontScaler; diff --git a/gpu/src/GrContext.cpp b/gpu/src/GrContext.cpp index 84611878e3..2d93e4bbd6 100644 --- a/gpu/src/GrContext.cpp +++ b/gpu/src/GrContext.cpp @@ -925,7 +925,7 @@ void GrContext::drawRect(const GrPaint& paint, GrVec strokeSize;; if (width > 0) { strokeSize.set(width, width); - combinedMatrix.mapVec(&strokeSize); + combinedMatrix.mapVectors(&strokeSize, 1); strokeSize.setAbs(strokeSize); } else { strokeSize.set(GR_Scalar1, GR_Scalar1); diff --git a/gpu/src/GrGpuGLFixed.cpp b/gpu/src/GrGpuGLFixed.cpp index dbfac436c8..e197a82533 100644 --- a/gpu/src/GrGpuGLFixed.cpp +++ b/gpu/src/GrGpuGLFixed.cpp @@ -32,17 +32,17 @@ struct GrGpuMatrix { void set(const GrMatrix& m) { Gr_bzero(fMat, sizeof(fMat)); - fMat[0] = GrScalarToFloat(m[GrMatrix::kScaleX]); - fMat[4] = GrScalarToFloat(m[GrMatrix::kSkewX]); - fMat[12] = GrScalarToFloat(m[GrMatrix::kTransX]); + fMat[0] = GrScalarToFloat(m[GrMatrix::kMScaleX]); + fMat[4] = GrScalarToFloat(m[GrMatrix::kMSkewX]); + fMat[12] = GrScalarToFloat(m[GrMatrix::kMTransX]); - fMat[1] = GrScalarToFloat(m[GrMatrix::kSkewY]); - fMat[5] = GrScalarToFloat(m[GrMatrix::kScaleY]); - fMat[13] = GrScalarToFloat(m[GrMatrix::kTransY]); + fMat[1] = GrScalarToFloat(m[GrMatrix::kMSkewY]); + fMat[5] = GrScalarToFloat(m[GrMatrix::kMScaleY]); + fMat[13] = GrScalarToFloat(m[GrMatrix::kMTransY]); - fMat[3] = GrScalarToFloat(m[GrMatrix::kPersp0]); - fMat[7] = GrScalarToFloat(m[GrMatrix::kPersp1]); - fMat[15] = GrScalarToFloat(m[GrMatrix::kPersp2]); + fMat[3] = GrScalarToFloat(m[GrMatrix::kMPersp0]); + fMat[7] = GrScalarToFloat(m[GrMatrix::kMPersp1]); + fMat[15] = GrScalarToFloat(m[GrMatrix::kMPersp2]); fMat[10] = 1.f; // z-scale } diff --git a/gpu/src/GrGpuGLShaders.cpp b/gpu/src/GrGpuGLShaders.cpp index c2b89716de..3ce6e55d69 100644 --- a/gpu/src/GrGpuGLShaders.cpp +++ b/gpu/src/GrGpuGLShaders.cpp @@ -273,7 +273,8 @@ void GrGpuGLShaders::resetContext() { void GrGpuGLShaders::flushViewMatrix() { GrAssert(NULL != fCurrDrawState.fRenderTarget); - GrMatrix m ( + GrMatrix m; + m.setAll( GrIntToScalar(2) / fCurrDrawState.fRenderTarget->width(), 0, -GR_Scalar1, 0,-GrIntToScalar(2) / fCurrDrawState.fRenderTarget->height(), GR_Scalar1, 0, 0, GrMatrix::I()[8]); @@ -282,15 +283,15 @@ void GrGpuGLShaders::flushViewMatrix() { // ES doesn't allow you to pass true to the transpose param, // so do our own transpose GrScalar mt[] = { - m[GrMatrix::kScaleX], - m[GrMatrix::kSkewY], - m[GrMatrix::kPersp0], - m[GrMatrix::kSkewX], - m[GrMatrix::kScaleY], - m[GrMatrix::kPersp1], - m[GrMatrix::kTransX], - m[GrMatrix::kTransY], - m[GrMatrix::kPersp2] + m[GrMatrix::kMScaleX], + m[GrMatrix::kMSkewY], + m[GrMatrix::kMPersp0], + m[GrMatrix::kMSkewX], + m[GrMatrix::kMScaleY], + m[GrMatrix::kMPersp1], + m[GrMatrix::kMTransX], + m[GrMatrix::kMTransY], + m[GrMatrix::kMPersp2] }; if (GrGLProgram::kSetAsAttribute == @@ -327,15 +328,15 @@ void GrGpuGLShaders::flushTextureMatrix(int s) { // ES doesn't allow you to pass true to the transpose param, // so do our own transpose GrScalar mt[] = { - m[GrMatrix::kScaleX], - m[GrMatrix::kSkewY], - m[GrMatrix::kPersp0], - m[GrMatrix::kSkewX], - m[GrMatrix::kScaleY], - m[GrMatrix::kPersp1], - m[GrMatrix::kTransX], - m[GrMatrix::kTransY], - m[GrMatrix::kPersp2] + m[GrMatrix::kMScaleX], + m[GrMatrix::kMSkewY], + m[GrMatrix::kMPersp0], + m[GrMatrix::kMSkewX], + m[GrMatrix::kMScaleY], + m[GrMatrix::kMPersp1], + m[GrMatrix::kMTransX], + m[GrMatrix::kMTransY], + m[GrMatrix::kMPersp2] }; if (GrGLProgram::kSetAsAttribute == fProgramData->fUniLocations.fStages[s].fTextureMatrixUni) { diff --git a/gpu/src/GrMatrix.cpp b/gpu/src/GrMatrix.cpp index c88c6e13f1..476d9a2293 100644 --- a/gpu/src/GrMatrix.cpp +++ b/gpu/src/GrMatrix.cpp @@ -19,6 +19,7 @@ #include "GrRect.h" #include <stddef.h> +#if 0 #if GR_SCALAR_IS_FLOAT const GrScalar GrMatrix::gRESCALE(GR_Scalar1); #else @@ -688,6 +689,7 @@ void GrMatrix::UnitTest() { } /////////////////////////////////////////////////////////////////////////////// +#endif int Gr_clz(uint32_t n) { if (0 == n) { @@ -716,4 +718,3 @@ int Gr_clz(uint32_t n) { } return count; } - diff --git a/gpu/src/gr_unittests.cpp b/gpu/src/gr_unittests.cpp index fd27f199a9..320dd15bd7 100644 --- a/gpu/src/gr_unittests.cpp +++ b/gpu/src/gr_unittests.cpp @@ -152,7 +152,6 @@ void gr_run_unittests() { test_tdarray(); test_bsearch(); test_binHashKey(); - GrMatrix::UnitTest(); GrRedBlackTree<int>::UnitTest(); GrPath::ConvexUnitTest(); GrDrawTarget::VertexLayoutUnitTest(); diff --git a/include/core/SkMatrix.h b/include/core/SkMatrix.h index 5ba9223058..7c779027be 100644 --- a/include/core/SkMatrix.h +++ b/include/core/SkMatrix.h @@ -70,6 +70,15 @@ public: } return (fTypeMask & kRectStaysRect_Mask) != 0; } + // alias for rectStaysRect() + bool preservesAxisAlignment() const { return this->rectStaysRect(); } + + /** + * Returns true if the perspective contains perspective elements. + */ + bool hasPerspective() const { + return SkToBool(this->getType() & kPerspective_Mask); + } enum { kMScaleX, @@ -123,10 +132,27 @@ public: void setPerspX(SkScalar v) { this->set(kMPersp0, v); } void setPerspY(SkScalar v) { this->set(kMPersp1, v); } + void setAll(SkScalar scaleX, SkScalar skewX, SkScalar transX, + SkScalar skewY, SkScalar scaleY, SkScalar transY, + SkScalar persp0, SkScalar persp1, SkScalar persp2) { + fMat[kMScaleX] = scaleX; + fMat[kMSkewX] = skewX; + fMat[kMTransX] = transX; + fMat[kMSkewY] = skewY; + fMat[kMScaleY] = scaleY; + fMat[kMTransY] = transY; + fMat[kMPersp0] = persp0; + fMat[kMPersp1] = persp1; + fMat[kMPersp2] = persp2; + this->setTypeMask(kUnknown_Mask); + } + /** Set the matrix to identity */ void reset(); - + // alias for reset() + void setIdentity() { this->reset(); } + /** Set the matrix to translate by (dx, dy). */ void setTranslate(SkScalar dx, SkScalar dy); @@ -369,6 +395,13 @@ public: return this->mapRect(rect, *rect); } + void mapPointsWithStride(SkPoint pts[], size_t stride, int count) const { + for (int i = 0; i < count; ++i) { + this->mapPoints(pts, pts, 1); + pts = (SkPoint*)((intptr_t)pts + stride); + } + } + /** Return the mean radius of a circle after it has been mapped by this matrix. NOTE: in perspective this value assumes the circle has its center at the origin. @@ -425,6 +458,25 @@ public: void dump() const; void toDumpString(SkString*) const; + /** + * Calculates the maximum stretching factor of the matrix. Only defined if + * the matrix does not have perspective. + * + * @return maximum strecthing factor or negative if matrix has perspective. + */ + SkScalar getMaxStretch() const; + + /** + * Return a reference to a const identity matrix + */ + static const SkMatrix& I(); + + /** + * Return a reference to a const matrix that is "invalid", one that could + * never be used. + */ + static const SkMatrix& InvalidMatrix(); + private: enum { /** Set if the matrix will map a rectangle to another rectangle. This diff --git a/include/gpu/SkGr.h b/include/gpu/SkGr.h index eef70b1287..75099b2df6 100644 --- a/include/gpu/SkGr.h +++ b/include/gpu/SkGr.h @@ -117,18 +117,6 @@ public: return BitmapConfig2PixelConfig(bm.config(), bm.isOpaque()); } - static void SkMatrix2GrMatrix(const SkMatrix& m, GrMatrix* g) { - g->setAll(SkScalarToGrScalar(m[0]), - SkScalarToGrScalar(m[1]), - SkScalarToGrScalar(m[2]), - SkScalarToGrScalar(m[3]), - SkScalarToGrScalar(m[4]), - SkScalarToGrScalar(m[5]), - SkScalarToGrScalar(m[6]), - SkScalarToGrScalar(m[7]), - SkScalarToGrScalar(m[8])); - } - static GrColor SkColor2GrColor(SkColor c) { SkPMColor pm = SkPreMultiplyColor(c); unsigned r = SkGetPackedR32(pm); diff --git a/src/core/SkMatrix.cpp b/src/core/SkMatrix.cpp index f2d1708114..983c8d21f2 100644 --- a/src/core/SkMatrix.cpp +++ b/src/core/SkMatrix.cpp @@ -1586,6 +1586,95 @@ bool SkMatrix::setPolyToPoly(const SkPoint src[], const SkPoint dst[], /////////////////////////////////////////////////////////////////////////////// +SkScalar SkMatrix::getMaxStretch() const { + TypeMask mask = this->getType(); + + if (mask & kPerspective_Mask) { + return -SK_Scalar1; + } + + SkScalar stretch; + + if (this->isIdentity()) { + stretch = SK_Scalar1; + } else if (!(mask & kAffine_Mask)) { + stretch = SkMaxScalar(SkScalarAbs(fMat[kMScaleX]), SkScalarAbs(fMat[kMScaleY])); +#if 0 // don't have this bit + } else if (mask & kZeroScale_TypeBit) { + stretch = SkMaxScalar(SkScalarAbs(fM[kSkewX]), SkScalarAbs(fM[kSkewY])); +#endif + } else { + // ignore the translation part of the matrix, just look at 2x2 portion. + // compute singular values, take largest abs value. + // [a b; b c] = A^T*A + SkScalar a = SkScalarMul(fMat[kMScaleX], fMat[kMScaleX]) + SkScalarMul(fMat[kMSkewY], fMat[kMSkewY]); + SkScalar b = SkScalarMul(fMat[kMScaleX], fMat[kMSkewX]) + SkScalarMul(fMat[kMScaleY], fMat[kMSkewY]); + SkScalar c = SkScalarMul(fMat[kMSkewX], fMat[kMSkewX]) + SkScalarMul(fMat[kMScaleY], fMat[kMScaleY]); + // eigenvalues of A^T*A are the squared singular values of A. + // characteristic equation is det((A^T*A) - l*I) = 0 + // l^2 - (a + c)l + (ac-b^2) + // solve using quadratic equation (divisor is non-zero since l^2 has 1 coeff + // and roots are guaraunteed to be pos and real). + SkScalar largerRoot; + SkScalar bSqd = SkScalarMul(b,b); + if (bSqd <= SkFloatToScalar(1e-10)) { // will be true if upper left 2x2 is orthogonal, which is common, so save some math + largerRoot = SkMaxScalar(a, c); + } else { + SkScalar aminusc = a - c; + SkScalar apluscdiv2 = (a + c) / 2; + SkScalar x = SkScalarSqrt(SkScalarMul(aminusc, aminusc) + 4 * bSqd) / 2; + largerRoot = apluscdiv2 + x; + } + + stretch = SkScalarSqrt(largerRoot); + } +#if defined(SK_DEBUG) && 0 + // test a bunch of vectors. None should be scaled by more than stretch + // (modulo some error) and we should find a vector that is scaled by almost + // stretch. + SkPoint pt; + SkScalar max = 0; + for (int i = 0; i < 1000; ++i) { + SkScalar x = (float)rand() / RAND_MAX; + SkScalar y = sqrtf(1 - (x*x)); + pt.fX = fMat[kMScaleX]*x + fMat[kMSkewX]*y; + pt.fY = fMat[kMSkewY]*x + fMat[kMScaleY]*y; + SkScalar d = pt.distanceToOrigin(); + SkASSERT(d <= (1.0001 * stretch)); + if (max < pt.distanceToOrigin()) { + max = pt.distanceToOrigin(); + } + } + SkASSERT((stretch - max) < .05*stretch); +#endif + return stretch; +} + +const SkMatrix& SkMatrix::I() { + static SkMatrix gIdentity; + static bool gOnce; + if (!gOnce) { + gIdentity.reset(); + gOnce = true; + } + return gIdentity; +}; + +const SkMatrix& SkMatrix::InvalidMatrix() { + static SkMatrix gInvalid; + static bool gOnce; + if (!gOnce) { + gInvalid.setAll(SK_ScalarMax, SK_ScalarMax, SK_ScalarMax, + SK_ScalarMax, SK_ScalarMax, SK_ScalarMax, + SK_ScalarMax, SK_ScalarMax, SK_ScalarMax); + gInvalid.getType(); // force the type to be computed + gOnce = true; + } + return gInvalid; +} + +/////////////////////////////////////////////////////////////////////////////// + uint32_t SkMatrix::flatten(void* buffer) const { // TODO write less for simple matrices if (buffer) { diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp index afd5bd37ab..8818dc0b06 100644 --- a/src/gpu/SkGpuDevice.cpp +++ b/src/gpu/SkGpuDevice.cpp @@ -39,23 +39,6 @@ #define CHECK_SHOULD_DRAW(draw) this->prepareRenderTarget(draw) #endif -class SkAutoExtMatrix { -public: - SkAutoExtMatrix(const SkMatrix* extMatrix) { - if (extMatrix) { - SkGr::SkMatrix2GrMatrix(*extMatrix, &fMatrix); - fExtMatrix = &fMatrix; - } else { - fExtMatrix = NULL; - } - } - const GrMatrix* extMatrix() const { return fExtMatrix; } - -private: - GrMatrix fMatrix; - GrMatrix* fExtMatrix; // NULL or &fMatrix -}; - /////////////////////////////////////////////////////////////////////////////// SkGpuDevice::SkAutoCachedTexture:: @@ -279,9 +262,7 @@ static void convert_matrixclip(GrContext* context, const SkMatrix& matrix, const SkClipStack& clipStack, const SkRegion& clipRegion, const SkIPoint& origin) { - GrMatrix grmat; - SkGr::SkMatrix2GrMatrix(matrix, &grmat); - context->setMatrix(grmat); + context->setMatrix(matrix); SkGrClipIterator iter; iter.reset(clipStack); @@ -460,9 +441,7 @@ bool SkGpuDevice::skPaint2GrPaintShader(const SkPaint& skPaint, GrScalar s = GrFixedToScalar(GR_Fixed1 / bitmap.width()); matrix.postScale(s, s); } - GrMatrix grMat; - SkGr::SkMatrix2GrMatrix(matrix, &grMat); - grPaint->fSampler.setMatrix(grMat); + grPaint->fSampler.setMatrix(matrix); return true; } @@ -975,10 +954,7 @@ void SkGpuDevice::internalDrawBitmap(const SkDraw& draw, GrFixedToScalar((srcRect.fRight << 16) / bitmap.width()), GrFixedToScalar((srcRect.fBottom << 16) / bitmap.height())); - GrMatrix grMat; - SkGr::SkMatrix2GrMatrix(m, &grMat); - - fContext->drawRectToRect(*grPaint, dstRect, paintRect, &grMat); + fContext->drawRectToRect(*grPaint, dstRect, paintRect, &m); } void SkGpuDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap, @@ -1178,7 +1154,6 @@ void SkGpuDevice::drawText(const SkDraw& draw, const void* text, // this guy will just call our drawPath() draw.drawText((const char*)text, byteLength, x, y, paint); } else { - SkAutoExtMatrix aem(draw.fExtMatrix); SkDraw myDraw(draw); GrPaint grPaint; @@ -1187,7 +1162,7 @@ void SkGpuDevice::drawText(const SkDraw& draw, const void* text, if (!this->skPaint2GrPaintShader(paint, &act, *draw.fMatrix, &grPaint)) { return; } - GrTextContext context(fContext, grPaint, aem.extMatrix()); + GrTextContext context(fContext, grPaint, draw.fExtMatrix); myDraw.fProcs = this->initDrawForText(&context); this->INHERITED::drawText(myDraw, text, byteLength, x, y, paint); } @@ -1204,7 +1179,6 @@ void SkGpuDevice::drawPosText(const SkDraw& draw, const void* text, draw.drawPosText((const char*)text, byteLength, pos, constY, scalarsPerPos, paint); } else { - SkAutoExtMatrix aem(draw.fExtMatrix); SkDraw myDraw(draw); GrPaint grPaint; @@ -1213,7 +1187,7 @@ void SkGpuDevice::drawPosText(const SkDraw& draw, const void* text, return; } - GrTextContext context(fContext, grPaint, aem.extMatrix()); + GrTextContext context(fContext, grPaint, draw.fExtMatrix); myDraw.fProcs = this->initDrawForText(&context); this->INHERITED::drawPosText(myDraw, text, byteLength, pos, constY, scalarsPerPos, paint); |