Move filter/wrap out of GrSamplerState into GrTextureParams
Review URL: http://codereview.appspot.com/6440046/
git-svn-id: http://skia.googlecode.com/svn/trunk@4773 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/include/gpu/GrContext.h b/include/gpu/GrContext.h
index 18abd4e..e0f5827 100644
--- a/include/gpu/GrContext.h
+++ b/include/gpu/GrContext.h
@@ -119,18 +119,16 @@
* Create a new entry, based on the specified key and texture, and return
* its "locked" entry. Must call be balanced with an unlockTexture() call.
*
- * @param sampler The sampler state used to draw a texture may be used
- * to determine how to store the pixel data in the texture
- * cache. (e.g. different versions may exist for different
- * wrap modes on GPUs with limited or no NPOT texture
- * support). Only the wrap and filter fields are used. NULL
- * implies clamp wrap modes and nearest filtering.
+ * @param params The tex params used to draw a texture may help determine
+ * the cache entry used. (e.g. different versions may exist
+ * for different wrap modes on GPUs with limited NPOT
+ * texture support). NULL implies clamp wrap modes.
* @param desc Description of the texture properties.
* @param srcData Pointer to the pixel values.
* @param rowBytes The number of bytes between rows of the texture. Zero
* implies tightly packed rows.
*/
- TextureCacheEntry createAndLockTexture(const GrSamplerState* sampler,
+ TextureCacheEntry createAndLockTexture(const GrTextureParams* params,
const GrTextureDesc& desc,
void* srcData, size_t rowBytes);
@@ -139,23 +137,21 @@
* return it. The entry's texture() function will return NULL if not found.
* Must be balanced with an unlockTexture() call.
*
- * @param desc Description of the texture properties.
- * @param sampler The sampler state used to draw a texture may be used
- * to determine the cache entry used. (e.g. different
- * versions may exist for different wrap modes on GPUs with
- * limited or no NPOT texture support). Only the wrap and
- * filter fields are used. NULL implies clamp wrap modes
- * and nearest filtering.
+ * @param desc Description of the texture properties.
+ * @param params The tex params used to draw a texture may help determine
+ * the cache entry used. (e.g. different versions may exist
+ * for different wrap modes on GPUs with limited NPOT
+ * texture support). NULL implies clamp wrap modes.
*/
TextureCacheEntry findAndLockTexture(const GrTextureDesc& desc,
- const GrSamplerState* sampler);
+ const GrTextureParams* params);
/**
* Determines whether a texture is in the cache. If the texture is found it
* will not be locked or returned. This call does not affect the priority of
* the texture for deletion.
*/
bool isTextureInCache(const GrTextureDesc& desc,
- const GrSamplerState* sampler) const;
+ const GrTextureParams* params) const;
/**
* Enum that determines how closely a returned scratch texture must match
@@ -212,9 +208,12 @@
size_t rowBytes);
/**
- * Returns true if the specified use of an indexed texture is supported.
+ * Returns true if the specified use of an indexed texture is supported.
+ * Support may depend upon whether the texture params indicate that the
+ * texture will be tiled. Passing NULL for the texture params indicates
+ * clamp mode.
*/
- bool supportsIndex8PixelConfig(const GrSamplerState* sampler,
+ bool supportsIndex8PixelConfig(const GrTextureParams*,
int width,
int height) const;
diff --git a/include/gpu/GrSamplerState.h b/include/gpu/GrSamplerState.h
index 0731848..04fbe00 100644
--- a/include/gpu/GrSamplerState.h
+++ b/include/gpu/GrSamplerState.h
@@ -15,31 +15,76 @@
#include "GrMatrix.h"
#include "GrTypes.h"
+#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:
- enum Filter {
- /**
- * Read the closest src texel to the sample position
- */
- kNearest_Filter,
- /**
- * Blend between closest 4 src texels to sample position (tent filter)
- */
- kBilinear_Filter,
- kDefault_Filter = kNearest_Filter
- };
+ static const bool kBilerpDefault = false;
- /**
- * Describes how a texture is sampled when coordinates are outside the
- * texture border
- */
- enum WrapMode {
- kClamp_WrapMode,
- kRepeat_WrapMode,
- kMirror_WrapMode,
-
- kDefault_WrapMode = kClamp_WrapMode
- };
+ static const SkShader::TileMode kTileModeDefault = SkShader::kClamp_TileMode;
/**
* Default sampler state is set to clamp, use normal sampling mode, be
@@ -74,9 +119,7 @@
GrSamplerState& operator =(const GrSamplerState& s) {
// memcpy() breaks refcounting
- fWrapX = s.fWrapX;
- fWrapY = s.fWrapY;
- fFilter = s.fFilter;
+ fTextureParams = s.fTextureParams;
fMatrix = s.fMatrix;
fSwapRAndB = s.fSwapRAndB;
@@ -85,15 +128,11 @@
return *this;
}
- WrapMode getWrapX() const { return fWrapX; }
- WrapMode getWrapY() const { return fWrapY; }
const GrMatrix& getMatrix() const { return fMatrix; }
- Filter getFilter() const { return fFilter; }
bool swapsRAndB() const { return fSwapRAndB; }
- void setWrapX(WrapMode mode) { fWrapX = mode; }
- void setWrapY(WrapMode mode) { fWrapY = mode; }
-
+ 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.
@@ -118,30 +157,22 @@
*/
void preConcatMatrix(const GrMatrix& matrix) { fMatrix.preConcat(matrix); }
- /**
- * Sets filtering type.
- * @param filter type of filtering to apply
- */
- void setFilter(Filter filter) { fFilter = filter; }
-
- void reset(WrapMode wrapXAndY,
- Filter filter,
+ void reset(SkShader::TileMode tileXAndY,
+ bool filter,
const GrMatrix& matrix) {
- fWrapX = wrapXAndY;
- fWrapY = wrapXAndY;
- fFilter = filter;
+ fTextureParams.reset(tileXAndY, filter);
fMatrix = matrix;
fSwapRAndB = false;
GrSafeSetNull(fCustomStage);
}
- void reset(WrapMode wrapXAndY, Filter filter) {
+ void reset(SkShader::TileMode wrapXAndY, bool filter) {
this->reset(wrapXAndY, filter, GrMatrix::I());
}
void reset(const GrMatrix& matrix) {
- this->reset(kDefault_WrapMode, kDefault_Filter, matrix);
+ this->reset(kTileModeDefault, kBilerpDefault, matrix);
}
void reset() {
- this->reset(kDefault_WrapMode, kDefault_Filter, GrMatrix::I());
+ this->reset(kTileModeDefault, kBilerpDefault, GrMatrix::I());
}
GrCustomStage* setCustomStage(GrCustomStage* stage) {
@@ -151,9 +182,7 @@
GrCustomStage* getCustomStage() const { return fCustomStage; }
private:
- WrapMode fWrapX : 8;
- WrapMode fWrapY : 8;
- Filter fFilter : 8;
+ GrTextureParams fTextureParams;
bool fSwapRAndB;
GrMatrix fMatrix;
diff --git a/include/gpu/GrTexture.h b/include/gpu/GrTexture.h
index 783a147..d4a7cc6 100644
--- a/include/gpu/GrTexture.h
+++ b/include/gpu/GrTexture.h
@@ -13,7 +13,7 @@
class GrRenderTarget;
class GrResourceKey;
-class GrSamplerState;
+class GrTextureParams;
/*
* All uncached textures should have this value as their fClientCacheID
@@ -162,7 +162,7 @@
#endif
static GrResourceKey ComputeKey(const GrGpu* gpu,
- const GrSamplerState* sampler,
+ const GrTextureParams* sampler,
const GrTextureDesc& desc,
bool scratch);
diff --git a/include/gpu/SkGpuDevice.h b/include/gpu/SkGpuDevice.h
index 2af1149..4a62813 100644
--- a/include/gpu/SkGpuDevice.h
+++ b/include/gpu/SkGpuDevice.h
@@ -118,7 +118,7 @@
protected:
typedef GrContext::TextureCacheEntry TexCache;
bool isBitmapInTextureCache(const SkBitmap& bitmap,
- const GrSamplerState& sampler) const;
+ const GrTextureParams& params) const;
// overrides from SkDevice
virtual bool onReadPixels(const SkBitmap& bitmap,
@@ -157,7 +157,7 @@
void prepareRenderTarget(const SkDraw&);
bool shouldTileBitmap(const SkBitmap& bitmap,
- const GrSamplerState& sampler,
+ const GrTextureParams& sampler,
const SkIRect* srcRectPtr,
int* tileSize) const;
void internalDrawBitmap(const SkDraw&, const SkBitmap&,
diff --git a/include/gpu/SkGr.h b/include/gpu/SkGr.h
index ea79c63..6c6e3da 100644
--- a/include/gpu/SkGr.h
+++ b/include/gpu/SkGr.h
@@ -24,7 +24,6 @@
#include "SkPath.h"
#include "SkPoint.h"
#include "SkRegion.h"
-#include "SkShader.h"
#include "SkClipStack.h"
#if (GR_DEBUG && defined(SK_RELEASE)) || (GR_RELEASE && defined(SK_DEBUG))
@@ -34,14 +33,6 @@
////////////////////////////////////////////////////////////////////////////////
// Sk to Gr Type conversions
-GR_STATIC_ASSERT((int)GrSamplerState::kClamp_WrapMode == (int)SkShader::kClamp_TileMode);
-GR_STATIC_ASSERT((int)GrSamplerState::kRepeat_WrapMode ==(
- int)SkShader::kRepeat_TileMode);
-GR_STATIC_ASSERT((int)GrSamplerState::kMirror_WrapMode ==
- (int)SkShader::kMirror_TileMode);
-
-#define sk_tile_mode_to_grwrap(X) ((GrSamplerState::WrapMode)(X))
-
GR_STATIC_ASSERT((int)kZero_GrBlendCoeff == (int)SkXfermode::kZero_Coeff);
GR_STATIC_ASSERT((int)kOne_GrBlendCoeff == (int)SkXfermode::kOne_Coeff);
GR_STATIC_ASSERT((int)kSC_GrBlendCoeff == (int)SkXfermode::kSC_Coeff);
@@ -85,11 +76,11 @@
////////////////////////////////////////////////////////////////////////////////
-GrContext::TextureCacheEntry GrLockCachedBitmapTexture(GrContext* ctx,
- const SkBitmap& bitmap,
- const GrSamplerState* sampler);
+GrContext::TextureCacheEntry GrLockCachedBitmapTexture(GrContext*,
+ const SkBitmap&,
+ const GrTextureParams*);
-void GrUnlockCachedBitmapTexture(GrContext* ctx, GrContext::TextureCacheEntry cache);
+void GrUnlockCachedBitmapTexture(GrContext*, GrContext::TextureCacheEntry);
////////////////////////////////////////////////////////////////////////////////
// Classes
diff --git a/src/effects/SkGradientShader.cpp b/src/effects/SkGradientShader.cpp
index 7a55bbb..ad27cd0 100644
--- a/src/effects/SkGradientShader.cpp
+++ b/src/effects/SkGradientShader.cpp
@@ -1050,9 +1050,9 @@
GrSamplerState* sampler) const {
SkASSERT(NULL != context && NULL != sampler);
sampler->matrix()->preConcat(fPtsToUnit);
- sampler->setWrapX(sk_tile_mode_to_grwrap(fTileMode));
- sampler->setWrapY(sk_tile_mode_to_grwrap(kClamp_TileMode));
- sampler->setFilter(GrSamplerState::kBilinear_Filter);
+ sampler->textureParams()->setTileModeX(fTileMode);
+ sampler->textureParams()->setTileModeY(kClamp_TileMode);
+ sampler->textureParams()->setBilerp(true);
return SkNEW_ARGS(GrLinearGradient, (context, *this, sampler));
}
@@ -1468,9 +1468,9 @@
GrSamplerState* sampler) const SK_OVERRIDE {
SkASSERT(NULL != context && NULL != sampler);
sampler->matrix()->preConcat(fPtsToUnit);
- sampler->setWrapX(sk_tile_mode_to_grwrap(fTileMode));
- sampler->setWrapY(sk_tile_mode_to_grwrap(kClamp_TileMode));
- sampler->setFilter(GrSamplerState::kBilinear_Filter);
+ sampler->textureParams()->setTileModeX(fTileMode);
+ sampler->textureParams()->setTileModeY(kClamp_TileMode);
+ sampler->textureParams()->setBilerp(true);
return SkNEW_ARGS(GrRadialGradient, (context, *this, sampler));
}
@@ -1930,9 +1930,9 @@
sampler->matrix()->reset();
}
sampler->matrix()->preConcat(fPtsToUnit);
- sampler->setWrapX(sk_tile_mode_to_grwrap(fTileMode));
- sampler->setWrapY(sk_tile_mode_to_grwrap(kClamp_TileMode));
- sampler->setFilter(GrSamplerState::kBilinear_Filter);
+ sampler->textureParams()->setTileModeX(fTileMode);
+ sampler->textureParams()->setTileModeY(kClamp_TileMode);
+ sampler->textureParams()->setBilerp(true);
return SkNEW_ARGS(GrRadial2Gradient, (context, *this, sampler,
diffLen, fStartRadius, fDiffRadius));
}
@@ -2395,9 +2395,9 @@
sampler->matrix()->reset();
}
sampler->matrix()->preTranslate(-fCenter1.fX, -fCenter1.fY);
- sampler->setWrapX(sk_tile_mode_to_grwrap(fTileMode));
- sampler->setWrapY(sk_tile_mode_to_grwrap(kClamp_TileMode));
- sampler->setFilter(GrSamplerState::kBilinear_Filter);
+ sampler->textureParams()->setTileModeX(fTileMode);
+ sampler->textureParams()->setTileModeY(kClamp_TileMode);
+ sampler->textureParams()->setBilerp(true);
return SkNEW_ARGS(GrConical2Gradient, (context, *this, sampler,
diffLen, fRadius1, fRadius2 - fRadius1));
}
@@ -2471,9 +2471,9 @@
virtual GrCustomStage* asNewCustomStage(GrContext* context,
GrSamplerState* sampler) const SK_OVERRIDE {
sampler->matrix()->preConcat(fPtsToUnit);
- sampler->setWrapX(sk_tile_mode_to_grwrap(fTileMode));
- sampler->setWrapY(sk_tile_mode_to_grwrap(kClamp_TileMode));
- sampler->setFilter(GrSamplerState::kBilinear_Filter);
+ sampler->textureParams()->setTileModeX(fTileMode);
+ sampler->textureParams()->setTileModeY(kClamp_TileMode);
+ sampler->textureParams()->setBilerp(true);
return SkNEW_ARGS(GrSweepGradient, (context, *this, sampler));
}
diff --git a/src/gpu/GrClipMaskManager.cpp b/src/gpu/GrClipMaskManager.cpp
index 4deebf4..d7287ea 100644
--- a/src/gpu/GrClipMaskManager.cpp
+++ b/src/gpu/GrClipMaskManager.cpp
@@ -37,9 +37,7 @@
mat.preTranslate(SkIntToScalar(-bound.fLeft), SkIntToScalar(-bound.fTop));
mat.preConcat(drawState->getViewMatrix());
- drawState->sampler(maskStage)->reset(GrSamplerState::kClamp_WrapMode,
- GrSamplerState::kNearest_Filter,
- mat);
+ drawState->sampler(maskStage)->reset(mat);
drawState->createTextureEffect(maskStage, result);
}
@@ -481,9 +479,7 @@
GrMatrix sampleM;
sampleM.setIDiv(texture->width(), texture->height());
- drawState->sampler(0)->reset(GrSamplerState::kClamp_WrapMode,
- GrSamplerState::kNearest_Filter,
- sampleM);
+ drawState->sampler(0)->reset(sampleM);
drawState->createTextureEffect(0, texture);
GrRect rect = GrRect::MakeWH(SkIntToScalar(target->width()),
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index 7321ffb..cd2b5a6 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -254,17 +254,16 @@
}
-GrContext::TextureCacheEntry GrContext::findAndLockTexture(
- const GrTextureDesc& desc,
- const GrSamplerState* sampler) {
- GrResourceKey resourceKey = GrTexture::ComputeKey(fGpu, sampler, desc, false);
+GrContext::TextureCacheEntry GrContext::findAndLockTexture(const GrTextureDesc& desc,
+ const GrTextureParams* params) {
+ GrResourceKey resourceKey = GrTexture::ComputeKey(fGpu, params, desc, false);
return TextureCacheEntry(fTextureCache->findAndLock(resourceKey,
GrResourceCache::kNested_LockType));
}
bool GrContext::isTextureInCache(const GrTextureDesc& desc,
- const GrSamplerState* sampler) const {
- GrResourceKey resourceKey = GrTexture::ComputeKey(fGpu, sampler, desc, false);
+ const GrTextureParams* params) const {
+ GrResourceKey resourceKey = GrTexture::ComputeKey(fGpu, params, desc, false);
return fTextureCache->hasKey(resourceKey);
}
@@ -324,7 +323,7 @@
}
GrContext::TextureCacheEntry GrContext::createAndLockTexture(
- const GrSamplerState* sampler,
+ const GrTextureParams* params,
const GrTextureDesc& desc,
void* srcData,
size_t rowBytes) {
@@ -336,19 +335,16 @@
TextureCacheEntry entry;
- GrResourceKey resourceKey = GrTexture::ComputeKey(fGpu, sampler,
- desc, false);
+ GrResourceKey resourceKey = GrTexture::ComputeKey(fGpu, params, desc, false);
if (GrTexture::NeedsResizing(resourceKey)) {
// The desired texture is NPOT and tiled but that isn't supported by
// the current hardware. Resize the texture to be a POT
- GrAssert(NULL != sampler);
- TextureCacheEntry clampEntry = this->findAndLockTexture(desc,
- NULL);
+ GrAssert(NULL != params);
+ TextureCacheEntry clampEntry = this->findAndLockTexture(desc, NULL);
if (NULL == clampEntry.texture()) {
- clampEntry = this->createAndLockTexture(NULL, desc,
- srcData, rowBytes);
+ clampEntry = this->createAndLockTexture(NULL, desc, srcData, rowBytes);
GrAssert(NULL != clampEntry.texture());
if (NULL == clampEntry.texture()) {
return entry;
@@ -364,22 +360,15 @@
GrTexture* texture = fGpu->createTexture(rtDesc, NULL, 0);
if (NULL != texture) {
- GrDrawTarget::AutoStateRestore asr(fGpu,
- GrDrawTarget::kReset_ASRInit);
+ GrDrawTarget::AutoStateRestore asr(fGpu, GrDrawTarget::kReset_ASRInit);
GrDrawState* drawState = fGpu->drawState();
drawState->setRenderTarget(texture->asRenderTarget());
- GrSamplerState::Filter filter;
// if filtering is not desired then we want to ensure all
// texels in the resampled image are copies of texels from
// the original.
- if (GrTexture::NeedsFiltering(resourceKey)) {
- filter = GrSamplerState::kBilinear_Filter;
- } else {
- filter = GrSamplerState::kNearest_Filter;
- }
- drawState->sampler(0)->reset(GrSamplerState::kClamp_WrapMode,
- filter);
+ drawState->sampler(0)->reset(SkShader::kClamp_TileMode,
+ GrTexture::NeedsFiltering(resourceKey));
drawState->createTextureEffect(0, clampEntry.texture());
static const GrVertexLayout layout =
@@ -570,7 +559,7 @@
///////////////////////////////////////////////////////////////////////////////
-bool GrContext::supportsIndex8PixelConfig(const GrSamplerState* sampler,
+bool GrContext::supportsIndex8PixelConfig(const GrTextureParams* params,
int width, int height) const {
const GrDrawTarget::Caps& caps = fGpu->getCaps();
if (!caps.f8BitPaletteSupport) {
@@ -580,9 +569,7 @@
bool isPow2 = GrIsPow2(width) && GrIsPow2(height);
if (!isPow2) {
- bool tiled = NULL != sampler &&
- (sampler->getWrapX() != GrSamplerState::kClamp_WrapMode ||
- sampler->getWrapY() != GrSamplerState::kClamp_WrapMode);
+ bool tiled = NULL != params && params->isTiled();
if (tiled && !caps.fNPOTTextureTileSupport) {
return false;
}
@@ -1540,9 +1527,7 @@
drawState->setRenderTarget(target);
matrix.setIDiv(texture->width(), texture->height());
- drawState->sampler(0)->reset(GrSamplerState::kClamp_WrapMode,
- GrSamplerState::kNearest_Filter,
- matrix);
+ drawState->sampler(0)->reset(matrix);
drawState->createTextureEffect(0, texture);
drawState->sampler(0)->setRAndBSwap(swapRAndB);
@@ -1823,7 +1808,7 @@
GrPaint paint;
paint.reset();
- paint.textureSampler(0)->setFilter(GrSamplerState::kBilinear_Filter);
+ paint.textureSampler(0)->textureParams()->setBilerp(true);
for (int i = 1; i < scaleFactorX || i < scaleFactorY; i *= 2) {
paint.textureSampler(0)->matrix()->setIDiv(srcTexture->width(),
@@ -1885,7 +1870,7 @@
1, srcIRect.height());
this->clear(&clearRect, 0x0);
// FIXME: This should be mitchell, not bilinear.
- paint.textureSampler(0)->setFilter(GrSamplerState::kBilinear_Filter);
+ paint.textureSampler(0)->textureParams()->setBilerp(true);
paint.textureSampler(0)->matrix()->setIDiv(srcTexture->width(),
srcTexture->height());
this->setRenderTarget(dstTexture->asRenderTarget());
diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp
index 051f112..75a2cd7 100644
--- a/src/gpu/GrDrawTarget.cpp
+++ b/src/gpu/GrDrawTarget.cpp
@@ -763,14 +763,13 @@
}
}
for (int s = 0; s < GrDrawState::kNumStages; ++s) {
- // We don't support using unpremultiplied textures with filters (other than nearest). Alpha-
- // premulling is not distributive WRT to filtering. We'd have to filter each texel before
- // filtering. We could do this for our custom filters but we would also have to disable
- // bilerp and do a custom bilerp in the shader. Until Skia itself supports unpremul configs
- // there is no pressure to implement this.
+ // We don't support using unpremultiplied textures with bilerp. Alpha-multiplication is not
+ // distributive with respect to filtering. We'd have to alpha-mul each texel before
+ // filtering. Until Skia itself supports unpremultiplied configs there is no pressure to
+ // implement this.
if (drawState.getTexture(s) &&
GrPixelConfigIsUnpremultiplied(drawState.getTexture(s)->config()) &&
- GrSamplerState::kNearest_Filter != drawState.getSampler(s).getFilter()) {
+ drawState.getSampler(s).getTextureParams().isBilerp()) {
return false;
}
}
diff --git a/src/gpu/GrTextContext.cpp b/src/gpu/GrTextContext.cpp
index 1fb17b5..925fdb3 100644
--- a/src/gpu/GrTextContext.cpp
+++ b/src/gpu/GrTextContext.cpp
@@ -29,14 +29,8 @@
GrDrawState* drawState = fDrawTarget->drawState();
if (fCurrVertex > 0) {
// setup our sampler state for our text texture/atlas
- GrSamplerState::Filter filter;
- if (fExtMatrix.isIdentity()) {
- filter = GrSamplerState::kNearest_Filter;
- } else {
- filter = GrSamplerState::kBilinear_Filter;
- }
- drawState->sampler(kGlyphMaskStage)->reset(
- GrSamplerState::kRepeat_WrapMode,filter);
+ drawState->sampler(kGlyphMaskStage)->reset(SkShader::kRepeat_TileMode,
+ fExtMatrix.isIdentity());
GrAssert(GrIsALIGN4(fCurrVertex));
GrAssert(fCurrTexture);
diff --git a/src/gpu/GrTexture.cpp b/src/gpu/GrTexture.cpp
index 8c12bd2..fbc3893 100644
--- a/src/gpu/GrTexture.cpp
+++ b/src/gpu/GrTexture.cpp
@@ -135,7 +135,7 @@
namespace {
void gen_texture_key_values(const GrGpu* gpu,
- const GrSamplerState* sampler,
+ const GrTextureParams* params,
const GrTextureDesc& desc,
bool scratch,
uint32_t v[4]) {
@@ -163,13 +163,11 @@
if (!gpu->getCaps().fNPOTTextureTileSupport) {
bool isPow2 = GrIsPow2(desc.fWidth) && GrIsPow2(desc.fHeight);
- bool tiled = NULL != sampler &&
- ((sampler->getWrapX() != GrSamplerState::kClamp_WrapMode) ||
- (sampler->getWrapY() != GrSamplerState::kClamp_WrapMode));
+ bool tiled = NULL != params && params->isTiled();
if (tiled && !isPow2) {
v[3] |= kNPOT_TextureBit;
- if (GrSamplerState::kNearest_Filter != sampler->getFilter()) {
+ if (params->isBilerp()) {
v[3] |= kFilter_TextureBit;
}
}
@@ -184,11 +182,11 @@
}
GrResourceKey GrTexture::ComputeKey(const GrGpu* gpu,
- const GrSamplerState* sampler,
+ const GrTextureParams* params,
const GrTextureDesc& desc,
bool scratch) {
uint32_t v[4];
- gen_texture_key_values(gpu, sampler, desc, scratch, v);
+ gen_texture_key_values(gpu, params, desc, scratch, v);
return GrResourceKey(v);
}
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index 80e3f37..f290239 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -85,10 +85,10 @@
SkAutoCachedTexture() { }
SkAutoCachedTexture(SkGpuDevice* device,
const SkBitmap& bitmap,
- const GrSamplerState* sampler,
+ const GrTextureParams* params,
GrTexture** texture) {
GrAssert(texture);
- *texture = this->set(device, bitmap, sampler);
+ *texture = this->set(device, bitmap, params);
}
~SkAutoCachedTexture() {
@@ -99,7 +99,7 @@
GrTexture* set(SkGpuDevice* device,
const SkBitmap& bitmap,
- const GrSamplerState* sampler) {
+ const GrTextureParams* params) {
if (fTex.texture()) {
GrUnlockCachedBitmapTexture(fDevice->context(), fTex);
}
@@ -110,7 +110,7 @@
fTex.reset();
} else {
// look it up in our cache
- fTex = GrLockCachedBitmapTexture(device->context(), bitmap, sampler);
+ fTex = GrLockCachedBitmapTexture(device->context(), bitmap, params);
texture = fTex.texture();
}
return texture;
@@ -564,9 +564,9 @@
grPaint->resetColorFilter();
GrSamplerState* colorSampler = grPaint->textureSampler(kColorFilterTextureIdx);
- GrTexture* texture = act->set(dev, colorTransformTable, colorSampler);
+ GrTexture* texture = act->set(dev, colorTransformTable, colorSampler->textureParams());
- colorSampler->reset(GrSamplerState::kClamp_WrapMode, GrSamplerState::kNearest_Filter);
+ colorSampler->reset();
colorSampler->setCustomStage(SkNEW_ARGS(GrColorTableEffect, (texture)))->unref();
} else {
grPaint->resetColorFilter();
@@ -641,14 +641,8 @@
}
// Must set wrap and filter on the sampler before requesting a texture.
- sampler->setWrapX(sk_tile_mode_to_grwrap(tileModes[0]));
- sampler->setWrapY(sk_tile_mode_to_grwrap(tileModes[1]));
- GrSamplerState::Filter filter = GrSamplerState::kNearest_Filter;
- if (skPaint.isFilterBitmap()) {
- filter = GrSamplerState::kBilinear_Filter;
- }
- sampler->setFilter(filter);
- GrTexture* texture = textures[kShaderTextureIdx].set(dev, bitmap, sampler);
+ sampler->textureParams()->reset(tileModes, skPaint.isFilterBitmap());
+ GrTexture* texture = textures[kShaderTextureIdx].set(dev, bitmap, sampler->textureParams());
if (NULL == texture) {
SkDebugf("Couldn't convert bitmap to texture.\n");
@@ -929,7 +923,7 @@
if (!isNormalBlur) {
GrPaint paint;
paint.reset();
- paint.textureSampler(0)->setFilter(GrSamplerState::kNearest_Filter);
+ paint.textureSampler(0)->textureParams()->setClampNoFilter();
paint.textureSampler(0)->matrix()->setIDiv(pathTexture->width(),
pathTexture->height());
// Blend pathTexture over blurTexture.
@@ -1197,7 +1191,7 @@
}
bool SkGpuDevice::shouldTileBitmap(const SkBitmap& bitmap,
- const GrSamplerState& sampler,
+ const GrTextureParams& params,
const SkIRect* srcRectPtr,
int* tileSize) const {
SkASSERT(NULL != tileSize);
@@ -1219,7 +1213,7 @@
return false;
}
// if the entire texture is already in our cache then no reason to tile it
- if (this->isBitmapInTextureCache(bitmap, sampler)) {
+ if (this->isBitmapInTextureCache(bitmap, params)) {
return false;
}
@@ -1298,15 +1292,11 @@
if (!skPaint2GrPaintNoShader(this, paint, true, false, &colorLutTexture, &grPaint)) {
return;
}
- GrSamplerState* sampler = grPaint.textureSampler(kBitmapTextureIdx);
- if (paint.isFilterBitmap()) {
- sampler->setFilter(GrSamplerState::kBilinear_Filter);
- } else {
- sampler->setFilter(GrSamplerState::kNearest_Filter);
- }
+ GrTextureParams* params = grPaint.textureSampler(kBitmapTextureIdx)->textureParams();
+ params->setBilerp(paint.isFilterBitmap());
int tileSize;
- if (!this->shouldTileBitmap(bitmap, *sampler, srcRectPtr, &tileSize)) {
+ if (!this->shouldTileBitmap(bitmap, *params, srcRectPtr, &tileSize)) {
// take the simple case
this->internalDrawBitmap(draw, bitmap, srcRect, m, &grPaint);
return;
@@ -1430,12 +1420,11 @@
GrSamplerState* sampler = grPaint->textureSampler(kBitmapTextureIdx);
- sampler->setWrapX(GrSamplerState::kClamp_WrapMode);
- sampler->setWrapY(GrSamplerState::kClamp_WrapMode);
+ sampler->textureParams()->setClamp();
sampler->matrix()->reset();
GrTexture* texture;
- SkAutoCachedTexture act(this, bitmap, sampler, &texture);
+ SkAutoCachedTexture act(this, bitmap, sampler->textureParams(), &texture);
if (NULL == texture) {
return;
}
@@ -1454,11 +1443,9 @@
SkFloatToScalar(srcRect.fBottom * hInv));
bool needsTextureDomain = false;
- if (GrSamplerState::kBilinear_Filter == sampler->getFilter())
- {
+ if (sampler->textureParams()->isBilerp()) {
// Need texture domain if drawing a sub rect.
- needsTextureDomain = srcRect.width() < bitmap.width() ||
- srcRect.height() < bitmap.height();
+ needsTextureDomain = srcRect.width() < bitmap.width() || srcRect.height() < bitmap.height();
if (m.rectStaysRect() && draw.fMatrix->rectStaysRect()) {
// sampling is axis-aligned
GrRect floatSrcRect, transformedRect;
@@ -1469,7 +1456,7 @@
if (hasAlignedSamples(floatSrcRect, transformedRect)) {
// Samples are texel-aligned, so filtering is futile
- sampler->setFilter(GrSamplerState::kNearest_Filter);
+ sampler->textureParams()->setBilerp(false);
needsTextureDomain = false;
} else {
needsTextureDomain = needsTextureDomain &&
@@ -1522,7 +1509,7 @@
sampleM.setIDiv(srcTexture->width(), srcTexture->height());
GrPaint paint;
paint.reset();
- paint.textureSampler(0)->setFilter(GrSamplerState::kBilinear_Filter);
+ paint.textureSampler(0)->textureParams()->setBilerp(true);
paint.textureSampler(0)->reset(sampleM);
paint.textureSampler(0)->setCustomStage(stage);
context->drawRect(paint, rect);
@@ -1589,7 +1576,7 @@
GrTexture* texture;
sampler->reset();
- SkAutoCachedTexture act(this, bitmap, sampler, &texture);
+ SkAutoCachedTexture act(this, bitmap, sampler->textureParams(), &texture);
grPaint.textureSampler(kBitmapTextureIdx)->setCustomStage(SkNEW_ARGS
(GrSingleTextureEffect, (texture)))->unref();
@@ -1701,7 +1688,7 @@
GrSamplerState* sampler = paint.textureSampler(kBitmapTextureIdx);
GrTexture* texture;
- SkAutoCachedTexture act(this, src, sampler, &texture);
+ SkAutoCachedTexture act(this, src, sampler->textureParams(), &texture);
result->setConfig(src.config(), src.width(), src.height());
GrRect rect = GrRect::MakeWH(SkIntToScalar(src.width()),
@@ -1933,7 +1920,7 @@
///////////////////////////////////////////////////////////////////////////////
bool SkGpuDevice::isBitmapInTextureCache(const SkBitmap& bitmap,
- const GrSamplerState& sampler) const {
+ const GrTextureParams& params) const {
uint64_t key = bitmap.getGenerationID();
key |= ((uint64_t) bitmap.pixelRefOffset()) << 32;
@@ -1943,7 +1930,7 @@
desc.fConfig = SkBitmapConfig2GrPixelConfig(bitmap.config());
desc.fClientCacheID = key;
- return this->context()->isTextureInCache(desc, &sampler);
+ return this->context()->isTextureInCache(desc, ¶ms);
}
diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp
index 41f50f5..dca0858 100644
--- a/src/gpu/SkGr.cpp
+++ b/src/gpu/SkGr.cpp
@@ -58,7 +58,7 @@
static GrContext::TextureCacheEntry sk_gr_create_bitmap_texture(GrContext* ctx,
uint64_t key,
- const GrSamplerState* sampler,
+ const GrTextureParams* params,
const SkBitmap& origBitmap) {
SkAutoLockPixels alp(origBitmap);
GrContext::TextureCacheEntry entry;
@@ -80,7 +80,7 @@
if (SkBitmap::kIndex8_Config == bitmap->config()) {
// build_compressed_data doesn't do npot->pot expansion
// and paletted textures can't be sub-updated
- if (ctx->supportsIndex8PixelConfig(sampler,
+ if (ctx->supportsIndex8PixelConfig(params,
bitmap->width(), bitmap->height())) {
size_t imagesize = bitmap->width() * bitmap->height() +
kGrColorTableSize;
@@ -92,7 +92,7 @@
// "rowBytes", since they are the same now.
if (kUncached_CacheID != key) {
- return ctx->createAndLockTexture(sampler, desc, storage.get(),
+ return ctx->createAndLockTexture(params, desc, storage.get(),
bitmap->width());
} else {
entry = ctx->lockScratchTexture(desc,
@@ -112,7 +112,7 @@
desc.fConfig = SkBitmapConfig2GrPixelConfig(bitmap->config());
if (kUncached_CacheID != key) {
- return ctx->createAndLockTexture(sampler, desc,
+ return ctx->createAndLockTexture(params, desc,
bitmap->getPixels(),
bitmap->rowBytes());
} else {
@@ -130,7 +130,8 @@
///////////////////////////////////////////////////////////////////////////////
GrContext::TextureCacheEntry GrLockCachedBitmapTexture(GrContext* ctx,
- const SkBitmap& bitmap, const GrSamplerState* sampler) {
+ const SkBitmap& bitmap,
+ const GrTextureParams* params) {
GrContext::TextureCacheEntry entry;
if (!bitmap.isVolatile()) {
@@ -143,14 +144,12 @@
desc.fConfig = SkBitmapConfig2GrPixelConfig(bitmap.config());
desc.fClientCacheID = key;
- entry = ctx->findAndLockTexture(desc, sampler);
+ entry = ctx->findAndLockTexture(desc, params);
if (NULL == entry.texture()) {
- entry = sk_gr_create_bitmap_texture(ctx, key, sampler,
- bitmap);
+ entry = sk_gr_create_bitmap_texture(ctx, key, params, bitmap);
}
} else {
- entry = sk_gr_create_bitmap_texture(ctx, kUncached_CacheID,
- sampler, bitmap);
+ entry = sk_gr_create_bitmap_texture(ctx, kUncached_CacheID, params, bitmap);
}
if (NULL == entry.texture()) {
GrPrintf("---- failed to create texture for cache [%d %d]\n",
diff --git a/src/gpu/effects/GrGradientEffects.cpp b/src/gpu/effects/GrGradientEffects.cpp
index 375b783..9c186e2 100644
--- a/src/gpu/effects/GrGradientEffects.cpp
+++ b/src/gpu/effects/GrGradientEffects.cpp
@@ -66,7 +66,7 @@
shader.asABitmap(&bitmap, NULL, NULL);
GrContext::TextureCacheEntry entry = GrLockCachedBitmapTexture(ctx, bitmap,
- sampler);
+ sampler->textureParams());
fTexture = entry.texture();
SkSafeRef(fTexture);
fUseTexture = true;
diff --git a/src/gpu/gl/GrGLTexture.cpp b/src/gpu/gl/GrGLTexture.cpp
index 16a5015..e360874 100644
--- a/src/gpu/gl/GrGLTexture.cpp
+++ b/src/gpu/gl/GrGLTexture.cpp
@@ -14,15 +14,6 @@
#define GL_CALL(X) GR_GL_CALL(GPUGL->glInterface(), X)
-const GrGLenum* GrGLTexture::WrapMode2GLWrap() {
- static const GrGLenum repeatModes[] = {
- GR_GL_CLAMP_TO_EDGE,
- GR_GL_REPEAT,
- GR_GL_MIRRORED_REPEAT
- };
- return repeatModes;
-};
-
void GrGLTexture::init(GrGpuGL* gpu,
const Desc& textureDesc,
const GrGLRenderTarget::Desc* rtDesc) {
diff --git a/src/gpu/gl/GrGLTexture.h b/src/gpu/gl/GrGLTexture.h
index 8e8c8c5..1095d53 100644
--- a/src/gpu/gl/GrGLTexture.h
+++ b/src/gpu/gl/GrGLTexture.h
@@ -105,8 +105,6 @@
// and it is up to the GrGpuGL derivative to handle y-mirroing.
Orientation orientation() const { return fOrientation; }
- static const GrGLenum* WrapMode2GLWrap();
-
protected:
// overrides of GrTexture
diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp
index 21cf3b8..79ea706 100644
--- a/src/gpu/gl/GrGpuGL.cpp
+++ b/src/gpu/gl/GrGpuGL.cpp
@@ -2087,18 +2087,6 @@
}
namespace {
-unsigned gr_to_gl_filter(GrSamplerState::Filter filter) {
- switch (filter) {
- case GrSamplerState::kBilinear_Filter:
- return GR_GL_LINEAR;
- case GrSamplerState::kNearest_Filter:
- return GR_GL_NEAREST;
- default:
- GrAssert(!"Unknown filter type");
- return GR_GL_LINEAR;
- }
-}
-
// get_swizzle is only called from this .cpp so it is OK to inline it here
inline const GrGLenum* get_swizzle(GrPixelConfig config,
const GrSamplerState& sampler,
@@ -2129,28 +2117,43 @@
GR_GL_TEXTURE_SWIZZLE_RGBA,
reinterpret_cast<const GrGLint*>(swizzle)));
}
+
+const GrGLenum tile_to_gl_wrap(SkShader::TileMode tm) {
+ static const GrGLenum gWrapModes[] = {
+ GR_GL_CLAMP_TO_EDGE,
+ GR_GL_REPEAT,
+ GR_GL_MIRRORED_REPEAT
+ };
+ GrAssert((unsigned) tm <= SK_ARRAY_COUNT(gWrapModes));
+ GR_STATIC_ASSERT(0 == SkShader::kClamp_TileMode);
+ GR_STATIC_ASSERT(1 == SkShader::kRepeat_TileMode);
+ GR_STATIC_ASSERT(2 == SkShader::kMirror_TileMode);
+ return gWrapModes[tm];
+}
+
}
void GrGpuGL::flushBoundTextureAndParams(int stage) {
GrDrawState* drawState = this->drawState();
- GrGLTexture* nextTexture =
- static_cast<GrGLTexture*>(drawState->getTexture(stage));
-
- flushBoundTextureAndParams(stage, nextTexture);
+ GrGLTexture* nextTexture = static_cast<GrGLTexture*>(drawState->getTexture(stage));
+ // 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();
+ this->flushBoundTextureAndParams(stage, texParams, nextTexture);
}
-void GrGpuGL::flushBoundTextureAndParams(int stage, GrGLTexture* nextTexture) {
+void GrGpuGL::flushBoundTextureAndParams(int stage,
+ const GrTextureParams& params,
+ GrGLTexture* nextTexture) {
GrDrawState* drawState = this->drawState();
// true for now, but maybe not with GrEffect.
GrAssert(NULL != nextTexture);
- // if we created a rt/tex and rendered to it without using a
- // texture and now we're texturing from the rt it will still be
- // the last bound texture, but it needs resolving. So keep this
+ // If we created a rt/tex and rendered to it without using a texture and now we're texturing
+ // from the rt it will still be the last bound texture, but it needs resolving. So keep this
// out of the "last != next" check.
- GrGLRenderTarget* texRT =
- static_cast<GrGLRenderTarget*>(nextTexture->asRenderTarget());
+ GrGLRenderTarget* texRT = static_cast<GrGLRenderTarget*>(nextTexture->asRenderTarget());
if (NULL != texRT) {
this->onResolveRenderTarget(texRT);
}
@@ -2162,20 +2165,18 @@
fHWBoundTextures[stage] = nextTexture;
}
- const GrSamplerState& sampler = drawState->getSampler(stage);
ResetTimestamp timestamp;
const GrGLTexture::TexParams& oldTexParams =
nextTexture->getCachedTexParams(×tamp);
bool setAll = timestamp < this->getResetTimestamp();
GrGLTexture::TexParams newTexParams;
- newTexParams.fFilter = gr_to_gl_filter(sampler.getFilter());
+ newTexParams.fFilter = params.isBilerp() ? GR_GL_LINEAR : GR_GL_NEAREST;
- const GrGLenum* wraps = GrGLTexture::WrapMode2GLWrap();
- newTexParams.fWrapS = wraps[sampler.getWrapX()];
- newTexParams.fWrapT = wraps[sampler.getWrapY()];
+ newTexParams.fWrapS = tile_to_gl_wrap(params.getTileModeX());
+ newTexParams.fWrapT = tile_to_gl_wrap(params.getTileModeY());
memcpy(newTexParams.fSwizzleRGBA,
- get_swizzle(nextTexture->config(), sampler, this->glCaps()),
+ get_swizzle(nextTexture->config(), drawState->getSampler(stage), this->glCaps()),
sizeof(newTexParams.fSwizzleRGBA));
if (setAll || newTexParams.fFilter != oldTexParams.fFilter) {
this->setTextureUnit(stage);
diff --git a/src/gpu/gl/GrGpuGL.h b/src/gpu/gl/GrGpuGL.h
index b3e8cf8..2e338a1 100644
--- a/src/gpu/gl/GrGpuGL.h
+++ b/src/gpu/gl/GrGpuGL.h
@@ -217,7 +217,9 @@
// call to flushScissor must occur after all textures have been flushed via
// this function.
void flushBoundTextureAndParams(int stage);
- void flushBoundTextureAndParams(int stage, GrGLTexture* nextTexture);
+ void flushBoundTextureAndParams(int stage,
+ const GrTextureParams& params,
+ GrGLTexture* nextTexture);
// sets the texture matrix for the currently bound program
void flushTextureMatrix(int stage);