From: bsalomon@google.com Date: Thu, 17 Feb 2011 16:43:10 +0000 (+0000) Subject: Hide alloc size vs content size below API X-Git-Tag: accepted/tizen/5.0/unified/20181102.025319~18962 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c6cf72381b212eb21e61d5c5e14247b483a77753;p=platform%2Fupstream%2FlibSkiaSharp.git Hide alloc size vs content size below API Remove old gl shaders class Move texture matrix to sampler class git-svn-id: http://skia.googlecode.com/svn/trunk@808 2bbb7eff-a529-9590-31e7-b0007b416f81 --- diff --git a/gpu/include/GrDrawTarget.h b/gpu/include/GrDrawTarget.h index 91af9ce..9c78902 100644 --- a/gpu/include/GrDrawTarget.h +++ b/gpu/include/GrDrawTarget.h @@ -39,12 +39,12 @@ public: * no per-vertex colors. For subsequent stages the input color is the output * color from the previous enabled stage. The output color of each stage is * the input color modulated with the result of a texture lookup. Texture - * lookups are specified by a texture (setTexture), a texture matrix - * (setTextureMatrix), and a sampler (setSamplerState). Texture coordinates - * for each stage come from the vertices based on a GrVertexLayout bitfield. - * The output fragment color is the output color of the last enabled stage. - * The presence or absence of texture coordinates for each stage in the - * vertex layout indicates whether a stage is enabled or not. + * lookups are specified by a texture a sampler (setSamplerState). Texture + * coordinates for each stage come from the vertices based on a + * GrVertexLayout bitfield. The output fragment color is the output color of + * the last enabled stage. The presence or absence of texture coordinates + * for each stage in the vertex layout indicates whether a stage is enabled + * or not. */ enum { kNumStages = 2, @@ -145,16 +145,15 @@ protected: struct DrState { uint32_t fFlagBits; - BlendCoeff fSrcBlend; - BlendCoeff fDstBlend; - GrTexture* fTextures[kNumStages]; - GrSamplerState fSamplerStates[kNumStages]; - GrRenderTarget* fRenderTarget; - GrColor fColor; + BlendCoeff fSrcBlend; + BlendCoeff fDstBlend; + GrTexture* fTextures[kNumStages]; + GrSamplerState fSamplerStates[kNumStages]; + GrRenderTarget* fRenderTarget; + GrColor fColor; StencilPass fStencilPass; bool fReverseFill; GrMatrix fViewMatrix; - GrMatrix fTextureMatrices[kNumStages]; bool operator ==(const DrState& s) const { return 0 == memcmp(this, &s, sizeof(DrState)); } @@ -217,49 +216,46 @@ public: GrRenderTarget* getRenderTarget(); /** - * Sets the sampler state for the next draw. + * Sets the sampler state for a stage used in subsequent draws. * - * The sampler state determines the address wrap modes and - * filtering + * The sampler state determines how texture coordinates are + * intepretted and used to sample the texture. * + * @param stage the stage of the sampler to set * @param samplerState Specifies the sampler state. */ void setSamplerState(int stage, const GrSamplerState& samplerState); /** - * Sets the matrix applied to texture coordinates for a stage. - * - * The post-matrix texture coordinates in the square [0,1]^2 cover the - * entire area of the texture. This means the full POT width when a NPOT - * texture is embedded in a POT width texture to meet the 3D API - * requirements. The texture matrix is applied both when the texture - * coordinates are explicit and when vertex positions are used as texture - * coordinates. In the latter case the texture matrix is applied to the - * pre-view-matrix position values. - * - * @param stage the stage for which to set a matrix. - * @param m the matrix used to transform the texture coordinates. + * Concats the matrix of a stage's sampler. + * + * @param stage the stage of the sampler to set + * @param matrix the matrix to concat */ - void setTextureMatrix(int stage, const GrMatrix& m); + void preConcatSamplerMatrix(int stage, const GrMatrix& matrix) { + GrAssert(stage >= 0 && stage < kNumStages); + fCurrDrawState.fSamplerStates[stage].preConcatMatrix(matrix); + } /** - * Multiplies the current texture matrix for a stage by a matrix - * - * After this call T' = T*m where T is the old tex matrix, - * m is the parameter to this function, and T' is the new tex matrix. - * (We consider positions to be column vectors so tex cood vector t is - * transformed by matrix X as t' = X*t.) + * Gets the matrix of a stage's sampler * - * @param m the matrix used to modify the texture matrix matrix. + * @param stage the stage to of sampler to get + * @return the sampler state's matrix */ - void concatTextureMatrix(int stage, const GrMatrix& m); + const GrMatrix& getSamplerMatrix(int stage) const { + return fCurrDrawState.fSamplerStates[stage].getMatrix(); + } /** - * Retrieves the current texture matrix for a stage - * @param stage index of stage - * @return the stage's current texture matrix. + * Sets the matrix of a stage's sampler + * + * @param stage the stage of sampler set + * @param matrix the matrix to set */ - const GrMatrix& getTextureMatrix(int stage) const; + const void setSamplerMatrix(int stage, const GrMatrix& matrix) { + fCurrDrawState.fSamplerStates[stage].setMatrix(matrix); + } /** * Sets the matrix applied to veretx positions. @@ -282,7 +278,7 @@ public: * * @param m the matrix used to modify the view matrix. */ - void concatViewMatrix(const GrMatrix& m); + void preConcatViewMatrix(const GrMatrix& m); /** * Retrieves the current view matrix diff --git a/gpu/include/GrGLTexture.h b/gpu/include/GrGLTexture.h index 165320f..6f1b961 100644 --- a/gpu/include/GrGLTexture.h +++ b/gpu/include/GrGLTexture.h @@ -142,6 +142,30 @@ public: GLenum uploadByteCount() const { return fUploadByteCount; } GLenum uploadType() const { return fUploadType; } + /** + * Retrieves the texture width actually allocated in texels. + * + * @return the width in texels + */ + int allocWidth() const { return fAllocWidth; } + + /** + * Retrieves the texture height actually allocated in texels. + * + * @return the height in texels + */ + int allocHeight() const { return fAllocHeight; } + + /** + * @return width() / allocWidth() + */ + GrScalar contentScaleX() const { return fScaleX; } + + /** + * @return height() / allocHeight() + */ + GrScalar contentScaleY() const { return fScaleY; } + // Ganesh assumes texture coordinates have their origin // in the top-left corner of the image. OpenGL, however, // has the origin in the lower-left corner. For content that @@ -158,10 +182,15 @@ private: GLenum fUploadFormat; GLenum fUploadByteCount; GLenum fUploadType; + int fAllocWidth; + int fAllocHeight; + // precomputed content / alloc ratios + GrScalar fScaleX; + GrScalar fScaleY; Orientation fOrientation; - GrGLRenderTarget* fRenderTarget; + GrGLRenderTarget* fRenderTarget; GrGpuGL* fGpuGL; - + static const GLenum gWrapMode2GLWrap[]; friend class GrGpuGL; diff --git a/gpu/include/GrMatrix.h b/gpu/include/GrMatrix.h index 43fd4a5..9a2e660 100644 --- a/gpu/include/GrMatrix.h +++ b/gpu/include/GrMatrix.h @@ -14,357 +14,387 @@ 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; - } - } -} - + +#ifndef GrMatrix_DEFINED +#define GrMatrix_DEFINED + +#include "GrPoint.h" + +struct GrRect; + +/* + * 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); + } + } + + /** + * 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: + 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; + } + } +} + #endif diff --git a/gpu/include/GrPaint.h b/gpu/include/GrPaint.h index 23902a8..770647a 100644 --- a/gpu/include/GrPaint.h +++ b/gpu/include/GrPaint.h @@ -36,7 +36,6 @@ public: GrColor fColor; - GrMatrix fTextureMatrix; GrSamplerState fSampler; void setTexture(GrTexture* texture) { @@ -60,7 +59,6 @@ public: fColor = paint.fColor; - fTextureMatrix = paint.fTextureMatrix; fSampler = paint.fSampler; fTexture = paint.fTexture; GrSafeRef(fTexture); @@ -97,7 +95,6 @@ private: void resetTexture() { setTexture(NULL); - fTextureMatrix = GrMatrix::I(); fSampler.setClampNoFilter(); } diff --git a/gpu/include/GrSamplerState.h b/gpu/include/GrSamplerState.h index 9715c45..910bc74 100644 --- a/gpu/include/GrSamplerState.h +++ b/gpu/include/GrSamplerState.h @@ -19,9 +19,32 @@ #define GrSamplerState_DEFINED #include "GrTypes.h" +#include "GrMatrix.h" class GrSamplerState { public: + /** + * The intepretation of the texture matrix depends on the sample mode. The + * texture matrix is applied both when the texture coordinates are explicit + * and when vertex positions are used as texture coordinates. In the latter + * case the texture matrix is applied to the pre-view-matrix position + * values. + * + * kNormal_SampleMode + * The post-matrix texture coordinates are in normalize space with (0,0) at + * the top-left and (1,1) at the bottom right. + * kRadial_SampleMode + * The matrix specifies the radial gradient parameters. + * (0,0) in the post-matrix space is center of the radial gradient. + * kRadial2_SampleMode + * Matrix transforms to space where first circle is centered at the + * origin. The second circle will be centered (x, 0) where x may be + * 0 and is provided by setRadial2Params. The post-matrix space is + * normalized such that 1 is the second radius - first radius. + * kSweepSampleMode + * The angle from the origin of texture coordinates in post-matrix space + * determines the gradient value. + */ enum SampleMode { kNormal_SampleMode, //!< sample color directly kRadial_SampleMode, //!< treat as radial gradient @@ -40,7 +63,8 @@ public: }; /** - * Default sampler state is set to kClamp and no-filter + * Default sampler state is set to clamp, use normal sampling mode, be + * unfiltered, and use identity matrix. */ GrSamplerState() { this->setClampNoFilter(); @@ -51,6 +75,7 @@ public: fWrapY = kClamp_WrapMode; fSampleMode = kNormal_SampleMode; fFilter = filter; + fMatrix.setIdentity(); } GrSamplerState(WrapMode wx, WrapMode wy, bool filter) { @@ -58,18 +83,29 @@ public: fWrapY = wy; fSampleMode = kNormal_SampleMode; fFilter = filter; + fMatrix.setIdentity(); + } + + GrSamplerState(WrapMode wx, WrapMode wy, const GrMatrix& matrix, bool filter) { + fWrapX = wx; + fWrapY = wy; + fSampleMode = kNormal_SampleMode; + fFilter = filter; + fMatrix = matrix; } - GrSamplerState(WrapMode wx, WrapMode wy, SampleMode sample, bool filter) { + GrSamplerState(WrapMode wx, WrapMode wy, SampleMode sample, const GrMatrix& matrix, bool filter) { fWrapX = wx; fWrapY = wy; fSampleMode = sample; + fMatrix = matrix; fFilter = filter; } WrapMode getWrapX() const { return fWrapX; } WrapMode getWrapY() const { return fWrapY; } SampleMode getSampleMode() const { return fSampleMode; } + const GrMatrix& getMatrix() const { return fMatrix; } bool isFilter() const { return fFilter; } bool isGradient() const { @@ -81,6 +117,30 @@ public: void setWrapX(WrapMode mode) { fWrapX = mode; } void setWrapY(WrapMode mode) { fWrapY = mode; } void setSampleMode(SampleMode mode) { fSampleMode = mode; } + + /** + * Sets the sampler's matrix. See SampleMode for explanation of + * relationship between the matrix and sample mode. + * @param matrix the matrix to set + */ + void setMatrix(const GrMatrix& matrix) { fMatrix = matrix; } + + /** + * Multiplies the current sampler matrix a matrix + * + * After this call M' = M*m where M is the old matrix, m is the parameter + * to this function, and M' is the new matrix. (We consider points to + * be column vectors so tex cood vector t is transformed by matrix X as + * t' = X*t.) + * + * @param matrix the matrix used to modify the matrix. + */ + void preConcatMatrix(const GrMatrix& matrix) { fMatrix.preConcat(matrix); } + + /** + * Enables or disables filtering. + * @param filter indicates whether filtering is applied. + */ void setFilter(bool filter) { fFilter = filter; } void setClampNoFilter() { @@ -88,6 +148,7 @@ public: fWrapY = kClamp_WrapMode; fSampleMode = kNormal_SampleMode; fFilter = false; + fMatrix.setIdentity(); } GrScalar getRadial2CenterX1() const { return fRadial2CenterX1; } @@ -116,6 +177,7 @@ private: WrapMode fWrapY; SampleMode fSampleMode; bool fFilter; + GrMatrix fMatrix; // these are undefined unless fSampleMode == kRadial2_SampleMode GrScalar fRadial2CenterX1; diff --git a/gpu/include/GrTexture.h b/gpu/include/GrTexture.h index 4776539..5b3ed09 100644 --- a/gpu/include/GrTexture.h +++ b/gpu/include/GrTexture.h @@ -65,58 +65,39 @@ public: static bool PixelConfigIsOpaque(PixelConfig); protected: - GrTexture(uint32_t contentWidth, - uint32_t contentHeight, - uint32_t allocWidth, - uint32_t allocHeight, + GrTexture(int width, + int height, PixelConfig config) : - fAllocWidth(allocWidth), - fAllocHeight(allocHeight), - fContentWidth(contentWidth), - fContentHeight(contentHeight), + fWidth(width), + fHeight(height), fConfig(config) { // only make sense if alloc size is pow2 - fShiftFixedX = 31 - Gr_clz(allocWidth); - fShiftFixedY = 31 - Gr_clz(allocHeight); + fShiftFixedX = 31 - Gr_clz(fWidth); + fShiftFixedY = 31 - Gr_clz(fHeight); } public: virtual ~GrTexture(); /** - * Retrieves the width of the content area of the texture. Reflects the - * width passed to GrGpu::createTexture(). + * Retrieves the width of the texture. * * @return the width in texels */ - uint32_t contentWidth() const { return fContentWidth; } + int width() const { return fWidth; } /** - * Retrieves the height of the content area of the texture. Reflects the - * height passed to GrGpu::createTexture(). + * Retrieves the height of the texture. * * @return the height in texels */ - uint32_t contentHeight() const { return fContentHeight; } - - /** - * Retrieves the texture width actually allocated in texels. - * - * @return the width in texels - */ - uint32_t allocWidth() const { return fAllocWidth; } - /** - * Retrieves the texture height actually allocated in texels. - * - * @return the height in texels - */ - uint32_t allocHeight() const { return fAllocHeight; } + int height() const { return fHeight; } /** * Convert from texels to normalized texture coords for POT textures * only. */ - GrFixed normalizeFixedX(GrFixed x) const { GrAssert(GrIsPow2(fAllocWidth)); + GrFixed normalizeFixedX(GrFixed x) const { GrAssert(GrIsPow2(fWidth)); return x >> fShiftFixedX; } - GrFixed normalizeFixedY(GrFixed y) const { GrAssert(GrIsPow2(fAllocHeight)); + GrFixed normalizeFixedY(GrFixed y) const { GrAssert(GrIsPow2(fHeight)); return y >> fShiftFixedY; } /** @@ -125,10 +106,10 @@ public: PixelConfig config() const { return fConfig; } /** - * The number of bytes used by the texture + * Approximate number of bytes used by the texture */ size_t sizeInBytes() const { - return fAllocWidth * fAllocHeight * BytesPerPixel(fConfig); + return fWidth * fHeight * BytesPerPixel(fConfig); } /** @@ -195,10 +176,8 @@ public: #endif private: - uint32_t fAllocWidth; - uint32_t fAllocHeight; - uint32_t fContentWidth; - uint32_t fContentHeight; + int fWidth; + int fHeight; // these two shift a fixed-point value into normalized coordinates // for this texture if the texture is power of two sized. int fShiftFixedX; diff --git a/gpu/include/GrUserConfig.h b/gpu/include/GrUserConfig.h index 4d44172..819f093 100644 --- a/gpu/include/GrUserConfig.h +++ b/gpu/include/GrUserConfig.h @@ -77,9 +77,6 @@ * temporary flags (may go away soon) */ -// disable 2-point-radial gradient shader programs -//#define GR_SKIP_2POINTRADIAL_PROGRAMS - /////////////////////////////////////////////////////////////////////////////// // Decide Ganesh types diff --git a/gpu/src/GrContext.cpp b/gpu/src/GrContext.cpp index ad7f776..0423483 100644 --- a/gpu/src/GrContext.cpp +++ b/gpu/src/GrContext.cpp @@ -129,7 +129,6 @@ GrTextureEntry* GrContext::createAndLockTexture(GrTextureKey* key, return NULL; } } - GrTexture* clampTexture = clampEntry->texture(); GrGpu::TextureDesc rtDesc = desc; rtDesc.fFlags |= GrGpu::kRenderTarget_TextureFlag | GrGpu::kNoPathRendering_TextureFlag; @@ -145,7 +144,6 @@ GrTextureEntry* GrContext::createAndLockTexture(GrTextureKey* key, fGpu->setRenderTarget(texture->asRenderTarget()); fGpu->setTexture(0, clampEntry->texture()); fGpu->setStencilPass(GrDrawTarget::kNone_StencilPass); - fGpu->setTextureMatrix(0, GrMatrix::I()); fGpu->setViewMatrix(GrMatrix::I()); fGpu->setAlpha(0xff); fGpu->setBlendFunc(GrDrawTarget::kOne_BlendCoeff, GrDrawTarget::kZero_BlendCoeff); @@ -164,16 +162,10 @@ GrTextureEntry* GrContext::createAndLockTexture(GrTextureKey* key, if (arg.succeeded()) { GrPoint* verts = (GrPoint*) arg.vertices(); verts[0].setIRectFan(0, 0, - texture->contentWidth(), - texture->contentHeight(), + texture->width(), + texture->height(), 2*sizeof(GrPoint)); - GrScalar tw = GrFixedToScalar(GR_Fixed1 * - clampTexture->contentWidth() / - clampTexture->allocWidth()); - GrScalar th = GrFixedToScalar(GR_Fixed1 * - clampTexture->contentHeight() / - clampTexture->allocHeight()); - verts[1].setRectFan(0, 0, tw, th, 2*sizeof(GrPoint)); + verts[1].setIRectFan(0, 0, 1, 1, 2*sizeof(GrPoint)); fGpu->drawNonIndexed(GrDrawTarget::kTriangleFan_PrimitiveType, 0, 4); entry = fTextureCache->createAndLock(*key, texture); @@ -377,8 +369,8 @@ void GrContext::drawRect(const GrPaint& paint, GrDrawTarget::AutoViewMatrixRestore avmr; if (NULL != matrix) { avmr.set(target); - target->concatViewMatrix(*matrix); - target->concatTextureMatrix(0, *matrix); + target->preConcatViewMatrix(*matrix); + target->preConcatSamplerMatrix(0, *matrix); } target->drawNonIndexed(primType, 0, vertCount); @@ -399,10 +391,10 @@ void GrContext::drawRect(const GrPaint& paint, m.postConcat(*matrix); } - target->concatViewMatrix(m); + target->preConcatViewMatrix(m); if (textured) { - target->concatTextureMatrix(0, m); + target->preConcatSamplerMatrix(0, m); } target->drawNonIndexed(GrDrawTarget::kTriangleFan_PrimitiveType, 0, 4); #else @@ -438,7 +430,7 @@ void GrContext::drawRectToRect(const GrPaint& paint, if (NULL != dstMatrix) { m.postConcat(*dstMatrix); } - target->concatViewMatrix(m); + target->preConcatViewMatrix(m); m.setAll(srcRect.width(), 0, srcRect.fLeft, 0, srcRect.height(), srcRect.fTop, @@ -446,7 +438,7 @@ void GrContext::drawRectToRect(const GrPaint& paint, if (NULL != srcMatrix) { m.postConcat(*srcMatrix); } - target->concatTextureMatrix(0, m); + target->preConcatSamplerMatrix(0, m); target->setVertexSourceToBuffer(layout, fGpu->getUnitSquareVertexBuffer()); target->drawNonIndexed(GrDrawTarget::kTriangleFan_PrimitiveType, 0, 4); @@ -921,16 +913,18 @@ void GrContext::writePixels(int left, int top, int width, int height, GrMatrix matrix; matrix.setTranslate(GrIntToScalar(left), GrIntToScalar(top)); fGpu->setViewMatrix(matrix); - matrix.setScale(GR_Scalar1 / texture->allocWidth(), - GR_Scalar1 / texture->allocHeight()); - fGpu->setTextureMatrix(0, matrix); fGpu->disableState(GrDrawTarget::kClip_StateBit); fGpu->setAlpha(0xFF); fGpu->setBlendFunc(GrDrawTarget::kOne_BlendCoeff, GrDrawTarget::kZero_BlendCoeff); fGpu->setTexture(0, texture); - fGpu->setSamplerState(0, GrSamplerState::ClampNoFilter()); + + GrSamplerState sampler; + sampler.setClampNoFilter(); + matrix.setScale(GR_Scalar1 / width, GR_Scalar1 / height); + sampler.setMatrix(matrix); + fGpu->setSamplerState(0, sampler); GrVertexLayout layout = GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(0); static const int VCOUNT = 4; @@ -946,7 +940,6 @@ void GrContext::writePixels(int left, int top, int width, int height, void GrContext::SetPaint(const GrPaint& paint, GrDrawTarget* target) { target->setTexture(0, paint.getTexture()); - target->setTextureMatrix(0, paint.fTextureMatrix); target->setSamplerState(0, paint.fSampler); target->setColor(paint.fColor); @@ -1019,7 +1012,7 @@ void GrContext::setMatrix(const GrMatrix& m) { } void GrContext::concatMatrix(const GrMatrix& m) const { - fGpu->concatViewMatrix(m); + fGpu->preConcatViewMatrix(m); } static inline intptr_t setOrClear(intptr_t bits, int shift, intptr_t pred) { diff --git a/gpu/src/GrDrawTarget.cpp b/gpu/src/GrDrawTarget.cpp index 06e5ab8b..63e59c4 100644 --- a/gpu/src/GrDrawTarget.cpp +++ b/gpu/src/GrDrawTarget.cpp @@ -331,7 +331,7 @@ void GrDrawTarget::setViewMatrix(const GrMatrix& m) { fCurrDrawState.fViewMatrix = m; } -void GrDrawTarget::concatViewMatrix(const GrMatrix& matrix) { +void GrDrawTarget::preConcatViewMatrix(const GrMatrix& matrix) { fCurrDrawState.fViewMatrix.preConcat(matrix); } @@ -358,21 +358,6 @@ void GrDrawTarget::setSamplerState(int stage, const GrSamplerState& state) { fCurrDrawState.fSamplerStates[stage] = state; } -void GrDrawTarget::setTextureMatrix(int stage, const GrMatrix& m) { - GrAssert(stage >= 0 && stage < kNumStages); - fCurrDrawState.fTextureMatrices[stage] = m; -} - -void GrDrawTarget::concatTextureMatrix(int stage, const GrMatrix& m) { - GrAssert(stage >= 0 && stage < kNumStages); - fCurrDrawState.fTextureMatrices[stage].preConcat(m); -} - -const GrMatrix& GrDrawTarget::getTextureMatrix(int stage) const { - GrAssert(stage >= 0 && stage < kNumStages); - return fCurrDrawState.fTextureMatrices[stage]; -} - void GrDrawTarget::setStencilPass(StencilPass pass) { fCurrDrawState.fStencilPass = pass; } diff --git a/gpu/src/GrGLTexture.cpp b/gpu/src/GrGLTexture.cpp index 9460086..110535f 100644 --- a/gpu/src/GrGLTexture.cpp +++ b/gpu/src/GrGLTexture.cpp @@ -76,20 +76,25 @@ const GLenum GrGLTexture::gWrapMode2GLWrap[] = { GrGLTexture::GrGLTexture(const GLTextureDesc& textureDesc, const GLRenderTargetIDs& rtIDs, const TexParams& initialTexParams, - GrGpuGL* gl) : - INHERITED(textureDesc.fContentWidth, - textureDesc.fContentHeight, - textureDesc.fAllocWidth, - textureDesc.fAllocHeight, - textureDesc.fFormat), - fTexParams(initialTexParams), - fTextureID(textureDesc.fTextureID), - fUploadFormat(textureDesc.fUploadFormat), - fUploadByteCount(textureDesc.fUploadByteCount), - fUploadType(textureDesc.fUploadType), - fOrientation(textureDesc.fOrientation), - fRenderTarget(NULL), - fGpuGL(gl) { + GrGpuGL* gl) + : INHERITED(textureDesc.fContentWidth, + textureDesc.fContentHeight, + textureDesc.fFormat) { + + fTexParams = initialTexParams; + fTextureID = textureDesc.fTextureID; + fUploadFormat = textureDesc.fUploadFormat; + fUploadByteCount = textureDesc.fUploadByteCount; + fUploadType = textureDesc.fUploadType; + fOrientation = textureDesc.fOrientation; + fAllocWidth = textureDesc.fAllocWidth; + fAllocHeight = textureDesc.fAllocHeight; + fScaleX = GrIntToScalar(textureDesc.fContentWidth) / + textureDesc.fAllocWidth; + fScaleY = GrIntToScalar(textureDesc.fContentHeight) / + textureDesc.fAllocHeight; + fRenderTarget = NULL; + fGpuGL = gl; GrAssert(0 != textureDesc.fTextureID); @@ -135,7 +140,7 @@ void GrGLTexture::removeRenderTarget() { // must do this notify before the delete fGpuGL->notifyTextureRemoveRenderTarget(this); delete fRenderTarget; - fRenderTarget = NULL; + fRenderTarget = NULL; } } diff --git a/gpu/src/GrGpu.cpp b/gpu/src/GrGpu.cpp index 5425b58..57d313c 100644 --- a/gpu/src/GrGpu.cpp +++ b/gpu/src/GrGpu.cpp @@ -427,6 +427,7 @@ const GrSamplerState GrSamplerState::gClampNoFilter( GrSamplerState::kClamp_WrapMode, GrSamplerState::kClamp_WrapMode, GrSamplerState::kNormal_SampleMode, + GrMatrix::I(), false); diff --git a/gpu/src/GrGpuFactory.cpp b/gpu/src/GrGpuFactory.cpp index 5e61609..2298776 100644 --- a/gpu/src/GrGpuFactory.cpp +++ b/gpu/src/GrGpuFactory.cpp @@ -24,18 +24,13 @@ #include "GrGLConfig.h" -#define GR_USE_GLSHADERS2 1 #if GR_SUPPORT_GLES1 || GR_SUPPORT_GLDESKTOP #include "GrGpuGLFixed.h" #endif #if GR_SUPPORT_GLES2 || GR_SUPPORT_GLDESKTOP - #if GR_USE_GLSHADERS2 - #include "GrGpuGLShaders2.h" - #else - #include "GrGpuGLShaders.h" - #endif + #include "GrGpuGLShaders2.h" #endif #include "GrGpu.h" @@ -47,11 +42,7 @@ GrGpu* GrGpu::Create(Engine engine, Platform3DContext context3D) { case kOpenGL_Shaders_Engine: GrAssert(NULL == context3D); #if GR_SUPPORT_GLES2 || GR_SUPPORT_GLDESKTOP - #if GR_USE_GLSHADERS2 gpu = new GrGpuGLShaders2; - #else - gpu = new GrGpuGLShaders; - #endif #endif break; case kOpenGL_Fixed_Engine: diff --git a/gpu/src/GrGpuGL.cpp b/gpu/src/GrGpuGL.cpp index 8d00af9..ba13372 100644 --- a/gpu/src/GrGpuGL.cpp +++ b/gpu/src/GrGpuGL.cpp @@ -49,6 +49,58 @@ static const GLenum gXfermodeCoeff2Blend[] = { /////////////////////////////////////////////////////////////////////////////// +void GrGpuGL::AdjustTextureMatrix(const GrGLTexture* texture, + GrSamplerState::SampleMode mode, + GrMatrix* matrix) { + GrAssert(NULL != texture); + GrAssert(NULL != matrix); + if (GR_Scalar1 != texture->contentScaleX() || + GR_Scalar1 != texture->contentScaleY()) { + if (GrSamplerState::kRadial_SampleMode == mode) { + GrMatrix scale; + scale.setScale(texture->contentScaleX(), texture->contentScaleX()); + matrix->postConcat(scale); + } else if (GrSamplerState::kNormal_SampleMode == mode) { + GrMatrix scale; + scale.setScale(texture->contentScaleX(), texture->contentScaleY()); + matrix->postConcat(scale); + } else { + GrPrintf("We haven't handled NPOT adjustment for other sample modes!"); + } + } + GrGLTexture::Orientation orientation = texture->orientation(); + if (GrGLTexture::kBottomUp_Orientation == orientation) { + GrMatrix invY; + invY.setAll(GR_Scalar1, 0, 0, + 0, -GR_Scalar1, GR_Scalar1, + 0, 0, GrMatrix::I()[8]); + matrix->postConcat(invY); + } else { + GrAssert(GrGLTexture::kTopDown_Orientation == orientation); + } +} + +bool GrGpuGL::TextureMatrixIsIdentity(const GrGLTexture* texture, + const GrSamplerState& sampler) { + GrAssert(NULL != texture); + if (!sampler.getMatrix().isIdentity()) { + return false; + } + if (GR_Scalar1 != texture->contentScaleX() || + GR_Scalar1 != texture->contentScaleY()) { + return false; + } + GrGLTexture::Orientation orientation = texture->orientation(); + if (GrGLTexture::kBottomUp_Orientation == orientation) { + return false; + } else { + GrAssert(GrGLTexture::kTopDown_Orientation == orientation); + } + return true; +} + +/////////////////////////////////////////////////////////////////////////////// + static bool gPrintStartupSpew; @@ -102,8 +154,7 @@ GrGpuGL::GrGpuGL() { resetContextHelper(); - fHWDrawState.fRenderTarget = NULL; - fRenderTargetChanged = true; + resetDirtyFlags(); GLint maxTextureUnits; // check FS and fixed-function texture unit limits @@ -265,6 +316,7 @@ GrGpuGL::GrGpuGL() { fNPOTTextureTileSupport = false; } #endif + //////////////////////////////////////////////////////////////////////////// // Experiments to determine limitations that can't be queried. TODO: Make // these a preprocess that generate some compile time constants. @@ -395,14 +447,15 @@ void GrGpuGL::resetContextHelper() { fHWDrawState.fDstBlend = (BlendCoeff)-1; fHWDrawState.fColor = GrColor_ILLEGAL; - fHWDrawState.fViewMatrix.setScale(GR_ScalarMax, GR_ScalarMax); // illegal + fHWDrawState.fViewMatrix = GrMatrix::InvalidMatrix(); for (int s = 0; s < kNumStages; ++s) { fHWDrawState.fTextures[s] = NULL; fHWDrawState.fSamplerStates[s].setRadial2Params(-GR_ScalarMax, -GR_ScalarMax, true); - fHWDrawState.fTextureMatrices[s].setScale(GR_ScalarMax, GR_ScalarMax); + + fHWDrawState.fSamplerStates[s].setMatrix(GrMatrix::InvalidMatrix()); } GR_GL(Scissor(0,0,0,0)); @@ -1017,7 +1070,7 @@ void GrGpuGL::eraseColor(GrColor color) { GrColorUnpackB(color)/255.f, GrColorUnpackA(color)/255.f)); GR_GL(Clear(GL_COLOR_BUFFER_BIT)); - fWriteMaskChanged = true; + fDirtyFlags.fWriteMaskChanged = true; } void GrGpuGL::eraseStencil(uint32_t value, uint32_t mask) { @@ -1032,7 +1085,7 @@ void GrGpuGL::eraseStencil(uint32_t value, uint32_t mask) { GR_GL(StencilMask(mask)); GR_GL(ClearStencil(value)); GR_GL(Clear(GL_STENCIL_BUFFER_BIT)); - fWriteMaskChanged = true; + fDirtyFlags.fWriteMaskChanged = true; } void GrGpuGL::eraseStencilClip() { @@ -1107,7 +1160,7 @@ void GrGpuGL::flushRenderTarget() { #endif fHWDrawState.fRenderTarget = fCurrDrawState.fRenderTarget; const GrIRect& vp = rt->viewport(); - fRenderTargetChanged = true; + fDirtyFlags.fRenderTargetChanged = true; if (fHWBounds.fViewportRect != vp) { GR_GL(Viewport(vp.fLeft, vp.fBottom, @@ -1181,10 +1234,10 @@ void GrGpuGL::resolveTextureRenderTarget(GrGLTexture* texture) { fHWDrawState.fRenderTarget = NULL; GLint left = 0; - GLint right = texture->contentWidth(); + GLint right = texture->width(); // we will have rendered to the top of the FBO. GLint top = texture->allocHeight(); - GLint bottom = texture->allocHeight() - texture->contentHeight(); + GLint bottom = texture->allocHeight() - texture->height(); if (kApple_MSFBO == fMSFBOType) { GR_GL(Enable(GL_SCISSOR_TEST)); GR_GL(Scissor(left, bottom, right-left, top-bottom)); @@ -1208,7 +1261,7 @@ void GrGpuGL::flushStencil() { bool stencilClip = fClipState.fClipInStencil && (kClip_StateBit & fCurrDrawState.fFlagBits); bool stencilChange = - fWriteMaskChanged || + fDirtyFlags.fWriteMaskChanged || fHWStencilClip != stencilClip || fHWDrawState.fStencilPass != fCurrDrawState.fStencilPass || (kNone_StencilPass != fCurrDrawState.fStencilPass && @@ -1399,7 +1452,6 @@ void GrGpuGL::flushStencil() { } fHWDrawState.fStencilPass = fCurrDrawState.fStencilPass; fHWDrawState.fReverseFill = fCurrDrawState.fReverseFill; - fWriteMaskChanged = false; fHWStencilClip = stencilClip; } } @@ -1468,6 +1520,10 @@ bool GrGpuGL::flushGLStateCommon(PrimitiveType type) { newTexParams.fWrapT)); } nextTexture->setTexParams(newTexParams); + + // The texture matrix has to compensate for texture width/height + // and NPOT-embedded-in-POT + fDirtyFlags.fTextureChangedMask |= (1 << s); } else { GrAssert(!"Rendering with texture vert flag set but no texture"); return false; @@ -1489,7 +1545,7 @@ bool GrGpuGL::flushGLStateCommon(PrimitiveType type) { #if GR_SUPPORT_GLDESKTOP // ES doesn't support toggling GL_MULTISAMPLE and doesn't have // smooth lines. - if (fRenderTargetChanged || + if (fDirtyFlags.fRenderTargetChanged || (fCurrDrawState.fFlagBits & kAntialias_StateBit) != (fHWDrawState.fFlagBits & kAntialias_StateBit)) { GLint msaa = 0; @@ -1712,6 +1768,10 @@ bool GrGpuGL::fboInternalFormat(GrTexture::PixelConfig config, GLenum* format) { } } +void GrGpuGL::resetDirtyFlags() { + Gr_bzero(&fDirtyFlags, sizeof(fDirtyFlags)); +} + void GrGpuGL::setBuffers(bool indexed, int* extraVertexOffset, int* extraIndexOffset) { diff --git a/gpu/src/GrGpuGL.h b/gpu/src/GrGpuGL.h index d89b8d5..a2ccc12 100644 --- a/gpu/src/GrGpuGL.h +++ b/gpu/src/GrGpuGL.h @@ -71,6 +71,26 @@ protected: DrState fHWDrawState; bool fHWStencilClip; + // As flush of GL state proceeds it updates fHDrawState + // to reflect the new state. Later parts of the state flush + // may perform cascaded changes but cannot refer to fHWDrawState. + // These code paths can refer to the dirty flags. Subclass should + // call resetDirtyFlags after its flush is complete + struct { + bool fRenderTargetChanged : 1; + bool fWriteMaskChanged : 1; + int fTextureChangedMask; + } fDirtyFlags; + GR_STATIC_ASSERT(8 * sizeof(int) >= kNumStages); + + // clears the dirty flags + void resetDirtyFlags(); + + // last scissor / viewport scissor state seen by the GL. + BoundsState fHWBounds; + + GrGLExts fExts; + // GrGpu overrides virtual void drawIndexedHelper(PrimitiveType type, uint32_t startVertex, @@ -103,18 +123,16 @@ protected: // line width bool flushGLStateCommon(PrimitiveType type); - // set when this class changes the rendertarget. - // Subclass should notice at flush time, take appropriate action, - // and set false. - bool fRenderTargetChanged; - - // set by eraseColor or eraseStencil. Picked up in in flushStencil. - bool fWriteMaskChanged; - - // last scissor / viewport scissor state seen by the GL. - BoundsState fHWBounds; + // adjusts texture matrix to account for orientation, size, and npotness + static void AdjustTextureMatrix(const GrGLTexture* texture, + GrSamplerState::SampleMode mode, + GrMatrix* matrix); - GrGLExts fExts; + // subclass may try to take advantage of identity tex matrices. + // This helper determines if matrix will be identity after all + // adjustments are applied. + static bool TextureMatrixIsIdentity(const GrGLTexture* texture, + const GrSamplerState& sampler); private: void resetContextHelper(); diff --git a/gpu/src/GrGpuGLFixed.cpp b/gpu/src/GrGpuGLFixed.cpp index 76494de..efb0990 100644 --- a/gpu/src/GrGpuGLFixed.cpp +++ b/gpu/src/GrGpuGLFixed.cpp @@ -25,7 +25,7 @@ #define SKIP_CACHE_CHECK true struct GrGpuMatrix { - GrScalar fMat[16]; + GLfloat fMat[16]; void reset() { Gr_bzero(fMat, sizeof(fMat)); @@ -34,19 +34,19 @@ struct GrGpuMatrix { void set(const GrMatrix& m) { Gr_bzero(fMat, sizeof(fMat)); - fMat[0] = m[GrMatrix::kScaleX]; - fMat[4] = m[GrMatrix::kSkewX]; - fMat[12] = m[GrMatrix::kTransX]; + fMat[0] = GrScalarToFloat(m[GrMatrix::kScaleX]); + fMat[4] = GrScalarToFloat(m[GrMatrix::kSkewX]); + fMat[12] = GrScalarToFloat(m[GrMatrix::kTransX]); - fMat[1] = m[GrMatrix::kSkewY]; - fMat[5] = m[GrMatrix::kScaleY]; - fMat[13] = m[GrMatrix::kTransY]; + fMat[1] = GrScalarToFloat(m[GrMatrix::kSkewY]); + fMat[5] = GrScalarToFloat(m[GrMatrix::kScaleY]); + fMat[13] = GrScalarToFloat(m[GrMatrix::kTransY]); - fMat[3] = m[GrMatrix::kPersp0]; - fMat[7] = m[GrMatrix::kPersp1]; - fMat[15] = m[GrMatrix::kPersp2]; + fMat[3] = GrScalarToFloat(m[GrMatrix::kPersp0]); + fMat[7] = GrScalarToFloat(m[GrMatrix::kPersp1]); + fMat[15] = GrScalarToFloat(m[GrMatrix::kPersp2]); - fMat[10] = GR_Scalar1; // z-scale + fMat[10] = 1.f; // z-scale } }; @@ -106,7 +106,6 @@ void GrGpuGLFixed::resetContextHelper() { GrGLClearErr(); fTextVerts = false; - fHWTextureOrientation = (GrGLTexture::Orientation)-1; // illegal fBaseVertex = 0xffffffff; } @@ -146,9 +145,8 @@ bool GrGpuGLFixed::flushGraphicsState(PrimitiveType type) { return false; } - if (fRenderTargetChanged) { + if (fDirtyFlags.fRenderTargetChanged) { flushProjectionMatrix(); - fRenderTargetChanged = false; } for (int s = 0; s < kNumStages; ++s) { @@ -205,28 +203,20 @@ bool GrGpuGLFixed::flushGraphicsState(PrimitiveType type) { fHWRGBOperand0[s] = nextRGBOperand0; } - if (fHWTextureOrientation != texture->orientation() || - fHWDrawState.fTextureMatrices[s] != - fCurrDrawState.fTextureMatrices[s]) { + if (((1 << s) & fDirtyFlags.fTextureChangedMask) || + (fHWDrawState.fSamplerStates[s].getMatrix() != + getSamplerMatrix(s))) { + + GrMatrix texMat = getSamplerMatrix(s); + AdjustTextureMatrix(texture, + GrSamplerState::kNormal_SampleMode, + &texMat); GrGpuMatrix glm; - if (GrGLTexture::kBottomUp_Orientation == - texture->orientation()) { - GrMatrix m( - GR_Scalar1, 0, 0, - 0, -GR_Scalar1, GR_Scalar1, - 0, 0, GrMatrix::I()[8] - ); - m.preConcat(fCurrDrawState.fTextureMatrices[s]); - glm.set(m); - } else { - glm.set(fCurrDrawState.fTextureMatrices[s]); - } + glm.set(texMat); setTextureUnit(s); GR_GL(MatrixMode(GL_TEXTURE)); GR_GL(LoadMatrixf(glm.fMat)); - fHWDrawState.fTextureMatrices[s] = - fCurrDrawState.fTextureMatrices[s]; - fHWTextureOrientation = texture->orientation(); + recordHWSamplerMatrix(s, getSamplerMatrix(s)); } } else { GrAssert(!"Rendering with texture vert flag set but no bound texture"); @@ -243,6 +233,7 @@ bool GrGpuGLFixed::flushGraphicsState(PrimitiveType type) { fHWDrawState.fViewMatrix = fCurrDrawState.fViewMatrix; } + resetDirtyFlags(); return true; } @@ -263,7 +254,7 @@ void GrGpuGLFixed::setupGeometry(int* startVertex, oldTexCoordOffsets, &oldColorOffset); - bool indexed = NULL == startIndex; + bool indexed = NULL != startIndex; int extraVertexOffset; int extraIndexOffset; diff --git a/gpu/src/GrGpuGLFixed.h b/gpu/src/GrGpuGLFixed.h index abb11aa..e5d472d 100644 --- a/gpu/src/GrGpuGLFixed.h +++ b/gpu/src/GrGpuGLFixed.h @@ -39,6 +39,14 @@ protected: private: void resetContextHelper(); + // Helpers to make code more readable + const GrMatrix& getHWSamplerMatrix(int stage) const { + return fHWDrawState.fSamplerStates[stage].getMatrix(); + } + const void recordHWSamplerMatrix(int stage, const GrMatrix& matrix) { + fHWDrawState.fSamplerStates[stage].setMatrix(matrix); + } + // when the texture is GL_RGBA we set the GL_COMBINE texture // environment rgb operand 0 to be GL_COLOR to modulate each incoming // R,G, & B by the texture's R, G, & B. When the texture is alpha-only we @@ -60,8 +68,6 @@ private: // glVertexPointer/glTexCoordPointer/etc int fBaseVertex; - GrGLTexture::Orientation fHWTextureOrientation; - typedef GrGpuGL INHERITED; }; diff --git a/gpu/src/GrGpuGLShaders.cpp b/gpu/src/GrGpuGLShaders.cpp deleted file mode 100644 index cf41b1d..0000000 --- a/gpu/src/GrGpuGLShaders.cpp +++ /dev/null @@ -1,933 +0,0 @@ -/* - 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. - */ - - -#include "GrGLConfig.h" - -#if GR_SUPPORT_GLES2 || GR_SUPPORT_GLDESKTOP - -#include "GrGpuGLShaders.h" -#include "GrGpuVertex.h" -#include "GrMemory.h" - -#define ATTRIBUTE_MATRIX 0 - -#define ATTRIBUTE_TEXT_COLOR 1 - -#if ATTRIBUTE_MATRIX - #define DECL_MATRIX(name) "attribute mat3 " #name ";\n" -#else - #define DECL_MATRIX(name) "uniform mat3 " #name ";\n" -#endif - -#define SKIP_CACHE_CHECK true - -#if GR_SUPPORT_GLES2 - #define GR_PRECISION "mediump" - #define GR_SHADER_PRECISION "precision mediump float;\n" -#else - #define GR_PRECISION "" - #define GR_SHADER_PRECISION "" -#endif - -static const char* gvshad[] = { - // 0: kTextureVertCoords_Program, kTextureVertCoordsProj_Program, - // kRadialTextureVertCoords_Program, kSweepTextureVertCoords_Program - "attribute vec2 aPosition;\n" - "attribute vec4 aColor;\n" - "varying vec3 vTexture;\n" - "varying vec4 vColor;\n" - DECL_MATRIX(viewM) - DECL_MATRIX(texM) - "void main() {\n" - " vec3 pos3 = viewM*vec3(aPosition,1);\n" - " gl_Position = vec4(pos3.xy,0,pos3.z);\n" - " gl_PointSize = 1.0;\n" - " vTexture = texM * vec3(aPosition,1);\n" - " vColor = aColor;\n" - "}\n", - - // 1: kTextureTexCoords_Program, kTextureTexCoordsProj_Program, - // kRadialTextureTexCoords_Program, kSweepTextureTexCoords_Program - "attribute vec2 aPosition;\n" - "attribute vec2 aTexture;\n" - "attribute vec4 aColor;\n" - "varying vec3 vTexture;\n" - "varying vec4 vColor;\n" - DECL_MATRIX(viewM) - DECL_MATRIX(texM) - "void main() {\n" - " vec3 pos3 = viewM*vec3(aPosition,1);\n" - " gl_Position = vec4(pos3.xy,0,pos3.z);\n" - " gl_PointSize = 1.0;\n" - " vTexture = texM * vec3(aTexture,1);\n" - " vColor = aColor;\n" - "}\n", - - // 2: kText_Program - "attribute vec2 aPosition;\n" - "attribute vec2 aTexture;\n" - "varying vec2 vTexture;\n" - DECL_MATRIX(viewM) -#if ATTRIBUTE_TEXT_COLOR - "varying vec4 vColor;\n" - "attribute vec4 aColor;\n" -#endif - "void main() {\n" - " vec3 pos3 = viewM*vec3(aPosition,1);\n" - " gl_Position = vec4(pos3.xy,0,pos3.z);\n" - " vTexture = aTexture;\n" -#if ATTRIBUTE_TEXT_COLOR - " vColor = aColor;\n" -#endif - "}\n", - - // 3: kNoTexture_Program - "attribute vec2 aPosition;\n" - "attribute vec4 aColor;\n" - "varying vec4 vColor;\n" - DECL_MATRIX(viewM) - "void main() {\n" - " vec3 pos3 = viewM*vec3(aPosition,1);\n" - " gl_Position = vec4(pos3.xy,0,pos3.z);\n" - " gl_PointSize = 1.0;\n" - " vColor = aColor;\n" - "}\n", - - // 4: kTextureVertCoordsNoColor_Program - "attribute vec2 aPosition;\n" - "attribute vec4 aColor;\n" - "varying vec3 vTexture;\n" - DECL_MATRIX(viewM) - DECL_MATRIX(texM) - "void main() {\n" - " vec3 pos3 = viewM*vec3(aPosition,1);\n" - " gl_Position = vec4(pos3.xy,0,pos3.z);\n" - " vTexture = texM * vec3(aPosition,1);\n" - "}\n", - - // 5: kTextureTexCoordsNoColor_Program - "attribute vec2 aPosition;\n" - "attribute vec2 aTexture;\n" - "varying vec3 vTexture;\n" - DECL_MATRIX(viewM) - DECL_MATRIX(texM) - "void main() {\n" - " vec3 pos3 = viewM*vec3(aPosition,1);\n" - " gl_Position = vec4(pos3.xy,0,pos3.z);\n" - " gl_PointSize = 1.0;\n" - " vTexture = texM * vec3(aTexture,1);\n" - "}\n", - - // 6: kTwoPointRadialTextureVertCoords_Program - "uniform " GR_PRECISION " float uParams[6];\n" - // 0 is t^2 term of quadratic - // 1 is one-half the inverse of above - // 2 is x offset of the second circle (post tex-matrix) - // 3 is the radius of the first circle (post tex-matrix) - // 4 is the first circle radius squared - // 5 is 1 to use + in the quadratic eq or -1 to use - - DECL_MATRIX(viewM) - DECL_MATRIX(texM) - "attribute vec2 aPosition;\n" - "attribute vec4 aColor;\n" - "varying vec4 vColor;\n" - "varying float vB;\n" // t coeffecient of quadratic. - "varying vec2 t;\n" // coordinates in canonical space - "void main() {\n" - " vec3 pos3 = viewM*vec3(aPosition,1);\n" - " gl_Position = vec4(pos3.xy,0,pos3.z);\n" - " t = vec2(texM * vec3(aPosition,1));\n" - " vColor = aColor;\n" - " vB = 2.0 * (uParams[2] * t.x - uParams[3]);\n" - "}\n", - - // 6: kTwoPointRadialTextureVertCoords_Program - "uniform " GR_PRECISION " float uParams[6];\n" - DECL_MATRIX(viewM) - DECL_MATRIX(texM) - "attribute vec2 aPosition;\n" - "attribute vec2 aTexture;\n" - "attribute vec4 aColor;\n" - "varying vec4 vColor;\n" - "varying float vB;\n" // t coeffecient of quadratic. - "varying vec2 t;\n" // coordinates in canonical space - "void main() {\n" - " vec3 pos3 = viewM*vec3(aPosition,1);\n" - " gl_Position = vec4(pos3.xy,0,pos3.z);\n" - " t = vec2(texM * vec3(aTexture,1));\n" - " vColor = aColor;\n" - " vB = 2.0 * (uParams[2] * t.x - uParams[3]);\n" - "}\n", -}; - -static const char* gfshad[] = { - // 0: kTextureVertCoords_Program, kTextureTexCoords_Program - GR_SHADER_PRECISION - "varying vec3 vTexture;\n" - "varying vec4 vColor;\n" - "uniform sampler2D sTexture;\n" - "void main() {\n" - " gl_FragColor = vColor * texture2D(sTexture, vTexture.xy);\n" - "}\n", - - // 1: kTextureVertCoordsProj_Program, kTextureTexCoordsProj_Program - GR_SHADER_PRECISION - "varying vec3 vTexture;\n" - "varying vec4 vColor;\n" - "uniform sampler2D sTexture;\n" - "void main() {\n" - // On Brian's PC laptop with Intel Gfx texture2DProj seems to be broken - // but it works everywhere else tested. - " gl_FragColor = vColor * texture2DProj(sTexture, vTexture);\n" - - "}\n", - - // 2: kText_Program - GR_SHADER_PRECISION - "varying vec2 vTexture;\n" -#if ATTRIBUTE_TEXT_COLOR - "varying vec4 vColor;\n" -#else - "uniform vec4 uColor;\n" -#endif - "uniform sampler2D sTexture;\n" - "void main() {\n" -#if ATTRIBUTE_TEXT_COLOR - " gl_FragColor = vColor * texture2D(sTexture, vTexture).a;\n" -#else - " gl_FragColor = uColor * texture2D(sTexture, vTexture).a;\n" -#endif - "}\n", - - // 3: kNoTexture_Program - GR_SHADER_PRECISION - "varying vec4 vColor;\n" - "void main() {\n" - " gl_FragColor = vColor;\n" - "}\n", - - // 4: kTextureVertCoordsNoColor_Program - GR_SHADER_PRECISION - "varying vec3 vTexture;\n" - "uniform sampler2D sTexture;\n" - "void main() {\n" - " gl_FragColor = texture2D(sTexture, vTexture.xy);\n" - "}\n", - - // 5: kRadialTextureVertCoords_Program, kRadialTextureTexCoords_Program - GR_SHADER_PRECISION - "varying vec3 vTexture;\n" - "varying vec4 vColor;\n" - "uniform sampler2D sTexture;\n" - "void main() {\n" - " gl_FragColor = vColor * texture2D(sTexture, vec2(length(vTexture.xy), 0.5));\n" - "}\n", - - // 6: kSweepTextureVertCoords_Program, kSweepTextureTexCoords_Program - GR_SHADER_PRECISION - "varying vec3 vTexture;\n" - "varying vec4 vColor;\n" - "uniform sampler2D sTexture;\n" - "void main() {\n" - " vec2 t = vec2(atan(-vTexture.y, -vTexture.x)*0.1591549430918 + 0.5,\n" - " 0.5);\n" - " gl_FragColor = vColor * texture2D(sTexture, t);\n" - "}\n", - - // 7: kTwoPointRadialTextureVertCoords_Program, kTwoPointRadialTextureTexCoords_Program - GR_SHADER_PRECISION - "varying vec4 vColor;\n" - "varying float vB;\n" // t coeffecient of quadratic. - "varying vec2 t;\n" // coordinates in canonical radial gradient space - "uniform sampler2D sTexture;\n" - "uniform float uParams[6];\n" - "void main() {\n" - "float c = t.x*t.x + t.y*t.y - uParams[4];\n" - "float ac4 = uParams[0] * c * 4.0;\n" - "float root = sqrt(abs(vB * vB - ac4));\n" - "float t = (-vB + uParams[5] * root) * uParams[1];\n" - "gl_FragColor = vColor * texture2D(sTexture, vec2(t,0.5))\n;" - "}\n", -}; - -// determines which frag/vert shaders are used for each program in Programs enum - -static const struct { - int fVShaderIdx; - int fFShaderIdx; - bool fHasTexMatrix; - bool fHasTexCoords; - bool fTwoPointRadial; - GrGpuGLShaders::ColorType fColorType; -} gProgramLoadData[] = { - // kTextureVertCoords_Program - {0, 0, true, false, false, GrGpuGLShaders::kAttrib_ColorType }, - // kTextureVertCoordsProj_Program - {0, 1, true, false, false, GrGpuGLShaders::kAttrib_ColorType }, - // kTextureTexCoords_Program - {1, 0, true, true, false, GrGpuGLShaders::kAttrib_ColorType }, - // kTextureTexCoordsProj_Program - {1, 1, true, true, false, GrGpuGLShaders::kAttrib_ColorType }, - // kTextureVertCoordsNoColor_Program - {4, 4, true, false, false, GrGpuGLShaders::kNone_ColorType }, - // kTextureTexCoordsNoColor_Program - {5, 4, true, false, false, GrGpuGLShaders::kNone_ColorType }, - // kText_Program -#if ATTRIBUTE_TEXT_COLOR - {2, 2, false, true, false, GrGpuGLShaders::kAttrib_ColorType }, -#else - {2, 2, false, true, false, GrGpuGLShaders::kUniform_ColorType }, -#endif - // kRadialTextureVertCoords_Program - {0, 5, true, false, false, GrGpuGLShaders::kAttrib_ColorType }, - // kRadialTextureTexCoords_Program - {1, 5, true, true, false, GrGpuGLShaders::kAttrib_ColorType }, - // kSweepTextureVertCoords_Program - {0, 6, true, false, false, GrGpuGLShaders::kAttrib_ColorType }, - // kSweepTextureTexCoords_Program - {1, 6, true, true, false, GrGpuGLShaders::kAttrib_ColorType }, - // kTwoPointRadialTextureVertCoords_Program - {6, 7, true, false, true, GrGpuGLShaders::kAttrib_ColorType }, - // kTwoPointRadialTextureTexCoords_Program - {7, 7, true, true, true, GrGpuGLShaders::kAttrib_ColorType }, - // kNoTexture_Program - {3, 3, false, false, false, GrGpuGLShaders::kAttrib_ColorType }, -}; - -#define GR_GL_POS_ATTR_LOCATION 0 -#define GR_GL_TEX_ATTR_LOCATION 1 -#define GR_GL_COL_ATTR_LOCATION 2 -#if ATTRIBUTE_MATRIX - #define GR_GL_MAT_ATTR_LOCATION 3 - #define GR_GL_TEXMAT_ATTR_LOCATION 6 -#endif - -GLuint GrGpuGLShaders::loadShader(GLenum type, const char* src) { - GLuint shader = GR_GL(CreateShader(type)); - if (0 == shader) { - return 0; - } - - GR_GL(ShaderSource(shader, 1, &src, NULL)); - GR_GL(CompileShader(shader)); - - GLint compiled = GR_GL_INIT_ZERO; - GR_GL(GetShaderiv(shader, GL_COMPILE_STATUS, &compiled)); - - if (!compiled) { - GLint infoLen = GR_GL_INIT_ZERO; - GR_GL(GetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen)); - GrAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debugger - if (infoLen > 0) { - GR_GL(GetShaderInfoLog(shader, infoLen+1, NULL, (char*)log.get())); - GrPrintf((char*)log.get()); - } - GrAssert(!"Shader compilation failed!"); - GR_GL(DeleteShader(shader)); - return 0; - } - return shader; -} - -bool GrGpuGLShaders::createProgram(GLuint vshader, GLuint fshader, - bool hasTexMatrix, - bool hasTexCoords, - GrGpuGLShaders::ColorType colorType, - bool twoPointRadial, - ProgramData* program) { - program->fProgramID = GR_GL(CreateProgram()); - program->fVShaderID = vshader; - program->fFShaderID = fshader; - - GrAssert(0 != program->fProgramID); - - GR_GL(AttachShader(program->fProgramID, vshader)); - GR_GL(AttachShader(program->fProgramID, fshader)); - - GR_GL(BindAttribLocation(program->fProgramID, - GR_GL_POS_ATTR_LOCATION, - "aPosition")); - if (hasTexCoords) { - GR_GL(BindAttribLocation(program->fProgramID, - GR_GL_TEX_ATTR_LOCATION, - "aTexture")); - } -#if ATTRIBUTE_MATRIX - if (hasTexMatrix) { - GR_GL(BindAttribLocation(program->fProgramID, - GR_GL_TEXMAT_ATTR_LOCATION, - "texM")); - // set to something arbitrary to signal to flush that program - // uses the texture matrix. - program->fTexMatrixLocation = 1000; - } -#endif - if (colorType == kAttrib_ColorType) { - GR_GL(BindAttribLocation(program->fProgramID, - GR_GL_COL_ATTR_LOCATION, - "aColor")); - } -#if ATTRIBUTE_MATRIX - GR_GL(BindAttribLocation(program->fProgramID, - GR_GL_MAT_ATTR_LOCATION, - "viewM")); -#endif - - GR_GL(LinkProgram(program->fProgramID)); - - GLint linked = GR_GL_INIT_ZERO; - GR_GL(GetProgramiv(program->fProgramID, GL_LINK_STATUS, &linked)); - if (!linked) { - GLint infoLen = GR_GL_INIT_ZERO; - GR_GL(GetProgramiv(program->fProgramID, GL_INFO_LOG_LENGTH, &infoLen)); - GrAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debugger - if (infoLen > 0) { - GR_GL(GetProgramInfoLog(program->fProgramID, - infoLen+1, - NULL, - (char*)log.get())); - GrPrintf((char*)log.get()); - } - GrAssert(!"Error linking program"); - GR_GL(DeleteProgram(program->fProgramID)); - program->fProgramID = 0; - return false; - } - program->fColorType = colorType; - -#if !ATTRIBUTE_MATRIX - program->fMatrixLocation = - GR_GL(GetUniformLocation(program->fProgramID, "viewM")); - program->fTexMatrixLocation = - GR_GL(GetUniformLocation(program->fProgramID, "texM")); -#endif - program->fColorLocation = - GR_GL(GetUniformLocation(program->fProgramID, "uColor")); - program->fTwoPointParamsLocation = - GR_GL(GetUniformLocation(program->fProgramID, "uParams")); - - GLint samplerLocation = - GR_GL(GetUniformLocation(program->fProgramID, "sTexture")); - -#if !ATTRIBUTE_MATRIX - if (-1 == program->fMatrixLocation) { - GrAssert(!"Cannot find matrix uniform in program"); - GR_GL(DeleteProgram(program->fProgramID)); - program->fProgramID = 0; - return false; - } -#endif - - bool hasTexture = hasTexCoords || hasTexMatrix; - - if (-1 == samplerLocation && hasTexture) { - GrAssert(!"Expected to find texture sampler"); - GR_GL(DeleteProgram(program->fProgramID)); - program->fProgramID = 0; - return false; - } else if (-1 != samplerLocation && !hasTexture) { - GrAssert(!"unexpectedly found texture sampler"); - } -#if !ATTRIBUTE_MATRIX && !defined(GR_SKIP_2POINTRADIAL_PROGRAMS) - if (-1 == program->fTexMatrixLocation && hasTexMatrix) { - GrAssert(!"Expected to find texture matrix"); - GR_GL(DeleteProgram(program->fProgramID)); - program->fProgramID = 0; - return false; - } else if (-1 != program->fTexMatrixLocation && !hasTexMatrix) { - GrAssert(!"unexpectedly found texture matrix"); - } -#endif - - if (-1 == program->fColorLocation && - (kUniform_ColorType == colorType)) { - GR_GL(DeleteProgram(program->fProgramID)); - program->fProgramID = 0; - return false; - } else if (-1 != program->fColorLocation && - (kUniform_ColorType != colorType)) { - GrAssert(!"Unexpectedly found color uniform"); - } - - if (twoPointRadial) { - if (-1 == program->fTwoPointParamsLocation) { - GrAssert(!"Didn't find expected uniform for 2pt radial gradient"); - GR_GL(DeleteProgram(program->fProgramID)); - program->fProgramID = 0; - return false; - } - } else { - GrAssert(-1 == program->fTwoPointParamsLocation); - } - - GR_GL(UseProgram(program->fProgramID)); - if (-1 != samplerLocation) { - GR_GL(Uniform1i(samplerLocation, 0)); - } - - return true; -} - -GrGpuGLShaders::GrGpuGLShaders() { - - resetContextHelper(); - - GLuint vshadIDs[GR_ARRAY_COUNT(gvshad)]; - for (size_t s = 0; s < GR_ARRAY_COUNT(gvshad); ++s) { - vshadIDs[s] = loadShader(GL_VERTEX_SHADER, gvshad[s]); - } - - GLuint fshadIDs[GR_ARRAY_COUNT(gfshad)]; - for (size_t s = 0; s < GR_ARRAY_COUNT(gfshad); ++s) { - fshadIDs[s] = loadShader(GL_FRAGMENT_SHADER, gfshad[s]); - } - - GR_STATIC_ASSERT(kProgramCount == GR_ARRAY_COUNT(gProgramLoadData)); - for (int p = 0; p < kProgramCount; ++p) { -#ifdef GR_SKIP_2POINTRADIAL_PROGRAMS - if (11 == p || 12 == p) continue; -#endif - GR_DEBUGCODE(bool result = ) - createProgram(vshadIDs[gProgramLoadData[p].fVShaderIdx], - fshadIDs[gProgramLoadData[p].fFShaderIdx], - gProgramLoadData[p].fHasTexMatrix, - gProgramLoadData[p].fHasTexCoords, - gProgramLoadData[p].fColorType, - gProgramLoadData[p].fTwoPointRadial, - &fPrograms[p]); - GR_DEBUGASSERT(result); - - fPrograms[p].fViewMatrix.setScale(GR_ScalarMax, GR_ScalarMax); - for (int s = 0; s < kNumStages; ++s) { - fPrograms[p].fTextureMatrices[s].setScale(GR_ScalarMax, - GR_ScalarMax); // illegal - }; - fPrograms[p].fColor = GrColor_ILLEGAL; - fPrograms[p].fTextureOrientation = (GrGLTexture::Orientation)-1; // illegal - - // these aren't strictly invalid, just really unlikely. - fPrograms[p].fRadial2CenterX1 = GR_ScalarMin; - fPrograms[p].fRadial2Radius0 = GR_ScalarMin; - fPrograms[p].fRadial2PosRoot = true; // arbitrary - } -} - -GrGpuGLShaders::~GrGpuGLShaders() { - // shaders get deleted once for each program that uses them, do we care? - // probably not - for (int i = 0; i < kProgramCount; ++i) { - GR_GL(DeleteProgram(fPrograms[i].fProgramID)); - GR_GL(DeleteShader(fPrograms[i].fVShaderID)); - GR_GL(DeleteShader(fPrograms[i].fFShaderID)); - } -} - -void GrGpuGLShaders::resetContext() { - INHERITED::resetContext(); - resetContextHelper(); -} - -void GrGpuGLShaders::resetContextHelper() { - fHWProgram = (Programs)-1; - fTextureOrientation = (GrGLTexture::Orientation)-1; // illegal - - fHWGeometryState.fVertexLayout = 0; - fHWGeometryState.fVertexOffset = ~0; - GR_GL(DisableVertexAttribArray(GR_GL_COL_ATTR_LOCATION)); - GR_GL(DisableVertexAttribArray(GR_GL_TEX_ATTR_LOCATION)); - GR_GL(EnableVertexAttribArray(GR_GL_POS_ATTR_LOCATION)); -} - - -void GrGpuGLShaders::flushMatrix(GLint location) { - GrAssert(NULL != fCurrDrawState.fRenderTarget); - GrMatrix m ( - GrIntToScalar(2) / fCurrDrawState.fRenderTarget->width(), 0, -GR_Scalar1, - 0,-GrIntToScalar(2) / fCurrDrawState.fRenderTarget->height(), GR_Scalar1, - 0, 0, GrMatrix::I()[8]); - m.setConcat(m, fCurrDrawState.fViewMatrix); - - // 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] - }; -#if ATTRIBUTE_MATRIX - GR_GL(VertexAttrib4fv(GR_GL_MAT_ATTR_LOCATION+0, mt+0)); - GR_GL(VertexAttrib4fv(GR_GL_MAT_ATTR_LOCATION+1, mt+3)); - GR_GL(VertexAttrib4fv(GR_GL_MAT_ATTR_LOCATION+2, mt+6)); -#else - GR_GL(UniformMatrix3fv(location,1,false,mt)); -#endif -} - -void GrGpuGLShaders::flushTexMatrix(GLint location, - GrGLTexture::Orientation orientation) { - GrMatrix* m; - GrMatrix temp; - if (GrGLTexture::kBottomUp_Orientation == orientation) { - temp.setAll( - GR_Scalar1, 0, 0, - 0, -GR_Scalar1, GR_Scalar1, - 0, 0, GrMatrix::I()[8] - ); - temp.preConcat(fCurrDrawState.fTextureMatrices[0]); - m = &temp; - } else { - GrAssert(GrGLTexture::kTopDown_Orientation == orientation); - m = &fCurrDrawState.fTextureMatrices[0]; - } - - // 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] - }; -#if ATTRIBUTE_MATRIX - GR_GL(VertexAttrib4fv(GR_GL_TEXMAT_ATTR_LOCATION+0, mt+0)); - GR_GL(VertexAttrib4fv(GR_GL_TEXMAT_ATTR_LOCATION+1, mt+3)); - GR_GL(VertexAttrib4fv(GR_GL_TEXMAT_ATTR_LOCATION+2, mt+6)); -#else - GR_GL(UniformMatrix3fv(location,1,false,mt)); -#endif -} - -void GrGpuGLShaders::flushTwoPointRadial(GLint paramsLocation, - const GrSamplerState& state) { - GrScalar centerX1 = state.getRadial2CenterX1(); - GrScalar radius0 = state.getRadial2Radius0(); - - GrScalar a = GrMul(centerX1, centerX1) - GR_Scalar1; - - float unis[6] = { - GrScalarToFloat(a), - 1 / (2.f * unis[0]), - GrScalarToFloat(centerX1), - GrScalarToFloat(radius0), - GrScalarToFloat(GrMul(radius0, radius0)), - state.isRadial2PosRoot() ? 1.f : -1.f - }; - GR_GL(Uniform1fv(paramsLocation, 6, unis)); -} - -void GrGpuGLShaders::flushProgram(PrimitiveType type) { - - Programs nextProgram = kNoTexture_Program; - - GrTexture* texture = fCurrDrawState.fTextures[0]; - bool posAsTex = - !!(StagePosAsTexCoordVertexLayoutBit(0) & fGeometrySrc.fVertexLayout); - - if (!VertexUsesStage(0, fGeometrySrc.fVertexLayout)) { - goto HAVE_NEXT_PROGRAM; - } - - GrAssert(NULL != texture); - - switch (fCurrDrawState.fSamplerStates[0].getSampleMode()) { - case GrSamplerState::kRadial_SampleMode: - GrAssert(!fCurrDrawState.fTextureMatrices[0].hasPerspective()); - GrAssert(GrTexture::kAlpha_8_PixelConfig != texture->config()); - if (posAsTex) { - nextProgram = kRadialTextureVertCoords_Program; - } else { - nextProgram = kRadialTextureTexCoords_Program; - } - break; - case GrSamplerState::kSweep_SampleMode: - GrAssert(!fCurrDrawState.fTextureMatrices[0].hasPerspective()); - GrAssert(GrTexture::kAlpha_8_PixelConfig != texture->config()); - if (posAsTex) { - nextProgram = kSweepTextureVertCoords_Program; - } else { - nextProgram = kSweepTextureTexCoords_Program; - } - break; - case GrSamplerState::kRadial2_SampleMode: - GrAssert(!fCurrDrawState.fTextureMatrices[0].hasPerspective()); - GrAssert(GrTexture::kAlpha_8_PixelConfig != texture->config()); - if (posAsTex) { - nextProgram = kTwoPointRadialTextureVertCoords_Program; - } else { - nextProgram = kTwoPointRadialTextureTexCoords_Program; - } - break; - case GrSamplerState::kNormal_SampleMode: - if (GrTexture::kAlpha_8_PixelConfig == texture->config()) { - GrAssert(((GrGLTexture*)texture)->orientation() == - GrGLTexture::kTopDown_Orientation); - GrAssert(!posAsTex); - nextProgram = kText_Program; - } else { - bool persp = fCurrDrawState.fTextureMatrices[0].hasPerspective(); - if (posAsTex) { - nextProgram = persp ? kTextureVertCoordsProj_Program : - kTextureVertCoords_Program; - } else { - nextProgram = persp ? kTextureTexCoordsProj_Program : - kTextureTexCoords_Program; - } - // check for case when frag shader can skip the color modulation - if (!persp && !(fGeometrySrc.fVertexLayout - & kColor_VertexLayoutBit) && - 0xffffffff == fCurrDrawState.fColor) { - switch (nextProgram) { - case kTextureVertCoords_Program: - nextProgram = kTextureVertCoordsNoColor_Program; - break; - case kTextureTexCoords_Program: - nextProgram = kTextureTexCoordsNoColor_Program; - break; - default: - GrAssert("Unexpected"); - break; - } - } - } - break; - default: - GrAssert(!"Unknown samplemode"); - break; - } - -HAVE_NEXT_PROGRAM: - if (fHWProgram != nextProgram) { - GR_GL(UseProgram(fPrograms[nextProgram].fProgramID)); - fHWProgram = nextProgram; -#if GR_COLLECT_STATS - ++fStats.fProgChngCnt; -#endif - } -} - -bool GrGpuGLShaders::flushGraphicsState(PrimitiveType type) { - - for (int s = 1; s < kNumStages; ++s) { - if (VertexUsesStage(s, fGeometrySrc.fVertexLayout)) { - unimpl("the hard-coded shaders used by this " - "class only support 1 stage"); - return false; - } - } - - if (!flushGLStateCommon(type)) { - return false; - } - - if (fRenderTargetChanged) { - // our coords are in pixel space and the GL matrices map to NDC - // so if the viewport changed, our matrix is now wrong. -#if ATTRIBUTE_MATRIX - fHWDrawState.fViewMatrix.setScale(GR_ScalarMax, GR_ScalarMax); -#else - // we assume all shader matrices may be wrong after viewport changes - for (int p = 0; p < kProgramCount; ++p) { - // set to illegal matrix - fPrograms[p].fViewMatrix.setScale(GR_ScalarMax, GR_ScalarMax); - } -#endif - fRenderTargetChanged = false; - } - - flushProgram(type); - - if (fGeometrySrc.fVertexLayout & kColor_VertexLayoutBit) { - // invalidate the immediate mode color - fHWDrawState.fColor = GrColor_ILLEGAL; - } else { - // if we don't have per-vert colors either set the color attr - // or color uniform (depending on which program). - if (-1 != fPrograms[fHWProgram].fColorLocation) { - GrAssert(kUniform_ColorType == fPrograms[fHWProgram].fColorType); - if (fPrograms[fHWProgram].fColor != fCurrDrawState.fColor) { - float c[] = { - GrColorUnpackR(fCurrDrawState.fColor) / 255.f, - GrColorUnpackG(fCurrDrawState.fColor) / 255.f, - GrColorUnpackB(fCurrDrawState.fColor) / 255.f, - GrColorUnpackA(fCurrDrawState.fColor) / 255.f - }; - GR_GL(Uniform4fv(fPrograms[fHWProgram].fColorLocation, 1, c)); - fPrograms[fHWProgram].fColor = fCurrDrawState.fColor; - } - } else if (kAttrib_ColorType == fPrograms[fHWProgram].fColorType && - fHWDrawState.fColor != fCurrDrawState.fColor) { - // OpenGL ES only supports the float varities of glVertexAttrib - float c[] = { - GrColorUnpackR(fCurrDrawState.fColor) / 255.f, - GrColorUnpackG(fCurrDrawState.fColor) / 255.f, - GrColorUnpackB(fCurrDrawState.fColor) / 255.f, - GrColorUnpackA(fCurrDrawState.fColor) / 255.f - }; - GR_GL(VertexAttrib4fv(GR_GL_COL_ATTR_LOCATION, c)); - fHWDrawState.fColor = fCurrDrawState.fColor; - } - } - -#if ATTRIBUTE_MATRIX - GrMatrix& currentViewMatrix = fHWDrawState.fViewMatrix; - GrMatrix& currentTexMatrix = fHWDrawState.fTextureMatrices[0]; - GrGLTexture::Orientation& orientation = fTextureOrientation; -#else - GrMatrix& currentViewMatrix = fPrograms[fHWProgram].fViewMatrix; - GrMatrix& currentTexMatrix = fPrograms[fHWProgram].fTextureMatrices[0]; - GrGLTexture::Orientation& orientation = - fPrograms[fHWProgram].fTextureOrientation; -#endif - - if (currentViewMatrix != - fCurrDrawState.fViewMatrix) { - flushMatrix(fPrograms[fHWProgram].fMatrixLocation); - currentViewMatrix = fCurrDrawState.fViewMatrix; - } - - GrGLTexture* texture = (GrGLTexture*) fCurrDrawState.fTextures[0]; - if (NULL != texture) { - if (-1 != fPrograms[fHWProgram].fTexMatrixLocation && - (currentTexMatrix != fCurrDrawState.fTextureMatrices[0] || - orientation != texture->orientation())) { - flushTexMatrix(fPrograms[fHWProgram].fTexMatrixLocation, - texture->orientation()); - currentTexMatrix = fCurrDrawState.fTextureMatrices[0]; - orientation = texture->orientation(); - } - } - - const GrSamplerState& sampler = fCurrDrawState.fSamplerStates[0]; - if (-1 != fPrograms[fHWProgram].fTwoPointParamsLocation && - (fPrograms[fHWProgram].fRadial2CenterX1 != sampler.getRadial2CenterX1() || - fPrograms[fHWProgram].fRadial2Radius0 != sampler.getRadial2Radius0() || - fPrograms[fHWProgram].fRadial2PosRoot != sampler.isRadial2PosRoot())) { - - flushTwoPointRadial(fPrograms[fHWProgram].fTwoPointParamsLocation, - sampler); - fPrograms[fHWProgram].fRadial2CenterX1 = sampler.getRadial2CenterX1(); - fPrograms[fHWProgram].fRadial2Radius0 = sampler.getRadial2Radius0(); - fPrograms[fHWProgram].fRadial2PosRoot = sampler.isRadial2PosRoot(); - } - - return true; -} - -void GrGpuGLShaders::setupGeometry(int* startVertex, - int* startIndex, - int vertexCount, - int indexCount) { - - int newColorOffset; - int newTexCoordOffsets[kNumStages]; - - GLsizei newStride = VertexSizeAndOffsetsByStage(fGeometrySrc.fVertexLayout, - newTexCoordOffsets, - &newColorOffset); - int oldColorOffset; - int oldTexCoordOffsets[kNumStages]; - GLsizei oldStride = VertexSizeAndOffsetsByStage(fHWGeometryState.fVertexLayout, - oldTexCoordOffsets, - &oldColorOffset); - bool indexed = NULL == startIndex; - - int extraVertexOffset; - int extraIndexOffset; - setBuffers(indexed, &extraVertexOffset, &extraIndexOffset); - - GLenum scalarType; - bool texCoordNorm; - if (fGeometrySrc.fVertexLayout & kTextFormat_VertexLayoutBit) { - scalarType = GrGLTextType; - texCoordNorm = GR_GL_TEXT_TEXTURE_NORMALIZED; - } else { - scalarType = GrGLType; - texCoordNorm = false; - } - - size_t vertexOffset = (*startVertex + extraVertexOffset) * newStride; - *startVertex = 0; - if (indexed) { - *startIndex += extraIndexOffset; - } - - // all the Pointers must be set if any of these are true - bool allOffsetsChange = fHWGeometryState.fArrayPtrsDirty || - vertexOffset != fHWGeometryState.fVertexOffset || - newStride != oldStride; - - // position and tex coord offsets change if above conditions are true - // or the type/normalization changed based on text vs nontext type coords. - bool posAndTexChange = allOffsetsChange || - (((GrGLTextType != GrGLType) || GR_GL_TEXT_TEXTURE_NORMALIZED) && - (kTextFormat_VertexLayoutBit & - (fHWGeometryState.fVertexLayout ^ - fGeometrySrc.fVertexLayout))); - - if (posAndTexChange) { - GR_GL(VertexAttribPointer(GR_GL_POS_ATTR_LOCATION, 2, scalarType, - false, newStride, (GLvoid*)vertexOffset)); - fHWGeometryState.fVertexOffset = vertexOffset; - } - - // this class only supports one stage. - if (newTexCoordOffsets[0] > 0) { - GLvoid* texCoordOffset = (GLvoid*)(vertexOffset + newTexCoordOffsets[0]); - if (oldTexCoordOffsets[0] <= 0) { - GR_GL(EnableVertexAttribArray(GR_GL_TEX_ATTR_LOCATION)); - GR_GL(VertexAttribPointer(GR_GL_TEX_ATTR_LOCATION, 2, scalarType, - texCoordNorm, newStride, texCoordOffset)); - } else if (posAndTexChange || - newTexCoordOffsets[0] != oldTexCoordOffsets[0]) { - GR_GL(VertexAttribPointer(GR_GL_TEX_ATTR_LOCATION, 2, scalarType, - texCoordNorm, newStride, texCoordOffset)); - } - } else if (oldTexCoordOffsets[0] > 0) { - GR_GL(DisableVertexAttribArray(GR_GL_TEX_ATTR_LOCATION)); - } - - if (newColorOffset > 0) { - GLvoid* colorOffset = (GLvoid*)(vertexOffset + newColorOffset); - if (oldColorOffset <= 0) { - GR_GL(EnableVertexAttribArray(GR_GL_COL_ATTR_LOCATION)); - GR_GL(VertexAttribPointer(GR_GL_COL_ATTR_LOCATION, 4, - GL_UNSIGNED_BYTE, - true, newStride, colorOffset)); - } else if (allOffsetsChange || newColorOffset != oldColorOffset) { - GR_GL(VertexAttribPointer(GR_GL_COL_ATTR_LOCATION, 4, - GL_UNSIGNED_BYTE, - true, newStride, colorOffset)); - } - } else if (oldColorOffset > 0) { - GR_GL(DisableVertexAttribArray(GR_GL_COL_ATTR_LOCATION)); - } - - fHWGeometryState.fVertexLayout = fGeometrySrc.fVertexLayout; - fHWGeometryState.fArrayPtrsDirty = false; -} -#endif diff --git a/gpu/src/GrGpuGLShaders.h b/gpu/src/GrGpuGLShaders.h deleted file mode 100644 index a048e93..0000000 --- a/gpu/src/GrGpuGLShaders.h +++ /dev/null @@ -1,154 +0,0 @@ -/* - 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 GrGpuGLShaders_DEFINED -#define GrGpuGLShaders_DEFINED - -#include "GrGpuGL.h" - -// Programmable OpenGL or OpenGL ES 2.0 -class GrGpuGLShaders : public GrGpuGL { -public: - GrGpuGLShaders(); - virtual ~GrGpuGLShaders(); - - virtual void resetContext(); - - // type of colors used by a program - enum ColorType { - kNone_ColorType, - kAttrib_ColorType, - kUniform_ColorType, - }; -protected: - // overrides from GrGpu - virtual bool flushGraphicsState(PrimitiveType type); - virtual void setupGeometry(int* startVertex, - int* startIndex, - int vertexCount, - int indexCount); - -private: - void resetContextHelper(); - - // sets the texture matrix uniform for currently bound program - void flushTexMatrix(GLint location, - GrGLTexture::Orientation orientation); - // sets the MVP matrix uniform for currently bound program - void flushMatrix(GLint location); - - void flushTwoPointRadial(GLint paramsLocation, const GrSamplerState&); - - // reads shader from array and compiles it with GL, returns shader ID or 0 if failed - GLuint loadShader(GLenum type, const char* src); - - struct ProgramData; - // creates a GL program with two shaders attached. - // Gets the relevant uniform locations. - // Sets the texture sampler if present to texture 0 - // Binds the program - // returns true if succeeded. - bool createProgram(GLuint vshader, - GLuint fshader, - bool hasTexMatrix, - bool hasTexCoords, - ColorType colorType, - bool twoPointRadial, - ProgramData* program); - - // called at flush time to setup the appropriate program - void flushProgram(PrimitiveType type); - - enum Programs { - // use vertex coordinates - kTextureVertCoords_Program = 0, - kTextureVertCoordsProj_Program, - - // use separate tex coords - kTextureTexCoords_Program, - kTextureTexCoordsProj_Program, - - // constant color texture, no proj - // verts as a tex coords - kTextureVertCoordsNoColor_Program, - - // constant color texture, no proj - // separate tex coords - kTextureTexCoordsNoColor_Program, - - // special program for text glyphs - kText_Program, - - // programs for radial texture lookup - kRadialTextureVertCoords_Program, - kRadialTextureTexCoords_Program, - - // programs for sweep texture lookup - kSweepTextureVertCoords_Program, - kSweepTextureTexCoords_Program, - - // programs for two-point radial lookup - kTwoPointRadialTextureVertCoords_Program, - kTwoPointRadialTextureTexCoords_Program, - - // color only drawing - kNoTexture_Program, - - kProgramCount - }; - - // Records per-program information - // we can specify the attribute locations so that they are constant - // across our shaders. But the driver determines the uniform locations - // at link time. We don't need to remember the sampler uniform location - // because we will bind a texture slot to it and never change it - // Uniforms are program-local so we can't rely on fHWState to hold the - // previous uniform state after a program change. - struct ProgramData { - // IDs - GLuint fVShaderID; - GLuint fFShaderID; - GLuint fProgramID; - - // shader uniform locations (-1 if shader doesn't use them) - GLint fMatrixLocation; - GLint fTexMatrixLocation; - GLint fColorLocation; - GLint fTwoPointParamsLocation; - - ColorType fColorType; - - // these reflect the current values of uniforms - // (GL uniform values travel with program) - GrMatrix fViewMatrix; - GrMatrix fTextureMatrices[kNumStages]; - GrColor fColor; - GrGLTexture::Orientation fTextureOrientation; - GrScalar fRadial2CenterX1; - GrScalar fRadial2Radius0; - bool fRadial2PosRoot; - }; - - ProgramData fPrograms[kProgramCount]; - Programs fHWProgram; - - GrGLTexture::Orientation fTextureOrientation; - - typedef GrGpuGL INHERITED; -}; - -#endif diff --git a/gpu/src/GrGpuGLShaders2.cpp b/gpu/src/GrGpuGLShaders2.cpp index d423ee2..34e7c87 100644 --- a/gpu/src/GrGpuGLShaders2.cpp +++ b/gpu/src/GrGpuGLShaders2.cpp @@ -81,8 +81,7 @@ struct GrGpuGLShaders2::Program { // these reflect the current values of uniforms // (GL uniform values travel with program) GrMatrix fViewMatrix; - GrMatrix fTextureMatrix[kNumStages]; - GrGLTexture::Orientation fTextureOrientation[kNumStages]; + GrMatrix fTextureMatrices[kNumStages]; GrScalar fRadial2CenterX1[kNumStages]; GrScalar fRadial2Radius0[kNumStages]; bool fRadial2PosRoot[kNumStages]; @@ -189,8 +188,7 @@ public: void invalidateViewMatrices() { for (int i = 0; i < fCount; ++i) { // set to illegal matrix - fEntries[i].fProgram.fViewMatrix.setScale(GR_ScalarMax, - GR_ScalarMax); + fEntries[i].fProgram.fViewMatrix = GrMatrix::InvalidMatrix(); } } @@ -684,7 +682,7 @@ void GrGpuGLShaders2::GenProgram(const ProgramDesc& desc, desc.fOptFlags); #if ATTRIBUTE_MATRIX - segments.fVSAttrs = "attribute mat3 " VIEW_MATRIX_NAME ";\n" + segments.fVSAttrs = "attribute mat3 " VIEW_MATRIX_NAME ";\n"; #else segments.fVSUnis = "uniform mat3 " VIEW_MATRIX_NAME ";\n"; segments.fVSAttrs = ""; @@ -883,9 +881,11 @@ void GrGpuGLShaders2::GenProgram(const ProgramDesc& desc, for (int s = 0; s < kNumStages; ++s) { if (desc.fStages[s].fEnabled) { + GrStringBuilder matName; + tex_matrix_name(s, &matName); GR_GL(BindAttribLocation(progID, TEXMAT_ATTR_LOCATION(s), - tex_matrix_name(i).cstr())); + matName.cstr())); program->fUniLocations.fStages[s].fTextureMatrixUni = BOGUS_MATRIX_UNI_LOCATION; } @@ -972,11 +972,11 @@ void GrGpuGLShaders2::GenProgram(const ProgramDesc& desc, if (-1 != program->fUniLocations.fStages[s].fSamplerUni) { GR_GL(Uniform1i(program->fUniLocations.fStages[s].fSamplerUni, s)); } - program->fTextureMatrix[s].setScale(GR_ScalarMax, GR_ScalarMax); + program->fTextureMatrices[s] = GrMatrix::InvalidMatrix(); program->fRadial2CenterX1[s] = GR_ScalarMax; program->fRadial2Radius0[s] = -GR_ScalarMax; } - program->fViewMatrix.setScale(GR_ScalarMax, GR_ScalarMax); + program->fViewMatrix = GrMatrix::InvalidMatrix(); } void GrGpuGLShaders2::getProgramDesc(PrimitiveType primType, ProgramDesc* desc) { @@ -1005,10 +1005,9 @@ void GrGpuGLShaders2::getProgramDesc(PrimitiveType primType, ProgramDesc* desc) GrAssert(NULL != texture); // we matrix to invert when orientation is TopDown, so make sure // we aren't in that case before flagging as identity. - if (fCurrDrawState.fTextureMatrices[s].isIdentity() && - GrGLTexture::kTopDown_Orientation == texture->orientation()) { + if (TextureMatrixIsIdentity(texture, fCurrDrawState.fSamplerStates[s])) { stage.fOptFlags = StageDesc::kIdentityMatrix_OptFlagBit; - } else if (!fCurrDrawState.fTextureMatrices[s].hasPerspective()) { + } else if (!getSamplerMatrix(s).hasPerspective()) { stage.fOptFlags = StageDesc::kNoPerspective_OptFlagBit; } else { stage.fOptFlags = 0; @@ -1103,14 +1102,28 @@ GrGpuGLShaders2::~GrGpuGLShaders2() { delete fProgramCache; } +const GrMatrix& GrGpuGLShaders2::getHWSamplerMatrix(int stage) { +#if ATTRIBUTE_MATRIX + return fHWDrawState.fSamplerStates[stage].getMatrix(); +#else + return fProgram->fTextureMatrices[stage]; +#endif +} + +void GrGpuGLShaders2::recordHWSamplerMatrix(int stage, const GrMatrix& matrix){ +#if ATTRIBUTE_MATRIX + fHWDrawState.fSamplerStates[stage].setMatrix(matrix); +#else + fProgram->fTextureMatrices[stage] = matrix; +#endif +} + void GrGpuGLShaders2::resetContext() { INHERITED::resetContext(); resetContextHelper(); } void GrGpuGLShaders2::resetContextHelper() { - fTextureOrientation = (GrGLTexture::Orientation)-1; // illegal - fHWGeometryState.fVertexLayout = 0; fHWGeometryState.fVertexOffset = ~0; GR_GL(DisableVertexAttribArray(COL_ATTR_LOCATION)); @@ -1153,38 +1166,27 @@ void GrGpuGLShaders2::flushViewMatrix() { } void GrGpuGLShaders2::flushTextureMatrix(int stage) { - GrAssert(NULL != fCurrDrawState.fTextures[stage]); - GrGLTexture::Orientation orientation = - ((GrGLTexture*)fCurrDrawState.fTextures[stage])->orientation(); - - GrMatrix* m; - GrMatrix temp; - if (GrGLTexture::kBottomUp_Orientation == orientation) { - temp.setAll( - GR_Scalar1, 0, 0, - 0, -GR_Scalar1, GR_Scalar1, - 0, 0, GrMatrix::I()[8] - ); - temp.preConcat(fCurrDrawState.fTextureMatrices[stage]); - m = &temp; - } else { - GrAssert(GrGLTexture::kTopDown_Orientation == orientation); - m = &fCurrDrawState.fTextureMatrices[stage]; - } + + GrGLTexture* texture = (GrGLTexture*) fCurrDrawState.fTextures[stage]; + + GrMatrix m = getSamplerMatrix(stage); + GrSamplerState::SampleMode mode = + fCurrDrawState.fSamplerStates[0].getSampleMode(); + AdjustTextureMatrix(texture, mode, &m); // 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::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] }; #if ATTRIBUTE_MATRIX GR_GL(VertexAttrib4fv(TEXMAT_ATTR_LOCATION(0)+0, mt+0)); @@ -1192,9 +1194,7 @@ void GrGpuGLShaders2::flushTextureMatrix(int stage) { GR_GL(VertexAttrib4fv(TEXMAT_ATTR_LOCATION(0)+2, mt+6)); #else GR_GL(UniformMatrix3fv(fProgram->fUniLocations.fStages[stage].fTextureMatrixUni, - 1, - false, - mt)); + 1, false, mt)); #endif } @@ -1240,16 +1240,15 @@ bool GrGpuGLShaders2::flushGraphicsState(PrimitiveType type) { return false; } - if (fRenderTargetChanged) { + if (fDirtyFlags.fRenderTargetChanged) { // our coords are in pixel space and the GL matrices map to NDC // so if the viewport changed, our matrix is now wrong. #if ATTRIBUTE_MATRIX - fHWDrawState.fViewMatrix.setScale(GR_ScalarMax, GR_ScalarMax); + fHWDrawState.fViewMatrix = GrMatrix::InvalidMatrix(); #else // we assume all shader matrices may be wrong after viewport changes fProgramCache->invalidateViewMatrices(); #endif - fRenderTargetChanged = false; } flushProgram(type); @@ -1273,12 +1272,8 @@ bool GrGpuGLShaders2::flushGraphicsState(PrimitiveType type) { #if ATTRIBUTE_MATRIX GrMatrix& currViewMatrix = fHWDrawState.fViewMatrix; - GrMatrix& currTextureMatrix = fHWDrawState.fMatrixModeCache[kTexture_MatrixMode]; - GrGLTexture::Orientation& orientation = fTextureOrientation; #else GrMatrix& currViewMatrix = fProgram->fViewMatrix; - GrMatrix& currTextureMatrix = fProgram->fTextureMatrix[0]; - GrGLTexture::Orientation& orientation = fProgram->fTextureOrientation[0]; #endif if (currViewMatrix != fCurrDrawState.fViewMatrix) { @@ -1290,11 +1285,10 @@ bool GrGpuGLShaders2::flushGraphicsState(PrimitiveType type) { GrGLTexture* texture = (GrGLTexture*) fCurrDrawState.fTextures[s]; if (NULL != texture) { if (-1 != fProgram->fUniLocations.fStages[s].fTextureMatrixUni && - (currTextureMatrix != fCurrDrawState.fTextureMatrices[s] || - orientation != texture->orientation())) { + (((1 << s) & fDirtyFlags.fTextureChangedMask) || + getHWSamplerMatrix(s) != getSamplerMatrix(s))) { flushTextureMatrix(s); - currTextureMatrix = fCurrDrawState.fTextureMatrices[s]; - orientation = texture->orientation(); + recordHWSamplerMatrix(s, getSamplerMatrix(s)); } } @@ -1311,7 +1305,7 @@ bool GrGpuGLShaders2::flushGraphicsState(PrimitiveType type) { fProgram->fRadial2PosRoot[s] = sampler.isRadial2PosRoot(); } } - + resetDirtyFlags(); return true; } diff --git a/gpu/src/GrGpuGLShaders2.h b/gpu/src/GrGpuGLShaders2.h index bb710e3..2647e23 100644 --- a/gpu/src/GrGpuGLShaders2.h +++ b/gpu/src/GrGpuGLShaders2.h @@ -40,6 +40,10 @@ private: void resetContextHelper(); + // Helpers to make code more readable + const GrMatrix& getHWSamplerMatrix(int stage); + void recordHWSamplerMatrix(int stage, const GrMatrix& matrix); + // sets the texture matrix uniform for currently bound program void flushTextureMatrix(int stage); @@ -89,8 +93,6 @@ private: void ProgramUnitTest(); - GrGLTexture::Orientation fTextureOrientation; - ProgramCache* fProgramCache; Program* fProgram; GLuint fHWProgramID; diff --git a/gpu/src/GrMatrix.cpp b/gpu/src/GrMatrix.cpp index 023968c..ee20679 100644 --- a/gpu/src/GrMatrix.cpp +++ b/gpu/src/GrMatrix.cpp @@ -70,15 +70,6 @@ const GrMatrix::MapProc GrMatrix::gMapProcs[] = { &GrMatrix::mapPerspective, }; -const GrMatrix& GrMatrix::I() { - static GrMatrix* gIdent; - if (NULL == gIdent) { - gIdent = new GrMatrix; - gIdent->setIdentity(); - } - return *gIdent; -} - void GrMatrix::setIdentity() { fM[0] = GR_Scalar1; fM[1] = 0; fM[2] = 0; fM[3] = 0; fM[4] = GR_Scalar1; fM[5] = 0; @@ -161,7 +152,7 @@ void GrMatrix::setConcat(const GrMatrix& a, const GrMatrix& b) { tmp.fM[8] = a.fM[6] * b.fM[2] + a.fM[7] * b.fM[5] + a.fM[8] * b.fM[8]; } *this = tmp; - setTypeMask(); + this->computeTypeMask(); } void GrMatrix::preConcat(const GrMatrix& m) { @@ -239,7 +230,7 @@ bool GrMatrix::invert(GrMatrix* inverted) const { inverted->fM[7] = 0; inverted->fM[8] = (GrScalar)(t[8] * det); } - inverted->setTypeMask(); + inverted->computeTypeMask(); return true; } @@ -347,26 +338,6 @@ bool GrMatrix::operator != (const GrMatrix& m) const { return !(*this == m); } -void GrMatrix::setTypeMask() -{ - 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; - } -} - //////////////////////////////////////////////////////////////////////////////// // Matrix transformation procs ////// @@ -648,17 +619,17 @@ void GrMatrix::UnitTest() { a.set(j, GR_Scalar1); mask = a.fTypeMask; - a.setTypeMask(); + a.computeTypeMask(); GrAssert(mask == a.fTypeMask); a.set(j, 0); mask = a.fTypeMask; - a.setTypeMask(); + a.computeTypeMask(); GrAssert(mask == a.fTypeMask); a.set(j, 10 * GR_Scalar1); mask = a.fTypeMask; - a.setTypeMask(); + a.computeTypeMask(); GrAssert(mask == a.fTypeMask); a.set(j, old); diff --git a/gpu/src/GrTextContext.cpp b/gpu/src/GrTextContext.cpp index 7341005..0f244a2 100644 --- a/gpu/src/GrTextContext.cpp +++ b/gpu/src/GrTextContext.cpp @@ -45,7 +45,6 @@ void GrTextContext::flushGlyphs() { int nIndices = fCurrVertex + (fCurrVertex >> 1); GrAssert(fCurrTexture); fDrawTarget->setTexture(TEXT_STAGE, fCurrTexture); - fDrawTarget->setTextureMatrix(TEXT_STAGE, GrMatrix::I()); fDrawTarget->setIndexSourceToBuffer(fContext->getQuadIndexBuffer()); fDrawTarget->drawIndexed(GrDrawTarget::kTriangles_PrimitiveType, @@ -94,7 +93,7 @@ GrTextContext::GrTextContext(GrContext* context, fVertexLayout |= GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(0); GrMatrix inverseViewMatrix; if (fOrigViewMatrix.invert(&inverseViewMatrix)) { - fPaint.fTextureMatrix.preConcat(inverseViewMatrix); + fPaint.fSampler.preConcatMatrix(inverseViewMatrix); } } diff --git a/gpu/src/GrTextureCache.cpp b/gpu/src/GrTextureCache.cpp index e27272e..fe3ff68 100644 --- a/gpu/src/GrTextureCache.cpp +++ b/gpu/src/GrTextureCache.cpp @@ -228,8 +228,8 @@ void GrTextureCache::purgeAsNeeded() { #if GR_DUMP_TEXTURE_UPLOAD GrPrintf("--- ~texture from cache %p [%d %d]\n", entry->texture(), - entry->texture()->contentWidth(), - entry->texture()->contentHeight()); + entry->texture()->width(), + entry->texture()->height()); #endif delete entry; } diff --git a/gpu/src/gr_files.mk b/gpu/src/gr_files.mk index 4c06345..e6d6997 100644 --- a/gpu/src/gr_files.mk +++ b/gpu/src/gr_files.mk @@ -8,11 +8,10 @@ SOURCE := \ GrGLTexture.cpp \ GrGLVertexBuffer.cpp \ GrGpu.cpp \ - GrGpuGLShaders.cpp \ GrGpuGLShaders2.cpp \ GrGpuGLFixed.cpp \ GrGpuFactory.cpp \ - GrGLUtil.cpp \ + GrGLUtil.cpp \ GrGpuGL.cpp \ GrInOrderDrawBuffer.cpp \ GrMatrix.cpp \ diff --git a/include/gpu/SkGpuDevice.h b/include/gpu/SkGpuDevice.h index 49a14da..db65e05 100644 --- a/include/gpu/SkGpuDevice.h +++ b/include/gpu/SkGpuDevice.h @@ -169,7 +169,7 @@ private: GrPaint* grPaint); SkDrawProcs* initDrawForText(GrTextContext*); - bool bindDeviceAsTexture(GrPaint* paint, SkPoint* max); + bool bindDeviceAsTexture(GrPaint* paint); void prepareRenderTarget(const SkDraw&); void internalDrawBitmap(const SkDraw&, const SkBitmap&, diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp index 22d5b20..faa31f6 100644 --- a/src/gpu/SkGpuDevice.cpp +++ b/src/gpu/SkGpuDevice.cpp @@ -314,15 +314,9 @@ void SkGpuDevice::gainFocus(SkCanvas* canvas, const SkMatrix& matrix, } } -bool SkGpuDevice::bindDeviceAsTexture(GrPaint* paint, SkPoint* max) { +bool SkGpuDevice::bindDeviceAsTexture(GrPaint* paint) { if (NULL != fTexture) { paint->setTexture(fTexture); - if (NULL != max) { - max->set(SkFixedToScalar((width() << 16) / - fTexture->allocWidth()), - SkFixedToScalar((height() << 16) / - fTexture->allocHeight())); - } return true; } return false; @@ -408,7 +402,6 @@ bool SkGpuDevice::skPaint2GrPaintShader(const SkPaint& skPaint, grPaint->fSampler.setFilter(skPaint.isFilterBitmap()); grPaint->fSampler.setWrapX(sk_tile_mode_to_grwrap(tileModes[0])); grPaint->fSampler.setWrapY(sk_tile_mode_to_grwrap(tileModes[1])); - if (GrSamplerState::kRadial2_SampleMode == sampleMode) { grPaint->fSampler.setRadial2Params(twoPointParams[0], twoPointParams[1], @@ -432,20 +425,16 @@ bool SkGpuDevice::skPaint2GrPaintShader(const SkPaint& skPaint, } } if (SkShader::kDefault_BitmapType == bmptype) { - GrScalar sx = (GR_Scalar1 * texture->contentWidth()) / - (bitmap.width() * texture->allocWidth()); - GrScalar sy = (GR_Scalar1 * texture->contentHeight()) / - (bitmap.height() * texture->allocHeight()); + GrScalar sx = GrFixedToScalar(GR_Fixed1 / bitmap.width()); + GrScalar sy = GrFixedToScalar(GR_Fixed1 / bitmap.height()); matrix.postScale(sx, sy); - } else if (SkShader::kRadial_BitmapType == bmptype) { - GrScalar s = (GR_Scalar1 * texture->contentWidth()) / - (bitmap.width() * texture->allocWidth()); + GrScalar s = GrFixedToScalar(GR_Fixed1 / bitmap.width()); matrix.postScale(s, s); } - - GrMatrix grmat; - SkGr::SkMatrix2GrMatrix(matrix, &grPaint->fTextureMatrix); + GrMatrix grMat; + SkGr::SkMatrix2GrMatrix(matrix, &grMat); + grPaint->fSampler.setMatrix(grMat); return true; } @@ -722,20 +711,15 @@ static bool drawWithMaskFilter(GrContext* context, const SkPath& path, grp->setTexture(texture); texture->unref(); grp->fSampler.setClampNoFilter(); - grp->fTextureMatrix.setIdentity(); - SkPoint max; - max.set(SkFixedToScalar((texture->contentWidth() << 16) / - texture->allocWidth()), - SkFixedToScalar((texture->contentHeight() << 16) / - texture->allocHeight())); - - GrRect r; - r.setLTRB(GrIntToScalar(dstM.fBounds.fLeft), + GrRect d; + d.setLTRB(GrIntToScalar(dstM.fBounds.fLeft), GrIntToScalar(dstM.fBounds.fTop), GrIntToScalar(dstM.fBounds.fRight), GrIntToScalar(dstM.fBounds.fBottom)); - context->drawRectToRect(*grp, r, GrRect(0, 0, max.fX, max.fY)); + GrRect s; + s.setLTRB(0, 0, GR_Scalar1, GR_Scalar1); + context->drawRectToRect(*grp, d, s); return true; } @@ -919,6 +903,7 @@ void SkGpuDevice::internalDrawBitmap(const SkDraw& draw, grPaint->fSampler.setWrapX(GrSamplerState::kClamp_WrapMode); grPaint->fSampler.setWrapY(GrSamplerState::kClamp_WrapMode); grPaint->fSampler.setSampleMode(GrSamplerState::kNormal_SampleMode); + grPaint->fSampler.setMatrix(GrMatrix::I()); GrTexture* texture; SkAutoCachedTexture act(this, bitmap, grPaint->fSampler, &texture); @@ -927,12 +912,13 @@ void SkGpuDevice::internalDrawBitmap(const SkDraw& draw, } grPaint->setTexture(texture); - grPaint->fTextureMatrix.setIdentity(); + GrRect dstRect(0, 0, GrIntToScalar(srcRect.width()), GrIntToScalar(srcRect.height())); - GrRect paintRect(GrIntToScalar(srcRect.fLeft) / texture->allocWidth(), - GrIntToScalar(srcRect.fTop) / texture->allocHeight(), - GrIntToScalar(srcRect.fRight) / texture->allocWidth(), - GrIntToScalar(srcRect.fBottom) / texture->allocHeight()); + GrRect paintRect; + paintRect.setLTRB(GrFixedToScalar((srcRect.fLeft << 16) / bitmap.width()), + GrFixedToScalar((srcRect.fTop << 16) / bitmap.height()), + GrFixedToScalar((srcRect.fRight << 16) / bitmap.width()), + GrFixedToScalar((srcRect.fBottom << 16) / bitmap.height())); GrMatrix grMat; SkGr::SkMatrix2GrMatrix(m, &grMat); @@ -960,29 +946,21 @@ void SkGpuDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap, grPaint.fSampler.setClampNoFilter(); SkAutoCachedTexture act(this, bitmap, grPaint.fSampler, &texture); - grPaint.fTextureMatrix.setIdentity(); grPaint.setTexture(texture); - SkPoint max; - max.set(SkFixedToScalar((texture->contentWidth() << 16) / - texture->allocWidth()), - SkFixedToScalar((texture->contentHeight() << 16) / - texture->allocHeight())); - fContext->drawRectToRect(grPaint, GrRect(GrIntToScalar(left), GrIntToScalar(top), GrIntToScalar(left + bitmap.width()), GrIntToScalar(top + bitmap.height())), - GrRect(0, 0, max.fX, max.fY)); + GrRect(0, 0, GR_Scalar1, GR_Scalar1)); } void SkGpuDevice::drawDevice(const SkDraw& draw, SkDevice* dev, int x, int y, const SkPaint& paint) { CHECK_SHOULD_DRAW(draw); - SkPoint max; GrPaint grPaint; - if (!((SkGpuDevice*)dev)->bindDeviceAsTexture(&grPaint, &max) || + if (!((SkGpuDevice*)dev)->bindDeviceAsTexture(&grPaint) || !this->skPaint2GrPaintNoShader(paint, true, &grPaint)) { return; } @@ -996,17 +974,13 @@ void SkGpuDevice::drawDevice(const SkDraw& draw, SkDevice* dev, GrAutoMatrix avm(fContext, GrMatrix::I()); grPaint.fSampler.setClampNoFilter(); - grPaint.fTextureMatrix.setIdentity(); fContext->drawRectToRect(grPaint, GrRect(GrIntToScalar(x), GrIntToScalar(y), GrIntToScalar(x + w), GrIntToScalar(y + h)), - GrRect(0, - 0, - GrIntToScalar(max.fX), - GrIntToScalar(max.fY))); + GrRect(0, 0, GR_Scalar1, GR_Scalar1)); } /////////////////////////////////////////////////////////////////////////////// diff --git a/vs/SampleApp/SampleApp.vcxproj b/vs/SampleApp/SampleApp.vcxproj index bf0f5fa..b1457fe 100644 --- a/vs/SampleApp/SampleApp.vcxproj +++ b/vs/SampleApp/SampleApp.vcxproj @@ -151,7 +151,6 @@ - @@ -225,7 +224,6 @@ - @@ -477,4 +475,4 @@ - + \ No newline at end of file diff --git a/xcode/gpu/gpu.xcodeproj/project.pbxproj b/xcode/gpu/gpu.xcodeproj/project.pbxproj index 53d6657..96128bc 100644 --- a/xcode/gpu/gpu.xcodeproj/project.pbxproj +++ b/xcode/gpu/gpu.xcodeproj/project.pbxproj @@ -22,8 +22,6 @@ 00115E1612C1167A008296FE /* GrGpuGL.h in Headers */ = {isa = PBXBuildFile; fileRef = 00115DE612C1167A008296FE /* GrGpuGL.h */; }; 00115E1712C1167A008296FE /* GrGpuGLFixed.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00115DE712C1167A008296FE /* GrGpuGLFixed.cpp */; }; 00115E1812C1167A008296FE /* GrGpuGLFixed.h in Headers */ = {isa = PBXBuildFile; fileRef = 00115DE812C1167A008296FE /* GrGpuGLFixed.h */; }; - 00115E1912C1167A008296FE /* GrGpuGLShaders.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00115DE912C1167A008296FE /* GrGpuGLShaders.cpp */; }; - 00115E1A12C1167A008296FE /* GrGpuGLShaders.h in Headers */ = {isa = PBXBuildFile; fileRef = 00115DEA12C1167A008296FE /* GrGpuGLShaders.h */; }; 00115E1B12C1167A008296FE /* GrGpuGLShaders2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00115DEB12C1167A008296FE /* GrGpuGLShaders2.cpp */; }; 00115E1C12C1167A008296FE /* GrGpuGLShaders2.h in Headers */ = {isa = PBXBuildFile; fileRef = 00115DEC12C1167A008296FE /* GrGpuGLShaders2.h */; }; 00115E1D12C1167A008296FE /* GrInOrderDrawBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00115DED12C1167A008296FE /* GrInOrderDrawBuffer.cpp */; }; @@ -113,8 +111,6 @@ 00115DE612C1167A008296FE /* GrGpuGL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GrGpuGL.h; path = ../../gpu/src/GrGpuGL.h; sourceTree = SOURCE_ROOT; }; 00115DE712C1167A008296FE /* GrGpuGLFixed.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = GrGpuGLFixed.cpp; path = ../../gpu/src/GrGpuGLFixed.cpp; sourceTree = SOURCE_ROOT; }; 00115DE812C1167A008296FE /* GrGpuGLFixed.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GrGpuGLFixed.h; path = ../../gpu/src/GrGpuGLFixed.h; sourceTree = SOURCE_ROOT; }; - 00115DE912C1167A008296FE /* GrGpuGLShaders.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = GrGpuGLShaders.cpp; path = ../../gpu/src/GrGpuGLShaders.cpp; sourceTree = SOURCE_ROOT; }; - 00115DEA12C1167A008296FE /* GrGpuGLShaders.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GrGpuGLShaders.h; path = ../../gpu/src/GrGpuGLShaders.h; sourceTree = SOURCE_ROOT; }; 00115DEB12C1167A008296FE /* GrGpuGLShaders2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = GrGpuGLShaders2.cpp; path = ../../gpu/src/GrGpuGLShaders2.cpp; sourceTree = SOURCE_ROOT; }; 00115DEC12C1167A008296FE /* GrGpuGLShaders2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GrGpuGLShaders2.h; path = ../../gpu/src/GrGpuGLShaders2.h; sourceTree = SOURCE_ROOT; }; 00115DED12C1167A008296FE /* GrInOrderDrawBuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = GrInOrderDrawBuffer.cpp; path = ../../gpu/src/GrInOrderDrawBuffer.cpp; sourceTree = SOURCE_ROOT; }; @@ -294,8 +290,6 @@ 00115DE612C1167A008296FE /* GrGpuGL.h */, 00115DE712C1167A008296FE /* GrGpuGLFixed.cpp */, 00115DE812C1167A008296FE /* GrGpuGLFixed.h */, - 00115DE912C1167A008296FE /* GrGpuGLShaders.cpp */, - 00115DEA12C1167A008296FE /* GrGpuGLShaders.h */, 00115DEB12C1167A008296FE /* GrGpuGLShaders2.cpp */, 00115DEC12C1167A008296FE /* GrGpuGLShaders2.h */, 00115DED12C1167A008296FE /* GrInOrderDrawBuffer.cpp */, @@ -337,7 +331,6 @@ files = ( 00115E1612C1167A008296FE /* GrGpuGL.h in Headers */, 00115E1812C1167A008296FE /* GrGpuGLFixed.h in Headers */, - 00115E1A12C1167A008296FE /* GrGpuGLShaders.h in Headers */, 00115E1C12C1167A008296FE /* GrGpuGLShaders2.h in Headers */, 00115E2712C1167A008296FE /* GrTextStrike_impl.h in Headers */, 00115E7512C116CA008296FE /* GrAllocator.h in Headers */, @@ -462,7 +455,6 @@ 00115E1412C1167A008296FE /* GrGpuFactory.cpp in Sources */, 00115E1512C1167A008296FE /* GrGpuGL.cpp in Sources */, 00115E1712C1167A008296FE /* GrGpuGLFixed.cpp in Sources */, - 00115E1912C1167A008296FE /* GrGpuGLShaders.cpp in Sources */, 00115E1B12C1167A008296FE /* GrGpuGLShaders2.cpp in Sources */, 00115E1D12C1167A008296FE /* GrInOrderDrawBuffer.cpp in Sources */, 00115E1E12C1167A008296FE /* GrMatrix.cpp in Sources */,