add gpu backend (not hooked up yet)



git-svn-id: http://skia.googlecode.com/svn/trunk@649 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gpu/include/GrMatrix.h b/gpu/include/GrMatrix.h
new file mode 100644
index 0000000..43fd4a5
--- /dev/null
+++ b/gpu/include/GrMatrix.h
@@ -0,0 +1,370 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+

+#ifndef GrMatrix_DEFINED

+#define GrMatrix_DEFINED

+

+#include "GrPoint.h"

+

+struct GrRect;

+

+/*

+ * 3x3 matrix

+ */

+class GrMatrix {

+public:

+    static const GrMatrix& I();

+    static const GrScalar gRESCALE;

+    /** 

+     * 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(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(GrScalar* values) {

+        for (int i = 0; i < 9; ++i) {

+            fM[i] = values[i];

+        }

+        setTypeMask();

+    }

+    

+    /**

+     * 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;

+        

+        setTypeMask();

+    }

+    

+    /**

+     * 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);

+        }

+    }

+    

+    /**

+     *  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;

+    

+    /**

+     * 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:

+    

+    void setTypeMask();

+    

+    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;

+        }

+    }

+}

+

+#endif