Move GrTextureParams from GrSamplerState to GrTextureAccess

Review URL: https://codereview.appspot.com/6496135/



git-svn-id: http://skia.googlecode.com/svn/trunk@5582 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
bsalomon@google.com 2012-09-18 14:14:49 +00:00
Родитель 10f9f4a844
Коммит 1ce49fc917
21 изменённых файлов: 300 добавлений и 198 удалений

Просмотреть файл

@ -17,69 +17,6 @@
#include "SkShader.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 { class GrSamplerState {
public: public:
static const bool kBilerpDefault = false; static const bool kBilerpDefault = false;
@ -118,19 +55,13 @@ public:
bool operator !=(const GrSamplerState& s) const { return !(*this == s); } bool operator !=(const GrSamplerState& s) const { return !(*this == s); }
GrSamplerState& operator =(const GrSamplerState& s) { GrSamplerState& operator =(const GrSamplerState& s) {
// memcpy() breaks refcounting
fTextureParams = s.fTextureParams;
fMatrix = s.fMatrix; fMatrix = s.fMatrix;
GrSafeAssign(fCustomStage, s.fCustomStage); GrSafeAssign(fCustomStage, s.fCustomStage);
return *this; return *this;
} }
const GrMatrix& getMatrix() const { return fMatrix; } 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 * Access the sampler's matrix. See SampleMode for explanation of
* relationship between the matrix and sample mode. * relationship between the matrix and sample mode.
@ -149,21 +80,14 @@ public:
*/ */
void preConcatMatrix(const GrMatrix& matrix) { fMatrix.preConcat(matrix); } void preConcatMatrix(const GrMatrix& matrix) { fMatrix.preConcat(matrix); }
void reset(SkShader::TileMode tileXAndY, void reset(const GrMatrix& matrix) {
bool filter,
const GrMatrix& matrix) {
fTextureParams.reset(tileXAndY, filter);
fMatrix = matrix; fMatrix = matrix;
GrSafeSetNull(fCustomStage); 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() { void reset() {
this->reset(kTileModeDefault, kBilerpDefault, GrMatrix::I()); fMatrix.reset();
GrSafeSetNull(fCustomStage);
} }
GrCustomStage* setCustomStage(GrCustomStage* stage) { GrCustomStage* setCustomStage(GrCustomStage* stage) {
@ -173,7 +97,6 @@ public:
const GrCustomStage* getCustomStage() const { return fCustomStage; } const GrCustomStage* getCustomStage() const { return fCustomStage; }
private: private:
GrTextureParams fTextureParams;
GrMatrix fMatrix; GrMatrix fMatrix;
GrCustomStage* fCustomStage; GrCustomStage* fCustomStage;

Просмотреть файл

@ -10,9 +10,96 @@
#include "GrNoncopyable.h" #include "GrNoncopyable.h"
#include "SkRefCnt.h" #include "SkRefCnt.h"
#include "SkShader.h"
class GrTexture; 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 /** 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 * 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 * to handle the r,g,b->a conversions for alpha textures is automatically included in the stage
@ -27,19 +114,45 @@ public:
*/ */
GrTextureAccess(); GrTextureAccess();
/**
* Uses the default swizzle, "rgba".
*/
GrTextureAccess(GrTexture*, const GrTextureParams&);
explicit GrTextureAccess(GrTexture*,
bool bilerp = false,
SkShader::TileMode tileXAndY = SkShader::kClamp_TileMode);
/** /**
* swizzle must be a string between one and four (inclusive) characters containing only 'r', * swizzle must be a string between one and four (inclusive) characters containing only 'r',
* 'g', 'b', and/or 'a'. * 'g', 'b', and/or 'a'.
*/ */
GrTextureAccess(GrTexture*, const char* swizzle); 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 GrTextureParams&);
* Uses the default swizzle, "rgba". void reset(GrTexture*,
*/ bool bilerp = false,
GrTextureAccess(GrTexture*); 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);
void reset(GrTexture*, const char* swizzle); bool operator== (const GrTextureAccess& other) const {
void reset(GrTexture*); #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(); } GrTexture* getTexture() const { return fTexture.get(); }
@ -60,10 +173,17 @@ public:
/** Returns a mask indicating which components are referenced in the swizzle. */ /** Returns a mask indicating which components are referenced in the swizzle. */
uint32_t swizzleMask() const { return fSwizzleMask; } uint32_t swizzleMask() const { return fSwizzleMask; }
const GrTextureParams& getParams() const { return fParams; }
private: private:
void setSwizzle(const char*);
GrTextureParams fParams;
SkAutoTUnref<GrTexture> fTexture; SkAutoTUnref<GrTexture> fTexture;
uint32_t fSwizzleMask; uint32_t fSwizzleMask;
char fSwizzle[5]; char fSwizzle[5];
typedef GrNoncopyable INHERITED;
}; };
#endif #endif

Просмотреть файл

@ -156,8 +156,12 @@ private:
const GrTextureParams& sampler, const GrTextureParams& sampler,
const SkIRect* srcRectPtr, const SkIRect* srcRectPtr,
int* tileSize) const; int* tileSize) const;
void internalDrawBitmap(const SkDraw&, const SkBitmap&, void internalDrawBitmap(const SkDraw&,
const SkIRect&, const SkMatrix&, GrPaint* grPaint); const SkBitmap&,
const SkIRect&,
const SkMatrix&,
const GrTextureParams& params,
GrPaint* grPaint);
/** /**
* Returns non-initialized instance. * Returns non-initialized instance.

Просмотреть файл

@ -718,7 +718,7 @@ void GrGLGradientStage::emitColorLookup(GrGLShaderBuilder* builder,
GrGradientEffect::GrGradientEffect(GrContext* ctx, GrGradientEffect::GrGradientEffect(GrContext* ctx,
const SkGradientShaderBase& shader, const SkGradientShaderBase& shader,
GrSamplerState* sampler) SkShader::TileMode tileMode)
: fUseTexture (true) { : fUseTexture (true) {
// TODO: check for simple cases where we don't need a texture: // TODO: check for simple cases where we don't need a texture:
//GradientInfo info; //GradientInfo info;
@ -737,14 +737,19 @@ GrGradientEffect::GrGradientEffect(GrContext* ctx,
fAtlas = GrTextureStripAtlas::GetAtlas(desc); fAtlas = GrTextureStripAtlas::GetAtlas(desc);
GrAssert(NULL != fAtlas); 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); fRow = fAtlas->lockRow(bitmap);
if (-1 != fRow) { if (-1 != fRow) {
fYCoord = fAtlas->getYOffset(fRow) + GR_ScalarHalf * fYCoord = fAtlas->getYOffset(fRow) + GR_ScalarHalf *
fAtlas->getVerticalScaleFactor(); fAtlas->getVerticalScaleFactor();
fTextureAccess.reset(fAtlas->getTexture()); fTextureAccess.reset(fAtlas->getTexture(), params);
} else { } else {
GrTexture* texture = GrLockCachedBitmapTexture(ctx, bitmap, sampler->textureParams()); GrTexture* texture = GrLockCachedBitmapTexture(ctx, bitmap, &params);
fTextureAccess.reset(texture); fTextureAccess.reset(texture, params);
fYCoord = GR_ScalarHalf; fYCoord = GR_ScalarHalf;
// Unlock immediately, this is not great, but we don't have a way of // Unlock immediately, this is not great, but we don't have a way of

Просмотреть файл

@ -226,8 +226,9 @@ class GrProgramStageFactory;
class GrGradientEffect : public GrCustomStage { class GrGradientEffect : public GrCustomStage {
public: public:
GrGradientEffect(GrContext* ctx, const SkGradientShaderBase& shader, GrGradientEffect(GrContext* ctx,
GrSamplerState* sampler); const SkGradientShaderBase& shader,
SkShader::TileMode tileMode);
virtual ~GrGradientEffect(); virtual ~GrGradientEffect();

Просмотреть файл

@ -503,9 +503,8 @@ private:
class GrLinearGradient : public GrGradientEffect { class GrLinearGradient : public GrGradientEffect {
public: public:
GrLinearGradient(GrContext* ctx, const SkLinearGradient& shader, GrLinearGradient(GrContext* ctx, const SkLinearGradient& shader, SkShader::TileMode tm)
GrSamplerState* sampler) : INHERITED(ctx, shader, tm) { }
: INHERITED(ctx, shader, sampler) { }
virtual ~GrLinearGradient() { } virtual ~GrLinearGradient() { }
static const char* Name() { return "Linear Gradient"; } static const char* Name() { return "Linear Gradient"; }
@ -562,10 +561,7 @@ GrCustomStage* SkLinearGradient::asNewCustomStage(GrContext* context,
GrSamplerState* sampler) const { GrSamplerState* sampler) const {
SkASSERT(NULL != context && NULL != sampler); SkASSERT(NULL != context && NULL != sampler);
sampler->matrix()->preConcat(fPtsToUnit); sampler->matrix()->preConcat(fPtsToUnit);
sampler->textureParams()->setTileModeX(fTileMode); return SkNEW_ARGS(GrLinearGradient, (context, *this, fTileMode));
sampler->textureParams()->setTileModeY(kClamp_TileMode);
sampler->textureParams()->setBilerp(true);
return SkNEW_ARGS(GrLinearGradient, (context, *this, sampler));
} }
#else #else

Просмотреть файл

@ -500,10 +500,8 @@ private:
class GrRadialGradient : public GrGradientEffect { class GrRadialGradient : public GrGradientEffect {
public: public:
GrRadialGradient(GrContext* ctx, GrRadialGradient(GrContext* ctx, const SkRadialGradient& shader, SkShader::TileMode tm)
const SkRadialGradient& shader, : INHERITED(ctx, shader, tm) {
GrSamplerState* sampler)
: INHERITED(ctx, shader, sampler) {
} }
virtual ~GrRadialGradient() { } virtual ~GrRadialGradient() { }
@ -562,10 +560,7 @@ GrCustomStage* SkRadialGradient::asNewCustomStage(GrContext* context,
GrSamplerState* sampler) const { GrSamplerState* sampler) const {
SkASSERT(NULL != context && NULL != sampler); SkASSERT(NULL != context && NULL != sampler);
sampler->matrix()->preConcat(fPtsToUnit); sampler->matrix()->preConcat(fPtsToUnit);
sampler->textureParams()->setTileModeX(fTileMode); return SkNEW_ARGS(GrRadialGradient, (context, *this, fTileMode));
sampler->textureParams()->setTileModeY(kClamp_TileMode);
sampler->textureParams()->setBilerp(true);
return SkNEW_ARGS(GrRadialGradient, (context, *this, sampler));
} }
#else #else

Просмотреть файл

@ -410,9 +410,8 @@ class GrSweepGradient : public GrGradientEffect {
public: public:
GrSweepGradient(GrContext* ctx, GrSweepGradient(GrContext* ctx,
const SkSweepGradient& shader, const SkSweepGradient& shader)
GrSamplerState* sampler) : INHERITED(ctx, shader, SkShader::kClamp_TileMode) { }
: INHERITED(ctx, shader, sampler) { }
virtual ~GrSweepGradient() { } virtual ~GrSweepGradient() { }
static const char* Name() { return "Sweep Gradient"; } static const char* Name() { return "Sweep Gradient"; }
@ -467,10 +466,7 @@ void GrGLSweepGradient::emitFS(GrGLShaderBuilder* builder,
GrCustomStage* SkSweepGradient::asNewCustomStage(GrContext* context, GrCustomStage* SkSweepGradient::asNewCustomStage(GrContext* context,
GrSamplerState* sampler) const { GrSamplerState* sampler) const {
sampler->matrix()->preConcat(fPtsToUnit); sampler->matrix()->preConcat(fPtsToUnit);
sampler->textureParams()->setTileModeX(fTileMode); return SkNEW_ARGS(GrSweepGradient, (context, *this));
sampler->textureParams()->setTileModeY(kClamp_TileMode);
sampler->textureParams()->setBilerp(true);
return SkNEW_ARGS(GrSweepGradient, (context, *this, sampler));
} }
#else #else

Просмотреть файл

@ -370,9 +370,10 @@ private:
class GrConical2Gradient : public GrGradientEffect { class GrConical2Gradient : public GrGradientEffect {
public: public:
GrConical2Gradient(GrContext* ctx, const SkTwoPointConicalGradient& shader, GrConical2Gradient(GrContext* ctx,
GrSamplerState* sampler) const SkTwoPointConicalGradient& shader,
: INHERITED(ctx, shader, sampler) SkShader::TileMode tm)
: INHERITED(ctx, shader, tm)
, fCenterX1(shader.getCenterX1()) , fCenterX1(shader.getCenterX1())
, fRadius0(shader.getStartRadius()) , fRadius0(shader.getStartRadius())
, fDiffRadius(shader.getDiffRadius()) { } , fDiffRadius(shader.getDiffRadius()) { }
@ -685,10 +686,7 @@ GrCustomStage* SkTwoPointConicalGradient::asNewCustomStage(
sampler->matrix()->reset(); sampler->matrix()->reset();
} }
sampler->matrix()->preTranslate(-fCenter1.fX, -fCenter1.fY); sampler->matrix()->preTranslate(-fCenter1.fX, -fCenter1.fY);
sampler->textureParams()->setTileModeX(fTileMode); return SkNEW_ARGS(GrConical2Gradient, (context, *this, fTileMode));
sampler->textureParams()->setTileModeY(kClamp_TileMode);
sampler->textureParams()->setBilerp(true);
return SkNEW_ARGS(GrConical2Gradient, (context, *this, sampler));
} }
#else #else

Просмотреть файл

@ -405,9 +405,8 @@ private:
class GrRadial2Gradient : public GrGradientEffect { class GrRadial2Gradient : public GrGradientEffect {
public: public:
GrRadial2Gradient(GrContext* ctx, const SkTwoPointRadialGradient& shader, GrRadial2Gradient(GrContext* ctx, const SkTwoPointRadialGradient& shader, SkShader::TileMode tm)
GrSamplerState* sampler) : INHERITED(ctx, shader, tm)
: INHERITED(ctx, shader, sampler)
, fCenterX1(shader.getCenterX1()) , fCenterX1(shader.getCenterX1())
, fRadius0(shader.getStartRadius()) , fRadius0(shader.getStartRadius())
, fPosRoot(shader.getDiffRadius() < 0) { } , fPosRoot(shader.getDiffRadius() < 0) { }
@ -660,10 +659,7 @@ GrCustomStage* SkTwoPointRadialGradient::asNewCustomStage(
sampler->matrix()->reset(); sampler->matrix()->reset();
} }
sampler->matrix()->preConcat(fPtsToUnit); sampler->matrix()->preConcat(fPtsToUnit);
sampler->textureParams()->setTileModeX(fTileMode); return SkNEW_ARGS(GrRadial2Gradient, (context, *this, fTileMode));
sampler->textureParams()->setTileModeY(kClamp_TileMode);
sampler->textureParams()->setBilerp(true);
return SkNEW_ARGS(GrRadial2Gradient, (context, *this, sampler));
} }
#else #else

Просмотреть файл

@ -309,9 +309,9 @@ GrTexture* GrContext::createResizedTexture(const GrTextureDesc& desc,
// if filtering is not desired then we want to ensure all // if filtering is not desired then we want to ensure all
// texels in the resampled image are copies of texels from // texels in the resampled image are copies of texels from
// the original. // the original.
drawState->sampler(0)->reset(SkShader::kClamp_TileMode, drawState->sampler(0)->reset();
needsFiltering); GrTextureParams params(SkShader::kClamp_TileMode, needsFiltering);
drawState->createTextureEffect(0, clampedTexture); drawState->createTextureEffect(0, clampedTexture, params);
static const GrVertexLayout layout = static const GrVertexLayout layout =
GrDrawTarget::StageTexCoordVertexLayoutBit(0,0); GrDrawTarget::StageTexCoordVertexLayoutBit(0,0);
@ -1864,7 +1864,6 @@ GrTexture* GrContext::gaussianBlur(GrTexture* srcTexture,
GrPaint paint; GrPaint paint;
paint.reset(); paint.reset();
paint.textureSampler(0)->textureParams()->setBilerp(true);
for (int i = 1; i < scaleFactorX || i < scaleFactorY; i *= 2) { for (int i = 1; i < scaleFactorX || i < scaleFactorY; i *= 2) {
paint.textureSampler(0)->matrix()->setIDiv(srcTexture->width(), 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, scale_rect(&dstRect, i < scaleFactorX ? 0.5f : 1.0f,
i < scaleFactorY ? 0.5f : 1.0f); i < scaleFactorY ? 0.5f : 1.0f);
paint.textureSampler(0)->setCustomStage(SkNEW_ARGS(GrSingleTextureEffect, paint.textureSampler(0)->setCustomStage(SkNEW_ARGS(GrSingleTextureEffect,
(srcTexture)))->unref(); (srcTexture, true)))->unref();
this->drawRectToRect(paint, dstRect, srcRect); this->drawRectToRect(paint, dstRect, srcRect);
srcRect = dstRect; srcRect = dstRect;
srcTexture = dstTexture; srcTexture = dstTexture;
@ -1928,12 +1927,11 @@ GrTexture* GrContext::gaussianBlur(GrTexture* srcTexture,
1, srcIRect.height()); 1, srcIRect.height());
this->clear(&clearRect, 0x0); this->clear(&clearRect, 0x0);
// FIXME: This should be mitchell, not bilinear. // FIXME: This should be mitchell, not bilinear.
paint.textureSampler(0)->textureParams()->setBilerp(true);
paint.textureSampler(0)->matrix()->setIDiv(srcTexture->width(), paint.textureSampler(0)->matrix()->setIDiv(srcTexture->width(),
srcTexture->height()); srcTexture->height());
this->setRenderTarget(dstTexture->asRenderTarget()); this->setRenderTarget(dstTexture->asRenderTarget());
paint.textureSampler(0)->setCustomStage(SkNEW_ARGS(GrSingleTextureEffect, paint.textureSampler(0)->setCustomStage(SkNEW_ARGS(GrSingleTextureEffect,
(srcTexture)))->unref(); (srcTexture, true)))->unref();
SkRect dstRect(srcRect); SkRect dstRect(srcRect);
scale_rect(&dstRect, (float) scaleFactorX, (float) scaleFactorY); scale_rect(&dstRect, (float) scaleFactorX, (float) scaleFactorY);
this->drawRectToRect(paint, dstRect, srcRect); this->drawRectToRect(paint, dstRect, srcRect);

Просмотреть файл

@ -55,7 +55,7 @@ bool GrCustomStage::isEqual(const GrCustomStage& s) const {
return false; return false;
} }
for (int i = 0; i < this->numTextures(); ++i) { for (int i = 0; i < this->numTextures(); ++i) {
if (this->texture(i) != s.texture(i)) { if (this->textureAccess(i) != s.textureAccess(i)) {
return false; return false;
} }
} }

Просмотреть файл

@ -181,6 +181,12 @@ public:
this->sampler(stage)->setCustomStage( this->sampler(stage)->setCustomStage(
SkNEW_ARGS(GrSingleTextureEffect, (texture)))->unref(); 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() { bool stagesDisabled() {
for (int i = 0; i < kNumStages; ++i) { for (int i = 0; i < kNumStages; ++i) {

Просмотреть файл

@ -19,6 +19,7 @@
#include "SkPath.h" #include "SkPath.h"
enum { enum {
kGlyphMaskStage = GrPaint::kTotalStages, kGlyphMaskStage = GrPaint::kTotalStages,
}; };
@ -29,12 +30,12 @@ void GrTextContext::flushGlyphs() {
GrDrawState* drawState = fDrawTarget->drawState(); GrDrawState* drawState = fDrawTarget->drawState();
if (fCurrVertex > 0) { if (fCurrVertex > 0) {
// setup our sampler state for our text texture/atlas // setup our sampler state for our text texture/atlas
drawState->sampler(kGlyphMaskStage)->reset(SkShader::kRepeat_TileMode, drawState->sampler(kGlyphMaskStage)->reset();
!fExtMatrix.isIdentity());
GrAssert(GrIsALIGN4(fCurrVertex)); GrAssert(GrIsALIGN4(fCurrVertex));
GrAssert(fCurrTexture); GrAssert(fCurrTexture);
drawState->createTextureEffect(kGlyphMaskStage, fCurrTexture); GrTextureParams params(SkShader::kRepeat_TileMode, !fExtMatrix.isIdentity());
drawState->createTextureEffect(kGlyphMaskStage, fCurrTexture, params);
if (!GrPixelConfigIsAlphaOnly(fCurrTexture->config())) { if (!GrPixelConfigIsAlphaOnly(fCurrTexture->config())) {
if (kOne_GrBlendCoeff != fPaint.fSrcBlendCoeff || if (kOne_GrBlendCoeff != fPaint.fSrcBlendCoeff ||

Просмотреть файл

@ -16,25 +16,76 @@ GrTextureAccess::GrTextureAccess() {
#endif #endif
} }
GrTextureAccess::GrTextureAccess(GrTexture* texture, const char* swizzle) { GrTextureAccess::GrTextureAccess(GrTexture* texture, const GrTextureParams& params) {
this->reset(texture, swizzle); this->reset(texture, params);
} }
GrTextureAccess::GrTextureAccess(GrTexture* texture) { GrTextureAccess::GrTextureAccess(GrTexture* texture,
this->reset(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(NULL != texture);
GrAssert(strlen(swizzle) >= 1 && strlen(swizzle) <= 4); GrAssert(strlen(swizzle) >= 1 && strlen(swizzle) <= 4);
texture->ref(); fParams = params;
fTexture.reset(texture); 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; fSwizzleMask = 0;
fSwizzle[4] = '\0'; memset(fSwizzle, '\0', 5);
int i = 0; int i = 0;
do { for (int i = 0; i < 4 && '\0' != swizzle[i]; ++i) {
fSwizzle[i] = swizzle[i]; fSwizzle[i] = swizzle[i];
switch (swizzle[i]) { switch (swizzle[i]) {
case 'r': case 'r':
@ -49,19 +100,9 @@ void GrTextureAccess::reset(GrTexture* texture, const char* swizzle) {
case 'a': case 'a':
fSwizzleMask |= kA_SwizzleFlag; fSwizzleMask |= kA_SwizzleFlag;
break; break;
case '\0':
break;
default: default:
GrCrash("Unexpected swizzle string character."); GrCrash("Unexpected swizzle string character.");
break; 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);
} }

Просмотреть файл

@ -545,6 +545,7 @@ inline bool skPaint2GrPaintNoShader(SkGpuDevice* dev,
SkScalar matrix[20]; SkScalar matrix[20];
SkBitmap colorTransformTable; SkBitmap colorTransformTable;
grPaint->resetColorFilter(); grPaint->resetColorFilter();
// TODO: SkColorFilter::asCustomStage()
if (colorFilter != NULL && colorFilter->asColorMode(&color, &filterMode)) { if (colorFilter != NULL && colorFilter->asColorMode(&color, &filterMode)) {
grPaint->fColorMatrixEnabled = false; grPaint->fColorMatrixEnabled = false;
if (!constantColor) { if (!constantColor) {
@ -558,13 +559,12 @@ inline bool skPaint2GrPaintNoShader(SkGpuDevice* dev,
grPaint->fColorMatrixEnabled = true; grPaint->fColorMatrixEnabled = true;
memcpy(grPaint->fColorMatrix, matrix, sizeof(matrix)); memcpy(grPaint->fColorMatrix, matrix, sizeof(matrix));
grPaint->fColorFilterXfermode = SkXfermode::kDst_Mode; grPaint->fColorFilterXfermode = SkXfermode::kDst_Mode;
} else if (colorFilter != NULL && colorFilter->asComponentTable( } else if (colorFilter != NULL && colorFilter->asComponentTable(&colorTransformTable)) {
&colorTransformTable)) {
grPaint->resetColorFilter(); 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); GrSamplerState* colorSampler = grPaint->textureSampler(kColorFilterTextureIdx);
GrTexture* texture = act->set(dev, colorTransformTable, colorSampler->textureParams());
colorSampler->reset(); colorSampler->reset();
colorSampler->setCustomStage(SkNEW_ARGS(GrColorTableEffect, (texture)))->unref(); 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. // Must set wrap and filter on the sampler before requesting a texture.
sampler->textureParams()->reset(tileModes, skPaint.isFilterBitmap()); GrTextureParams params(tileModes, skPaint.isFilterBitmap());
GrTexture* texture = textures[kShaderTextureIdx].set(dev, bitmap, sampler->textureParams()); GrTexture* texture = textures[kShaderTextureIdx].set(dev, bitmap, &params);
if (NULL == texture) { if (NULL == texture) {
SkDebugf("Couldn't convert bitmap to texture.\n"); SkDebugf("Couldn't convert bitmap to texture.\n");
return false; 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 // 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 // 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) { if (!isNormalBlur) {
GrPaint paint; GrPaint paint;
paint.reset(); paint.reset();
paint.textureSampler(0)->textureParams()->setClampNoFilter();
paint.textureSampler(0)->matrix()->setIDiv(pathTexture->width(), paint.textureSampler(0)->matrix()->setIDiv(pathTexture->width(),
pathTexture->height()); pathTexture->height());
// Blend pathTexture over blurTexture. // Blend pathTexture over blurTexture.
@ -1269,7 +1269,7 @@ void SkGpuDevice::drawBitmap(const SkDraw& draw,
srcRect.set(0,0, srcRect.width(), srcRect.height()); srcRect.set(0,0, srcRect.width(), srcRect.height());
} }
SkPaint paintWithTexture(paint); SkPaint paintWithTexture(paint);
paintWithTexture.setShader(SkShader::CreateBitmapShader( *bitmapPtr, paintWithTexture.setShader(SkShader::CreateBitmapShader(*bitmapPtr,
SkShader::kClamp_TileMode, SkShader::kClamp_TileMode))->unref(); SkShader::kClamp_TileMode, SkShader::kClamp_TileMode))->unref();
SkRect ScalarRect; SkRect ScalarRect;
ScalarRect.set(srcRect); ScalarRect.set(srcRect);
@ -1292,13 +1292,13 @@ void SkGpuDevice::drawBitmap(const SkDraw& draw,
if (!skPaint2GrPaintNoShader(this, paint, true, false, &colorLutTexture, &grPaint)) { if (!skPaint2GrPaintNoShader(this, paint, true, false, &colorLutTexture, &grPaint)) {
return; return;
} }
GrTextureParams* params = grPaint.textureSampler(kBitmapTextureIdx)->textureParams(); GrTextureParams params;
params->setBilerp(paint.isFilterBitmap()); params.setBilerp(paint.isFilterBitmap());
int tileSize; int tileSize;
if (!this->shouldTileBitmap(bitmap, *params, srcRectPtr, &tileSize)) { if (!this->shouldTileBitmap(bitmap, params, srcRectPtr, &tileSize)) {
// take the simple case // take the simple case
this->internalDrawBitmap(draw, bitmap, srcRect, m, &grPaint); this->internalDrawBitmap(draw, bitmap, srcRect, m, params, &grPaint);
return; return;
} }
@ -1348,7 +1348,7 @@ void SkGpuDevice::drawBitmap(const SkDraw& draw,
int dy = tileR.fTop - DY + SkMax32(0, srcR.fTop); int dy = tileR.fTop - DY + SkMax32(0, srcR.fTop);
tmpM.preTranslate(SkIntToScalar(dx), SkIntToScalar(dy)); 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 SkBitmap& bitmap,
const SkIRect& srcRect, const SkIRect& srcRect,
const SkMatrix& m, const SkMatrix& m,
const GrTextureParams& params,
GrPaint* grPaint) { GrPaint* grPaint) {
SkASSERT(bitmap.width() <= fContext->getMaxTextureSize() && SkASSERT(bitmap.width() <= fContext->getMaxTextureSize() &&
bitmap.height() <= fContext->getMaxTextureSize()); bitmap.height() <= fContext->getMaxTextureSize());
@ -1420,18 +1421,14 @@ void SkGpuDevice::internalDrawBitmap(const SkDraw& draw,
GrSamplerState* sampler = grPaint->textureSampler(kBitmapTextureIdx); GrSamplerState* sampler = grPaint->textureSampler(kBitmapTextureIdx);
sampler->textureParams()->setClamp();
sampler->matrix()->reset(); sampler->matrix()->reset();
GrTexture* texture; GrTexture* texture;
SkAutoCachedTexture act(this, bitmap, sampler->textureParams(), &texture); SkAutoCachedTexture act(this, bitmap, &params, &texture);
if (NULL == texture) { if (NULL == texture) {
return; return;
} }
grPaint->textureSampler(kBitmapTextureIdx)->setCustomStage(SkNEW_ARGS
(GrSingleTextureEffect, (texture)))->unref();
GrRect dstRect = SkRect::MakeWH(GrIntToScalar(srcRect.width()), GrRect dstRect = SkRect::MakeWH(GrIntToScalar(srcRect.width()),
GrIntToScalar(srcRect.height())); GrIntToScalar(srcRect.height()));
GrRect paintRect; GrRect paintRect;
@ -1443,7 +1440,7 @@ void SkGpuDevice::internalDrawBitmap(const SkDraw& draw,
SkFloatToScalar(srcRect.fBottom * hInv)); SkFloatToScalar(srcRect.fBottom * hInv));
bool needsTextureDomain = false; bool needsTextureDomain = false;
if (sampler->textureParams()->isBilerp()) { if (params.isBilerp()) {
// Need texture domain if drawing a sub rect. // 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()) { if (m.rectStaysRect() && draw.fMatrix->rectStaysRect()) {
@ -1455,8 +1452,8 @@ void SkGpuDevice::internalDrawBitmap(const SkDraw& draw,
srcToDeviceMatrix.mapRect(&transformedRect, floatSrcRect); srcToDeviceMatrix.mapRect(&transformedRect, floatSrcRect);
if (hasAlignedSamples(floatSrcRect, transformedRect)) { if (hasAlignedSamples(floatSrcRect, transformedRect)) {
// Samples are texel-aligned, so filtering is futile // We could also turn off filtering here (but we already did a cache lookup with
sampler->textureParams()->setBilerp(false); // params).
needsTextureDomain = false; needsTextureDomain = false;
} else { } else {
needsTextureDomain = needsTextureDomain && needsTextureDomain = needsTextureDomain &&
@ -1466,7 +1463,7 @@ void SkGpuDevice::internalDrawBitmap(const SkDraw& draw,
} }
GrRect textureDomain = GrRect::MakeEmpty(); GrRect textureDomain = GrRect::MakeEmpty();
SkAutoTUnref<GrCustomStage> stage;
if (needsTextureDomain) { if (needsTextureDomain) {
// Use a constrained texture domain to avoid color bleeding // Use a constrained texture domain to avoid color bleeding
GrScalar left, top, right, bottom; GrScalar left, top, right, bottom;
@ -1485,11 +1482,11 @@ void SkGpuDevice::internalDrawBitmap(const SkDraw& draw,
top = bottom = GrScalarHalf(paintRect.top() + paintRect.bottom()); top = bottom = GrScalarHalf(paintRect.top() + paintRect.bottom());
} }
textureDomain.setLTRB(left, top, right, bottom); textureDomain.setLTRB(left, top, right, bottom);
sampler->setCustomStage(SkNEW_ARGS(GrTextureDomainEffect, stage.reset(SkNEW_ARGS(GrTextureDomainEffect, (texture, textureDomain, params)));
(texture, } else {
textureDomain)))->unref(); stage.reset(SkNEW_ARGS(GrSingleTextureEffect, (texture, params)));
} }
grPaint->textureSampler(kBitmapTextureIdx)->setCustomStage(stage);
fContext->drawRectToRect(*grPaint, dstRect, paintRect, &m); fContext->drawRectToRect(*grPaint, dstRect, paintRect, &m);
} }
@ -1509,7 +1506,6 @@ void apply_custom_stage(GrContext* context,
sampleM.setIDiv(srcTexture->width(), srcTexture->height()); sampleM.setIDiv(srcTexture->width(), srcTexture->height());
GrPaint paint; GrPaint paint;
paint.reset(); paint.reset();
paint.textureSampler(0)->textureParams()->setBilerp(true);
paint.textureSampler(0)->reset(sampleM); paint.textureSampler(0)->reset(sampleM);
paint.textureSampler(0)->setCustomStage(stage); paint.textureSampler(0)->setCustomStage(stage);
context->drawRect(paint, rect); context->drawRect(paint, rect);
@ -1563,7 +1559,8 @@ void SkGpuDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap,
GrTexture* texture; GrTexture* texture;
sampler->reset(); 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 grPaint.textureSampler(kBitmapTextureIdx)->setCustomStage(SkNEW_ARGS
(GrSingleTextureEffect, (texture)))->unref(); (GrSingleTextureEffect, (texture)))->unref();
@ -1668,7 +1665,9 @@ bool SkGpuDevice::filterImage(SkImageFilter* filter, const SkBitmap& src,
GrSamplerState* sampler = paint.textureSampler(kBitmapTextureIdx); GrSamplerState* sampler = paint.textureSampler(kBitmapTextureIdx);
GrTexture* texture; 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()); result->setConfig(src.config(), src.width(), src.height());
GrRect rect = GrRect::MakeWH(SkIntToScalar(src.width()), GrRect rect = GrRect::MakeWH(SkIntToScalar(src.width()),

Просмотреть файл

@ -41,6 +41,14 @@ GrSingleTextureEffect::GrSingleTextureEffect(GrTexture* texture)
: fTextureAccess(texture) { : fTextureAccess(texture) {
} }
GrSingleTextureEffect::GrSingleTextureEffect(GrTexture* texture, bool bilerp)
: fTextureAccess(texture, bilerp) {
}
GrSingleTextureEffect::GrSingleTextureEffect(GrTexture* texture, const GrTextureParams& params)
: fTextureAccess(texture, params) {
}
GrSingleTextureEffect::~GrSingleTextureEffect() { GrSingleTextureEffect::~GrSingleTextureEffect() {
} }

Просмотреть файл

@ -18,7 +18,14 @@ class GrGLSingleTextureEffect;
class GrSingleTextureEffect : public GrCustomStage { class GrSingleTextureEffect : public GrCustomStage {
public: public:
/** Uses default texture params (unfiltered, clamp) */
GrSingleTextureEffect(GrTexture* texture); GrSingleTextureEffect(GrTexture* texture);
/** Uses default tile mode (clamp) */
GrSingleTextureEffect(GrTexture* texture, bool bilerp);
GrSingleTextureEffect(GrTexture* texture, const GrTextureParams&);
virtual ~GrSingleTextureEffect(); virtual ~GrSingleTextureEffect();
virtual int numTextures() const SK_OVERRIDE; virtual int numTextures() const SK_OVERRIDE;

