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:
parent
a8a977a97b
commit
2f68e7684b
@ -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',
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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);
|
||||
}
|
||||
|
126
src/gpu/effects/GrTextureDomainEffect.cpp
Normal file
126
src/gpu/effects/GrTextureDomainEffect.cpp
Normal 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);
|
||||
}
|
||||
|
||||
|
45
src/gpu/effects/GrTextureDomainEffect.h
Normal file
45
src/gpu/effects/GrTextureDomainEffect.h
Normal 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
|
@ -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) {
|
||||
|
@ -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];
|
||||
|
@ -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())) {
|
||||
|
Loading…
Reference in New Issue
Block a user