Factory method for creating GrGLProgram
authorbsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Wed, 18 Jul 2012 13:20:29 +0000 (13:20 +0000)
committerbsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Wed, 18 Jul 2012 13:20:29 +0000 (13:20 +0000)
Review URL: http://codereview.appspot.com/6407049/

git-svn-id: http://skia.googlecode.com/svn/trunk@4646 2bbb7eff-a529-9590-31e7-b0007b416f81

src/gpu/gl/GrGLProgram.cpp
src/gpu/gl/GrGLProgram.h
src/gpu/gl/GrGpuGL.h
src/gpu/gl/GrGpuGL_program.cpp
src/gpu/gl/GrGpuGL_unittest.cpp

index 49cb1616528f183067b23ece084b8f048ecbabe8..52a4bd3b5c9c05d77da49c821703462106e8e289 100644 (file)
@@ -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) {
@@ -656,15 +695,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
 
@@ -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,
index 9381cfbe7dad3f047c3d55be9f71284272c270a9..6b6454d4dfd4ddbdd8ab43a69ee4c16b2d665cfe 100644 (file)
@@ -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.
 
index 5b33e0e47fdf0101239f4969301a62027b721ba8..fb78ad2973d83004f0ced624f4a449103e16ec07 100644 (file)
@@ -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,
index 7f982e724d231ef70137b0dbcf9e636ccef92d30..56a893dc3a464ccff1cc896635491996a309de8d 100644 (file)
@@ -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(){
index 9dd3e77178315f42d8d742d753e2f3f0a2f74989..e0aa5b56dcfb6f81811a899bdad07b9fd41a5919 100644 (file)
@@ -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;
 }