Просмотреть файл

@ -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) : GrSingleTextureEffect(texture)
, fTextureDomain(domain) { , fTextureDomain(domain) {
} }
GrTextureDomainEffect::GrTextureDomainEffect(GrTexture* texture,
const GrRect& domain,
const GrTextureParams& params)
: GrSingleTextureEffect(texture, params)
, fTextureDomain(domain) {
}
GrTextureDomainEffect::~GrTextureDomainEffect() { GrTextureDomainEffect::~GrTextureDomainEffect() {
} }

Просмотреть файл

@ -20,8 +20,11 @@ class GrGLTextureDomainEffect;
class GrTextureDomainEffect : public GrSingleTextureEffect { class GrTextureDomainEffect : public GrSingleTextureEffect {
public: 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(); virtual ~GrTextureDomainEffect();
static const char* Name() { return "TextureDomain"; } static const char* Name() { return "TextureDomain"; }

Просмотреть файл

@ -2024,9 +2024,7 @@ void GrGpuGL::flushBoundTextureAndParams(int stage) {
const GrCustomStage* customStage = drawState->sampler(stage)->getCustomStage(); const GrCustomStage* customStage = drawState->sampler(stage)->getCustomStage();
GrGLTexture* nextTexture = static_cast<GrGLTexture*>(customStage->texture(0)); GrGLTexture* nextTexture = static_cast<GrGLTexture*>(customStage->texture(0));
if (NULL != nextTexture) { if (NULL != nextTexture) {
// Currently we always use the texture params from the GrSamplerState. Soon custom stages const GrTextureParams& texParams = customStage->textureAccess(0).getParams();
// will provide their own params.
const GrTextureParams& texParams = drawState->getSampler(stage).getTextureParams();
this->flushBoundTextureAndParams(stage, texParams, nextTexture); this->flushBoundTextureAndParams(stage, texParams, nextTexture);
} }
} }