aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu
diff options
context:
space:
mode:
authorGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-07-18 13:20:29 +0000
committerGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-07-18 13:20:29 +0000
commitecb60aad5c6fe5b1dbcfc86ac00bfc9326103c8d (patch)
treeafb61c24ca683260e40b6e0ad8e7ad0e297f27e6 /src/gpu
parent5836b6dec5563e6273099fcf23984dd3818a168f (diff)
Factory method for creating GrGLProgram
Review URL: http://codereview.appspot.com/6407049/ git-svn-id: http://skia.googlecode.com/svn/trunk@4646 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/gpu')
-rw-r--r--src/gpu/gl/GrGLProgram.cpp140
-rw-r--r--src/gpu/gl/GrGLProgram.h50
-rw-r--r--src/gpu/gl/GrGpuGL.h3
-rw-r--r--src/gpu/gl/GrGpuGL_program.cpp27
-rw-r--r--src/gpu/gl/GrGpuGL_unittest.cpp6
5 files changed, 118 insertions, 108 deletions
diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp
index 49cb161652..52a4bd3b5c 100644
--- a/src/gpu/gl/GrGLProgram.cpp
+++ b/src/gpu/gl/GrGLProgram.cpp
@@ -18,6 +18,9 @@
SK_DEFINE_INST_COUNT(GrGLProgram)
+#define GL_CALL(X) GR_GL_CALL(fContextInfo.interface(), X)
+#define GL_CALL_RET(R, X) GR_GL_CALL_RET(fContextInfo.interface(), R, X)
+
namespace {
enum {
@@ -88,15 +91,57 @@ inline void sampler_name(int stage, SkString* s) {
}
}
-GrGLProgram::GrGLProgram() {
+GrGLProgram* GrGLProgram::Create(const GrGLContextInfo& gl,
+ const Desc& desc,
+ GrCustomStage** customStages) {
+ GrGLProgram* program = SkNEW_ARGS(GrGLProgram, (gl, desc, customStages));
+ if (!program->succeeded()) {
+ delete program;
+ program = NULL;
+ }
+ return program;
+}
+
+GrGLProgram::GrGLProgram(const GrGLContextInfo& gl,
+ const Desc& desc,
+ GrCustomStage** customStages) : fContextInfo(gl) {
+ fDesc = desc;
+ fVShaderID = 0;
+ fGShaderID = 0;
+ fFShaderID = 0;
+ fProgramID = 0;
+ for (int s = 0; s < GrDrawState::kNumStages; ++s) {
+ fProgramStage[s] = NULL;
+ }
+ this->genProgram(customStages);
}
GrGLProgram::~GrGLProgram() {
+ if (fVShaderID) {
+ GL_CALL(DeleteShader(fVShaderID));
+ }
+ if (fGShaderID) {
+ GL_CALL(DeleteShader(fGShaderID));
+ }
+ if (fFShaderID) {
+ GL_CALL(DeleteShader(fFShaderID));
+ }
+ if (fProgramID) {
+ GL_CALL(DeleteProgram(fProgramID));
+ }
+
for (int i = 0; i < GrDrawState::kNumStages; ++i) {
delete fProgramStage[i];
}
}
+void GrGLProgram::abandon() {
+ fVShaderID = 0;
+ fGShaderID = 0;
+ fFShaderID = 0;
+ fProgramID = 0;
+}
+
void GrGLProgram::overrideBlend(GrBlendCoeff* srcCoeff,
GrBlendCoeff* dstCoeff) const {
switch (fDesc.fDualSrcOutput) {
@@ -280,8 +325,7 @@ static void addColorMatrix(SkString* fsCode, const char * outputVar,
fsCode->appendf("\t%s.rgb *= %s.a;\n", outputVar, outputVar);
}
-void GrGLProgram::genEdgeCoverage(const GrGLContextInfo& gl,
- SkString* coverageVar,
+void GrGLProgram::genEdgeCoverage(SkString* coverageVar,
GrGLShaderBuilder* segments) const {
if (fDesc.fVertexLayout & GrDrawTarget::kEdge_VertexLayoutBit) {
const char *vsName, *fsName;
@@ -309,7 +353,7 @@ void GrGLProgram::genEdgeCoverage(const GrGLContextInfo& gl,
segments->fFSCode.appendf("\t\tedgeAlpha = (%s.x*%s.x - %s.y);\n", fsName, fsName, fsName);
segments->fFSCode.append("\t\tedgeAlpha = clamp(0.5 - edgeAlpha / length(gF), 0.0, 1.0);\n"
"\t}\n");
- if (kES2_GrGLBinding == gl.binding()) {
+ if (kES2_GrGLBinding == fContextInfo.binding()) {
segments->fHeader.printf("#extension GL_OES_standard_derivatives: enable\n");
}
break;
@@ -322,7 +366,7 @@ void GrGLProgram::genEdgeCoverage(const GrGLContextInfo& gl,
segments->fFSCode.appendf("\tfloat edgeAlpha = (%s.x*%s.x - %s.y);\n", fsName, fsName, fsName);
segments->fFSCode.append("\tedgeAlpha = sqrt(edgeAlpha*edgeAlpha / dot(gF, gF));\n");
segments->fFSCode.append("\tedgeAlpha = max(1.0 - edgeAlpha, 0.0);\n");
- if (kES2_GrGLBinding == gl.binding()) {
+ if (kES2_GrGLBinding == fContextInfo.binding()) {
segments->fHeader.printf("#extension GL_OES_standard_derivatives: enable\n");
}
break;
@@ -403,11 +447,10 @@ void gen_attribute_coverage(GrGLShaderBuilder* segments,
}
}
-void GrGLProgram::genGeometryShader(const GrGLContextInfo& gl,
- GrGLShaderBuilder* segments) const {
+void GrGLProgram::genGeometryShader(GrGLShaderBuilder* segments) const {
#if GR_GL_EXPERIMENTAL_GS
if (fDesc.fExperimentalGS) {
- GrAssert(gl.glslGeneration() >= k150_GrGLSLGeneration);
+ GrAssert(fContextInfo.glslGeneration() >= k150_GrGLSLGeneration);
segments->fGSHeader.append("layout(triangles) in;\n"
"layout(triangle_strip, max_vertices = 6) out;\n");
segments->fGSCode.append("void main() {\n"
@@ -444,9 +487,6 @@ const char* GrGLProgram::adjustInColor(const SkString& inColor) const {
}
namespace {
-#define GL_CALL(X) GR_GL_CALL(gl.interface(), X)
-#define GL_CALL_RET(R, X) GR_GL_CALL_RET(gl.interface(), R, X)
-
// prints a shader using params similar to glShaderSource
void print_shader(GrGLint stringCnt,
const GrGLchar** strings,
@@ -470,31 +510,32 @@ GrGLuint compile_shader(const GrGLContextInfo& gl,
"stringCount", SkStringPrintf("%i", stringCnt).c_str());
GrGLuint shader;
- GL_CALL_RET(shader, CreateShader(type));
+ GR_GL_CALL_RET(gl.interface(), shader, CreateShader(type));
if (0 == shader) {
return 0;
}
+ const GrGLInterface* gli = gl.interface();
GrGLint compiled = GR_GL_INIT_ZERO;
- GL_CALL(ShaderSource(shader, stringCnt, strings, stringLengths));
- GL_CALL(CompileShader(shader));
- GL_CALL(GetShaderiv(shader, GR_GL_COMPILE_STATUS, &compiled));
+ GR_GL_CALL(gli, ShaderSource(shader, stringCnt, strings, stringLengths));
+ GR_GL_CALL(gli, CompileShader(shader));
+ GR_GL_CALL(gli, GetShaderiv(shader, GR_GL_COMPILE_STATUS, &compiled));
if (!compiled) {
GrGLint infoLen = GR_GL_INIT_ZERO;
- GL_CALL(GetShaderiv(shader, GR_GL_INFO_LOG_LENGTH, &infoLen));
+ GR_GL_CALL(gli, GetShaderiv(shader, GR_GL_INFO_LOG_LENGTH, &infoLen));
SkAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debugger
if (infoLen > 0) {
// retrieve length even though we don't need it to workaround bug in chrome cmd buffer
// param validation.
GrGLsizei length = GR_GL_INIT_ZERO;
- GL_CALL(GetShaderInfoLog(shader, infoLen+1,
- &length, (char*)log.get()));
+ GR_GL_CALL(gli, GetShaderInfoLog(shader, infoLen+1,
+ &length, (char*)log.get()));
print_shader(stringCnt, strings, stringLengths);
GrPrintf("\n%s", log.get());
}
GrAssert(!"Shader compilation failed!");
- GL_CALL(DeleteShader(shader));
+ GR_GL_CALL(gli, DeleteShader(shader));
return 0;
}
return shader;
@@ -510,8 +551,7 @@ GrGLuint compile_shader(const GrGLContextInfo& gl, GrGLenum type, const SkString
}
// compiles all the shaders from builder and stores the shader IDs
-bool GrGLProgram::compileShaders(const GrGLContextInfo& gl,
- const GrGLShaderBuilder& builder) {
+bool GrGLProgram::compileShaders(const GrGLShaderBuilder& builder) {
SkString shader;
@@ -520,7 +560,7 @@ bool GrGLProgram::compileShaders(const GrGLContextInfo& gl,
GrPrintf(shader.c_str());
GrPrintf("\n");
#endif
- if (!(fVShaderID = compile_shader(gl, GR_GL_VERTEX_SHADER, shader))) {
+ if (!(fVShaderID = compile_shader(fContextInfo, GR_GL_VERTEX_SHADER, shader))) {
return false;
}
@@ -530,7 +570,7 @@ bool GrGLProgram::compileShaders(const GrGLContextInfo& gl,
GrPrintf(shader.c_str());
GrPrintf("\n");
#endif
- if (!(fGShaderID = compile_shader(gl, GR_GL_GEOMETRY_SHADER, shader))) {
+ if (!(fGShaderID = compile_shader(fContextInfo, GR_GL_GEOMETRY_SHADER, shader))) {
return false;
}
} else {
@@ -542,7 +582,7 @@ bool GrGLProgram::compileShaders(const GrGLContextInfo& gl,
GrPrintf(shader.c_str());
GrPrintf("\n");
#endif
- if (!(fFShaderID = compile_shader(gl, GR_GL_FRAGMENT_SHADER, shader))) {
+ if (!(fFShaderID = compile_shader(fContextInfo, GR_GL_FRAGMENT_SHADER, shader))) {
return false;
}
@@ -550,11 +590,10 @@ bool GrGLProgram::compileShaders(const GrGLContextInfo& gl,
}
-bool GrGLProgram::genProgram(const GrGLContextInfo& gl,
- const Desc& desc,
- GrCustomStage** customStages) {
- fDesc = desc;
- GrGLShaderBuilder builder(gl);
+bool GrGLProgram::genProgram(GrCustomStage** customStages) {
+ GrAssert(0 == fProgramID);
+
+ GrGLShaderBuilder builder(fContextInfo);
const uint32_t& layout = fDesc.fVertexLayout;
fUniLocations.reset();
@@ -608,11 +647,11 @@ bool GrGLProgram::genProgram(const GrGLContextInfo& gl,
// the dual source output has no canonical var name, have to
// declare an output, which is incompatible with gl_FragColor/gl_FragData.
bool dualSourceOutputWritten = false;
- builder.fHeader.append(GrGetGLSLVersionDecl(gl.binding(),
- gl.glslGeneration()));
+ builder.fHeader.append(GrGetGLSLVersionDecl(fContextInfo.binding(),
+ fContextInfo.glslGeneration()));
GrGLShaderVar colorOutput;
- bool isColorDeclared = GrGLSLSetupFSColorOuput(gl.glslGeneration(),
+ bool isColorDeclared = GrGLSLSetupFSColorOuput(fContextInfo.glslGeneration(),
declared_color_output_name(),
&colorOutput);
if (isColorDeclared) {
@@ -657,15 +696,6 @@ bool GrGLProgram::genProgram(const GrGLContextInfo& gl,
}
///////////////////////////////////////////////////////////////////////////
- // We need to convert generic effect representations to GL-specific
- // backends so they can be accesseed in genStageCode() and in subsequent,
- // uses of programData, but it's safest to do so below when we're *sure*
- // we need them.
- for (int s = 0; s < GrDrawState::kNumStages; ++s) {
- fProgramStage[s] = NULL;
- }
-
- ///////////////////////////////////////////////////////////////////////////
// compute the final color
// if we have color stages string them together, feeding the output color
@@ -694,8 +724,7 @@ bool GrGLProgram::genProgram(const GrGLContextInfo& gl,
const GrProgramStageFactory& factory = customStages[s]->getFactory();
fProgramStage[s] = factory.createGLInstance(*customStages[s]);
}
- this->genStageCode(gl,
- s,
+ this->genStageCode(s,
inColor.size() ? inColor.c_str() : NULL,
outColor.c_str(),
inCoords,
@@ -761,7 +790,7 @@ bool GrGLProgram::genProgram(const GrGLContextInfo& gl,
if (!wroteFragColorZero || Desc::kNone_DualSrcOutput != fDesc.fDualSrcOutput) {
if (!coverageIsZero) {
- this->genEdgeCoverage(gl, &inCoverage, &builder);
+ this->genEdgeCoverage(&inCoverage, &builder);
switch (fDesc.fCoverageInput) {
case Desc::kSolidWhite_ColorInput:
@@ -804,8 +833,7 @@ bool GrGLProgram::genProgram(const GrGLContextInfo& gl,
const GrProgramStageFactory& factory = customStages[s]->getFactory();
fProgramStage[s] = factory.createGLInstance(*customStages[s]);
}
- this->genStageCode(gl,
- s,
+ this->genStageCode(s,
inCoverage.size() ? inCoverage.c_str() : NULL,
outCoverage.c_str(),
inCoords,
@@ -883,30 +911,28 @@ bool GrGLProgram::genProgram(const GrGLContextInfo& gl,
///////////////////////////////////////////////////////////////////////////
// insert GS
#if GR_DEBUG
- this->genGeometryShader(gl, &builder);
+ this->genGeometryShader(&builder);
#endif
///////////////////////////////////////////////////////////////////////////
// compile and setup attribs and unis
- if (!this->compileShaders(gl, builder)) {
+ if (!this->compileShaders(builder)) {
return false;
}
- if (!this->bindOutputsAttribsAndLinkProgram(gl,
- texCoordAttrs,
+ if (!this->bindOutputsAttribsAndLinkProgram(texCoordAttrs,
isColorDeclared,
dualSourceOutputWritten)) {
return false;
}
- this->getUniformLocationsAndInitCache(gl, builder);
+ this->getUniformLocationsAndInitCache(builder);
return true;
}
-bool GrGLProgram::bindOutputsAttribsAndLinkProgram(const GrGLContextInfo& gl,
- SkString texCoordAttrNames[],
+bool GrGLProgram::bindOutputsAttribsAndLinkProgram(SkString texCoordAttrNames[],
bool bindColorOut,
bool bindDualSrcOut) {
GL_CALL_RET(fProgramID, CreateProgram());
@@ -967,8 +993,7 @@ bool GrGLProgram::bindOutputsAttribsAndLinkProgram(const GrGLContextInfo& gl,
return true;
}
-void GrGLProgram::getUniformLocationsAndInitCache(const GrGLContextInfo& gl,
- const GrGLShaderBuilder& builder) {
+void GrGLProgram::getUniformLocationsAndInitCache(const GrGLShaderBuilder& builder) {
if (kUseUniform == fUniLocations.fViewMatrixUni) {
GL_CALL_RET(fUniLocations.fViewMatrixUni, GetUniformLocation(fProgramID, VIEW_MATRIX_NAME));
@@ -1019,7 +1044,7 @@ void GrGLProgram::getUniformLocationsAndInitCache(const GrGLContextInfo& gl,
}
if (NULL != fProgramStage[s]) {
- fProgramStage[s]->initUniforms(&builder, gl.interface(), fProgramID);
+ fProgramStage[s]->initUniforms(&builder, fContextInfo.interface(), fProgramID);
}
}
}
@@ -1044,8 +1069,7 @@ void GrGLProgram::getUniformLocationsAndInitCache(const GrGLContextInfo& gl,
///////////////////////////////////////////////////////////////////////////////
// Stage code generation
-void GrGLProgram::genStageCode(const GrGLContextInfo& gl,
- int stageNum,
+void GrGLProgram::genStageCode(int stageNum,
const char* fsInColor, // NULL means no incoming color
const char* fsOutColor,
const char* vsInCoord,
diff --git a/src/gpu/gl/GrGLProgram.h b/src/gpu/gl/GrGLProgram.h
index 9381cfbe7d..6b6454d4df 100644
--- a/src/gpu/gl/GrGLProgram.h
+++ b/src/gpu/gl/GrGLProgram.h
@@ -41,22 +41,21 @@ public:
struct Desc;
- GrGLProgram();
+ static GrGLProgram* Create(const GrGLContextInfo& gl,
+ const Desc& desc,
+ GrCustomStage** customStages);
+
virtual ~GrGLProgram();
+ /** Call to abandon GL objects owned by this program */
+ void abandon();
+
/**
- * This is the heavy initilization routine for building a GLProgram.
+ * The shader may modify the blend coeffecients. Params are in/out
*/
- bool genProgram(const GrGLContextInfo& gl,
- const Desc& desc,
- GrCustomStage** customStages);
+ void overrideBlend(GrBlendCoeff* srcCoeff, GrBlendCoeff* dstCoeff) const;
- /**
- * The shader may modify the blend coeffecients. Params are in/out
- */
- void overrideBlend(GrBlendCoeff* srcCoeff, GrBlendCoeff* dstCoeff) const;
-
- const Desc& getDesc() { return fDesc; }
+ const Desc& getDesc() { return fDesc; }
/**
* Attribute indices. These should not overlap. Matrices consume 3 slots.
@@ -238,36 +237,42 @@ public:
typedef Desc::StageDesc StageDesc;
private:
+ GrGLProgram(const GrGLContextInfo& gl,
+ const Desc& desc,
+ GrCustomStage** customStages);
+
+ bool succeeded() const { return 0 != fProgramID; }
+
+ /**
+ * This is the heavy initilization routine for building a GLProgram.
+ */
+ bool genProgram(GrCustomStage** customStages);
+
void genInputColor(GrGLShaderBuilder* builder, SkString* inColor);
// Determines which uniforms will need to be bound.
- void genStageCode(const GrGLContextInfo& gl,
- int stageNum,
+ void genStageCode(int stageNum,
const char* fsInColor, // NULL means no incoming color
const char* fsOutColor,
const char* vsInCoord,
GrGLShaderBuilder* builder);
- void genGeometryShader(const GrGLContextInfo& gl, GrGLShaderBuilder* segments) const;
+ void genGeometryShader(GrGLShaderBuilder* segments) const;
void genUniformCoverage(GrGLShaderBuilder* segments, SkString* inOutCoverage);
// generates code to compute coverage based on edge AA.
- void genEdgeCoverage(const GrGLContextInfo& gl,
- SkString* coverageVar,
- GrGLShaderBuilder* builder) const;
+ void genEdgeCoverage(SkString* coverageVar, GrGLShaderBuilder* builder) const;
// Creates a GL program ID, binds shader attributes to GL vertex attrs, and links the program
- bool bindOutputsAttribsAndLinkProgram(const GrGLContextInfo& gl,
- SkString texCoordAttrNames[GrDrawState::kMaxTexCoords],
+ bool bindOutputsAttribsAndLinkProgram(SkString texCoordAttrNames[GrDrawState::kMaxTexCoords],
bool bindColorOut,
bool bindDualSrcOut);
// Binds uniforms; initializes cache to invalid values.
- void getUniformLocationsAndInitCache(const GrGLContextInfo& gl,
- const GrGLShaderBuilder& builder);
+ void getUniformLocationsAndInitCache(const GrGLShaderBuilder& builder);
- bool compileShaders(const GrGLContextInfo& gl, const GrGLShaderBuilder& builder);
+ bool compileShaders(const GrGLShaderBuilder& builder);
const char* adjustInColor(const SkString& inColor) const;
@@ -329,6 +334,7 @@ private:
GrGLProgramStage* fProgramStage[GrDrawState::kNumStages];
Desc fDesc;
+ const GrGLContextInfo& fContextInfo;
friend class GrGpuGL; // TODO: remove this by adding getters and moving functionality.
diff --git a/src/gpu/gl/GrGpuGL.h b/src/gpu/gl/GrGpuGL.h
index 5b33e0e47f..fb78ad2973 100644
--- a/src/gpu/gl/GrGpuGL.h
+++ b/src/gpu/gl/GrGpuGL.h
@@ -168,7 +168,6 @@ private:
class ProgramCache : public ::GrNoncopyable {
public:
ProgramCache(const GrGLContextInfo& gl);
- ~ProgramCache();
void abandon();
GrGLProgram* getProgram(const GrGLProgram::Desc& desc, GrCustomStage** stages);
@@ -248,8 +247,6 @@ private:
// flushing the scissor after that function is called.
void flushScissor();
- static void DeleteProgram(const GrGLInterface* gl, GrGLProgram* programData);
-
void buildProgram(bool isPoints,
BlendOptFlags blendOpts,
GrBlendCoeff dstCoeff,
diff --git a/src/gpu/gl/GrGpuGL_program.cpp b/src/gpu/gl/GrGpuGL_program.cpp
index 7f982e724d..56a893dc3a 100644
--- a/src/gpu/gl/GrGpuGL_program.cpp
+++ b/src/gpu/gl/GrGpuGL_program.cpp
@@ -20,13 +20,12 @@ GrGpuGL::ProgramCache::ProgramCache(const GrGLContextInfo& gl)
, fGL(gl) {
}
-GrGpuGL::ProgramCache::~ProgramCache() {
+void GrGpuGL::ProgramCache::abandon() {
for (int i = 0; i < fCount; ++i) {
- GrGpuGL::DeleteProgram(fGL.interface(), fEntries[i].fProgram);
+ GrAssert(NULL != fEntries[i].fProgram.get());
+ fEntries[i].fProgram->abandon();
+ fEntries[i].fProgram.reset(NULL);
}
-}
-
-void GrGpuGL::ProgramCache::abandon() {
fCount = 0;
}
@@ -36,8 +35,8 @@ GrGLProgram* GrGpuGL::ProgramCache::getProgram(const ProgramDesc& desc, GrCustom
Entry* entry = fHashCache.find(newEntry.fKey);
if (NULL == entry) {
- newEntry.fProgram.reset(SkNEW(GrGLProgram));
- if (!newEntry.fProgram->genProgram(fGL, desc, stages)) {
+ newEntry.fProgram.reset(GrGLProgram::Create(fGL, desc, stages));
+ if (NULL == newEntry.fProgram.get()) {
return NULL;
}
if (fCount < kMaxEntries) {
@@ -52,7 +51,6 @@ GrGLProgram* GrGpuGL::ProgramCache::getProgram(const ProgramDesc& desc, GrCustom
}
}
fHashCache.remove(entry->fKey, entry);
- GrGpuGL::DeleteProgram(fGL.interface(), entry->fProgram);
}
*entry = newEntry;
fHashCache.insert(entry->fKey, entry);
@@ -69,19 +67,6 @@ GrGLProgram* GrGpuGL::ProgramCache::getProgram(const ProgramDesc& desc, GrCustom
return entry->fProgram;
}
-void GrGpuGL::DeleteProgram(const GrGLInterface* gl, GrGLProgram* program) {
- GR_GL_CALL(gl, DeleteShader(program->fVShaderID));
- if (program->fGShaderID) {
- GR_GL_CALL(gl, DeleteShader(program->fGShaderID));
- }
- GR_GL_CALL(gl, DeleteShader(program->fFShaderID));
- GR_GL_CALL(gl, DeleteProgram(program->fProgramID));
- GR_DEBUGCODE(program->fVShaderID = 0);
- GR_DEBUGCODE(program->fGShaderID = 0);
- GR_DEBUGCODE(program->fFShaderID = 0);
- GR_DEBUGCODE(program->fProgramID = 0);
-}
-
////////////////////////////////////////////////////////////////////////////////
void GrGpuGL::abandonResources(){
diff --git a/src/gpu/gl/GrGpuGL_unittest.cpp b/src/gpu/gl/GrGpuGL_unittest.cpp
index 9dd3e77178..e0aa5b56dc 100644
--- a/src/gpu/gl/GrGpuGL_unittest.cpp
+++ b/src/gpu/gl/GrGpuGL_unittest.cpp
@@ -319,12 +319,10 @@ bool GrGpuGL::programUnitTest() {
GR_STATIC_ASSERT(sizeof(customStages) ==
GrDrawState::kNumStages * sizeof(GrCustomStage*));
GrCustomStage** stages = reinterpret_cast<GrCustomStage**>(&customStages);
- SkAutoTUnref<GrGLProgram> program(SkNEW(GrGLProgram));
-
- if (!program->genProgram(this->glContextInfo(), pdesc, stages)) {
+ SkAutoTUnref<GrGLProgram> program(GrGLProgram::Create(this->glContextInfo(), pdesc, stages));
+ if (NULL == program.get()) {
return false;
}
- DeleteProgram(this->glInterface(), program);
}
return true;
}