aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/gpu/gl/GrGLEffectMatrix.cpp2
-rw-r--r--src/gpu/gl/GrGLProgram.cpp74
-rw-r--r--src/gpu/gl/GrGLProgramDesc.h2
-rw-r--r--src/gpu/gl/GrGLShaderBuilder.cpp166
-rw-r--r--src/gpu/gl/GrGLShaderBuilder.h89
-rw-r--r--tests/GLProgramsTest.cpp26
6 files changed, 210 insertions, 149 deletions
diff --git a/src/gpu/gl/GrGLEffectMatrix.cpp b/src/gpu/gl/GrGLEffectMatrix.cpp
index 7e7a9c940a..523b37e72e 100644
--- a/src/gpu/gl/GrGLEffectMatrix.cpp
+++ b/src/gpu/gl/GrGLEffectMatrix.cpp
@@ -87,7 +87,7 @@ GrSLType GrGLEffectMatrix::emitCode(GrGLShaderBuilder* builder,
&uniName);
}
- const char* varyingName = "StageCoord";
+ const char* varyingName = "MatrixCoord";
SkString suffixedVaryingName;
if (NULL != suffix) {
suffixedVaryingName.append(varyingName);
diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp
index 1b4baa40ea..1b9c3a293a 100644
--- a/src/gpu/gl/GrGLProgram.cpp
+++ b/src/gpu/gl/GrGLProgram.cpp
@@ -485,35 +485,21 @@ bool GrGLProgram::genProgram(const GrEffectStage* stages[]) {
bool needColor, needFilterColor;
need_blend_inputs(filterColorCoeff, colorCoeff, &needFilterColor, &needColor);
+ // used in order for builder to return the per-stage uniform handles.
+ SkTArray<GrGLUniformManager::UniformHandle, true>* stageUniformArrays[GrDrawState::kNumStages];
+
if (needColor) {
- ///////////////////////////////////////////////////////////////////////////
- // compute the color
- // if we have color stages string them together, feeding the output color
- // of each to the next and generating code for each stage.
- SkString outColor;
for (int s = 0; s < fDesc.fFirstCoverageStage; ++s) {
- if (GrGLEffect::kNoEffectKey != fDesc.fEffectKeys[s]) {
- if (kZeros_GrSLConstantVec == knownColorValue) {
- // Effects have no way to communicate zeros, they treat an empty string as ones.
- inColor = "initialColor";
- builder.fsCodeAppendf("\tvec4 %s = %s;\n", inColor.c_str(), GrGLSLZerosVecf(4));
- }
- // create var to hold stage result
- outColor = "color";
- outColor.appendS32(s);
- builder.fsCodeAppendf("\tvec4 %s;\n", outColor.c_str());
-
- builder.setCurrentStage(s);
- fEffects[s] = builder.createAndEmitGLEffect(*stages[s],
- fDesc.fEffectKeys[s],
- inColor.size() ? inColor.c_str() : NULL,
- outColor.c_str(),
- &fUniformHandles.fEffectSamplerUnis[s]);
- builder.setNonStage();
- inColor = outColor;
- knownColorValue = kNone_GrSLConstantVec;
- }
+ stageUniformArrays[s] = &fUniformHandles.fEffectSamplerUnis[s];
}
+
+ builder.emitEffects(stages,
+ fDesc.fEffectKeys,
+ fDesc.fFirstCoverageStage,
+ &inColor,
+ &knownColorValue,
+ stageUniformArrays,
+ fEffects);
}
// Insert the color filter. This will soon be replaced by a color effect.
@@ -540,37 +526,21 @@ bool GrGLProgram::genProgram(const GrEffectStage* stages[]) {
///////////////////////////////////////////////////////////////////////////
// compute the partial coverage
-
- // incoming coverage to current stage being processed.
SkString inCoverage;
GrSLConstantVec knownCoverageValue = this->genInputCoverage(&builder, &inCoverage);
- SkString outCoverage;
- for (int s = fDesc.fFirstCoverageStage; s < GrDrawState::kNumStages; ++s) {
- if (fDesc.fEffectKeys[s]) {
- if (kZeros_GrSLConstantVec == knownCoverageValue) {
- // Effects have no way to communicate zeros, they treat an empty string as ones.
- inCoverage = "initialCoverage";
- builder.fsCodeAppendf("\tvec4 %s = %s;\n", inCoverage.c_str(), GrGLSLZerosVecf(4));
- }
- // create var to hold stage output
- outCoverage = "coverage";
- outCoverage.appendS32(s);
- builder.fsCodeAppendf("\tvec4 %s;\n", outCoverage.c_str());
-
- builder.setCurrentStage(s);
- fEffects[s] = builder.createAndEmitGLEffect(
- *stages[s],
- fDesc.fEffectKeys[s],
- inCoverage.size() ? inCoverage.c_str() : NULL,
- outCoverage.c_str(),
- &fUniformHandles.fEffectSamplerUnis[s]);
- builder.setNonStage();
- inCoverage = outCoverage;
- knownCoverageValue = kNone_GrSLConstantVec;
- }
+ for (int s = fDesc.fFirstCoverageStage, i = 0; s < GrDrawState::kNumStages; ++s, ++i) {
+ stageUniformArrays[i] = &fUniformHandles.fEffectSamplerUnis[s];
}
+ builder.emitEffects(stages + fDesc.fFirstCoverageStage,
+ fDesc.fEffectKeys + fDesc.fFirstCoverageStage,
+ GrDrawState::kNumStages - fDesc.fFirstCoverageStage,
+ &inCoverage,
+ &knownCoverageValue,
+ stageUniformArrays,
+ fEffects + fDesc.fFirstCoverageStage);
+
// discard if coverage is zero
if (fDesc.fDiscardIfZeroCoverage && kOnes_GrSLConstantVec != knownCoverageValue) {
if (kZeros_GrSLConstantVec == knownCoverageValue) {
diff --git a/src/gpu/gl/GrGLProgramDesc.h b/src/gpu/gl/GrGLProgramDesc.h
index 8d7ca8d1bc..45714a0dc6 100644
--- a/src/gpu/gl/GrGLProgramDesc.h
+++ b/src/gpu/gl/GrGLProgramDesc.h
@@ -39,7 +39,7 @@ public:
void setRandom(SkMWCRandom*,
const GrGpuGL* gpu,
const GrTexture* dummyDstTexture,
- const GrEffectStage stages[GrDrawState::kNumStages],
+ const GrEffectStage* stages[GrDrawState::kNumStages],
int currAttribIndex);
/**
diff --git a/src/gpu/gl/GrGLShaderBuilder.cpp b/src/gpu/gl/GrGLShaderBuilder.cpp
index b379c78432..c1732b20e7 100644
--- a/src/gpu/gl/GrGLShaderBuilder.cpp
+++ b/src/gpu/gl/GrGLShaderBuilder.cpp
@@ -103,7 +103,6 @@ GrGLShaderBuilder::GrGLShaderBuilder(const GrGLContextInfo& ctxInfo,
, fFSOutputs(kMaxFSOutputs)
, fCtxInfo(ctxInfo)
, fUniformManager(uniformManager)
- , fCurrentStageIdx(kNonStageIdx)
, fFSFeaturesAddedMask(0)
#if GR_GL_EXPERIMENTAL_GS
, fUsesGS(desc.fExperimentalGS)
@@ -215,6 +214,21 @@ void GrGLShaderBuilder::addFSFeature(uint32_t featureBit, const char* extensionN
}
}
+void GrGLShaderBuilder::nameVariable(SkString* out, char prefix, const char* name) {
+ if ('\0' == prefix) {
+ *out = name;
+ } else {
+ out->printf("%c%s", prefix, name);
+ }
+ if (fCodeStage.inStageCode()) {
+ if (out->endsWith('_')) {
+ // Names containing "__" are reserved.
+ out->append("x");
+ }
+ out->appendf("_Stage%d", fCodeStage.stageIndex());
+ }
+}
+
const char* GrGLShaderBuilder::dstColor() {
static const char kFBFetchColorName[] = "gl_LastFragData[0]";
GrGLCaps::FBFetchType fetchType = fCtxInfo.caps()->fbFetchType();
@@ -364,12 +378,7 @@ GrGLUniformManager::UniformHandle GrGLShaderBuilder::addUniformArray(uint32_t vi
GrAssert(h2 == h);
uni.fVariable.setType(type);
uni.fVariable.setTypeModifier(GrGLShaderVar::kUniform_TypeModifier);
- SkString* uniName = uni.fVariable.accessName();
- if (kNonStageIdx == fCurrentStageIdx) {
- uniName->printf("u%s", name);
- } else {
- uniName->printf("u%s%d", name, fCurrentStageIdx);
- }
+ this->nameVariable(uni.fVariable.accessName(), 'u', name);
uni.fVariable.setArrayCount(count);
uni.fVisibility = visibility;
@@ -415,11 +424,8 @@ void GrGLShaderBuilder::addVarying(GrSLType type,
fVSOutputs.push_back();
fVSOutputs.back().setType(type);
fVSOutputs.back().setTypeModifier(GrGLShaderVar::kVaryingOut_TypeModifier);
- if (kNonStageIdx == fCurrentStageIdx) {
- fVSOutputs.back().accessName()->printf("v%s", name);
- } else {
- fVSOutputs.back().accessName()->printf("v%s%d", name, fCurrentStageIdx);
- }
+ this->nameVariable(fVSOutputs.back().accessName(), 'v', name);
+
if (vsOutName) {
*vsOutName = fVSOutputs.back().getName().c_str();
}
@@ -436,11 +442,7 @@ void GrGLShaderBuilder::addVarying(GrSLType type,
fGSOutputs.push_back();
fGSOutputs.back().setType(type);
fGSOutputs.back().setTypeModifier(GrGLShaderVar::kVaryingOut_TypeModifier);
- if (kNonStageIdx == fCurrentStageIdx) {
- fGSOutputs.back().accessName()->printf("g%s", name);
- } else {
- fGSOutputs.back().accessName()->printf("g%s%d", name, fCurrentStageIdx);
- }
+ this->nameVariable(fGSOutputs.back().accessName(), 'g', name);
fsName = fGSOutputs.back().accessName();
} else {
fsName = fVSOutputs.back().accessName();
@@ -470,18 +472,16 @@ const char* GrGLShaderBuilder::fragmentPosition() {
} else {
static const char* kCoordName = "fragCoordYDown";
if (!fSetupFragPosition) {
+ // temporarily change the stage index because we're inserting non-stage code.
+ CodeStage::AutoStageRestore csar(&fCodeStage, NULL);
+
GrAssert(GrGLUniformManager::kInvalidUniformHandle == fRTHeightUniform);
const char* rtHeightName;
- // temporarily change the stage index because we're inserting a uniform whose name
- // shouldn't be mangled to be stage-specific.
- int oldStageIdx = fCurrentStageIdx;
- fCurrentStageIdx = kNonStageIdx;
fRTHeightUniform = this->addUniform(kFragment_ShaderType,
kFloat_GrSLType,
"RTHeight",
&rtHeightName);
- fCurrentStageIdx = oldStageIdx;
this->fFSCode.prependf("\tvec4 %s = vec4(gl_FragCoord.x, %s - gl_FragCoord.y, gl_FragCoord.zw);\n",
kCoordName, rtHeightName);
@@ -514,11 +514,7 @@ void GrGLShaderBuilder::emitFunction(ShaderType shader,
SkString* outName) {
GrAssert(kFragment_ShaderType == shader);
fFSFunctions.append(GrGLSLTypeString(returnType));
- if (kNonStageIdx != fCurrentStageIdx) {
- outName->printf("%s_%d", name, fCurrentStageIdx);
- } else {
- *outName = name;
- }
+ this->nameVariable(outName, '\0', name);
fFSFunctions.appendf(" %s", outName->c_str());
fFSFunctions.append("(");
for (int i = 0; i < argCnt; ++i) {
@@ -623,52 +619,86 @@ void GrGLShaderBuilder::finished(GrGLuint programID) {
fUniformManager.getUniformLocations(programID, fUniforms);
}
-GrGLEffect* GrGLShaderBuilder::createAndEmitGLEffect(
- const GrEffectStage& stage,
- GrGLEffect::EffectKey key,
- const char* fsInColor,
- const char* fsOutColor,
- SkTArray<GrGLUniformManager::UniformHandle, true>* samplerHandles) {
- GrAssert(NULL != stage.getEffect());
-
- const GrEffectRef& effect = *stage.getEffect();
- int numTextures = effect->numTextures();
- SkSTArray<8, GrGLShaderBuilder::TextureSampler> textureSamplers;
- textureSamplers.push_back_n(numTextures);
- for (int i = 0; i < numTextures; ++i) {
- textureSamplers[i].init(this, &effect->textureAccess(i), i);
- samplerHandles->push_back(textureSamplers[i].fSamplerUniform);
- }
- GrDrawEffect drawEffect(stage, this->hasExplicitLocalCoords());
-
- int numAttributes = stage.getVertexAttribIndexCount();
- const int* attributeIndices = stage.getVertexAttribIndices();
- SkSTArray<GrEffect::kMaxVertexAttribs, SkString> attributeNames;
- for (int i = 0; i < numAttributes; ++i) {
- SkString attributeName("aAttr");
- attributeName.appendS32(attributeIndices[i]);
-
- if (this->addAttribute(effect->vertexAttribType(i), attributeName.c_str())) {
- fEffectAttributes.push_back().set(attributeIndices[i], attributeName);
+void GrGLShaderBuilder::emitEffects(
+ const GrEffectStage* effectStages[],
+ const GrBackendEffectFactory::EffectKey effectKeys[],
+ int effectCnt,
+ SkString* fsInOutColor,
+ GrSLConstantVec* fsInOutColorKnownValue,
+ SkTArray<GrGLUniformManager::UniformHandle, true>* effectSamplerHandles[],
+ GrGLEffect* glEffects[]) {
+ bool effectEmitted = false;
+
+ SkString inColor = *fsInOutColor;
+ SkString outColor;
+
+ for (int e = 0; e < effectCnt; ++e) {
+ if (NULL == effectStages[e] || GrGLEffect::kNoEffectKey == effectKeys[e]) {
+ continue;
+ }
+
+ GrAssert(NULL != effectStages[e]->getEffect());
+ const GrEffectStage& stage = *effectStages[e];
+ const GrEffectRef& effect = *stage.getEffect();
+
+ CodeStage::AutoStageRestore csar(&fCodeStage, &stage);
+
+ int numTextures = effect->numTextures();
+ SkSTArray<8, GrGLShaderBuilder::TextureSampler> textureSamplers;
+ textureSamplers.push_back_n(numTextures);
+ for (int t = 0; t < numTextures; ++t) {
+ textureSamplers[t].init(this, &effect->textureAccess(t), t);
+ effectSamplerHandles[e]->push_back(textureSamplers[t].fSamplerUniform);
+ }
+ GrDrawEffect drawEffect(stage, this->hasExplicitLocalCoords());
+
+ int numAttributes = stage.getVertexAttribIndexCount();
+ const int* attributeIndices = stage.getVertexAttribIndices();
+ SkSTArray<GrEffect::kMaxVertexAttribs, SkString> attributeNames;
+ for (int a = 0; a < numAttributes; ++a) {
+ // TODO: Make addAttribute mangle the name.
+ SkString attributeName("aAttr");
+ attributeName.appendS32(attributeIndices[a]);
+ if (this->addAttribute(effect->vertexAttribType(a), attributeName.c_str())) {
+ fEffectAttributes.push_back().set(attributeIndices[a], attributeName);
+ }
+ }
+
+ glEffects[e] = effect->getFactory().createGLInstance(drawEffect);
+
+ if (kZeros_GrSLConstantVec == *fsInOutColorKnownValue) {
+ // Effects have no way to communicate zeros, they treat an empty string as ones.
+ this->nameVariable(&inColor, '\0', "input");
+ this->fsCodeAppendf("\tvec4 %s = %s;\n", inColor.c_str(), GrGLSLZerosVecf(4));
}
- }
- GrGLEffect* glEffect = effect->getFactory().createGLInstance(drawEffect);
+ // create var to hold stage result
+ this->nameVariable(&outColor, '\0', "output");
+ this->fsCodeAppendf("\tvec4 %s;\n", outColor.c_str());
- // Enclose custom code in a block to avoid namespace conflicts
- this->fVSCode.appendf("\t{ // %s\n", glEffect->name());
- this->fFSCode.appendf("\t{ // %s \n", glEffect->name());
+ // Enclose custom code in a block to avoid namespace conflicts
+ SkString openBrace;
+ openBrace.printf("\t{ // Stage %d: %s\n", fCodeStage.stageIndex(), glEffects[e]->name());
+ this->fVSCode.append(openBrace);
+ this->fFSCode.append(openBrace);
- glEffect->emitCode(this,
- drawEffect,
- key,
- fsOutColor,
- fsInColor,
- textureSamplers);
- this->fVSCode.appendf("\t}\n");
- this->fFSCode.appendf("\t}\n");
+ glEffects[e]->emitCode(this,
+ drawEffect,
+ effectKeys[e],
+ outColor.c_str(),
+ inColor.isEmpty() ? NULL : inColor.c_str(),
+ textureSamplers);
+ this->fVSCode.append("\t}\n");
+ this->fFSCode.append("\t}\n");
- return glEffect;
+ inColor = outColor;
+ *fsInOutColorKnownValue = kNone_GrSLConstantVec;
+ effectEmitted = true;
+ }
+
+ if (effectEmitted) {
+ *fsInOutColor = outColor;
+ }
}
const SkString* GrGLShaderBuilder::getEffectAttributeName(int attributeIndex) const {
diff --git a/src/gpu/gl/GrGLShaderBuilder.h b/src/gpu/gl/GrGLShaderBuilder.h
index 9021a0dee1..765a2edf8d 100644
--- a/src/gpu/gl/GrGLShaderBuilder.h
+++ b/src/gpu/gl/GrGLShaderBuilder.h
@@ -71,7 +71,7 @@ public:
GrAssert(NULL != builder);
SkString name;
- name.printf("Sampler%d_", idx);
+ name.printf("Sampler%d", idx);
fSamplerUniform = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
kSampler2D_GrSLType,
name.c_str());
@@ -275,16 +275,24 @@ public:
/** Called after building is complete to get the final shader string. */
void getShader(ShaderType, SkString*) const;
- void setCurrentStage(int stageIdx) { fCurrentStageIdx = stageIdx; }
- void setNonStage() { fCurrentStageIdx = kNonStageIdx; }
- // TODO: move remainder of shader code generation to this class and call this privately
- // Handles of sampler uniforms generated for the effect are appended to samplerHandles.
- GrGLEffect* createAndEmitGLEffect(
- const GrEffectStage& stage,
- GrBackendEffectFactory::EffectKey key,
- const char* fsInColor, // NULL means no incoming color
- const char* fsOutColor,
- SkTArray<GrGLUniformManager::UniformHandle, true>* samplerHandles);
+ /**
+ * Adds code for effects. effectStages contains the effects to add. effectKeys[i] is the key
+ * generated from effectStages[i]. An entry in effectStages can be NULL, in which case it is
+ * skipped. Moreover, if the corresponding key is GrGLEffect::NoEffectKey then it is skipped.
+ * inOutFSColor specifies the input color to the first stage and is updated to be the
+ * output color of the last stage. fsInOutColorKnownValue specifies whether the input color
+ * has a known constant value and is updated to refer to the status of the output color.
+ * The handles to texture samplers for effectStage[i] are added to effectSamplerHandles[i]. The
+ * glEffects array is updated to contain the GrGLEffect generated for each entry in
+ * effectStages.
+ */
+ void emitEffects(const GrEffectStage* effectStages[],
+ const GrBackendEffectFactory::EffectKey effectKeys[],
+ int effectCnt,
+ SkString* inOutFSColor,
+ GrSLConstantVec* fsInOutColorKnownValue,
+ SkTArray<GrGLUniformManager::UniformHandle, true>* effectSamplerHandles[],
+ GrGLEffect* glEffects[]);
GrGLUniformManager::UniformHandle getRTHeightUniform() const { return fRTHeightUniform; }
GrGLUniformManager::UniformHandle getDstCopyTopLeftUniform() const {
@@ -338,9 +346,56 @@ public:
VarArray fFSOutputs;
private:
- enum {
- kNonStageIdx = -1,
- };
+ class CodeStage : GrNoncopyable {
+ public:
+ CodeStage() : fNextIndex(0), fCurrentIndex(-1), fEffectStage(NULL) {}
+
+ bool inStageCode() const {
+ this->validate();
+ return NULL != fEffectStage;
+ }
+
+ const GrEffectStage* effectStage() const {
+ this->validate();
+ return fEffectStage;
+ }
+
+ int stageIndex() const {
+ this->validate();
+ return fCurrentIndex;
+ }
+
+ class AutoStageRestore : GrNoncopyable {
+ public:
+ AutoStageRestore(CodeStage* codeStage, const GrEffectStage* newStage) {
+ GrAssert(NULL != codeStage);
+ fSavedIndex = codeStage->fCurrentIndex;
+ fSavedEffectStage = codeStage->fEffectStage;
+
+ if (NULL == newStage) {
+ codeStage->fCurrentIndex = -1;
+ } else {
+ codeStage->fCurrentIndex = codeStage->fNextIndex++;
+ }
+ codeStage->fEffectStage = newStage;
+
+ fCodeStage = codeStage;
+ }
+ ~AutoStageRestore() {
+ fCodeStage->fCurrentIndex = fSavedIndex;
+ fCodeStage->fEffectStage = fSavedEffectStage;
+ }
+ private:
+ CodeStage* fCodeStage;
+ int fSavedIndex;
+ const GrEffectStage* fSavedEffectStage;
+ };
+ private:
+ void validate() const { GrAssert((NULL == fEffectStage) == (-1 == fCurrentIndex)); }
+ int fNextIndex;
+ int fCurrentIndex;
+ const GrEffectStage* fEffectStage;
+ } fCodeStage;
/**
* Features that should only be enabled by GrGLShaderBuilder itself.
@@ -356,6 +411,11 @@ private:
// the enables separately for each shader.
void addFSFeature(uint32_t featureBit, const char* extensionName);
+ // Generates a name for a variable. The generated string will be name prefixed by the prefix
+ // char (unless the prefix is '\0'). It also mangles the name to be stage-specific if we're
+ // generating stage code.
+ void nameVariable(SkString* out, char prefix, const char* name);
+
// Interpretation of DstReadKey when generating code
enum {
kNoDstRead_DstReadKey = 0,
@@ -366,7 +426,6 @@ private:
const GrGLContextInfo& fCtxInfo;
GrGLUniformManager& fUniformManager;
- int fCurrentStageIdx;
uint32_t fFSFeaturesAddedMask;
SkString fFSFunctions;
SkString fFSExtensions;
diff --git a/tests/GLProgramsTest.cpp b/tests/GLProgramsTest.cpp
index ae6fe7b3c4..95187a6e39 100644
--- a/tests/GLProgramsTest.cpp
+++ b/tests/GLProgramsTest.cpp
@@ -24,7 +24,7 @@
void GrGLProgramDesc::setRandom(SkMWCRandom* random,
const GrGpuGL* gpu,
const GrTexture* dstTexture,
- const GrEffectStage stages[GrDrawState::kNumStages],
+ const GrEffectStage* stages[GrDrawState::kNumStages],
int currAttribIndex) {
fEmitsPointSize = random->nextBool();
@@ -59,11 +59,11 @@ void GrGLProgramDesc::setRandom(SkMWCRandom* random,
bool dstRead = false;
for (int s = 0; s < GrDrawState::kNumStages; ++s) {
- if (NULL != stages[s].getEffect()) {
- const GrBackendEffectFactory& factory = (*stages[s].getEffect())->getFactory();
- GrDrawEffect drawEffect(stages[s], useLocalCoords);
+ if (NULL != stages[s]) {
+ const GrBackendEffectFactory& factory = (*stages[s]->getEffect())->getFactory();
+ GrDrawEffect drawEffect(*stages[s], useLocalCoords);
fEffectKeys[s] = factory.glEffectKey(drawEffect, gpu->glCaps());
- if ((*stages[s].getEffect())->willReadDst()) {
+ if ((*stages[s]->getEffect())->willReadDst()) {
dstRead = true;
}
}
@@ -113,7 +113,8 @@ bool GrGpuGL::programUnitTest(int maxStages) {
#endif
GrGLProgramDesc pdesc;
- GrEffectStage stages[GrDrawState::kNumStages];
+ const GrEffectStage* stages[GrDrawState::kNumStages];
+ memset(stages, 0, sizeof(stages));
int currAttribIndex = 1; // we need to always leave room for position
int attribIndices[2];
@@ -137,19 +138,20 @@ bool GrGpuGL::programUnitTest(int maxStages) {
for (int i = 0; i < numAttribs; ++i) {
attribIndices[i] = currAttribIndex++;
}
- stages[s].setEffect(effect.get(), attribIndices[0], attribIndices[1]);
+ GrEffectStage* stage = SkNEW(GrEffectStage);
+ stage->setEffect(effect.get(), attribIndices[0], attribIndices[1]);
+ stages[s] = stage;
}
}
const GrTexture* dstTexture = random.nextBool() ? dummyTextures[0] : dummyTextures[1];
pdesc.setRandom(&random, this, dstTexture, stages, currAttribIndex);
- const GrEffectStage* stagePtrs[GrDrawState::kNumStages];
- for (int s = 0; s < GrDrawState::kNumStages; ++s) {
- stagePtrs[s] = &stages[s];
- }
SkAutoTUnref<GrGLProgram> program(GrGLProgram::Create(this->glContext(),
pdesc,
- stagePtrs));
+ stages));
+ for (int s = 0; s < maxStages; ++s) {
+ SkDELETE(stages[s]);
+ }
if (NULL == program.get()) {
return false;
}