Move GrTextureParams from GrSamplerState to GrTextureAccess
authorbsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Tue, 18 Sep 2012 14:14:49 +0000 (14:14 +0000)
committerbsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Tue, 18 Sep 2012 14:14:49 +0000 (14:14 +0000)
Review URL: https://codereview.appspot.com/6496135/

git-svn-id: http://skia.googlecode.com/svn/trunk@5582 2bbb7eff-a529-9590-31e7-b0007b416f81

21 files changed:
include/gpu/GrSamplerState.h
include/gpu/GrTextureAccess.h
include/gpu/SkGpuDevice.h
src/effects/gradients/SkGradientShader.cpp
src/effects/gradients/SkGradientShaderPriv.h
src/effects/gradients/SkLinearGradient.cpp
src/effects/gradients/SkRadialGradient.cpp
src/effects/gradients/SkSweepGradient.cpp
src/effects/gradients/SkTwoPointConicalGradient.cpp
src/effects/gradients/SkTwoPointRadialGradient.cpp
src/gpu/GrContext.cpp
src/gpu/GrCustomStage.cpp
src/gpu/GrDrawState.h
src/gpu/GrTextContext.cpp
src/gpu/GrTextureAccess.cpp
src/gpu/SkGpuDevice.cpp
src/gpu/effects/GrSingleTextureEffect.cpp
src/gpu/effects/GrSingleTextureEffect.h
src/gpu/effects/GrTextureDomainEffect.cpp
src/gpu/effects/GrTextureDomainEffect.h
src/gpu/gl/GrGpuGL.cpp

index e8182f9..385dba7 100644 (file)
 
 #include "SkShader.h"
 
