Add 4x4 downsample filter with 4 bilinear texture reads, use for ssaa.
Review URL: http://codereview.appspot.com/4483042/ git-svn-id: http://skia.googlecode.com/svn/trunk@1250 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
5fd9243fd6
commit
6aef1fb4eb
@ -21,6 +21,11 @@ struct GrContext::OffscreenRecord {
|
||||
OffscreenRecord() { fEntry0 = NULL; fEntry1 = NULL; }
|
||||
~OffscreenRecord() { GrAssert(NULL == fEntry0 && NULL == fEntry1); }
|
||||
|
||||
enum Downsample {
|
||||
k4x4TwoPass_Downsample,
|
||||
k4x4SinglePass_Downsample,
|
||||
kFSAA_Downsample
|
||||
} fDownsample;
|
||||
GrTextureEntry* fEntry0;
|
||||
GrTextureEntry* fEntry1;
|
||||
GrDrawTarget::SavedDrawState fSavedState;
|
||||
|
@ -198,6 +198,11 @@ public:
|
||||
*/
|
||||
bool supportsAALines() const { return fAALineSupport; }
|
||||
|
||||
/**
|
||||
* Does the subclass support GrSamplerState::k4x4Downsample_Filter
|
||||
*/
|
||||
bool supports4x4DownsampleFilter() const { return f4X4DownsampleFilterSupport; }
|
||||
|
||||
/**
|
||||
* Gets the minimum width of a render target. If a texture/rt is created
|
||||
* with a width less than this size the GrGpu object will clamp it to this
|
||||
@ -379,6 +384,7 @@ protected:
|
||||
bool fStencilWrapOpsSupport;
|
||||
bool fAALineSupport;
|
||||
bool fFSAASupport;
|
||||
bool f4X4DownsampleFilterSupport; // supports GrSamplerState::k4x4Downsample_Filter
|
||||
|
||||
// set by subclass to true if index and vertex buffers can be locked, false
|
||||
// otherwise.
|
||||
|
@ -23,6 +23,24 @@
|
||||
|
||||
class GrSamplerState {
|
||||
public:
|
||||
enum Filter {
|
||||
/**
|
||||
* Read the closest src texel to the sample position
|
||||
*/
|
||||
kNearest_Filter,
|
||||
/**
|
||||
* Blend between closest 4 src texels to sample position (tent filter)
|
||||
*/
|
||||
kBilinear_Filter,
|
||||
/**
|
||||
* Average of 4 bilinear filterings spaced +/- 1 texel from sample
|
||||
* position in x and y. Intended for averaging 16 texels in a downsample
|
||||
* pass. (rasterizing such that texture samples fall exactly halfway
|
||||
* between texels in x and y spaced 4 texels apart.)
|
||||
*/
|
||||
k4x4Downsample_Filter,
|
||||
};
|
||||
|
||||
/**
|
||||
* The intepretation of the texture matrix depends on the sample mode. The
|
||||
* texture matrix is applied both when the texture coordinates are explicit
|
||||
@ -70,7 +88,7 @@ public:
|
||||
this->setClampNoFilter();
|
||||
}
|
||||
|
||||
explicit GrSamplerState(bool filter) {
|
||||
explicit GrSamplerState(Filter filter) {
|
||||
fWrapX = kClamp_WrapMode;
|
||||
fWrapY = kClamp_WrapMode;
|
||||
fSampleMode = kNormal_SampleMode;
|
||||
@ -78,7 +96,7 @@ public:
|
||||
fMatrix.setIdentity();
|
||||
}
|
||||
|
||||
GrSamplerState(WrapMode wx, WrapMode wy, bool filter) {
|
||||
GrSamplerState(WrapMode wx, WrapMode wy, Filter filter) {
|
||||
fWrapX = wx;
|
||||
fWrapY = wy;
|
||||
fSampleMode = kNormal_SampleMode;
|
||||
@ -86,7 +104,8 @@ public:
|
||||
fMatrix.setIdentity();
|
||||
}
|
||||
|
||||
GrSamplerState(WrapMode wx, WrapMode wy, const GrMatrix& matrix, bool filter) {
|
||||
GrSamplerState(WrapMode wx, WrapMode wy,
|
||||
const GrMatrix& matrix, Filter filter) {
|
||||
fWrapX = wx;
|
||||
fWrapY = wy;
|
||||
fSampleMode = kNormal_SampleMode;
|
||||
@ -94,7 +113,8 @@ public:
|
||||
fMatrix = matrix;
|
||||
}
|
||||
|
||||
GrSamplerState(WrapMode wx, WrapMode wy, SampleMode sample, const GrMatrix& matrix, bool filter) {
|
||||
GrSamplerState(WrapMode wx, WrapMode wy, SampleMode sample,
|
||||
const GrMatrix& matrix, Filter filter) {
|
||||
fWrapX = wx;
|
||||
fWrapY = wy;
|
||||
fSampleMode = sample;
|
||||
@ -106,7 +126,7 @@ public:
|
||||
WrapMode getWrapY() const { return fWrapY; }
|
||||
SampleMode getSampleMode() const { return fSampleMode; }
|
||||
const GrMatrix& getMatrix() const { return fMatrix; }
|
||||
bool isFilter() const { return fFilter; }
|
||||
Filter getFilter() const { return fFilter; }
|
||||
|
||||
bool isGradient() const {
|
||||
return kRadial_SampleMode == fSampleMode ||
|
||||
@ -138,16 +158,16 @@ public:
|
||||
void preConcatMatrix(const GrMatrix& matrix) { fMatrix.preConcat(matrix); }
|
||||
|
||||
/**
|
||||
* Enables or disables filtering.
|
||||
* @param filter indicates whether filtering is applied.
|
||||
* Sets filtering type.
|
||||
* @param filter type of filtering to apply
|
||||
*/
|
||||
void setFilter(bool filter) { fFilter = filter; }
|
||||
void setFilter(Filter filter) { fFilter = filter; }
|
||||
|
||||
void setClampNoFilter() {
|
||||
fWrapX = kClamp_WrapMode;
|
||||
fWrapY = kClamp_WrapMode;
|
||||
fSampleMode = kNormal_SampleMode;
|
||||
fFilter = false;
|
||||
fFilter = kNearest_Filter;
|
||||
fMatrix.setIdentity();
|
||||
}
|
||||
|
||||
@ -176,7 +196,7 @@ private:
|
||||
WrapMode fWrapX;
|
||||
WrapMode fWrapY;
|
||||
SampleMode fSampleMode;
|
||||
bool fFilter;
|
||||
Filter fFilter;
|
||||
GrMatrix fMatrix;
|
||||
|
||||
// these are undefined unless fSampleMode == kRadial2_SampleMode
|
||||
|
@ -128,7 +128,7 @@ bool GrContext::finalizeTextureKey(GrTextureKey* key,
|
||||
|
||||
if (tiled && !isPow2) {
|
||||
bits |= kNPOTBit;
|
||||
if (sampler.isFilter()) {
|
||||
if (GrSamplerState::kNearest_Filter != sampler.getFilter()) {
|
||||
bits |= kFilterBit;
|
||||
}
|
||||
}
|
||||
@ -223,9 +223,18 @@ GrTextureEntry* GrContext::createAndLockTexture(GrTextureKey* key,
|
||||
fGpu->disableState(GrDrawTarget::kDither_StateBit |
|
||||
GrDrawTarget::kClip_StateBit |
|
||||
GrDrawTarget::kAntialias_StateBit);
|
||||
GrSamplerState::Filter filter;
|
||||
// if filtering is not desired then we want to ensure all
|
||||
// texels in the resampled image are copies of texels from
|
||||
// the original.
|
||||
if (GrSamplerState::kNearest_Filter == sampler.getFilter()) {
|
||||
filter = GrSamplerState::kNearest_Filter;
|
||||
} else {
|
||||
filter = GrSamplerState::kBilinear_Filter;
|
||||
}
|
||||
GrSamplerState stretchSampler(GrSamplerState::kClamp_WrapMode,
|
||||
GrSamplerState::kClamp_WrapMode,
|
||||
sampler.isFilter());
|
||||
filter);
|
||||
fGpu->setSamplerState(0, stretchSampler);
|
||||
|
||||
static const GrVertexLayout layout =
|
||||
@ -490,9 +499,13 @@ bool GrContext::setupOffscreenAAPass1(GrDrawTarget* target,
|
||||
int scale;
|
||||
// Using MSAA seems to be slower for some yet unknown reason.
|
||||
if (false && fGpu->supportsFullsceneAA()) {
|
||||
record->fDownsample = OffscreenRecord::kFSAA_Downsample;
|
||||
scale = GR_Scalar1;
|
||||
desc.fAALevel = kMed_GrAALevel;
|
||||
} else {
|
||||
record->fDownsample = (fGpu->supports4x4DownsampleFilter()) ?
|
||||
OffscreenRecord::k4x4SinglePass_Downsample :
|
||||
OffscreenRecord::k4x4TwoPass_Downsample;
|
||||
scale = 4;
|
||||
desc.fAALevel = kNone_GrAALevel;
|
||||
}
|
||||
@ -506,7 +519,7 @@ bool GrContext::setupOffscreenAAPass1(GrDrawTarget* target,
|
||||
return false;
|
||||
}
|
||||
|
||||
if (scale > 1) {
|
||||
if (OffscreenRecord::k4x4TwoPass_Downsample == record->fDownsample) {
|
||||
desc.fWidth /= 2;
|
||||
desc.fHeight /= 2;
|
||||
record->fEntry1 = this->lockKeylessTexture(desc);
|
||||
@ -550,16 +563,22 @@ void GrContext::offscreenAAPass2(GrDrawTarget* target,
|
||||
|
||||
GrAssert(NULL != record->fEntry0);
|
||||
|
||||
bool downsample = NULL != record->fEntry1;
|
||||
GrSamplerState::Filter filter;
|
||||
if (OffscreenRecord::k4x4SinglePass_Downsample == record->fDownsample) {
|
||||
filter = GrSamplerState::k4x4Downsample_Filter;
|
||||
} else {
|
||||
filter = GrSamplerState::kBilinear_Filter;
|
||||
}
|
||||
|
||||
GrMatrix sampleM;
|
||||
GrSamplerState sampler(GrSamplerState::kClamp_WrapMode,
|
||||
GrSamplerState::kClamp_WrapMode, true);
|
||||
GrSamplerState::kClamp_WrapMode, filter);
|
||||
|
||||
GrTexture* src = record->fEntry0->texture();
|
||||
int scale;
|
||||
|
||||
if (downsample) {
|
||||
if (OffscreenRecord::k4x4TwoPass_Downsample == record->fDownsample) {
|
||||
GrAssert(NULL != record->fEntry1);
|
||||
scale = 2;
|
||||
GrRenderTarget* dst = record->fEntry1->texture()->asRenderTarget();
|
||||
|
||||
@ -577,10 +596,14 @@ void GrContext::offscreenAAPass2(GrDrawTarget* target,
|
||||
target->drawSimpleRect(rect, NULL, 1 << kOffscreenStage);
|
||||
|
||||
src = record->fEntry1->texture();
|
||||
} else {
|
||||
} else if (OffscreenRecord::kFSAA_Downsample == record->fDownsample) {
|
||||
scale = 1;
|
||||
GrIRect rect(0, 0, boundRect.width(), boundRect.height());
|
||||
src->asRenderTarget()->overrideResolveRect(rect);
|
||||
} else {
|
||||
GrAssert(OffscreenRecord::k4x4SinglePass_Downsample ==
|
||||
record->fDownsample);
|
||||
scale = 4;
|
||||
}
|
||||
|
||||
// setup for draw back to main RT
|
||||
@ -607,7 +630,7 @@ void GrContext::offscreenAAPass2(GrDrawTarget* target,
|
||||
|
||||
this->unlockTexture(record->fEntry0);
|
||||
record->fEntry0 = NULL;
|
||||
if (downsample) {
|
||||
if (NULL != record->fEntry1) {
|
||||
this->unlockTexture(record->fEntry1);
|
||||
record->fEntry1 = NULL;
|
||||
}
|
||||
|
@ -42,6 +42,8 @@ const char* GrShaderPrecision() {
|
||||
|
||||
} // namespace
|
||||
|
||||
#define PRINT_SHADERS 0
|
||||
|
||||
#if GR_GL_ATTRIBUTE_MATRICES
|
||||
#define VIEW_MATRIX_NAME "aViewM"
|
||||
#else
|
||||
@ -93,6 +95,11 @@ static void tex_matrix_name(int stage, GrStringBuilder* s) {
|
||||
s->appendInt(stage);
|
||||
}
|
||||
|
||||
static void normalized_texel_size_name(int stage, GrStringBuilder* s) {
|
||||
*s = "uTexelSize";
|
||||
s->appendInt(stage);
|
||||
}
|
||||
|
||||
static void sampler_name(int stage, GrStringBuilder* s) {
|
||||
*s = "uSampler";
|
||||
s->appendInt(stage);
|
||||
@ -172,8 +179,7 @@ void GrGLProgram::doGLPost() const {
|
||||
}
|
||||
}
|
||||
|
||||
void GrGLProgram::genProgram(GrGLProgram::CachedData* programData,
|
||||
const GrDrawTarget* target) const {
|
||||
void GrGLProgram::genProgram(GrGLProgram::CachedData* programData) const {
|
||||
|
||||
ShaderCodeSegments segments;
|
||||
const uint32_t& layout = fProgramDesc.fVertexLayout;
|
||||
@ -219,7 +225,7 @@ void GrGLProgram::genProgram(GrGLProgram::CachedData* programData,
|
||||
// add texture coordinates that are used to the list of vertex attr decls
|
||||
GrTokenString texCoordAttrs[GrDrawTarget::kMaxTexCoords];
|
||||
for (int t = 0; t < GrDrawTarget::kMaxTexCoords; ++t) {
|
||||
if (target->VertexUsesTexCoordIdx(t, layout)) {
|
||||
if (GrDrawTarget::VertexUsesTexCoordIdx(t, layout)) {
|
||||
tex_attr_name(t, texCoordAttrs + t);
|
||||
|
||||
segments.fVSAttrs += "attribute vec2 ";
|
||||
@ -315,11 +321,11 @@ void GrGLProgram::genProgram(GrGLProgram::CachedData* programData,
|
||||
++stringCnt;
|
||||
|
||||
#if PRINT_SHADERS
|
||||
GrPrintf("%s%s%s%s\n",
|
||||
segments.fVSUnis.cstr(),
|
||||
segments.fVSAttrs.cstr(),
|
||||
segments.fVaryings.cstr(),
|
||||
segments.fVSCode.cstr());
|
||||
GrPrintf(segments.fVSUnis.cstr());
|
||||
GrPrintf(segments.fVSAttrs.cstr());
|
||||
GrPrintf(segments.fVaryings.cstr());
|
||||
GrPrintf(segments.fVSCode.cstr());
|
||||
GrPrintf("\n");
|
||||
#endif
|
||||
programData->fVShaderID = CompileShader(GR_GL_VERTEX_SHADER,
|
||||
stringCnt,
|
||||
@ -350,11 +356,11 @@ void GrGLProgram::genProgram(GrGLProgram::CachedData* programData,
|
||||
++stringCnt;
|
||||
|
||||
#if PRINT_SHADERS
|
||||
GrPrintf("%s%s%s%s\n",
|
||||
GR_SHADER_PRECISION,
|
||||
segments.fFSUnis.cstr(),
|
||||
segments.fVaryings.cstr(),
|
||||
segments.fFSCode.cstr());
|
||||
GrPrintf(GrShaderPrecision());
|
||||
GrPrintf(segments.fFSUnis.cstr());
|
||||
GrPrintf(segments.fVaryings.cstr());
|
||||
GrPrintf(segments.fFSCode.cstr());
|
||||
GrPrintf("\n");
|
||||
#endif
|
||||
programData->fFShaderID = CompileShader(GR_GL_FRAGMENT_SHADER,
|
||||
stringCnt,
|
||||
@ -464,6 +470,16 @@ void GrGLProgram::genProgram(GrGLProgram::CachedData* programData,
|
||||
locations.fSamplerUni = -1;
|
||||
}
|
||||
|
||||
if (locations.fNormalizedTexelSizeUni) {
|
||||
GrTokenString texelSizeName;
|
||||
normalized_texel_size_name(s, &texelSizeName);
|
||||
locations.fNormalizedTexelSizeUni =
|
||||
GR_GL(GetUniformLocation(progID, texelSizeName.cstr()));
|
||||
GrAssert(-1 != locations.fNormalizedTexelSizeUni);
|
||||
} else {
|
||||
locations.fNormalizedTexelSizeUni = -1;
|
||||
}
|
||||
|
||||
if (locations.fRadial2Uni) {
|
||||
GrTokenString radial2ParamName;
|
||||
radial2_param_name(s, &radial2ParamName);
|
||||
@ -478,6 +494,7 @@ void GrGLProgram::genProgram(GrGLProgram::CachedData* programData,
|
||||
locations.fSamplerUni = -1;
|
||||
locations.fRadial2Uni = -1;
|
||||
locations.fTextureMatrixUni = -1;
|
||||
locations.fNormalizedTexelSizeUni = -1;
|
||||
}
|
||||
}
|
||||
GR_GL(UseProgram(progID));
|
||||
@ -490,8 +507,11 @@ void GrGLProgram::genProgram(GrGLProgram::CachedData* programData,
|
||||
programData->fTextureMatrices[s] = GrMatrix::InvalidMatrix();
|
||||
programData->fRadial2CenterX1[s] = GR_ScalarMax;
|
||||
programData->fRadial2Radius0[s] = -GR_ScalarMax;
|
||||
programData->fTextureWidth[s] = -1;
|
||||
programData->fTextureHeight[s] = -1;
|
||||
}
|
||||
programData->fViewMatrix = GrMatrix::InvalidMatrix();
|
||||
programData->fColor = GrColor_ILLEGAL;
|
||||
}
|
||||
|
||||
GrGLuint GrGLProgram::CompileShader(GrGLenum type,
|
||||
@ -535,12 +555,12 @@ GrGLuint GrGLProgram::CompileShader(GrGLenum type,
|
||||
//============================================================================
|
||||
|
||||
void GrGLProgram::genStageCode(int stageNum,
|
||||
const GrGLProgram::ProgramDesc::StageDesc& desc,
|
||||
const char* fsInColor, // NULL means no incoming color
|
||||
const char* fsOutColor,
|
||||
const char* vsInCoord,
|
||||
ShaderCodeSegments* segments,
|
||||
StageUniLocations* locations) const {
|
||||
const GrGLProgram::ProgramDesc::StageDesc& desc,
|
||||
const char* fsInColor, // NULL means no incoming color
|
||||
const char* fsOutColor,
|
||||
const char* vsInCoord,
|
||||
ShaderCodeSegments* segments,
|
||||
StageUniLocations* locations) const {
|
||||
|
||||
GrAssert(stageNum >= 0 && stageNum <= 9);
|
||||
|
||||
@ -585,6 +605,14 @@ void GrGLProgram::genStageCode(int stageNum,
|
||||
segments->fFSUnis += ";\n";
|
||||
locations->fSamplerUni = 1;
|
||||
|
||||
GrTokenString texelSizeName;
|
||||
if (ProgramDesc::StageDesc::k2x2_FetchMode == desc.fFetchMode) {
|
||||
normalized_texel_size_name(stageNum, &texelSizeName);
|
||||
segments->fFSUnis += "uniform vec2 ";
|
||||
segments->fFSUnis += texelSizeName;
|
||||
segments->fFSUnis += ";\n";
|
||||
}
|
||||
|
||||
segments->fVaryings += "varying ";
|
||||
segments->fVaryings += float_vector_type(varyingDims);
|
||||
segments->fVaryings += " ";
|
||||
@ -661,14 +689,15 @@ void GrGLProgram::genStageCode(int stageNum,
|
||||
GrAssert(varyingDims == coordDims);
|
||||
fsCoordName = varyingName;
|
||||
} else {
|
||||
// if we have to do some non-matrix op on the varyings to get
|
||||
// if we have to do some special op on the varyings to get
|
||||
// our final tex coords then when in perspective we have to
|
||||
// do an explicit divide
|
||||
if (ProgramDesc::StageDesc::kIdentity_CoordMapping == desc.fCoordMapping) {
|
||||
if (ProgramDesc::StageDesc::kIdentity_CoordMapping == desc.fCoordMapping &&
|
||||
ProgramDesc::StageDesc::kSingle_FetchMode == desc.fFetchMode) {
|
||||
texFunc += "Proj";
|
||||
fsCoordName = varyingName;
|
||||
} else {
|
||||
fsCoordName = "tCoord";
|
||||
fsCoordName = "inCoord";
|
||||
fsCoordName.appendInt(stageNum);
|
||||
|
||||
segments->fFSCode += "\t";
|
||||
@ -686,6 +715,7 @@ void GrGLProgram::genStageCode(int stageNum,
|
||||
}
|
||||
|
||||
GrSStringBuilder<96> sampleCoords;
|
||||
bool complexCoord = false;
|
||||
switch (desc.fCoordMapping) {
|
||||
case ProgramDesc::StageDesc::kIdentity_CoordMapping:
|
||||
sampleCoords = fsCoordName;
|
||||
@ -696,11 +726,13 @@ void GrGLProgram::genStageCode(int stageNum,
|
||||
sampleCoords += ".y, -";
|
||||
sampleCoords += fsCoordName;
|
||||
sampleCoords += ".x)*0.1591549430918 + 0.5, 0.5)";
|
||||
complexCoord = true;
|
||||
break;
|
||||
case ProgramDesc::StageDesc::kRadialGradient_CoordMapping:
|
||||
sampleCoords = "vec2(length(";
|
||||
sampleCoords += fsCoordName;
|
||||
sampleCoords += ".xy), 0.5)";
|
||||
complexCoord = true;
|
||||
break;
|
||||
case ProgramDesc::StageDesc::kRadial2Gradient_CoordMapping: {
|
||||
GrTokenString cName = "c";
|
||||
@ -769,26 +801,85 @@ void GrGLProgram::genStageCode(int stageNum,
|
||||
sampleCoords += ") * ";
|
||||
sampleCoords += radial2ParamsName;
|
||||
sampleCoords += "[1], 0.5)\n";
|
||||
complexCoord = true;
|
||||
break;}
|
||||
};
|
||||
|
||||
segments->fFSCode += "\t";
|
||||
segments->fFSCode += fsOutColor;
|
||||
segments->fFSCode += " = ";
|
||||
if (NULL != fsInColor) {
|
||||
segments->fFSCode += fsInColor;
|
||||
segments->fFSCode += " * ";
|
||||
if (ProgramDesc::StageDesc::k2x2_FetchMode == desc.fFetchMode) {
|
||||
locations->fNormalizedTexelSizeUni = 1;
|
||||
if (complexCoord) {
|
||||
GrTokenString coordVar("tCoord");
|
||||
coordVar.appendInt(stageNum);
|
||||
segments->fFSCode += "\t";
|
||||
segments->fFSCode += float_vector_type(coordDims);
|
||||
segments->fFSCode += " ";
|
||||
segments->fFSCode += coordVar;
|
||||
segments->fFSCode += " = ";
|
||||
segments->fFSCode += sampleCoords;
|
||||
segments->fFSCode += ";\n";
|
||||
sampleCoords = coordVar;
|
||||
}
|
||||
static const char sign[] = {'-','+'};
|
||||
GrTokenString stageAccumVar("stage2x2Accum");
|
||||
stageAccumVar.appendInt(stageNum);
|
||||
segments->fFSCode += "\tvec4 ";
|
||||
segments->fFSCode += stageAccumVar;
|
||||
segments->fFSCode += " = ";
|
||||
GrAssert(2 == coordDims);
|
||||
for (int y = 0; y < 2; ++y) {
|
||||
for (int x = 0; x < 2; ++x) {
|
||||
segments->fFSCode += texFunc;
|
||||
segments->fFSCode += "(";
|
||||
segments->fFSCode += samplerName;
|
||||
segments->fFSCode += ", ";
|
||||
segments->fFSCode += sampleCoords;
|
||||
segments->fFSCode += " + vec2(";
|
||||
segments->fFSCode += sign[x];
|
||||
segments->fFSCode += texelSizeName;
|
||||
segments->fFSCode += ".x, ";
|
||||
segments->fFSCode += sign[y];
|
||||
segments->fFSCode += texelSizeName;
|
||||
segments->fFSCode += ".y))";
|
||||
if (desc.fModulation == ProgramDesc::StageDesc::kAlpha_Modulation) {
|
||||
segments->fFSCode += ".aaaa";
|
||||
}
|
||||
segments->fFSCode += ";\n";
|
||||
if (1 != x || 1 !=y ) {
|
||||
segments->fFSCode += "\t";
|
||||
segments->fFSCode += stageAccumVar;
|
||||
segments->fFSCode += " += ";
|
||||
}
|
||||
}
|
||||
}
|
||||
segments->fFSCode += "\t";
|
||||
segments->fFSCode += fsOutColor;
|
||||
segments->fFSCode += " = ";
|
||||
if (NULL != fsInColor) {
|
||||
segments->fFSCode += fsInColor;
|
||||
segments->fFSCode += " * ";
|
||||
}
|
||||
segments->fFSCode += stageAccumVar;
|
||||
segments->fFSCode += " / 4;\n";
|
||||
} else {
|
||||
segments->fFSCode += "\t";
|
||||
segments->fFSCode += fsOutColor;
|
||||
segments->fFSCode += " = ";
|
||||
if (NULL != fsInColor) {
|
||||
segments->fFSCode += fsInColor;
|
||||
segments->fFSCode += " * ";
|
||||
}
|
||||
|
||||
segments->fFSCode += texFunc;
|
||||
segments->fFSCode += "(";
|
||||
segments->fFSCode += samplerName;
|
||||
segments->fFSCode += ", ";
|
||||
segments->fFSCode += sampleCoords;
|
||||
segments->fFSCode += ")";
|
||||
if (desc.fModulation == ProgramDesc::StageDesc::kAlpha_Modulation) {
|
||||
segments->fFSCode += ".aaaa";
|
||||
}
|
||||
segments->fFSCode += ";\n";
|
||||
}
|
||||
segments->fFSCode += texFunc;
|
||||
segments->fFSCode += "(";
|
||||
segments->fFSCode += samplerName;
|
||||
segments->fFSCode += ", ";
|
||||
segments->fFSCode += sampleCoords;
|
||||
segments->fFSCode += ")";
|
||||
if (desc.fModulation == ProgramDesc::StageDesc::kAlpha_Modulation) {
|
||||
segments->fFSCode += ".aaaa";
|
||||
}
|
||||
segments->fFSCode += ";\n";
|
||||
|
||||
if(fStageEffects[stageNum]) {
|
||||
fStageEffects[stageNum]->genShaderCode(segments);
|
||||
|
@ -58,7 +58,7 @@ public:
|
||||
* The result of heavy init is not stored in datamembers of GrGLProgam,
|
||||
* but in a separate cacheable container.
|
||||
*/
|
||||
void genProgram(CachedData* programData, const GrDrawTarget* target) const;
|
||||
void genProgram(CachedData* programData) const;
|
||||
|
||||
/**
|
||||
* Routine that is called before rendering. Sets-up all the state and
|
||||
@ -107,20 +107,25 @@ private:
|
||||
kIdentityMatrix_OptFlagBit = 0x2
|
||||
};
|
||||
|
||||
unsigned fOptFlags : 8;
|
||||
unsigned fEnabled : 8;
|
||||
unsigned fOptFlags;
|
||||
bool fEnabled;
|
||||
|
||||
enum Modulation {
|
||||
kColor_Modulation,
|
||||
kAlpha_Modulation
|
||||
} fModulation : 8;
|
||||
} fModulation;
|
||||
|
||||
enum FetchMode {
|
||||
kSingle_FetchMode,
|
||||
k2x2_FetchMode
|
||||
} fFetchMode;
|
||||
|
||||
enum CoordMapping {
|
||||
kIdentity_CoordMapping,
|
||||
kRadialGradient_CoordMapping,
|
||||
kSweepGradient_CoordMapping,
|
||||
kRadial2Gradient_CoordMapping
|
||||
} fCoordMapping : 8;
|
||||
} fCoordMapping;
|
||||
} fStages[GrDrawTarget::kNumStages];
|
||||
} fProgramDesc;
|
||||
|
||||
@ -129,6 +134,7 @@ private:
|
||||
public:
|
||||
struct StageUniLocations {
|
||||
GrGLint fTextureMatrixUni;
|
||||
GrGLint fNormalizedTexelSizeUni;
|
||||
GrGLint fSamplerUni;
|
||||
GrGLint fRadial2Uni;
|
||||
};
|
||||
@ -188,6 +194,9 @@ public:
|
||||
// (GL uniform values travel with program)
|
||||
GrColor fColor;
|
||||
GrMatrix fTextureMatrices[GrDrawTarget::kNumStages];
|
||||
// width and height used for normalized texel size
|
||||
int fTextureWidth[GrDrawTarget::kNumStages];
|
||||
int fTextureHeight[GrDrawTarget::kNumStages];
|
||||
GrScalar fRadial2CenterX1[GrDrawTarget::kNumStages];
|
||||
GrScalar fRadial2Radius0[GrDrawTarget::kNumStages];
|
||||
bool fRadial2PosRoot[GrDrawTarget::kNumStages];
|
||||
|
@ -755,7 +755,7 @@ const GrSamplerState GrSamplerState::gClampNoFilter(
|
||||
GrSamplerState::kClamp_WrapMode,
|
||||
GrSamplerState::kNormal_SampleMode,
|
||||
GrMatrix::I(),
|
||||
false);
|
||||
GrSamplerState::kNearest_Filter);
|
||||
|
||||
|
||||
|
||||
|
@ -1754,8 +1754,12 @@ bool GrGpuGL::flushGLStateCommon(GrPrimitiveType type) {
|
||||
nextTexture->getTexParams();
|
||||
GrGLTexture::TexParams newTexParams;
|
||||
|
||||
newTexParams.fFilter = sampler.isFilter() ? GR_GL_LINEAR :
|
||||
GR_GL_NEAREST;
|
||||
if (GrSamplerState::kNearest_Filter == sampler.getFilter()) {
|
||||
newTexParams.fFilter = GR_GL_NEAREST;
|
||||
} else {
|
||||
newTexParams.fFilter = GR_GL_LINEAR;
|
||||
}
|
||||
|
||||
newTexParams.fWrapS =
|
||||
GrGLTexture::WrapMode2GLWrap()[sampler.getWrapX()];
|
||||
newTexParams.fWrapT =
|
||||
|
@ -56,6 +56,7 @@ static const GrGLenum gMatrixMode2Enum[] = {
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
GrGpuGLFixed::GrGpuGLFixed() {
|
||||
f4X4DownsampleFilterSupport = false;
|
||||
}
|
||||
|
||||
GrGpuGLFixed::~GrGpuGLFixed() {
|
||||
|
@ -22,8 +22,8 @@
|
||||
#include "GrMemory.h"
|
||||
#include "GrNoncopyable.h"
|
||||
#include "GrStringBuilder.h"
|
||||
#include "GrRandom.h"
|
||||
|
||||
#define PRINT_SHADERS 0
|
||||
#define SKIP_CACHE_CHECK true
|
||||
#define GR_UINT32_MAX static_cast<uint32_t>(-1)
|
||||
|
||||
@ -96,8 +96,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
GrGLProgram::CachedData* getProgramData(const GrGLProgram& desc,
|
||||
const GrDrawTarget* target) {
|
||||
GrGLProgram::CachedData* getProgramData(const GrGLProgram& desc) {
|
||||
ProgramHashKey key;
|
||||
while (key.doPass()) {
|
||||
desc.buildKey(key);
|
||||
@ -119,7 +118,7 @@ public:
|
||||
GrGpuGLShaders::DeleteProgram(&entry->fProgramData);
|
||||
}
|
||||
entry->fKey.copyAndTakeOwnership(key);
|
||||
desc.genProgram(&entry->fProgramData, target);
|
||||
desc.genProgram(&entry->fProgramData);
|
||||
fHashCache.insert(entry->fKey, entry);
|
||||
}
|
||||
|
||||
@ -142,13 +141,99 @@ void GrGpuGLShaders::DeleteProgram(GrGLProgram::CachedData* programData) {
|
||||
GR_DEBUGCODE(memset(programData, 0, sizeof(*programData));)
|
||||
}
|
||||
|
||||
void GrGpuGLShaders::ProgramUnitTest() {
|
||||
|
||||
static const int STAGE_OPTS[] = {
|
||||
0,
|
||||
GrGLProgram::ProgramDesc::StageDesc::kNoPerspective_OptFlagBit,
|
||||
GrGLProgram::ProgramDesc::StageDesc::kIdentity_CoordMapping
|
||||
};
|
||||
static const GrGLProgram::ProgramDesc::StageDesc::Modulation STAGE_MODULATES[] = {
|
||||
GrGLProgram::ProgramDesc::StageDesc::kColor_Modulation,
|
||||
GrGLProgram::ProgramDesc::StageDesc::kAlpha_Modulation
|
||||
};
|
||||
static const GrGLProgram::ProgramDesc::StageDesc::CoordMapping STAGE_COORD_MAPPINGS[] = {
|
||||
GrGLProgram::ProgramDesc::StageDesc::kIdentity_CoordMapping,
|
||||
GrGLProgram::ProgramDesc::StageDesc::kRadialGradient_CoordMapping,
|
||||
GrGLProgram::ProgramDesc::StageDesc::kSweepGradient_CoordMapping,
|
||||
GrGLProgram::ProgramDesc::StageDesc::kRadial2Gradient_CoordMapping
|
||||
};
|
||||
static const GrGLProgram::ProgramDesc::StageDesc::FetchMode FETCH_MODES[] = {
|
||||
GrGLProgram::ProgramDesc::StageDesc::kSingle_FetchMode,
|
||||
GrGLProgram::ProgramDesc::StageDesc::k2x2_FetchMode,
|
||||
};
|
||||
GrGLProgram program;
|
||||
GrGLProgram::ProgramDesc& pdesc = program.fProgramDesc;
|
||||
|
||||
static const int NUM_TESTS = 512;
|
||||
|
||||
// GrRandoms nextU() values have patterns in the low bits
|
||||
// So using nextU() % array_count might never take some values.
|
||||
GrRandom random;
|
||||
for (int t = 0; t < NUM_TESTS; ++t) {
|
||||
|
||||
pdesc.fVertexLayout = 0;
|
||||
pdesc.fEmitsPointSize = random.nextF() > .5f;
|
||||
float colorType = random.nextF();
|
||||
if (colorType < 1.f / 3.f) {
|
||||
pdesc.fColorType = GrGLProgram::ProgramDesc::kAttribute_ColorType;
|
||||
} else if (colorType < 2.f / 3.f) {
|
||||
pdesc.fColorType = GrGLProgram::ProgramDesc::kUniform_ColorType;
|
||||
} else {
|
||||
pdesc.fColorType = GrGLProgram::ProgramDesc::kNone_ColorType;
|
||||
}
|
||||
for (int s = 0; s < kNumStages; ++s) {
|
||||
// enable the stage?
|
||||
if (random.nextF() > .5f) {
|
||||
// use separate tex coords?
|
||||
if (random.nextF() > .5f) {
|
||||
int t = (int)(random.nextF() * kMaxTexCoords);
|
||||
pdesc.fVertexLayout |= StageTexCoordVertexLayoutBit(s, t);
|
||||
} else {
|
||||
pdesc.fVertexLayout |= StagePosAsTexCoordVertexLayoutBit(s);
|
||||
}
|
||||
}
|
||||
// use text-formatted verts?
|
||||
if (random.nextF() > .5f) {
|
||||
pdesc.fVertexLayout |= kTextFormat_VertexLayoutBit;
|
||||
}
|
||||
}
|
||||
|
||||
for (int s = 0; s < kNumStages; ++s) {
|
||||
int x;
|
||||
pdesc.fStages[s].fEnabled = VertexUsesStage(s, pdesc.fVertexLayout);
|
||||
x = (int)(random.nextF() * GR_ARRAY_COUNT(STAGE_OPTS));
|
||||
pdesc.fStages[s].fOptFlags = STAGE_OPTS[x];
|
||||
x = (int)(random.nextF() * GR_ARRAY_COUNT(STAGE_MODULATES));
|
||||
pdesc.fStages[s].fModulation = STAGE_MODULATES[x];
|
||||
x = (int)(random.nextF() * GR_ARRAY_COUNT(STAGE_COORD_MAPPINGS));
|
||||
pdesc.fStages[s].fCoordMapping = STAGE_COORD_MAPPINGS[x];
|
||||
x = (int)(random.nextF() * GR_ARRAY_COUNT(FETCH_MODES));
|
||||
pdesc.fStages[s].fFetchMode = FETCH_MODES[x];
|
||||
}
|
||||
GrGLProgram::CachedData cachedData;
|
||||
program.genProgram(&cachedData);
|
||||
DeleteProgram(&cachedData);
|
||||
bool again = false;
|
||||
if (again) {
|
||||
program.genProgram(&cachedData);
|
||||
DeleteProgram(&cachedData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
GrGpuGLShaders::GrGpuGLShaders() {
|
||||
|
||||
resetContext();
|
||||
f4X4DownsampleFilterSupport = true;
|
||||
|
||||
fProgramData = NULL;
|
||||
fProgramCache = new ProgramCache();
|
||||
|
||||
#if 0
|
||||
ProgramUnitTest();
|
||||
#endif
|
||||
}
|
||||
|
||||
GrGpuGLShaders::~GrGpuGLShaders() {
|
||||
@ -217,59 +302,90 @@ void GrGpuGLShaders::flushViewMatrix() {
|
||||
#endif
|
||||
}
|
||||
|
||||
void GrGpuGLShaders::flushTextureMatrix(int stage) {
|
||||
GrAssert(NULL != fCurrDrawState.fTextures[stage]);
|
||||
void GrGpuGLShaders::flushTextureMatrix(int s) {
|
||||
const int& uni = fProgramData->fUniLocations.fStages[s].fTextureMatrixUni;
|
||||
GrGLTexture* texture = (GrGLTexture*) fCurrDrawState.fTextures[s];
|
||||
if (NULL != texture) {
|
||||
if (-1 != uni &&
|
||||
(((1 << s) & fDirtyFlags.fTextureChangedMask) ||
|
||||
getHWSamplerMatrix(s) != getSamplerMatrix(s))) {
|
||||
|
||||
GrGLTexture* texture = (GrGLTexture*) fCurrDrawState.fTextures[stage];
|
||||
GrAssert(NULL != fCurrDrawState.fTextures[s]);
|
||||
|
||||
GrMatrix m = getSamplerMatrix(stage);
|
||||
GrSamplerState::SampleMode mode =
|
||||
fCurrDrawState.fSamplerStates[stage].getSampleMode();
|
||||
AdjustTextureMatrix(texture, mode, &m);
|
||||
GrGLTexture* texture = (GrGLTexture*) fCurrDrawState.fTextures[s];
|
||||
|
||||
// ES doesn't allow you to pass true to the transpose param,
|
||||
// so do our own transpose
|
||||
GrScalar mt[] = {
|
||||
m[GrMatrix::kScaleX],
|
||||
m[GrMatrix::kSkewY],
|
||||
m[GrMatrix::kPersp0],
|
||||
m[GrMatrix::kSkewX],
|
||||
m[GrMatrix::kScaleY],
|
||||
m[GrMatrix::kPersp1],
|
||||
m[GrMatrix::kTransX],
|
||||
m[GrMatrix::kTransY],
|
||||
m[GrMatrix::kPersp2]
|
||||
};
|
||||
#if GR_GL_ATTRIBUTE_MATRICES
|
||||
GR_GL(VertexAttrib4fv(TEXMAT_ATTR_LOCATION(0)+0, mt+0));
|
||||
GR_GL(VertexAttrib4fv(TEXMAT_ATTR_LOCATION(0)+1, mt+3));
|
||||
GR_GL(VertexAttrib4fv(TEXMAT_ATTR_LOCATION(0)+2, mt+6));
|
||||
#else
|
||||
GR_GL(UniformMatrix3fv(fProgramData->fUniLocations.fStages[stage].fTextureMatrixUni,
|
||||
1, false, mt));
|
||||
#endif
|
||||
GrMatrix m = getSamplerMatrix(s);
|
||||
GrSamplerState::SampleMode mode =
|
||||
fCurrDrawState.fSamplerStates[s].getSampleMode();
|
||||
AdjustTextureMatrix(texture, mode, &m);
|
||||
|
||||
// ES doesn't allow you to pass true to the transpose param,
|
||||
// so do our own transpose
|
||||
GrScalar mt[] = {
|
||||
m[GrMatrix::kScaleX],
|
||||
m[GrMatrix::kSkewY],
|
||||
m[GrMatrix::kPersp0],
|
||||
m[GrMatrix::kSkewX],
|
||||
m[GrMatrix::kScaleY],
|
||||
m[GrMatrix::kPersp1],
|
||||
m[GrMatrix::kTransX],
|
||||
m[GrMatrix::kTransY],
|
||||
m[GrMatrix::kPersp2]
|
||||
};
|
||||
#if GR_GL_ATTRIBUTE_MATRICES
|
||||
GR_GL(VertexAttrib4fv(TEXMAT_ATTR_LOCATION(0)+0, mt+0));
|
||||
GR_GL(VertexAttrib4fv(TEXMAT_ATTR_LOCATION(0)+1, mt+3));
|
||||
GR_GL(VertexAttrib4fv(TEXMAT_ATTR_LOCATION(0)+2, mt+6));
|
||||
#else
|
||||
GR_GL(UniformMatrix3fv(uni, 1, false, mt));
|
||||
#endif
|
||||
recordHWSamplerMatrix(s, getSamplerMatrix(s));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GrGpuGLShaders::flushRadial2(int stage) {
|
||||
void GrGpuGLShaders::flushRadial2(int s) {
|
||||
|
||||
const GrSamplerState& sampler = fCurrDrawState.fSamplerStates[stage];
|
||||
const int &uni = fProgramData->fUniLocations.fStages[s].fRadial2Uni;
|
||||
const GrSamplerState& sampler = fCurrDrawState.fSamplerStates[s];
|
||||
if (-1 != uni &&
|
||||
(fProgramData->fRadial2CenterX1[s] != sampler.getRadial2CenterX1() ||
|
||||
fProgramData->fRadial2Radius0[s] != sampler.getRadial2Radius0() ||
|
||||
fProgramData->fRadial2PosRoot[s] != sampler.isRadial2PosRoot())) {
|
||||
|
||||
GrScalar centerX1 = sampler.getRadial2CenterX1();
|
||||
GrScalar radius0 = sampler.getRadial2Radius0();
|
||||
GrScalar centerX1 = sampler.getRadial2CenterX1();
|
||||
GrScalar radius0 = sampler.getRadial2Radius0();
|
||||
|
||||
GrScalar a = GrMul(centerX1, centerX1) - GR_Scalar1;
|
||||
GrScalar a = GrMul(centerX1, centerX1) - GR_Scalar1;
|
||||
|
||||
float unis[6] = {
|
||||
GrScalarToFloat(a),
|
||||
1 / (2.f * unis[0]),
|
||||
GrScalarToFloat(centerX1),
|
||||
GrScalarToFloat(radius0),
|
||||
GrScalarToFloat(GrMul(radius0, radius0)),
|
||||
sampler.isRadial2PosRoot() ? 1.f : -1.f
|
||||
};
|
||||
GR_GL(Uniform1fv(fProgramData->fUniLocations.fStages[stage].fRadial2Uni,
|
||||
6,
|
||||
unis));
|
||||
float values[6] = {
|
||||
GrScalarToFloat(a),
|
||||
1 / (2.f * values[0]),
|
||||
GrScalarToFloat(centerX1),
|
||||
GrScalarToFloat(radius0),
|
||||
GrScalarToFloat(GrMul(radius0, radius0)),
|
||||
sampler.isRadial2PosRoot() ? 1.f : -1.f
|
||||
};
|
||||
GR_GL(Uniform1fv(uni, 6, values));
|
||||
fProgramData->fRadial2CenterX1[s] = sampler.getRadial2CenterX1();
|
||||
fProgramData->fRadial2Radius0[s] = sampler.getRadial2Radius0();
|
||||
fProgramData->fRadial2PosRoot[s] = sampler.isRadial2PosRoot();
|
||||
}
|
||||
}
|
||||
|
||||
void GrGpuGLShaders::flushTexelSize(int s) {
|
||||
const GrSamplerState& sampler = fCurrDrawState.fSamplerStates[s];
|
||||
const int& uni = fProgramData->fUniLocations.fStages[s].fNormalizedTexelSizeUni;
|
||||
if (-1 != uni) {
|
||||
GrGLTexture* texture = (GrGLTexture*) fCurrDrawState.fTextures[s];
|
||||
if (texture->allocWidth() != fProgramData->fTextureWidth[s] ||
|
||||
texture->allocHeight() != fProgramData->fTextureWidth[s]) {
|
||||
|
||||
float texelSize[] = {1.f / texture->allocWidth(),
|
||||
1.f / texture->allocHeight()};
|
||||
GR_GL(Uniform2fv(uni, 1, texelSize));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GrGpuGLShaders::flushColor() {
|
||||
@ -334,7 +450,7 @@ bool GrGpuGLShaders::flushGraphicsState(GrPrimitiveType type) {
|
||||
}
|
||||
|
||||
buildProgram(type);
|
||||
fProgramData = fProgramCache->getProgramData(fCurrentProgram, this);
|
||||
fProgramData = fProgramCache->getProgramData(fCurrentProgram);
|
||||
|
||||
if (fHWProgramID != fProgramData->fProgramID) {
|
||||
GR_GL(UseProgram(fProgramData->fProgramID));
|
||||
@ -345,7 +461,7 @@ bool GrGpuGLShaders::flushGraphicsState(GrPrimitiveType type) {
|
||||
return false;
|
||||
}
|
||||
|
||||
flushColor();
|
||||
this->flushColor();
|
||||
|
||||
#if GR_GL_ATTRIBUTE_MATRICES
|
||||
GrMatrix& currViewMatrix = fHWDrawState.fViewMatrix;
|
||||
@ -359,28 +475,11 @@ bool GrGpuGLShaders::flushGraphicsState(GrPrimitiveType type) {
|
||||
}
|
||||
|
||||
for (int s = 0; s < kNumStages; ++s) {
|
||||
GrGLTexture* texture = (GrGLTexture*) fCurrDrawState.fTextures[s];
|
||||
if (NULL != texture) {
|
||||
if (-1 != fProgramData->fUniLocations.fStages[s].fTextureMatrixUni &&
|
||||
(((1 << s) & fDirtyFlags.fTextureChangedMask) ||
|
||||
getHWSamplerMatrix(s) != getSamplerMatrix(s))) {
|
||||
flushTextureMatrix(s);
|
||||
recordHWSamplerMatrix(s, getSamplerMatrix(s));
|
||||
}
|
||||
}
|
||||
this->flushTextureMatrix(s);
|
||||
|
||||
const GrSamplerState& sampler = fCurrDrawState.fSamplerStates[s];
|
||||
if (-1 != fProgramData->fUniLocations.fStages[s].fRadial2Uni &&
|
||||
(fProgramData->fRadial2CenterX1[s] != sampler.getRadial2CenterX1() ||
|
||||
fProgramData->fRadial2Radius0[s] != sampler.getRadial2Radius0() ||
|
||||
fProgramData->fRadial2PosRoot[s] != sampler.isRadial2PosRoot())) {
|
||||
this->flushRadial2(s);
|
||||
|
||||
flushRadial2(s);
|
||||
|
||||
fProgramData->fRadial2CenterX1[s] = sampler.getRadial2CenterX1();
|
||||
fProgramData->fRadial2Radius0[s] = sampler.getRadial2Radius0();
|
||||
fProgramData->fRadial2PosRoot[s] = sampler.isRadial2PosRoot();
|
||||
}
|
||||
this->flushTexelSize(s);
|
||||
}
|
||||
resetDirtyFlags();
|
||||
return true;
|
||||
@ -531,21 +630,36 @@ void GrGpuGLShaders::buildProgram(GrPrimitiveType type) {
|
||||
stage.fOptFlags = 0;
|
||||
}
|
||||
switch (fCurrDrawState.fSamplerStates[s].getSampleMode()) {
|
||||
case GrSamplerState::kNormal_SampleMode:
|
||||
stage.fCoordMapping = GrGLProgram::ProgramDesc::StageDesc::kIdentity_CoordMapping;
|
||||
break;
|
||||
case GrSamplerState::kRadial_SampleMode:
|
||||
stage.fCoordMapping = GrGLProgram::ProgramDesc::StageDesc::kRadialGradient_CoordMapping;
|
||||
break;
|
||||
case GrSamplerState::kRadial2_SampleMode:
|
||||
stage.fCoordMapping = GrGLProgram::ProgramDesc::StageDesc::kRadial2Gradient_CoordMapping;
|
||||
break;
|
||||
case GrSamplerState::kSweep_SampleMode:
|
||||
stage.fCoordMapping = GrGLProgram::ProgramDesc::StageDesc::kSweepGradient_CoordMapping;
|
||||
break;
|
||||
default:
|
||||
GrAssert(!"Unexpected sample mode!");
|
||||
break;
|
||||
case GrSamplerState::kNormal_SampleMode:
|
||||
stage.fCoordMapping = GrGLProgram::ProgramDesc::StageDesc::kIdentity_CoordMapping;
|
||||
break;
|
||||
case GrSamplerState::kRadial_SampleMode:
|
||||
stage.fCoordMapping = GrGLProgram::ProgramDesc::StageDesc::kRadialGradient_CoordMapping;
|
||||
break;
|
||||
case GrSamplerState::kRadial2_SampleMode:
|
||||
stage.fCoordMapping = GrGLProgram::ProgramDesc::StageDesc::kRadial2Gradient_CoordMapping;
|
||||
break;
|
||||
case GrSamplerState::kSweep_SampleMode:
|
||||
stage.fCoordMapping = GrGLProgram::ProgramDesc::StageDesc::kSweepGradient_CoordMapping;
|
||||
break;
|
||||
default:
|
||||
GrCrash("Unexpected sample mode!");
|
||||
break;
|
||||
}
|
||||
|
||||
switch (fCurrDrawState.fSamplerStates[s].getFilter()) {
|
||||
// these both can use a regular texture2D()
|
||||
case GrSamplerState::kNearest_Filter:
|
||||
case GrSamplerState::kBilinear_Filter:
|
||||
stage.fFetchMode = GrGLProgram::ProgramDesc::StageDesc::kSingle_FetchMode;
|
||||
break;
|
||||
// performs 4 texture2D()s
|
||||
case GrSamplerState::k4x4Downsample_Filter:
|
||||
stage.fFetchMode = GrGLProgram::ProgramDesc::StageDesc::k2x2_FetchMode;
|
||||
break;
|
||||
default:
|
||||
GrCrash("Unexpected filter!");
|
||||
break;
|
||||
}
|
||||
|
||||
if (GrPixelConfigIsAlphaOnly(texture->config())) {
|
||||
|
@ -60,6 +60,9 @@ private:
|
||||
// flushes the parameters to two point radial gradient
|
||||
void flushRadial2(int stage);
|
||||
|
||||
// flushes the normalized texel size
|
||||
void flushTexelSize(int stage);
|
||||
|
||||
static void DeleteProgram(GrGLProgram::CachedData* programData);
|
||||
|
||||
void ProgramUnitTest();
|
||||
|
@ -1135,6 +1135,7 @@ void GrGpuGLShaders2::DeleteProgram(Program* program) {
|
||||
|
||||
GrGpuGLShaders2::GrGpuGLShaders2() {
|
||||
|
||||
f4X4DownsampleFilterSupport = false;
|
||||
fProgram = NULL;
|
||||
fProgramCache = new ProgramCache();
|
||||
|
||||
|
@ -36,10 +36,15 @@ void GrTextContext::flushGlyphs() {
|
||||
GrDrawTarget::AutoStateRestore asr(fDrawTarget);
|
||||
|
||||
// setup our sampler state for our text texture/atlas
|
||||
|
||||
GrSamplerState::Filter filter;
|
||||
if (fExtMatrix.isIdentity()) {
|
||||
filter = GrSamplerState::kNearest_Filter;
|
||||
} else {
|
||||
filter = GrSamplerState::kBilinear_Filter;
|
||||
}
|
||||
GrSamplerState sampler(GrSamplerState::kRepeat_WrapMode,
|
||||
GrSamplerState::kRepeat_WrapMode,
|
||||
!fExtMatrix.isIdentity());
|
||||
filter);
|
||||
fDrawTarget->setSamplerState(TEXT_STAGE, sampler);
|
||||
|
||||
GrAssert(GrIsALIGN4(fCurrVertex));
|
||||
|
@ -423,7 +423,11 @@ bool SkGpuDevice::skPaint2GrPaintShader(const SkPaint& skPaint,
|
||||
return false;
|
||||
}
|
||||
grPaint->fSampler.setSampleMode(sampleMode);
|
||||
grPaint->fSampler.setFilter(skPaint.isFilterBitmap());
|
||||
if (skPaint.isFilterBitmap()) {
|
||||
grPaint->fSampler.setFilter(GrSamplerState::kBilinear_Filter);
|
||||
} else {
|
||||
grPaint->fSampler.setFilter(GrSamplerState::kNearest_Filter);
|
||||
}
|
||||
grPaint->fSampler.setWrapX(sk_tile_mode_to_grwrap(tileModes[0]));
|
||||
grPaint->fSampler.setWrapY(sk_tile_mode_to_grwrap(tileModes[1]));
|
||||
if (GrSamplerState::kRadial2_SampleMode == sampleMode) {
|
||||
@ -863,7 +867,12 @@ void SkGpuDevice::drawBitmap(const SkDraw& draw,
|
||||
if (!this->skPaint2GrPaintNoShader(paint, true, &grPaint)) {
|
||||
return;
|
||||
}
|
||||
grPaint.fSampler.setFilter(paint.isFilterBitmap());
|
||||
if (paint.isFilterBitmap()) {
|
||||
grPaint.fSampler.setFilter(GrSamplerState::kBilinear_Filter);
|
||||
} else {
|
||||
grPaint.fSampler.setFilter(GrSamplerState::kNearest_Filter);
|
||||
}
|
||||
|
||||
|
||||
const int maxTextureDim = fContext->getMaxTextureDimension();
|
||||
if (bitmap.getTexture() || (bitmap.width() <= maxTextureDim &&
|
||||
|
Loading…
Reference in New Issue
Block a user