Move texture domains onto a GrCustomStage, off of GrSamplerState.
This will require gyp changes to roll into Chrome.
http://codereview.appspot.com/6405050/
git-svn-id: http://skia.googlecode.com/svn/trunk@4641 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gyp/gpu.gyp b/gyp/gpu.gyp
index 4a708d8..523ba52 100644
--- a/gyp/gpu.gyp
+++ b/gyp/gpu.gyp
@@ -295,6 +295,8 @@
'../src/gpu/effects/GrMorphologyEffect.h',
'../src/gpu/effects/GrSingleTextureEffect.cpp',
'../src/gpu/effects/GrSingleTextureEffect.h',
+ '../src/gpu/effects/GrTextureDomainEffect.cpp',
+ '../src/gpu/effects/GrTextureDomainEffect.h',
'../src/gpu/gl/GrGLCaps.cpp',
'../src/gpu/gl/GrGLCaps.h',
diff --git a/include/gpu/GrSamplerState.h b/include/gpu/GrSamplerState.h
index 1f81afa..0731848 100644
--- a/include/gpu/GrSamplerState.h
+++ b/include/gpu/GrSamplerState.h
@@ -79,7 +79,6 @@
fFilter = s.fFilter;
fMatrix = s.fMatrix;
fSwapRAndB = s.fSwapRAndB;
- fTextureDomain = s.fTextureDomain;
GrSafeAssign(fCustomStage, s.fCustomStage);
@@ -89,8 +88,6 @@
WrapMode getWrapX() const { return fWrapX; }
WrapMode getWrapY() const { return fWrapY; }
const GrMatrix& getMatrix() const { return fMatrix; }
- const GrRect& getTextureDomain() const { return fTextureDomain; }
- bool hasTextureDomain() const {return SkIntToScalar(0) != fTextureDomain.right();}
Filter getFilter() const { return fFilter; }
bool swapsRAndB() const { return fSwapRAndB; }
@@ -104,13 +101,6 @@
GrMatrix* matrix() { return &fMatrix; }
/**
- * Sets the sampler's texture coordinate domain to a
- * custom rectangle, rather than the default (0,1).
- * This option is currently only supported with kClamp_WrapMode
- */
- void setTextureDomain(const GrRect& textureDomain) { fTextureDomain = textureDomain; }
-
- /**
* Swaps the R and B components when reading from the texture. Has no effect
* if the texture is alpha only.
*/
@@ -141,7 +131,6 @@
fWrapY = wrapXAndY;
fFilter = filter;
fMatrix = matrix;
- fTextureDomain.setEmpty();
fSwapRAndB = false;
GrSafeSetNull(fCustomStage);
}
@@ -167,7 +156,6 @@
Filter fFilter : 8;
bool fSwapRAndB;
GrMatrix fMatrix;
- GrRect fTextureDomain;
GrCustomStage* fCustomStage;
};
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index dfded26..d0d4604 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -8,6 +8,7 @@
#include "SkGpuDevice.h"
#include "effects/GrGradientEffects.h"
+#include "effects/GrTextureDomainEffect.h"
#include "GrContext.h"
#include "GrTextContext.h"
@@ -1453,8 +1454,10 @@
top = bottom = GrScalarHalf(paintRect.top() + paintRect.bottom());
}
textureDomain.setLTRB(left, top, right, bottom);
+ sampler->setCustomStage(SkNEW_ARGS(GrTextureDomainEffect,
+ (texture,
+ textureDomain)))->unref();
}
- sampler->setTextureDomain(textureDomain);
fContext->drawRectToRect(*grPaint, dstRect, paintRect, &m);
}
diff --git a/src/gpu/effects/GrTextureDomainEffect.cpp b/src/gpu/effects/GrTextureDomainEffect.cpp
new file mode 100644
index 0000000..e639df8
--- /dev/null
+++ b/src/gpu/effects/GrTextureDomainEffect.cpp
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "GrTextureDomainEffect.h"
+#include "gl/GrGLProgramStage.h"
+#include "GrProgramStageFactory.h"
+
+class GrGLTextureDomainEffect : public GrGLProgramStage {
+public:
+ GrGLTextureDomainEffect(const GrProgramStageFactory& factory,
+ const GrCustomStage& stage);
+
+ virtual void setupVariables(GrGLShaderBuilder* state,
+ int stage) SK_OVERRIDE;
+ virtual void emitVS(GrGLShaderBuilder* state,
+ const char* vertexCoords) SK_OVERRIDE { }
+ virtual void emitFS(GrGLShaderBuilder* state,
+ const char* outputColor,
+ const char* inputColor,
+ const char* samplerName) SK_OVERRIDE;
+
+ virtual void initUniforms(const GrGLInterface*, int programID) SK_OVERRIDE;
+
+ virtual void setData(const GrGLInterface*,
+ const GrCustomStage&,
+ const GrRenderTarget*,
+ int stageNum) SK_OVERRIDE;
+
+ static inline StageKey GenKey(const GrCustomStage&) { return 0; }
+
+private:
+ const GrGLShaderVar* fNameVar;
+ int fNameLocation;
+
+ typedef GrGLProgramStage INHERITED;
+};
+
+GrGLTextureDomainEffect::GrGLTextureDomainEffect(const GrProgramStageFactory& factory,
+ const GrCustomStage& stage)
+ : GrGLProgramStage(factory)
+ , fNameVar(NULL)
+ , fNameLocation(0) {
+}
+
+void GrGLTextureDomainEffect::setupVariables(GrGLShaderBuilder* state,
+ int stage) {
+ fNameVar = &state->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
+ kVec4f_GrSLType, "uTexDom", stage);
+ fNameLocation = kUseUniform;
+};
+
+void GrGLTextureDomainEffect::emitFS(GrGLShaderBuilder* state,
+ const char* outputColor,
+ const char* inputColor,
+ const char* samplerName) {
+ SkString coordVar("clampCoord");
+ state->fFSCode.appendf("\t%s %s = clamp(%s, %s.xy, %s.zw);\n",
+ GrGLShaderVar::TypeString(GrSLFloatVectorType(state->fCoordDims)),
+ coordVar.c_str(),
+ state->fSampleCoords.c_str(),
+ fNameVar->getName().c_str(),
+ fNameVar->getName().c_str());
+ state->fSampleCoords = coordVar;
+
+ state->emitDefaultFetch(outputColor, samplerName);
+}
+
+void GrGLTextureDomainEffect::initUniforms(const GrGLInterface* gl, int programID) {
+ GR_GL_CALL_RET(gl, fNameLocation,
+ GetUniformLocation(programID, fNameVar->getName().c_str()));
+ GrAssert(kUnusedUniform != fNameLocation);
+}
+
+void GrGLTextureDomainEffect::setData(const GrGLInterface* gl,
+ const GrCustomStage& data,
+ const GrRenderTarget*,
+ int stageNum) {
+ const GrTextureDomainEffect& effect = static_cast<const GrTextureDomainEffect&>(data);
+ const GrRect& domain = effect.domain();
+
+ float values[4] = {
+ GrScalarToFloat(domain.left()),
+ GrScalarToFloat(domain.top()),
+ GrScalarToFloat(domain.right()),
+ GrScalarToFloat(domain.bottom())
+ };
+ // vertical flip if necessary
+ const GrGLTexture* texture = static_cast<const GrGLTexture*>(effect.texture(0));
+ if (GrGLTexture::kBottomUp_Orientation == texture->orientation()) {
+ values[1] = 1.0f - values[1];
+ values[3] = 1.0f - values[3];
+ // The top and bottom were just flipped, so correct the ordering
+ // of elements so that values = (l, t, r, b).
+ SkTSwap(values[1], values[3]);
+ }
+
+ GR_GL_CALL(gl, Uniform4fv(fNameLocation, 1, values));
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+
+GrTextureDomainEffect::GrTextureDomainEffect(GrTexture* texture, GrRect domain)
+ : GrSingleTextureEffect(texture)
+ , fTextureDomain(domain) {
+
+}
+
+GrTextureDomainEffect::~GrTextureDomainEffect() {
+
+}
+
+const GrProgramStageFactory& GrTextureDomainEffect::getFactory() const {
+ return GrTProgramStageFactory<GrTextureDomainEffect>::getInstance();
+}
+
+bool GrTextureDomainEffect::isEqual(const GrCustomStage& sBase) const {
+ const GrTextureDomainEffect& s = static_cast<const GrTextureDomainEffect&>(sBase);
+ return (INHERITED::isEqual(sBase) && this->fTextureDomain == s.fTextureDomain);
+}
+
+
diff --git a/src/gpu/effects/GrTextureDomainEffect.h b/src/gpu/effects/GrTextureDomainEffect.h
new file mode 100644
index 0000000..6157175
--- /dev/null
+++ b/src/gpu/effects/GrTextureDomainEffect.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrTextureDomainEffect_DEFINED
+#define GrTextureDomainEffect_DEFINED
+
+//#include "GrCustomStage.h"
+#include "GrSingleTextureEffect.h"
+#include "GrRect.h"
+
+class GrGLTextureDomainEffect;
+
+/**
+ * Limits a texture's lookup coordinates to a domain.
+ */
+class GrTextureDomainEffect : public GrSingleTextureEffect {
+
+public:
+
+ GrTextureDomainEffect(GrTexture*, GrRect domain);
+ virtual ~GrTextureDomainEffect();
+
+ static const char* Name() { return "TextureDomain"; }
+
+ typedef GrGLTextureDomainEffect GLProgramStage;
+
+ virtual const GrProgramStageFactory& getFactory() const SK_OVERRIDE;
+ virtual bool isEqual(const GrCustomStage&) const SK_OVERRIDE;
+
+ const GrRect& domain() const { return fTextureDomain; }
+
+protected:
+
+ GrRect fTextureDomain;
+
+private:
+
+ typedef GrSingleTextureEffect INHERITED;
+};
+
+#endif
diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp
index 4f549d0..49cb161 100644
--- a/src/gpu/gl/GrGLProgram.cpp
+++ b/src/gpu/gl/GrGLProgram.cpp
@@ -86,11 +86,6 @@
*s = "uSampler";
s->appendS32(stage);
}
-
-inline void tex_domain_name(int stage, SkString* s) {
- *s = "uTexDom";
- s->appendS32(stage);
-}
}
GrGLProgram::GrGLProgram() {
@@ -1023,14 +1018,6 @@
GrAssert(kUnusedUniform != locations.fSamplerUni);
}
- if (kUseUniform == locations.fTexDomUni) {
- SkString texDomName;
- tex_domain_name(s, &texDomName);
- GL_CALL_RET(locations.fTexDomUni,
- GetUniformLocation(fProgramID, texDomName.c_str()));
- GrAssert(kUnusedUniform != locations.fTexDomUni);
- }
-
if (NULL != fProgramStage[s]) {
fProgramStage[s]->initUniforms(&builder, gl.interface(), fProgramID);
}
@@ -1044,7 +1031,6 @@
GL_CALL(Uniform1i(fUniLocations.fStages[s].fSamplerUni, s));
}
fTextureMatrices[s] = GrMatrix::InvalidMatrix();
- fTextureDomain[s].setEmpty();
// this is arbitrary, just initialize to something
fTextureOrientation[s] = GrGLTexture::kBottomUp_Orientation;
// Must not reset fStageOverride[] here.
@@ -1154,22 +1140,6 @@
(StageDesc::kMulRGBByAlpha_RoundUp_InConfigFlag |
StageDesc::kMulRGBByAlpha_RoundDown_InConfigFlag);
- if (desc.fOptFlags & StageDesc::kCustomTextureDomain_OptFlagBit) {
- SkString texDomainName;
- tex_domain_name(stageNum, &texDomainName);
- segments->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
- kVec4f_GrSLType, texDomainName.c_str());
- SkString coordVar("clampCoord");
- segments->fFSCode.appendf("\t%s %s = clamp(%s, %s.xy, %s.zw);\n",
- float_vector_type_str(segments->fCoordDims),
- coordVar.c_str(),
- segments->fSampleCoords.c_str(),
- texDomainName.c_str(),
- texDomainName.c_str());
- segments->fSampleCoords = coordVar;
- locations.fTexDomUni = kUseUniform;
- }
-
// NOTE: GrGLProgramStages are now responsible for fetching
if (NULL == customStage) {
if (desc.fInConfigFlags & kMulByAlphaMask) {
diff --git a/src/gpu/gl/GrGLProgram.h b/src/gpu/gl/GrGLProgram.h
index c397d74..9381cfb 100644
--- a/src/gpu/gl/GrGLProgram.h
+++ b/src/gpu/gl/GrGLProgram.h
@@ -112,7 +112,6 @@
enum OptFlagBits {
kNoPerspective_OptFlagBit = 1 << 0,
kIdentityMatrix_OptFlagBit = 1 << 1,
- kCustomTextureDomain_OptFlagBit = 1 << 2,
kIsEnabled_OptFlagBit = 1 << 7
};
@@ -322,10 +321,9 @@
GrColor fColor;
GrColor fCoverage;
GrColor fColorFilterColor;
+ /// When it is sent to GL, the texture matrix will be flipped if the texture orientation
+ /// (below) requires.
GrMatrix fTextureMatrices[GrDrawState::kNumStages];
- GrRect fTextureDomain[GrDrawState::kNumStages];
- // The texture domain and texture matrix sent to GL depend upon the
- // orientation.
GrGLTexture::Orientation fTextureOrientation[GrDrawState::kNumStages];
GrGLProgramStage* fProgramStage[GrDrawState::kNumStages];
diff --git a/src/gpu/gl/GrGpuGL_program.cpp b/src/gpu/gl/GrGpuGL_program.cpp
index 077f807..7f982e7 100644
--- a/src/gpu/gl/GrGpuGL_program.cpp
+++ b/src/gpu/gl/GrGpuGL_program.cpp
@@ -248,30 +248,6 @@
fCurrentProgram->fTextureMatrices[s] = samplerMatrix;
}
- const GrGLint& domUni = fCurrentProgram->fUniLocations.fStages[s].fTexDomUni;
- const GrRect &texDom = drawState.getSampler(s).getTextureDomain();
- if (GrGLProgram::kUnusedUniform != domUni &&
- (orientationChange ||fCurrentProgram->fTextureDomain[s] != texDom)) {
-
- fCurrentProgram->fTextureDomain[s] = texDom;
-
- float values[4] = {
- GrScalarToFloat(texDom.left()),
- GrScalarToFloat(texDom.top()),
- GrScalarToFloat(texDom.right()),
- GrScalarToFloat(texDom.bottom())
- };
-
- // vertical flip if necessary
- if (GrGLTexture::kBottomUp_Orientation == texture->orientation()) {
- values[1] = 1.0f - values[1];
- values[3] = 1.0f - values[3];
- // The top and bottom were just flipped, so correct the ordering
- // of elements so that values = (l, t, r, b).
- SkTSwap(values[1], values[3]);
- }
- GL_CALL(Uniform4fv(domUni, 1, values));
- }
fCurrentProgram->fTextureOrientation[s] = texture->orientation();
}
}
@@ -768,14 +744,6 @@
stage.fOptFlags |= StageDesc::kNoPerspective_OptFlagBit;
}
- if (sampler.hasTextureDomain()) {
- GrAssert(GrSamplerState::kClamp_WrapMode ==
- sampler.getWrapX() &&
- GrSamplerState::kClamp_WrapMode ==
- sampler.getWrapY());
- stage.fOptFlags |= StageDesc::kCustomTextureDomain_OptFlagBit;
- }
-
stage.fInConfigFlags = 0;
if (!this->glCaps().textureSwizzleSupport()) {
if (GrPixelConfigIsAlphaOnly(texture->config())) {