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
This commit is contained in:
tomhudson@google.com 2012-07-17 18:43:21 +00:00
parent a8a977a97b
commit 2f68e7684b
8 changed files with 179 additions and 79 deletions

View File

@ -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',

View File

@ -79,7 +79,6 @@ public:
fFilter = s.fFilter;
fMatrix = s.fMatrix;
fSwapRAndB = s.fSwapRAndB;
fTextureDomain = s.fTextureDomain;
GrSafeAssign(fCustomStage, s.fCustomStage);
@ -89,8 +88,6 @@ public:
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; }
@ -103,13 +100,6 @@ public:
*/
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 @@ public:
fWrapY = wrapXAndY;
fFilter = filter;
fMatrix = matrix;
fTextureDomain.setEmpty();
fSwapRAndB = false;
GrSafeSetNull(fCustomStage);
}
@ -167,7 +156,6 @@ private:
Filter fFilter : 8;
bool fSwapRAndB;
GrMatrix fMatrix;
GrRect fTextureDomain;
GrCustomStage* fCustomStage;
};

View File

@ -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 @@ void SkGpuDevice::internalDrawBitmap(const SkDraw& draw,
top = bottom = GrScalarHalf(paintRect.top() + paintRect.bottom());
}
textureDomain.setLTRB(left, top, right, bottom);
sampler->setCustomStage(SkNEW_ARGS(GrTextureDomainEffect,
(texture,
textureDomain)))->unref();
}
sampler->setTextureDomain(textureDomain);
fContext->drawRectToRect(*grPaint, dstRect, paintRect, &m);
}

View File

@ -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);
}

View File

@ -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

View File

@ -86,11 +86,6 @@ inline void sampler_name(int stage, SkString* s) {
*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 @@ void GrGLProgram::getUniformLocationsAndInitCache(const GrGLContextInfo& gl,
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 @@ void GrGLProgram::getUniformLocationsAndInitCache(const GrGLContextInfo& gl,
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 @@ void GrGLProgram::genStageCode(const GrGLContextInfo& gl,
(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) {

View File

@ -112,7 +112,6 @@ public:
enum OptFlagBits {
kNoPerspective_OptFlagBit = 1 << 0,
kIdentityMatrix_OptFlagBit = 1 << 1,
kCustomTextureDomain_OptFlagBit = 1 << 2,
kIsEnabled_OptFlagBit = 1 << 7
};
@ -322,10 +321,9 @@ private:
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];

View File

@ -248,30 +248,6 @@ void GrGpuGL::flushTextureMatrixAndDomain(int s) {
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 @@ void GrGpuGL::buildProgram(bool isPoints,
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())) {