aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu
diff options
context:
space:
mode:
authorGravatar joshualitt <joshualitt@chromium.org>2014-07-29 12:59:27 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2014-07-29 12:59:27 -0700
commit5ae5fc59b27a48711e514b3ede548b228e393e9b (patch)
tree94f6fe685a1bfcc9e15704cda869c67b97f057d3 /src/gpu
parent937fca81067d31bb74fc299469b2406a12064436 (diff)
Adding repeat mode to texture domain
BUG=skia: R=bsalomon@chromium.org, senorblanco@chromium.org, bsalomon@google.com, junov@chromium.org Author: joshualitt@chromium.org Review URL: https://codereview.chromium.org/422123003
Diffstat (limited to 'src/gpu')
-rw-r--r--src/gpu/effects/GrMatrixConvolutionEffect.cpp133
-rw-r--r--src/gpu/effects/GrMatrixConvolutionEffect.h32
-rw-r--r--src/gpu/effects/GrTextureDomain.cpp122
-rw-r--r--src/gpu/effects/GrTextureDomain.h17
4 files changed, 140 insertions, 164 deletions
diff --git a/src/gpu/effects/GrMatrixConvolutionEffect.cpp b/src/gpu/effects/GrMatrixConvolutionEffect.cpp
index 283138e133..04ab4f41ca 100644
--- a/src/gpu/effects/GrMatrixConvolutionEffect.cpp
+++ b/src/gpu/effects/GrMatrixConvolutionEffect.cpp
@@ -29,17 +29,16 @@ public:
private:
typedef GrGLUniformManager::UniformHandle UniformHandle;
- typedef GrMatrixConvolutionEffect::TileMode TileMode;
- SkISize fKernelSize;
- TileMode fTileMode;
- bool fConvolveAlpha;
+ SkISize fKernelSize;
+ bool fConvolveAlpha;
- UniformHandle fBoundsUni;
- UniformHandle fKernelUni;
- UniformHandle fImageIncrementUni;
- UniformHandle fKernelOffsetUni;
- UniformHandle fGainUni;
- UniformHandle fBiasUni;
+ UniformHandle fBoundsUni;
+ UniformHandle fKernelUni;
+ UniformHandle fImageIncrementUni;
+ UniformHandle fKernelOffsetUni;
+ UniformHandle fGainUni;
+ UniformHandle fBiasUni;
+ GrTextureDomain::GLDomain fDomain;
typedef GrGLEffect INHERITED;
};
@@ -49,57 +48,34 @@ GrGLMatrixConvolutionEffect::GrGLMatrixConvolutionEffect(const GrBackendEffectFa
: INHERITED(factory) {
const GrMatrixConvolutionEffect& m = drawEffect.castEffect<GrMatrixConvolutionEffect>();
fKernelSize = m.kernelSize();
- fTileMode = m.tileMode();
fConvolveAlpha = m.convolveAlpha();
}
-static void appendTextureLookup(GrGLShaderBuilder* builder,
- const GrGLShaderBuilder::TextureSampler& sampler,
- const char* coord,
- const char* bounds,
- GrMatrixConvolutionEffect::TileMode tileMode) {
- SkString clampedCoord;
- switch (tileMode) {
- case GrMatrixConvolutionEffect::kClamp_TileMode:
- clampedCoord.printf("clamp(%s, %s.xy, %s.zw)", coord, bounds, bounds);
- coord = clampedCoord.c_str();
- break;
- case GrMatrixConvolutionEffect::kRepeat_TileMode:
- clampedCoord.printf("mod(%s - %s.xy, %s.zw - %s.xy) + %s.xy", coord, bounds, bounds, bounds, bounds);
- coord = clampedCoord.c_str();
- break;
- case GrMatrixConvolutionEffect::kClampToBlack_TileMode:
- builder->fsCodeAppendf("clamp(%s, %s.xy, %s.zw) != %s ? vec4(0, 0, 0, 0) : ", coord, bounds, bounds, coord);
- break;
- }
- builder->fsAppendTextureLookup(sampler, coord);
-}
-
void GrGLMatrixConvolutionEffect::emitCode(GrGLShaderBuilder* builder,
- const GrDrawEffect&,
+ const GrDrawEffect& drawEffect,
const GrEffectKey& key,
const char* outputColor,
const char* inputColor,
const TransformedCoordsArray& coords,
const TextureSamplerArray& samplers) {
sk_ignore_unused_variable(inputColor);
+ const GrTextureDomain& domain = drawEffect.castEffect<GrMatrixConvolutionEffect>().domain();
SkString coords2D = builder->ensureFSCoords2D(coords, 0);
fBoundsUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
kVec4f_GrSLType, "Bounds");
fImageIncrementUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
kVec2f_GrSLType, "ImageIncrement");
fKernelUni = builder->addUniformArray(GrGLShaderBuilder::kFragment_Visibility,
- kFloat_GrSLType,
- "Kernel",
- fKernelSize.width() * fKernelSize.height());
+ kFloat_GrSLType,
+ "Kernel",
+ fKernelSize.width() * fKernelSize.height());
fKernelOffsetUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
- kVec2f_GrSLType, "KernelOffset");
+ kVec2f_GrSLType, "KernelOffset");
fGainUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
kFloat_GrSLType, "Gain");
fBiasUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
kFloat_GrSLType, "Bias");
- const char* bounds = builder->getUniformCStr(fBoundsUni);
const char* kernelOffset = builder->getUniformCStr(fKernelOffsetUni);
const char* imgInc = builder->getUniformCStr(fImageIncrementUni);
const char* kernel = builder->getUniformCStr(fKernelUni);
@@ -109,53 +85,43 @@ void GrGLMatrixConvolutionEffect::emitCode(GrGLShaderBuilder* builder,
int kHeight = fKernelSize.height();
builder->fsCodeAppend("\t\tvec4 sum = vec4(0, 0, 0, 0);\n");
- builder->fsCodeAppendf("\t\tvec2 coord = %s - %s * %s;\n", coords2D.c_str(), kernelOffset, imgInc);
- builder->fsCodeAppendf("\t\tfor (int y = 0; y < %d; y++) {\n", kHeight);
- builder->fsCodeAppendf("\t\t\tfor (int x = 0; x < %d; x++) {\n", kWidth);
- builder->fsCodeAppendf("\t\t\t\tfloat k = %s[y * %d + x];\n", kernel, kWidth);
- builder->fsCodeAppendf("\t\t\t\tvec2 coord2 = coord + vec2(x, y) * %s;\n", imgInc);
- builder->fsCodeAppend("\t\t\t\tvec4 c = ");
- appendTextureLookup(builder, samplers[0], "coord2", bounds, fTileMode);
- builder->fsCodeAppend(";\n");
- if (!fConvolveAlpha) {
- builder->fsCodeAppend("\t\t\t\tc.rgb /= c.a;\n");
+ builder->fsCodeAppendf("\t\tvec2 coord = %s - %s * %s;\n", coords2D.c_str(), kernelOffset,
+ imgInc);
+ builder->fsCodeAppend("\t\tvec4 c;\n");
+
+ for (int y = 0; y < kHeight; y++) {
+ for (int x = 0; x < kWidth; x++) {
+ GrGLShaderBuilder::FSBlock block(builder);
+ builder->fsCodeAppendf("\t\tfloat k = %s[%d * %d + %d];\n", kernel, y, kWidth, x);
+ SkString coord;
+ coord.printf("coord + vec2(%d, %d) * %s", x, y, imgInc);
+ fDomain.sampleTexture(builder, domain, "c", coord, samplers[0]);
+ if (!fConvolveAlpha) {
+ builder->fsCodeAppend("\t\tc.rgb /= c.a;\n");
+ }
+ builder->fsCodeAppend("\t\tsum += c * k;\n");
+ }
}
- builder->fsCodeAppend("\t\t\t\tsum += c * k;\n");
- builder->fsCodeAppend("\t\t\t}\n");
- builder->fsCodeAppend("\t\t}\n");
if (fConvolveAlpha) {
builder->fsCodeAppendf("\t\t%s = sum * %s + %s;\n", outputColor, gain, bias);
builder->fsCodeAppendf("\t\t%s.rgb = clamp(%s.rgb, 0.0, %s.a);\n",
- outputColor, outputColor, outputColor);
+ outputColor, outputColor, outputColor);
} else {
- builder->fsCodeAppend("\t\tvec4 c = ");
- appendTextureLookup(builder, samplers[0], coords2D.c_str(), bounds, fTileMode);
- builder->fsCodeAppend(";\n");
+ fDomain.sampleTexture(builder, domain, "c", coords2D, samplers[0]);
builder->fsCodeAppendf("\t\t%s.a = c.a;\n", outputColor);
builder->fsCodeAppendf("\t\t%s.rgb = sum.rgb * %s + %s;\n", outputColor, gain, bias);
builder->fsCodeAppendf("\t\t%s.rgb *= %s.a;\n", outputColor, outputColor);
}
}
-namespace {
-
-int encodeXY(int x, int y) {
- SkASSERT(x >= 1 && y >= 1 && x * y <= 32);
- if (y < x)
- return 0x40 | encodeXY(y, x);
- else
- return (0x40 >> x) | (y - x);
-}
-
-};
-
void GrGLMatrixConvolutionEffect::GenKey(const GrDrawEffect& drawEffect,
const GrGLCaps&, GrEffectKeyBuilder* b) {
const GrMatrixConvolutionEffect& m = drawEffect.castEffect<GrMatrixConvolutionEffect>();
- uint32_t key = encodeXY(m.kernelSize().width(), m.kernelSize().height());
- key |= m.tileMode() << 7;
- key |= m.convolveAlpha() ? 1 << 9 : 0;
+ SkASSERT(m.kernelSize().width() <= 0x7FFF && m.kernelSize().height() <= 0xFFFF);
+ uint32_t key = m.kernelSize().width() << 16 | m.kernelSize().height();
+ key |= m.convolveAlpha() ? 1 << 31 : 0;
b->add32(key);
+ b->add32(GrTextureDomain::GLDomain::DomainKey(m.domain()));
}
void GrGLMatrixConvolutionEffect::setData(const GrGLUniformManager& uman,
@@ -164,7 +130,6 @@ void GrGLMatrixConvolutionEffect::setData(const GrGLUniformManager& uman,
GrTexture& texture = *conv.texture(0);
// the code we generated was for a specific kernel size
SkASSERT(conv.kernelSize() == fKernelSize);
- SkASSERT(conv.tileMode() == fTileMode);
float imageIncrement[2];
float ySign = texture.origin() == kTopLeft_GrSurfaceOrigin ? 1.0f : -1.0f;
imageIncrement[0] = 1.0f / texture.width();
@@ -174,16 +139,7 @@ void GrGLMatrixConvolutionEffect::setData(const GrGLUniformManager& uman,
uman.set1fv(fKernelUni, fKernelSize.width() * fKernelSize.height(), conv.kernel());
uman.set1f(fGainUni, conv.gain());
uman.set1f(fBiasUni, conv.bias());
- const SkIRect& bounds = conv.bounds();
- float left = (float) bounds.left() / texture.width();
- float top = (float) bounds.top() / texture.height();
- float right = (float) bounds.right() / texture.width();
- float bottom = (float) bounds.bottom() / texture.height();
- if (texture.origin() == kBottomLeft_GrSurfaceOrigin) {
- uman.set4f(fBoundsUni, left, 1.0f - bottom, right, 1.0f - top);
- } else {
- uman.set4f(fBoundsUni, left, top, right, bottom);
- }
+ fDomain.setData(uman, conv.domain(), texture.origin());
}
GrMatrixConvolutionEffect::GrMatrixConvolutionEffect(GrTexture* texture,
@@ -193,15 +149,14 @@ GrMatrixConvolutionEffect::GrMatrixConvolutionEffect(GrTexture* texture,
SkScalar gain,
SkScalar bias,
const SkIPoint& kernelOffset,
- TileMode tileMode,
+ GrTextureDomain::Mode tileMode,
bool convolveAlpha)
: INHERITED(texture, MakeDivByTextureWHMatrix(texture)),
- fBounds(bounds),
fKernelSize(kernelSize),
fGain(SkScalarToFloat(gain)),
fBias(SkScalarToFloat(bias) / 255.0f),
- fTileMode(tileMode),
- fConvolveAlpha(convolveAlpha) {
+ fConvolveAlpha(convolveAlpha),
+ fDomain(GrTextureDomain::MakeTexelDomain(texture, bounds), tileMode) {
fKernel = new float[kernelSize.width() * kernelSize.height()];
for (int i = 0; i < kernelSize.width() * kernelSize.height(); i++) {
fKernel[i] = SkScalarToFloat(kernel[i]);
@@ -228,8 +183,8 @@ bool GrMatrixConvolutionEffect::onIsEqual(const GrEffect& sBase) const {
fGain == s.gain() &&
fBias == s.bias() &&
fKernelOffset == s.kernelOffset() &&
- fTileMode == s.tileMode() &&
- fConvolveAlpha == s.convolveAlpha();
+ fConvolveAlpha == s.convolveAlpha() &&
+ fDomain == s.domain();
}
GR_DEFINE_EFFECT_TEST(GrMatrixConvolutionEffect);
@@ -255,7 +210,7 @@ GrEffect* GrMatrixConvolutionEffect::TestCreate(SkRandom* random,
random->nextRangeU(0, textures[texIdx]->height()),
random->nextRangeU(0, textures[texIdx]->width()),
random->nextRangeU(0, textures[texIdx]->height()));
- TileMode tileMode = static_cast<TileMode>(random->nextRangeU(0, 2));
+ GrTextureDomain::Mode tileMode = static_cast<GrTextureDomain::Mode>(random->nextRangeU(0, 2));
bool convolveAlpha = random->nextBool();
return GrMatrixConvolutionEffect::Create(textures[texIdx],
bounds,
diff --git a/src/gpu/effects/GrMatrixConvolutionEffect.h b/src/gpu/effects/GrMatrixConvolutionEffect.h
index 6fdd85b7c7..24c3bdb285 100644
--- a/src/gpu/effects/GrMatrixConvolutionEffect.h
+++ b/src/gpu/effects/GrMatrixConvolutionEffect.h
@@ -9,6 +9,7 @@
#define GrMatrixConvolutionEffect_DEFINED
#include "GrSingleTextureEffect.h"
+#include "GrTextureDomain.h"
// A little bit less than the minimum # uniforms required by DX9SM2 (32).
// Allows for a 5x5 kernel (or 25x1, for that matter).
@@ -18,15 +19,6 @@ class GrGLMatrixConvolutionEffect;
class GrMatrixConvolutionEffect : public GrSingleTextureEffect {
public:
- /*! \enum TileMode */
- enum TileMode {
- kClamp_TileMode = 0, /*!< Clamp to the image's edge pixels. */
- kRepeat_TileMode, /*!< Wrap around to the image's opposite edge. */
- kClampToBlack_TileMode, /*!< Fill with transparent black. */
- kMax_TileMode = kClampToBlack_TileMode
- };
-
- typedef GrMatrixConvolutionEffect::TileMode TileMode;
static GrEffect* Create(GrTexture* texture,
const SkIRect& bounds,
const SkISize& kernelSize,
@@ -34,7 +26,7 @@ public:
SkScalar gain,
SkScalar bias,
const SkIPoint& kernelOffset,
- TileMode tileMode,
+ GrTextureDomain::Mode tileMode,
bool convolveAlpha) {
return SkNEW_ARGS(GrMatrixConvolutionEffect, (texture,
bounds,
@@ -61,8 +53,8 @@ public:
const float* kernel() const { return fKernel; }
float gain() const { return fGain; }
float bias() const { return fBias; }
- TileMode tileMode() const { return fTileMode; }
bool convolveAlpha() const { return fConvolveAlpha; }
+ const GrTextureDomain& domain() const { return fDomain; }
typedef GrGLMatrixConvolutionEffect GLEffect;
@@ -76,19 +68,19 @@ private:
SkScalar gain,
SkScalar bias,
const SkIPoint& kernelOffset,
- TileMode tileMode,
+ GrTextureDomain::Mode tileMode,
bool convolveAlpha);
virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE;
- SkIRect fBounds;
- SkISize fKernelSize;
- float *fKernel;
- float fGain;
- float fBias;
- float fKernelOffset[2];
- TileMode fTileMode;
- bool fConvolveAlpha;
+ SkIRect fBounds;
+ SkISize fKernelSize;
+ float* fKernel;
+ float fGain;
+ float fBias;
+ float fKernelOffset[2];
+ bool fConvolveAlpha;
+ GrTextureDomain fDomain;
GR_DECLARE_EFFECT_TEST;
diff --git a/src/gpu/effects/GrTextureDomain.cpp b/src/gpu/effects/GrTextureDomain.cpp
index 5af5bc86f3..b0004229ad 100644
--- a/src/gpu/effects/GrTextureDomain.cpp
+++ b/src/gpu/effects/GrTextureDomain.cpp
@@ -49,65 +49,85 @@ void GrTextureDomain::GLDomain::sampleTexture(GrGLShaderBuilder* builder,
SkASSERT((Mode)-1 == fMode || textureDomain.mode() == fMode);
SkDEBUGCODE(fMode = textureDomain.mode();)
- if (kIgnore_Mode == textureDomain.mode()) {
- builder->fsCodeAppendf("\t%s = ", outColor);
- builder->fsAppendTextureLookupAndModulate(inModulateColor, sampler,
- inCoords.c_str());
- builder->fsCodeAppend(";\n");
- return;
- }
-
- if (!fDomainUni.isValid()) {
+ if (textureDomain.mode() != kIgnore_Mode && !fDomainUni.isValid()) {
const char* name;
SkString uniName("TexDom");
if (textureDomain.fIndex >= 0) {
uniName.appendS32(textureDomain.fIndex);
}
fDomainUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
- kVec4f_GrSLType, uniName.c_str(), &name);
+ kVec4f_GrSLType, uniName.c_str(), &name);
fDomainName = name;
}
- if (kClamp_Mode == textureDomain.mode()) {
- SkString clampedCoords;
- clampedCoords.appendf("\tclamp(%s, %s.xy, %s.zw)",
- inCoords.c_str(), fDomainName.c_str(), fDomainName.c_str());
-
- builder->fsCodeAppendf("\t%s = ", outColor);
- builder->fsAppendTextureLookupAndModulate(inModulateColor, sampler, clampedCoords.c_str());
- builder->fsCodeAppend(";\n");
- } else {
- SkASSERT(GrTextureDomain::kDecal_Mode == textureDomain.mode());
- // Add a block since we're going to declare variables.
- GrGLShaderBuilder::FSBlock block(builder);
-
- const char* domain = fDomainName.c_str();
- if (kImagination_GrGLVendor == builder->ctxInfo().vendor()) {
- // On the NexusS and GalaxyNexus, the other path (with the 'any'
- // call) causes the compilation error "Calls to any function that
- // may require a gradient calculation inside a conditional block
- // may return undefined results". This appears to be an issue with
- // the 'any' call since even the simple "result=black; if (any())
- // result=white;" code fails to compile.
- builder->fsCodeAppend("\tvec4 outside = vec4(0.0, 0.0, 0.0, 0.0);\n");
- builder->fsCodeAppend("\tvec4 inside = ");
- builder->fsAppendTextureLookupAndModulate(inModulateColor, sampler, inCoords.c_str());
- builder->fsCodeAppend(";\n");
- builder->fsCodeAppendf("\tfloat x = abs(2.0*(%s.x - %s.x)/(%s.z - %s.x) - 1.0);\n",
- inCoords.c_str(), domain, domain, domain);
- builder->fsCodeAppendf("\tfloat y = abs(2.0*(%s.y - %s.y)/(%s.w - %s.y) - 1.0);\n",
- inCoords.c_str(), domain, domain, domain);
- builder->fsCodeAppend("\tfloat blend = step(1.0, max(x, y));\n");
- builder->fsCodeAppendf("\t%s = mix(inside, outside, blend);\n", outColor);
- } else {
- builder->fsCodeAppend("\tbvec4 outside;\n");
- builder->fsCodeAppendf("\toutside.xy = lessThan(%s, %s.xy);\n", inCoords.c_str(),
- domain);
- builder->fsCodeAppendf("\toutside.zw = greaterThan(%s, %s.zw);\n", inCoords.c_str(),
- domain);
- builder->fsCodeAppendf("\t%s = any(outside) ? vec4(0.0, 0.0, 0.0, 0.0) : ", outColor);
- builder->fsAppendTextureLookupAndModulate(inModulateColor, sampler, inCoords.c_str());
+ switch (textureDomain.mode()) {
+ case kIgnore_Mode: {
+ builder->fsCodeAppendf("\t%s = ", outColor);
+ builder->fsAppendTextureLookupAndModulate(inModulateColor, sampler,
+ inCoords.c_str());
+ builder->fsCodeAppend(";\n");
+ break;
+ }
+ case kClamp_Mode: {
+ SkString clampedCoords;
+ clampedCoords.appendf("\tclamp(%s, %s.xy, %s.zw)",
+ inCoords.c_str(), fDomainName.c_str(), fDomainName.c_str());
+
+ builder->fsCodeAppendf("\t%s = ", outColor);
+ builder->fsAppendTextureLookupAndModulate(inModulateColor, sampler,
+ clampedCoords.c_str());
+ builder->fsCodeAppend(";\n");
+ break;
+ }
+ case kDecal_Mode: {
+ // Add a block since we're going to declare variables.
+ GrGLShaderBuilder::FSBlock block(builder);
+
+ const char* domain = fDomainName.c_str();
+ if (kImagination_GrGLVendor == builder->ctxInfo().vendor()) {
+ // On the NexusS and GalaxyNexus, the other path (with the 'any'
+ // call) causes the compilation error "Calls to any function that
+ // may require a gradient calculation inside a conditional block
+ // may return undefined results". This appears to be an issue with
+ // the 'any' call since even the simple "result=black; if (any())
+ // result=white;" code fails to compile.
+ builder->fsCodeAppend("\tvec4 outside = vec4(0.0, 0.0, 0.0, 0.0);\n");
+ builder->fsCodeAppend("\tvec4 inside = ");
+ builder->fsAppendTextureLookupAndModulate(inModulateColor, sampler,
+ inCoords.c_str());
+ builder->fsCodeAppend(";\n");
+
+ builder->fsCodeAppendf("\tfloat x = abs(2.0*(%s.x - %s.x)/(%s.z - %s.x) - 1.0);\n",
+ inCoords.c_str(), domain, domain, domain);
+ builder->fsCodeAppendf("\tfloat y = abs(2.0*(%s.y - %s.y)/(%s.w - %s.y) - 1.0);\n",
+ inCoords.c_str(), domain, domain, domain);
+ builder->fsCodeAppend("\tfloat blend = step(1.0, max(x, y));\n");
+ builder->fsCodeAppendf("\t%s = mix(inside, outside, blend);\n", outColor);
+ } else {
+ builder->fsCodeAppend("\tbvec4 outside;\n");
+ builder->fsCodeAppendf("\toutside.xy = lessThan(%s, %s.xy);\n", inCoords.c_str(),
+ domain);
+ builder->fsCodeAppendf("\toutside.zw = greaterThan(%s, %s.zw);\n", inCoords.c_str(),
+ domain);
+ builder->fsCodeAppendf("\t%s = any(outside) ? vec4(0.0, 0.0, 0.0, 0.0) : ",
+ outColor);
+ builder->fsAppendTextureLookupAndModulate(inModulateColor, sampler,
+ inCoords.c_str());
+ builder->fsCodeAppend(";\n");
+ }
+ break;
+ }
+ case kRepeat_Mode: {
+ SkString clampedCoords;
+ clampedCoords.printf("\tmod(%s - %s.xy, %s.zw - %s.xy) + %s.xy",
+ inCoords.c_str(), fDomainName.c_str(), fDomainName.c_str(),
+ fDomainName.c_str(), fDomainName.c_str());
+
+ builder->fsCodeAppendf("\t%s = ", outColor);
+ builder->fsAppendTextureLookupAndModulate(inModulateColor, sampler,
+ clampedCoords.c_str());
builder->fsCodeAppend(";\n");
+ break;
}
}
}
@@ -226,6 +246,8 @@ GrTextureDomainEffect::GrTextureDomainEffect(GrTexture* texture,
GrCoordSet coordSet)
: GrSingleTextureEffect(texture, matrix, filterMode, coordSet)
, fTextureDomain(domain, mode) {
+ SkASSERT(mode != GrTextureDomain::kRepeat_Mode ||
+ filterMode == GrTextureParams::kNone_FilterMode);
}
GrTextureDomainEffect::~GrTextureDomainEffect() {
@@ -268,7 +290,7 @@ GrEffect* GrTextureDomainEffect::TestCreate(SkRandom* random,
GrTextureDomain::Mode mode =
(GrTextureDomain::Mode) random->nextULessThan(GrTextureDomain::kModeCount);
const SkMatrix& matrix = GrEffectUnitTest::TestMatrix(random);
- bool bilerp = random->nextBool();
+ bool bilerp = mode != GrTextureDomain::kRepeat_Mode ? random->nextBool() : false;
GrCoordSet coords = random->nextBool() ? kLocal_GrCoordSet : kPosition_GrCoordSet;
return GrTextureDomainEffect::Create(textures[texIdx],
matrix,
diff --git a/src/gpu/effects/GrTextureDomain.h b/src/gpu/effects/GrTextureDomain.h
index 80a617ef72..7e270f8218 100644
--- a/src/gpu/effects/GrTextureDomain.h
+++ b/src/gpu/effects/GrTextureDomain.h
@@ -23,11 +23,18 @@ struct SkRect;
class GrTextureDomain {
public:
enum Mode {
- kIgnore_Mode, // Ignore the texture domain rectangle.
- kClamp_Mode, // Clamp texture coords to the domain rectangle.
- kDecal_Mode, // Treat the area outside the domain rectangle as fully transparent.
-
- kLastMode = kDecal_Mode
+ // Ignore the texture domain rectangle.
+ kIgnore_Mode,
+ // Clamp texture coords to the domain rectangle.
+ kClamp_Mode,
+ // Treat the area outside the domain rectangle as fully transparent.
+ kDecal_Mode,
+ // Wrap texture coordinates. NOTE: filtering may not work as expected because Bilerp will
+ // read texels outside of the domain. We could perform additional texture reads and filter
+ // in the shader, but are not currently doing this for performance reasons
+ kRepeat_Mode,
+
+ kLastMode = kRepeat_Mode
};
static const int kModeCount = kLastMode + 1;