-class GrTextureParams {
-public:
-    GrTextureParams() {
-        this->reset();
-    }
-
-    GrTextureParams(const GrTextureParams& params) {
-        *this = params;
-    }
-
-    GrTextureParams& operator =(const GrTextureParams& params) {
-        fTileModes[0] = params.fTileModes[0];
-        fTileModes[1] = params.fTileModes[1];
-        fBilerp = params.fBilerp;
-        return *this;
-    }
-
-    void reset() {
-        this->reset(SkShader::kClamp_TileMode, false);
-    }
-
-    void reset(SkShader::TileMode tileXAndY, bool filter) {
-        fTileModes[0] = fTileModes[1] = tileXAndY;
-        fBilerp = filter;
-    }
-    void reset(SkShader::TileMode tileModes[2], bool filter) {
-        fTileModes[0] = tileModes[0];
-        fTileModes[1] = tileModes[1];
-        fBilerp = filter;
-    }
-
-    void setClampNoFilter() {
-        fTileModes[0] = fTileModes[1] = SkShader::kClamp_TileMode;
-        fBilerp = false;
-    }
-
-    void setClamp() {
-        fTileModes[0] = fTileModes[1] = SkShader::kClamp_TileMode;
-    }
-
-    void setBilerp(bool bilerp) { fBilerp = bilerp; }
-
-    void setTileModeX(const SkShader::TileMode tm) { fTileModes[0] = tm; }
-    void setTileModeY(const SkShader::TileMode tm) { fTileModes[1] = tm; }
-    void setTileModeXAndY(const SkShader::TileMode tm) { fTileModes[0] = fTileModes[1] = tm; }
-
-    SkShader::TileMode getTileModeX() const { return fTileModes[0]; }
-
-    SkShader::TileMode getTileModeY() const { return fTileModes[1]; }
-
-    bool isTiled() const {
-        return SkShader::kClamp_TileMode != fTileModes[0] ||
-               SkShader::kClamp_TileMode != fTileModes[1];
-    }
-
-    bool isBilerp() const { return fBilerp; }
-
-private:
-
-    SkShader::TileMode fTileModes[2];
-    bool               fBilerp;
-};
-
 class GrSamplerState {
 public:
     static const bool kBilerpDefault = false;
@@ -118,19 +55,13 @@ public:
     bool operator !=(const GrSamplerState& s) const { return !(*this == s); }
 
     GrSamplerState& operator =(const GrSamplerState& s) {
-        // memcpy() breaks refcounting
-        fTextureParams = s.fTextureParams;
         fMatrix = s.fMatrix;
-
         GrSafeAssign(fCustomStage, s.fCustomStage);
-
         return *this;
     }
 
     const GrMatrix& getMatrix() const { return fMatrix; }
 
-    GrTextureParams* textureParams() { return &fTextureParams; }
-    const GrTextureParams& getTextureParams() const { return fTextureParams; }
     /**
      * Access the sampler's matrix. See SampleMode for explanation of
      * relationship between the matrix and sample mode.
@@ -149,21 +80,14 @@ public:
      */
     void preConcatMatrix(const GrMatrix& matrix) { fMatrix.preConcat(matrix); }
 
-    void reset(SkShader::TileMode tileXAndY,
-               bool filter,
-               const GrMatrix& matrix) {
-        fTextureParams.reset(tileXAndY, filter);
+    void reset(const GrMatrix& matrix) {
         fMatrix = matrix;
         GrSafeSetNull(fCustomStage);
     }
-    void reset(SkShader::TileMode wrapXAndY, bool filter) {
-        this->reset(wrapXAndY, filter, GrMatrix::I());
-    }
-    void reset(const GrMatrix& matrix) {
-        this->reset(kTileModeDefault, kBilerpDefault, matrix);
-    }
+
     void reset() {
-        this->reset(kTileModeDefault, kBilerpDefault, GrMatrix::I());
+        fMatrix.reset();
+        GrSafeSetNull(fCustomStage);
     }
 
     GrCustomStage* setCustomStage(GrCustomStage* stage) {
@@ -173,7 +97,6 @@ public:
     const GrCustomStage* getCustomStage() const { return fCustomStage; }
 
 private:
-    GrTextureParams     fTextureParams;
     GrMatrix            fMatrix;
 
     GrCustomStage*      fCustomStage;
index e4e3732..7f47b6e 100644 (file)
 
 #include "GrNoncopyable.h"
 #include "SkRefCnt.h"
+#include "SkShader.h"
 
 class GrTexture;
 
+/**
+ * Represents the filtering and tile modes used to access a texture. It is mostly used with
+ * GrTextureAccess (defined below). Also, some of the texture cache methods require knowledge about
+ * filtering and tiling to perform a cache lookup. If it wasn't for this latter usage this would
+ * be folded into GrTextureAccess.
+ */
+class GrTextureParams {
+public:
+    GrTextureParams() {
+        this->reset();
+    }
+
+    GrTextureParams(SkShader::TileMode tileXAndY, bool bilerp) {
+        this->reset(tileXAndY, bilerp);
+    }
+
+    GrTextureParams(SkShader::TileMode tileModes[2], bool bilerp) {
+        this->reset(tileModes, bilerp);
+    }
+
+    GrTextureParams(const GrTextureParams& params) {
+        *this = params;
+    }
+
+    GrTextureParams& operator= (const GrTextureParams& params) {
+        fTileModes[0] = params.fTileModes[0];
+        fTileModes[1] = params.fTileModes[1];
+        fBilerp = params.fBilerp;
+        return *this;
+    }
+
+    void reset() {
+        this->reset(SkShader::kClamp_TileMode, false);
+    }
+
+    void reset(SkShader::TileMode tileXAndY, bool bilerp) {
+        fTileModes[0] = fTileModes[1] = tileXAndY;
+        fBilerp = bilerp;
+    }
+
+    void reset(SkShader::TileMode tileModes[2], bool bilerp) {
+        fTileModes[0] = tileModes[0];
+        fTileModes[1] = tileModes[1];
+        fBilerp = bilerp;
+    }
+
+    void setClampNoFilter() {
+        fTileModes[0] = fTileModes[1] = SkShader::kClamp_TileMode;
+        fBilerp = false;
+    }
+
+    void setClamp() {
+        fTileModes[0] = fTileModes[1] = SkShader::kClamp_TileMode;
+    }
+
+    void setBilerp(bool bilerp) { fBilerp = bilerp; }
+
+    void setTileModeX(const SkShader::TileMode tm) { fTileModes[0] = tm; }
+    void setTileModeY(const SkShader::TileMode tm) { fTileModes[1] = tm; }
+    void setTileModeXAndY(const SkShader::TileMode tm) { fTileModes[0] = fTileModes[1] = tm; }
+
+    SkShader::TileMode getTileModeX() const { return fTileModes[0]; }
+
+    SkShader::TileMode getTileModeY() const { return fTileModes[1]; }
+
+    bool isTiled() const {
+        return SkShader::kClamp_TileMode != fTileModes[0] ||
+               SkShader::kClamp_TileMode != fTileModes[1];
+    }
+
+    bool isBilerp() const { return fBilerp; }
+
+    bool operator== (const GrTextureParams& other) const {
+        return fTileModes[0] == other.fTileModes[0] &&
+               fTileModes[1] == other.fTileModes[1] &&
+               fBilerp == other.fBilerp;
+    }
+
+    bool operator!= (const GrTextureParams& other) const { return !(*this == other); }
+
+private:
+
+    SkShader::TileMode fTileModes[2];
+    bool               fBilerp;
+};
+
 /** A class representing the swizzle access pattern for a texture. Note that if the texture is
  *  an alpha-only texture then the alpha channel is substituted for other components. Any mangling
  *  to handle the r,g,b->a conversions for alpha textures is automatically included in the stage
@@ -28,18 +115,44 @@ public:
     GrTextureAccess();
 
     /**
-     * swizzle must be a string between one and four (inclusive) characters containing only 'r',
-     * 'g', 'b',  and/or 'a'.
+     * Uses the default swizzle, "rgba".
      */
-    GrTextureAccess(GrTexture*, const char* swizzle);
+    GrTextureAccess(GrTexture*, const GrTextureParams&);
+    explicit GrTextureAccess(GrTexture*,
+                             bool bilerp = false,
+                             SkShader::TileMode tileXAndY = SkShader::kClamp_TileMode);
 
     /**
-     * Uses the default swizzle, "rgba".
+     * swizzle must be a string between one and four (inclusive) characters containing only 'r',
+     * 'g', 'b',  and/or 'a'.
      */
-    GrTextureAccess(GrTexture*);
+    GrTextureAccess(GrTexture*, const char* swizzle, const GrTextureParams&);
+    GrTextureAccess(GrTexture*,
+                    const char* swizzle,
+                    bool bilerp = false,
+                    SkShader::TileMode tileXAndY = SkShader::kClamp_TileMode);
 
-    void reset(GrTexture*, const char* swizzle);
-    void reset(GrTexture*);
+    void reset(GrTexture*, const GrTextureParams&);
+    void reset(GrTexture*,
+               bool bilerp = false,
+               SkShader::TileMode tileXAndY = SkShader::kClamp_TileMode);
+    void reset(GrTexture*, const char* swizzle, const GrTextureParams&);
+    void reset(GrTexture*,
+               const char* swizzle,
+               bool bilerp = false,
+               SkShader::TileMode tileXAndY = SkShader::kClamp_TileMode);
+
+    bool operator== (const GrTextureAccess& other) const {
+#if GR_DEBUG
+        // below assumes all chars in fSwizzle are initialized even if string is < 4 chars long.
+        GrAssert(memcmp(fSwizzle, other.fSwizzle, sizeof(fSwizzle)) ==
+                 strcmp(fSwizzle, other.fSwizzle));
+#endif
+        return fParams == other.fParams &&
+               memcmp(fSwizzle, other.fSwizzle, sizeof(fSwizzle));
+    }
+
+    bool operator!= (const GrTextureAccess& other) const { return !(*this == other); }
 
     GrTexture* getTexture() const { return fTexture.get(); }
 
@@ -60,10 +173,17 @@ public:
     /** Returns a mask indicating which components are referenced in the swizzle. */
     uint32_t swizzleMask() const { return fSwizzleMask; }
 
+    const GrTextureParams& getParams() const { return fParams; }
+
 private:
+    void setSwizzle(const char*);
+
+    GrTextureParams         fParams;
     SkAutoTUnref<GrTexture> fTexture;
     uint32_t                fSwizzleMask;
     char                    fSwizzle[5];
+
+    typedef GrNoncopyable INHERITED;
 };
 
 #endif
index 49eea26..04c4e0f 100644 (file)
@@ -156,8 +156,12 @@ private:
                           const GrTextureParams& sampler,
                           const SkIRect* srcRectPtr,
                           int* tileSize) const;
-    void internalDrawBitmap(const SkDraw&, const SkBitmap&,
-                            const SkIRect&, const SkMatrix&, GrPaint* grPaint);
+    void internalDrawBitmap(const SkDraw&,
+                            const SkBitmap&,
+                            const SkIRect&,
+                            const SkMatrix&,
+                            const GrTextureParams& params,
+                            GrPaint* grPaint);
 
     /**
      * Returns non-initialized instance.
index f0dac4d..9a965ff 100644 (file)
@@ -718,7 +718,7 @@ void GrGLGradientStage::emitColorLookup(GrGLShaderBuilder* builder,
 
 GrGradientEffect::GrGradientEffect(GrContext* ctx,
                                    const SkGradientShaderBase& shader,
-                                   GrSamplerState* sampler)
+                                   SkShader::TileMode tileMode)
     : fUseTexture (true) {
     // TODO: check for simple cases where we don't need a texture:
     //GradientInfo info;
@@ -737,14 +737,19 @@ GrGradientEffect::GrGradientEffect(GrContext* ctx,
     fAtlas = GrTextureStripAtlas::GetAtlas(desc);
     GrAssert(NULL != fAtlas);
 
+    // We always filter the gradient table. Each table is one row of a texture, so always y-clamp.
+    GrTextureParams params;
+    params.setBilerp(true);
+    params.setTileModeX(tileMode);
+
     fRow = fAtlas->lockRow(bitmap);
     if (-1 != fRow) {
         fYCoord = fAtlas->getYOffset(fRow) + GR_ScalarHalf *
                   fAtlas->getVerticalScaleFactor();
-        fTextureAccess.reset(fAtlas->getTexture());
+        fTextureAccess.reset(fAtlas->getTexture(), params);
     } else {
-        GrTexture* texture = GrLockCachedBitmapTexture(ctx, bitmap, sampler->textureParams());
-        fTextureAccess.reset(texture);
+        GrTexture* texture = GrLockCachedBitmapTexture(ctx, bitmap, &params);
+        fTextureAccess.reset(texture, params);
         fYCoord = GR_ScalarHalf;
 
         // Unlock immediately, this is not great, but we don't have a way of
index 0e7c2fc..bdea900 100644 (file)
@@ -226,8 +226,9 @@ class GrProgramStageFactory;
 class GrGradientEffect : public GrCustomStage {
 public:
 
-    GrGradientEffect(GrContext* ctx, const SkGradientShaderBase& shader,
-                     GrSamplerState* sampler);
+    GrGradientEffect(GrContext* ctx,
+                     const SkGradientShaderBase& shader,
+                     SkShader::TileMode tileMode);
 
     virtual ~GrGradientEffect();
 
index bcebc26..4b673f6 100644 (file)
@@ -503,9 +503,8 @@ private:
 class GrLinearGradient : public GrGradientEffect {
 public:
 
-    GrLinearGradient(GrContext* ctx, const SkLinearGradient& shader,
-                     GrSamplerState* sampler)
-        : INHERITED(ctx, shader, sampler) { }
+    GrLinearGradient(GrContext* ctx, const SkLinearGradient& shader, SkShader::TileMode tm)
+        : INHERITED(ctx, shader, tm) { }
     virtual ~GrLinearGradient() { }
 
     static const char* Name() { return "Linear Gradient"; }
@@ -562,10 +561,7 @@ GrCustomStage* SkLinearGradient::asNewCustomStage(GrContext* context,
                                                   GrSamplerState* sampler) const {
     SkASSERT(NULL != context && NULL != sampler);
     sampler->matrix()->preConcat(fPtsToUnit);
-    sampler->textureParams()->setTileModeX(fTileMode);
-    sampler->textureParams()->setTileModeY(kClamp_TileMode);
-    sampler->textureParams()->setBilerp(true);
-    return SkNEW_ARGS(GrLinearGradient, (context, *this, sampler));
+    return SkNEW_ARGS(GrLinearGradient, (context, *this, fTileMode));
 }
 
 #else
index 799e548..512eafb 100644 (file)
@@ -500,10 +500,8 @@ private:
 class GrRadialGradient : public GrGradientEffect {
 public:
 
-    GrRadialGradient(GrContext* ctx,
-                     const SkRadialGradient& shader,
-                     GrSamplerState* sampler)
-        : INHERITED(ctx, shader, sampler) {
+    GrRadialGradient(GrContext* ctx, const SkRadialGradient& shader, SkShader::TileMode tm)
+        : INHERITED(ctx, shader, tm) {
     }
 
     virtual ~GrRadialGradient() { }
@@ -562,10 +560,7 @@ GrCustomStage* SkRadialGradient::asNewCustomStage(GrContext* context,
     GrSamplerState* sampler) const {
     SkASSERT(NULL != context && NULL != sampler);
     sampler->matrix()->preConcat(fPtsToUnit);
-    sampler->textureParams()->setTileModeX(fTileMode);
-    sampler->textureParams()->setTileModeY(kClamp_TileMode);
-    sampler->textureParams()->setBilerp(true);
-    return SkNEW_ARGS(GrRadialGradient, (context, *this, sampler));
+    return SkNEW_ARGS(GrRadialGradient, (context, *this, fTileMode));
 }
 
 #else
index 843d1aa..f18b08e 100644 (file)
@@ -410,9 +410,8 @@ class GrSweepGradient : public GrGradientEffect {
 public:
 
     GrSweepGradient(GrContext* ctx,
-                    const SkSweepGradient& shader,
-                    GrSamplerState* sampler)
-    : INHERITED(ctx, shader, sampler) { }
+                    const SkSweepGradient& shader)
+    : INHERITED(ctx, shader, SkShader::kClamp_TileMode) { }
     virtual ~GrSweepGradient() { }
 
     static const char* Name() { return "Sweep Gradient"; }
@@ -467,10 +466,7 @@ void GrGLSweepGradient::emitFS(GrGLShaderBuilder* builder,
 GrCustomStage* SkSweepGradient::asNewCustomStage(GrContext* context,
     GrSamplerState* sampler) const {
     sampler->matrix()->preConcat(fPtsToUnit);
-    sampler->textureParams()->setTileModeX(fTileMode);
-    sampler->textureParams()->setTileModeY(kClamp_TileMode);
-    sampler->textureParams()->setBilerp(true);
-    return SkNEW_ARGS(GrSweepGradient, (context, *this, sampler));
+    return SkNEW_ARGS(GrSweepGradient, (context, *this));
 }
 
 #else
index 3466d2c..31e3b37 100644 (file)
@@ -370,9 +370,10 @@ private:
 class GrConical2Gradient : public GrGradientEffect {
 public:
 
-    GrConical2Gradient(GrContext* ctx, const SkTwoPointConicalGradient& shader,
-                       GrSamplerState* sampler)
-        : INHERITED(ctx, shader, sampler)
+    GrConical2Gradient(GrContext* ctx,
+                       const SkTwoPointConicalGradient& shader,
+                       SkShader::TileMode tm)
+        : INHERITED(ctx, shader, tm)
         , fCenterX1(shader.getCenterX1())
         , fRadius0(shader.getStartRadius())
         , fDiffRadius(shader.getDiffRadius()) { }
@@ -685,10 +686,7 @@ GrCustomStage* SkTwoPointConicalGradient::asNewCustomStage(
         sampler->matrix()->reset();
     }
     sampler->matrix()->preTranslate(-fCenter1.fX, -fCenter1.fY);
-    sampler->textureParams()->setTileModeX(fTileMode);
-    sampler->textureParams()->setTileModeY(kClamp_TileMode);
-    sampler->textureParams()->setBilerp(true);
-    return SkNEW_ARGS(GrConical2Gradient, (context, *this, sampler));
+    return SkNEW_ARGS(GrConical2Gradient, (context, *this, fTileMode));
 }
 
 #else
index 9362ded..97f335d 100644 (file)
@@ -405,9 +405,8 @@ private:
 class GrRadial2Gradient : public GrGradientEffect {
 public:
 
-    GrRadial2Gradient(GrContext* ctx, const SkTwoPointRadialGradient& shader,
-                      GrSamplerState* sampler)
-        : INHERITED(ctx, shader, sampler)
+    GrRadial2Gradient(GrContext* ctx, const SkTwoPointRadialGradient& shader, SkShader::TileMode tm)
+        : INHERITED(ctx, shader, tm)
         , fCenterX1(shader.getCenterX1())
         , fRadius0(shader.getStartRadius())
         , fPosRoot(shader.getDiffRadius() < 0) { }
@@ -660,10 +659,7 @@ GrCustomStage* SkTwoPointRadialGradient::asNewCustomStage(
         sampler->matrix()->reset();
     }
     sampler->matrix()->preConcat(fPtsToUnit);
-    sampler->textureParams()->setTileModeX(fTileMode);
-    sampler->textureParams()->setTileModeY(kClamp_TileMode);
-    sampler->textureParams()->setBilerp(true);
-    return SkNEW_ARGS(GrRadial2Gradient, (context, *this, sampler));
+    return SkNEW_ARGS(GrRadial2Gradient, (context, *this, fTileMode));
 }
 
 #else
index 9e2e014..05ca687 100644 (file)
@@ -309,9 +309,9 @@ GrTexture* GrContext::createResizedTexture(const GrTextureDesc& desc,
         // if filtering is not desired then we want to ensure all
         // texels in the resampled image are copies of texels from
         // the original.
-        drawState->sampler(0)->reset(SkShader::kClamp_TileMode,
-                                     needsFiltering);
-        drawState->createTextureEffect(0, clampedTexture);
+        drawState->sampler(0)->reset();
+        GrTextureParams params(SkShader::kClamp_TileMode, needsFiltering);
+        drawState->createTextureEffect(0, clampedTexture, params);
 
         static const GrVertexLayout layout =
                             GrDrawTarget::StageTexCoordVertexLayoutBit(0,0);
@@ -1864,7 +1864,6 @@ GrTexture* GrContext::gaussianBlur(GrTexture* srcTexture,
 
     GrPaint paint;
     paint.reset();
-    paint.textureSampler(0)->textureParams()->setBilerp(true);
 
     for (int i = 1; i < scaleFactorX || i < scaleFactorY; i *= 2) {
         paint.textureSampler(0)->matrix()->setIDiv(srcTexture->width(),
@@ -1874,7 +1873,7 @@ GrTexture* GrContext::gaussianBlur(GrTexture* srcTexture,
         scale_rect(&dstRect, i < scaleFactorX ? 0.5f : 1.0f,
                             i < scaleFactorY ? 0.5f : 1.0f);
         paint.textureSampler(0)->setCustomStage(SkNEW_ARGS(GrSingleTextureEffect,
-                                                           (srcTexture)))->unref();
+                                                           (srcTexture, true)))->unref();
         this->drawRectToRect(paint, dstRect, srcRect);
         srcRect = dstRect;
         srcTexture = dstTexture;
@@ -1928,12 +1927,11 @@ GrTexture* GrContext::gaussianBlur(GrTexture* srcTexture,
                                       1, srcIRect.height());
         this->clear(&clearRect, 0x0);
         // FIXME:  This should be mitchell, not bilinear.
-        paint.textureSampler(0)->textureParams()->setBilerp(true);
         paint.textureSampler(0)->matrix()->setIDiv(srcTexture->width(),
                                                    srcTexture->height());
         this->setRenderTarget(dstTexture->asRenderTarget());
         paint.textureSampler(0)->setCustomStage(SkNEW_ARGS(GrSingleTextureEffect,
-                                                           (srcTexture)))->unref();
+                                                           (srcTexture, true)))->unref();
         SkRect dstRect(srcRect);
         scale_rect(&dstRect, (float) scaleFactorX, (float) scaleFactorY);
         this->drawRectToRect(paint, dstRect, srcRect);
index 3f79af8..b9ad4ea 100644 (file)
@@ -55,7 +55,7 @@ bool GrCustomStage::isEqual(const GrCustomStage& s) const {
         return false;
     }
     for (int i = 0; i < this->numTextures(); ++i) {
-        if (this->texture(i) != s.texture(i)) {
+        if (this->textureAccess(i) != s.textureAccess(i)) {
             return false;
         }
     }
index 8be76b3..648c83e 100644 (file)
@@ -181,6 +181,12 @@ public:
         this->sampler(stage)->setCustomStage(
             SkNEW_ARGS(GrSingleTextureEffect, (texture)))->unref();
     }
+    void createTextureEffect(int stage, GrTexture* texture, const GrTextureParams& params) {
+        GrAssert(!this->getSampler(stage).getCustomStage());
+        this->sampler(stage)->setCustomStage(
+            SkNEW_ARGS(GrSingleTextureEffect, (texture, params)))->unref();
+    }
+
 
     bool stagesDisabled() {
         for (int i = 0; i < kNumStages; ++i) {
index edd92db..109fc6b 100644 (file)
@@ -19,6 +19,7 @@
 #include "SkPath.h"
 
 enum {
+
     kGlyphMaskStage = GrPaint::kTotalStages,
 };
 
@@ -29,12 +30,12 @@ void GrTextContext::flushGlyphs() {
     GrDrawState* drawState = fDrawTarget->drawState();
     if (fCurrVertex > 0) {
         // setup our sampler state for our text texture/atlas
-        drawState->sampler(kGlyphMaskStage)->reset(SkShader::kRepeat_TileMode,
-                                                   !fExtMatrix.isIdentity());
+        drawState->sampler(kGlyphMaskStage)->reset();
 
         GrAssert(GrIsALIGN4(fCurrVertex));
         GrAssert(fCurrTexture);
-        drawState->createTextureEffect(kGlyphMaskStage, fCurrTexture);
+        GrTextureParams params(SkShader::kRepeat_TileMode, !fExtMatrix.isIdentity());
+        drawState->createTextureEffect(kGlyphMaskStage, fCurrTexture, params);
 
         if (!GrPixelConfigIsAlphaOnly(fCurrTexture->config())) {
             if (kOne_GrBlendCoeff != fPaint.fSrcBlendCoeff ||
index c3c8038..1156ec2 100644 (file)
@@ -16,25 +16,76 @@ GrTextureAccess::GrTextureAccess() {
 #endif
 }
 
-GrTextureAccess::GrTextureAccess(GrTexture* texture, const char* swizzle) {
-    this->reset(texture, swizzle);
+GrTextureAccess::GrTextureAccess(GrTexture* texture, const GrTextureParams& params) {
+    this->reset(texture, params);
 }
 
-GrTextureAccess::GrTextureAccess(GrTexture* texture) {
-    this->reset(texture);
+GrTextureAccess::GrTextureAccess(GrTexture* texture,
+                                 bool bilerp,
+                                 SkShader::TileMode tileXAndY) {
+    this->reset(texture, bilerp, tileXAndY);
 }
 
-void GrTextureAccess::reset(GrTexture* texture, const char* swizzle) {
+GrTextureAccess::GrTextureAccess(GrTexture* texture,
+                                 const char* swizzle,
+                                 const GrTextureParams& params) {
+    this->reset(texture, swizzle, params);
+}
+
+GrTextureAccess::GrTextureAccess(GrTexture* texture,
+                                 const char* swizzle,
+                                 bool bilerp,
+                                 SkShader::TileMode tileXAndY) {
+    this->reset(texture, swizzle, bilerp, tileXAndY);
+}
+
+void GrTextureAccess::reset(GrTexture* texture,
+                            const char* swizzle,
+                            const GrTextureParams& params) {
     GrAssert(NULL != texture);
     GrAssert(strlen(swizzle) >= 1 && strlen(swizzle) <= 4);
 
-    texture->ref();
-    fTexture.reset(texture);
+    fParams = params;
+    fTexture.reset(SkRef(texture));
+    this->setSwizzle(swizzle);
+}
+
+void GrTextureAccess::reset(GrTexture* texture,
+                            const char* swizzle,
+                            bool bilerp,
+                            SkShader::TileMode tileXAndY) {
+    GrAssert(NULL != texture);
+    GrAssert(strlen(swizzle) >= 1 && strlen(swizzle) <= 4);
+
+    fParams.reset(tileXAndY, bilerp);
+    fTexture.reset(SkRef(texture));
+    this->setSwizzle(swizzle);
+}
+
+void GrTextureAccess::reset(GrTexture* texture,
+                            const GrTextureParams& params) {
+    GrAssert(NULL != texture);
+    fTexture.reset(SkRef(texture));
+    fParams = params;
+    memcpy(fSwizzle, "rgba", 5);
+    fSwizzleMask = (kRGB_SwizzleMask | kA_SwizzleFlag);
+}
+
+void GrTextureAccess::reset(GrTexture* texture,
+                            bool bilerp,
+                            SkShader::TileMode tileXAndY) {
+    GrAssert(NULL != texture);
+    fTexture.reset(SkRef(texture));
+    fParams.reset(tileXAndY, bilerp);
+    memcpy(fSwizzle, "rgba", 5);
+    fSwizzleMask = (kRGB_SwizzleMask | kA_SwizzleFlag);
+}
 
+void GrTextureAccess::setSwizzle(const char* swizzle) {
     fSwizzleMask = 0;
-    fSwizzle[4] = '\0';
+    memset(fSwizzle, '\0', 5);
     int i = 0;
-    do {
+    for (int i = 0; i < 4 && '\0' != swizzle[i]; ++i) {
         fSwizzle[i] = swizzle[i];
         switch (swizzle[i]) {
             case 'r':
@@ -49,19 +100,9 @@ void GrTextureAccess::reset(GrTexture* texture, const char* swizzle) {
             case 'a':
                 fSwizzleMask |= kA_SwizzleFlag;
                 break;
-            case '\0':
-                break;
             default:
                 GrCrash("Unexpected swizzle string character.");
                 break;
         }
-    } while ('\0' != swizzle[i] && ++i < 4);
-}
-
-void GrTextureAccess::reset(GrTexture* texture) {
-    GrAssert(NULL != texture);
-    texture->ref();
-    fTexture.reset(texture);
-    memcpy(fSwizzle, "rgba", 5);
-    fSwizzleMask = (kRGB_SwizzleMask | kA_SwizzleFlag);
+    }
 }
index fa0f60e..e7fd8c4 100644 (file)
@@ -545,6 +545,7 @@ inline bool skPaint2GrPaintNoShader(SkGpuDevice* dev,
     SkScalar matrix[20];
     SkBitmap colorTransformTable;
     grPaint->resetColorFilter();
+    // TODO: SkColorFilter::asCustomStage()
     if (colorFilter != NULL && colorFilter->asColorMode(&color, &filterMode)) {
         grPaint->fColorMatrixEnabled = false;
         if (!constantColor) {
@@ -558,13 +559,12 @@ inline bool skPaint2GrPaintNoShader(SkGpuDevice* dev,
         grPaint->fColorMatrixEnabled = true;
         memcpy(grPaint->fColorMatrix, matrix, sizeof(matrix));
         grPaint->fColorFilterXfermode = SkXfermode::kDst_Mode;
-    } else if (colorFilter != NULL && colorFilter->asComponentTable(
-        &colorTransformTable)) {
+    } else if (colorFilter != NULL && colorFilter->asComponentTable(&colorTransformTable)) {
         grPaint->resetColorFilter();
 
+        // pass NULL because the color table effect doesn't use tiling or filtering.
+        GrTexture* texture = act->set(dev, colorTransformTable, NULL);
         GrSamplerState* colorSampler = grPaint->textureSampler(kColorFilterTextureIdx);
-        GrTexture* texture = act->set(dev, colorTransformTable, colorSampler->textureParams());
-
         colorSampler->reset();
         colorSampler->setCustomStage(SkNEW_ARGS(GrColorTableEffect, (texture)))->unref();
     }
@@ -638,15 +638,16 @@ inline bool skPaint2GrPaintShader(SkGpuDevice* dev,
     }
 
     // Must set wrap and filter on the sampler before requesting a texture.
-    sampler->textureParams()->reset(tileModes, skPaint.isFilterBitmap());
-    GrTexture* texture = textures[kShaderTextureIdx].set(dev, bitmap, sampler->textureParams());
+    GrTextureParams params(tileModes, skPaint.isFilterBitmap());
+    GrTexture* texture = textures[kShaderTextureIdx].set(dev, bitmap, &params);
 
     if (NULL == texture) {
         SkDebugf("Couldn't convert bitmap to texture.\n");
         return false;
     }
 
-    sampler->setCustomStage(SkNEW_ARGS(GrSingleTextureEffect, (texture)))->unref();
+    sampler->reset();
+    sampler->setCustomStage(SkNEW_ARGS(GrSingleTextureEffect, (texture, params)))->unref();
 
     // since our texture coords will be in local space, we wack the texture
     // matrix to map them back into 0...1 before we load it
@@ -923,7 +924,6 @@ bool drawWithGPUMaskFilter(GrContext* context, const SkPath& path,
     if (!isNormalBlur) {
         GrPaint paint;
         paint.reset();
-        paint.textureSampler(0)->textureParams()->setClampNoFilter();
         paint.textureSampler(0)->matrix()->setIDiv(pathTexture->width(),
                                                    pathTexture->height());
         // Blend pathTexture over blurTexture.
@@ -1269,7 +1269,7 @@ void SkGpuDevice::drawBitmap(const SkDraw& draw,
             srcRect.set(0,0, srcRect.width(), srcRect.height());
         }
         SkPaint paintWithTexture(paint);
-        paintWithTexture.setShader(SkShader::CreateBitmapShader( *bitmapPtr,
+        paintWithTexture.setShader(SkShader::CreateBitmapShader(*bitmapPtr,
             SkShader::kClamp_TileMode, SkShader::kClamp_TileMode))->unref();
         SkRect ScalarRect;
         ScalarRect.set(srcRect);
@@ -1292,13 +1292,13 @@ void SkGpuDevice::drawBitmap(const SkDraw& draw,
     if (!skPaint2GrPaintNoShader(this, paint, true, false, &colorLutTexture, &grPaint)) {
         return;
     }
-    GrTextureParams* params = grPaint.textureSampler(kBitmapTextureIdx)->textureParams();
-    params->setBilerp(paint.isFilterBitmap());
+    GrTextureParams params;
+    params.setBilerp(paint.isFilterBitmap());
 
     int tileSize;
-    if (!this->shouldTileBitmap(bitmap, *params, srcRectPtr, &tileSize)) {
+    if (!this->shouldTileBitmap(bitmap, params, srcRectPtr, &tileSize)) {
         // take the simple case
-        this->internalDrawBitmap(draw, bitmap, srcRect, m, &grPaint);
+        this->internalDrawBitmap(draw, bitmap, srcRect, m, params, &grPaint);
         return;
     }
 
@@ -1348,7 +1348,7 @@ void SkGpuDevice::drawBitmap(const SkDraw& draw,
                     int dy = tileR.fTop -  DY + SkMax32(0, srcR.fTop);
                     tmpM.preTranslate(SkIntToScalar(dx), SkIntToScalar(dy));
                 }
-                this->internalDrawBitmap(draw, tmpB, srcR, tmpM, &grPaint);
+                this->internalDrawBitmap(draw, tmpB, srcR, tmpM, params, &grPaint);
             }
         }
     }
@@ -1408,6 +1408,7 @@ void SkGpuDevice::internalDrawBitmap(const SkDraw& draw,
                                      const SkBitmap& bitmap,
                                      const SkIRect& srcRect,
                                      const SkMatrix& m,
+                                     const GrTextureParams& params,
                                      GrPaint* grPaint) {
     SkASSERT(bitmap.width() <= fContext->getMaxTextureSize() &&
              bitmap.height() <= fContext->getMaxTextureSize());
@@ -1420,18 +1421,14 @@ void SkGpuDevice::internalDrawBitmap(const SkDraw& draw,
 
     GrSamplerState* sampler = grPaint->textureSampler(kBitmapTextureIdx);
 
-    sampler->textureParams()->setClamp();
     sampler->matrix()->reset();
 
     GrTexture* texture;
-    SkAutoCachedTexture act(this, bitmap, sampler->textureParams(), &texture);
+    SkAutoCachedTexture act(this, bitmap, &params, &texture);
     if (NULL == texture) {
         return;
     }
 
-    grPaint->textureSampler(kBitmapTextureIdx)->setCustomStage(SkNEW_ARGS
-        (GrSingleTextureEffect, (texture)))->unref();
-
     GrRect dstRect = SkRect::MakeWH(GrIntToScalar(srcRect.width()),
                                     GrIntToScalar(srcRect.height()));
     GrRect paintRect;
@@ -1443,7 +1440,7 @@ void SkGpuDevice::internalDrawBitmap(const SkDraw& draw,
                       SkFloatToScalar(srcRect.fBottom * hInv));
 
     bool needsTextureDomain = false;
-    if (sampler->textureParams()->isBilerp()) {
+    if (params.isBilerp()) {
         // Need texture domain if drawing a sub rect.
         needsTextureDomain = srcRect.width() < bitmap.width() || srcRect.height() < bitmap.height();
         if (m.rectStaysRect() && draw.fMatrix->rectStaysRect()) {
@@ -1455,8 +1452,8 @@ void SkGpuDevice::internalDrawBitmap(const SkDraw& draw,
             srcToDeviceMatrix.mapRect(&transformedRect, floatSrcRect);
 
             if (hasAlignedSamples(floatSrcRect, transformedRect)) {
-                // Samples are texel-aligned, so filtering is futile
-                sampler->textureParams()->setBilerp(false);
+                // We could also turn off filtering here (but we already did a cache lookup with
+                // params).
                 needsTextureDomain = false;
             } else {
                 needsTextureDomain = needsTextureDomain &&
@@ -1466,7 +1463,7 @@ void SkGpuDevice::internalDrawBitmap(const SkDraw& draw,
     }
 
     GrRect textureDomain = GrRect::MakeEmpty();
-
+    SkAutoTUnref<GrCustomStage> stage;
     if (needsTextureDomain) {
         // Use a constrained texture domain to avoid color bleeding
         GrScalar left, top, right, bottom;
@@ -1485,11 +1482,11 @@ void SkGpuDevice::internalDrawBitmap(const SkDraw& draw,
             top = bottom = GrScalarHalf(paintRect.top() + paintRect.bottom());
         }
         textureDomain.setLTRB(left, top, right, bottom);
-        sampler->setCustomStage(SkNEW_ARGS(GrTextureDomainEffect,
-                     (texture,
-                      textureDomain)))->unref();
+        stage.reset(SkNEW_ARGS(GrTextureDomainEffect, (texture, textureDomain, params)));
+    } else {
+        stage.reset(SkNEW_ARGS(GrSingleTextureEffect, (texture, params)));
     }
-
+    grPaint->textureSampler(kBitmapTextureIdx)->setCustomStage(stage);
     fContext->drawRectToRect(*grPaint, dstRect, paintRect, &m);
 }
 
@@ -1509,7 +1506,6 @@ void apply_custom_stage(GrContext* context,
     sampleM.setIDiv(srcTexture->width(), srcTexture->height());
     GrPaint paint;
     paint.reset();
-    paint.textureSampler(0)->textureParams()->setBilerp(true);
     paint.textureSampler(0)->reset(sampleM);
     paint.textureSampler(0)->setCustomStage(stage);
     context->drawRect(paint, rect);
@@ -1563,7 +1559,8 @@ void SkGpuDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap,
 
     GrTexture* texture;
     sampler->reset();
-    SkAutoCachedTexture act(this, bitmap, sampler->textureParams(), &texture);
+    // draw sprite uses the default texture params
+    SkAutoCachedTexture act(this, bitmap, NULL, &texture);
     grPaint.textureSampler(kBitmapTextureIdx)->setCustomStage(SkNEW_ARGS
         (GrSingleTextureEffect, (texture)))->unref();
 
@@ -1668,7 +1665,9 @@ bool SkGpuDevice::filterImage(SkImageFilter* filter, const SkBitmap& src,
     GrSamplerState* sampler = paint.textureSampler(kBitmapTextureIdx);
 
     GrTexture* texture;
-    SkAutoCachedTexture act(this, src, sampler->textureParams(), &texture);
+    // We assume here that the filter will not attempt to tile the src. Otherwise, this cache lookup
+    // must be pushed upstack.
+    SkAutoCachedTexture act(this, src, NULL, &texture);
 
     result->setConfig(src.config(), src.width(), src.height());
     GrRect rect = GrRect::MakeWH(SkIntToScalar(src.width()),
index b2e9205..e96eb47 100644 (file)
@@ -41,6 +41,14 @@ GrSingleTextureEffect::GrSingleTextureEffect(GrTexture* texture)
     : fTextureAccess(texture) {
 }
 
+GrSingleTextureEffect::GrSingleTextureEffect(GrTexture* texture, bool bilerp)
+    : fTextureAccess(texture, bilerp) {
+}
+
+GrSingleTextureEffect::GrSingleTextureEffect(GrTexture* texture, const GrTextureParams& params)
+    : fTextureAccess(texture, params) {
+}
+
 GrSingleTextureEffect::~GrSingleTextureEffect() {
 }
 
index 2090196..4d0a40f 100644 (file)
@@ -18,7 +18,14 @@ class GrGLSingleTextureEffect;
 class GrSingleTextureEffect : public GrCustomStage {
 
 public:
+    /** Uses default texture params (unfiltered, clamp) */
     GrSingleTextureEffect(GrTexture* texture);
+
+    /** Uses default tile mode (clamp) */
+    GrSingleTextureEffect(GrTexture* texture, bool bilerp);
+
+    GrSingleTextureEffect(GrTexture* texture, const GrTextureParams&);
+
     virtual ~GrSingleTextureEffect();
 
     virtual int numTextures() const SK_OVERRIDE;
index 279e481..c00f40f 100644 (file)
@@ -91,11 +91,18 @@ void GrGLTextureDomainEffect::setData(const GrGLUniformManager& uman,
 
 ///////////////////////////////////////////////////////////////////////////////
 
-GrTextureDomainEffect::GrTextureDomainEffect(GrTexture* texture, GrRect domain)
+GrTextureDomainEffect::GrTextureDomainEffect(GrTexture* texture, const GrRect& domain)
     : GrSingleTextureEffect(texture)
     , fTextureDomain(domain) {
 }
 
+GrTextureDomainEffect::GrTextureDomainEffect(GrTexture* texture,
+                                             const GrRect& domain,
+                                             const GrTextureParams& params)
+    : GrSingleTextureEffect(texture, params)
+    , fTextureDomain(domain) {
+}
+
 GrTextureDomainEffect::~GrTextureDomainEffect() {
 
 }
index 559398e..872d57d 100644 (file)
@@ -20,8 +20,11 @@ class GrGLTextureDomainEffect;
 class GrTextureDomainEffect : public GrSingleTextureEffect {
 
 public:
+    /** Uses default texture params (no filter, clamp) */
+    GrTextureDomainEffect(GrTexture*, const GrRect& domain);
+
+    GrTextureDomainEffect(GrTexture*, const GrRect& domain, const GrTextureParams& params);
 
-    GrTextureDomainEffect(GrTexture*, GrRect domain);
     virtual ~GrTextureDomainEffect();
 
     static const char* Name() { return "TextureDomain"; }
index 1cca043..d9988c4 100644 (file)
@@ -2024,9 +2024,7 @@ void GrGpuGL::flushBoundTextureAndParams(int stage) {
     const GrCustomStage* customStage = drawState->sampler(stage)->getCustomStage();
     GrGLTexture* nextTexture =  static_cast<GrGLTexture*>(customStage->texture(0));
     if (NULL != nextTexture) {
-        // Currently we always use the texture params from the GrSamplerState. Soon custom stages
-        // will provide their own params.
-        const GrTextureParams& texParams = drawState->getSampler(stage).getTextureParams();
+        const GrTextureParams& texParams = customStage->textureAccess(0).getParams();
         this->flushBoundTextureAndParams(stage, texParams, nextTexture);
     }
 }