Merge GrGpuGLShaders into its parent class, GrGpuGL

Review URL: http://codereview.appspot.com/6245076/



git-svn-id: http://skia.googlecode.com/svn/trunk@4095 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/gpu/GrGpuFactory.cpp b/src/gpu/GrGpuFactory.cpp
index 319fc42..4a9bcf6 100644
--- a/src/gpu/GrGpuFactory.cpp
+++ b/src/gpu/GrGpuFactory.cpp
@@ -12,7 +12,7 @@
 #include "gl/GrGLConfig.h"
 
 #include "GrGpu.h"
-#include "gl/GrGpuGLShaders.h"
+#include "gl/GrGpuGL.h"
 
 GrGpu* GrGpu::Create(GrEngine engine, GrPlatform3DContext context3D) {
 
@@ -36,7 +36,7 @@
         }
         GrGLContextInfo ctxInfo(glInterface);
         if (ctxInfo.isInitialized()) {
-            return new GrGpuGLShaders(ctxInfo);
+            return new GrGpuGL(ctxInfo);
         }
     }
     return NULL;
diff --git a/src/gpu/gl/GrGLProgram.h b/src/gpu/gl/GrGLProgram.h
index be12b9c..189e876 100644
--- a/src/gpu/gl/GrGLProgram.h
+++ b/src/gpu/gl/GrGLProgram.h
@@ -410,7 +410,7 @@
     void getUniformLocationsAndInitCache(const GrGLContextInfo& gl,
                                          CachedData* programData) const;
 
-    friend class GrGpuGLShaders;
+    friend class GrGpuGL;
 };
 
 #endif
diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp
index 62dcb4f..b465a88 100644
--- a/src/gpu/gl/GrGpuGL.cpp
+++ b/src/gpu/gl/GrGpuGL.cpp
@@ -207,11 +207,26 @@
 
     this->initCaps();
 
+    this->createProgramCache();
+
+#if 0
+    this->programUnitTest();
+#endif
+
     fLastSuccessfulStencilFmtIdx = 0;
     fCanPreserveUnpremulRoundtrip = kUnknown_CanPreserveUnpremulRoundtrip;
 }
 
 GrGpuGL::~GrGpuGL() {
+    if (fProgramData && 0 != fHWProgramID) {
+        // detach the current program so there is no confusion on OpenGL's part
+        // that we want it to be deleted
+        GrAssert(fHWProgramID == fProgramData->fProgramID);
+        GL_CALL(UseProgram(0));
+    }
+
+    this->deleteProgramCache();
+
     // This must be called by before the GrDrawTarget destructor
     this->releaseGeometry();
     // This subclass must do this before the base class destructor runs
@@ -283,6 +298,26 @@
     fCaps.fMaxRenderTargetSize = GrMin(fCaps.fMaxTextureSize, fCaps.fMaxRenderTargetSize);
 
     fCaps.fFSAASupport = GrGLCaps::kNone_MSFBOType != this->glCaps().msFBOType();
+
+    // Enable supported shader-related caps
+    if (kDesktop_GrGLBinding == this->glBinding()) {
+        fCaps.fDualSourceBlendingSupport =
+                            this->glVersion() >= GR_GL_VER(3,3) ||
+                            this->hasExtension("GL_ARB_blend_func_extended");
+        fCaps.fShaderDerivativeSupport = true;
+        // we don't support GL_ARB_geometry_shader4, just GL 3.2+ GS
+        fCaps.fGeometryShaderSupport = 
+                                this->glVersion() >= GR_GL_VER(3,2) &&
+                                this->glslGeneration() >= k150_GrGLSLGeneration;
+    } else {
+        fCaps.fShaderDerivativeSupport =
+                            this->hasExtension("GL_OES_standard_derivatives");
+    }
+
+    GR_GL_GetIntegerv(this->glInterface(),
+                      GR_GL_MAX_VERTEX_ATTRIBS,
+                      &fMaxVertexAttribs);
+
 }
 
 void GrGpuGL::fillInConfigRenderableTable() {
@@ -530,6 +565,32 @@
     if (this->glCaps().packFlipYSupport()) {
         GL_CALL(PixelStorei(GR_GL_PACK_REVERSE_ROW_ORDER, GR_GL_FALSE));
     }
+
+    fHWGeometryState.fVertexOffset = ~0;
+
+    // Third party GL code may have left vertex attributes enabled. Some GL
+    // implementations (osmesa) may read vetex attributes that are not required
+    // by the current shader. Therefore, we have to ensure that only the
+    // attributes we require for the current draw are enabled or we may cause an
+    // invalid read.
+
+    // Disable all vertex layout bits so that next flush will assume all
+    // optional vertex attributes are disabled.
+    fHWGeometryState.fVertexLayout = 0;
+
+    // We always use the this attribute and assume it is always enabled.
+    int posAttrIdx = GrGLProgram::PositionAttributeIdx();
+    GL_CALL(EnableVertexAttribArray(posAttrIdx));
+    // Disable all other vertex attributes.
+    for  (int va = 0; va < fMaxVertexAttribs; ++va) {
+        if (va != posAttrIdx) {
+            GL_CALL(DisableVertexAttribArray(va));
+        }
+    }
+
+    fHWProgramID = 0;
+    fHWConstAttribColor = GrColor_ILLEGAL;
+    fHWConstAttribCoverage = GrColor_ILLEGAL;
 }
 
 GrTexture* GrGpuGL::onCreatePlatformTexture(const GrPlatformTextureDesc& desc) {
diff --git a/src/gpu/gl/GrGpuGL.h b/src/gpu/gl/GrGpuGL.h
index d255740..24d491d 100644
--- a/src/gpu/gl/GrGpuGL.h
+++ b/src/gpu/gl/GrGpuGL.h
@@ -15,12 +15,14 @@
 #include "GrGLContextInfo.h"
 #include "GrGLIndexBuffer.h"
 #include "GrGLIRect.h"
+#include "GrGLProgram.h"
 #include "GrGLStencilBuffer.h"
 #include "GrGLTexture.h"
 #include "GrGLVertexBuffer.h"
 
 class GrGpuGL : public GrGpu {
 public:
+    GrGpuGL(const GrGLContextInfo& ctxInfo);
     virtual ~GrGpuGL();
 
     const GrGLInterface* glInterface() const { 
@@ -47,8 +49,11 @@
 
     virtual bool canPreserveReadWriteUnpremulPixels() SK_OVERRIDE;
 
+    virtual void abandonResources() SK_OVERRIDE;
+
+    bool programUnitTest();
+
 protected:
-    GrGpuGL(const GrGLContextInfo& ctxInfo);
 
     enum TriState {
         kNo_TriState,
@@ -153,6 +158,12 @@
     virtual void clearStencil() SK_OVERRIDE;
     virtual void clearStencilClip(const GrIRect& rect,
                                   bool insideClip) SK_OVERRIDE;
+    virtual bool flushGraphicsState(GrPrimitiveType type) SK_OVERRIDE;
+    virtual void setupGeometry(int* startVertex,
+                               int* startIndex,
+                               int vertexCount,
+                               int indexCount) SK_OVERRIDE;
+
 
     // binds texture unit in GL
     void setTextureUnit(int unitIdx);
@@ -200,6 +211,52 @@
     static bool BlendCoeffReferencesConstant(GrBlendCoeff coeff);
 
 private:
+
+    // for readability of function impls
+    typedef GrGLProgram::ProgramDesc ProgramDesc;
+    typedef ProgramDesc::StageDesc   StageDesc;
+    typedef GrGLProgram::CachedData  CachedData;
+
+    class ProgramCache;
+
+    void createProgramCache();
+    void deleteProgramCache();
+
+    // sets the texture matrix uniform for currently bound program
+    void flushTextureMatrix(int stage);
+
+    // sets the texture domain uniform for currently bound program
+    void flushTextureDomain(int stage);
+
+    // sets the color specified by GrDrawState::setColor()
+    void flushColor(GrColor color);
+
+    // sets the color specified by GrDrawState::setCoverage()
+    void flushCoverage(GrColor color);
+
+    // sets the MVP matrix uniform for currently bound program
+    void flushViewMatrix();
+
+    // flushes the parameters to two point radial gradient
+    void flushRadial2(int stage);
+
+    // flushes the parameters for convolution
+    void flushConvolution(int stage);
+
+    // flushes the normalized texel size
+    void flushTexelSize(int stage);
+
+    // flushes the color matrix
+    void flushColorMatrix();
+
+    static void DeleteProgram(const GrGLInterface* gl,
+                              CachedData* programData);
+
+    void buildProgram(GrPrimitiveType typeBlend,
+                      BlendOptFlags blendOpts,
+                      GrBlendCoeff dstCoeff,
+                      GrCustomStage** customStages);
+
     // Inits GrDrawTarget::Caps, sublcass may enable additional caps.
     void initCaps();
 
@@ -251,6 +308,17 @@
 
     GrGLContextInfo fGLContextInfo;
 
+    // GL program-related state
+    ProgramCache*               fProgramCache;
+    CachedData*                 fProgramData;
+    GrGLuint                    fHWProgramID;
+    GrColor                     fHWConstAttribColor;
+    GrColor                     fHWConstAttribCoverage;
+    GrGLProgram                 fCurrentProgram;
+    // If we get rid of fixed function subclass this should move
+    // to the GLCaps struct in parent class
+    GrGLint                     fMaxVertexAttribs;
+
     int fActiveTextureUnitIdx;
 
     struct {
diff --git a/src/gpu/gl/GrGpuGLShaders.h b/src/gpu/gl/GrGpuGLShaders.h
deleted file mode 100644
index c7cdd2b..0000000
--- a/src/gpu/gl/GrGpuGLShaders.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright 2011 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-
-
-#ifndef GrGpuGLShaders_DEFINED
-#define GrGpuGLShaders_DEFINED
-
-#include "GrGpuGL.h"
-#include "GrGLProgram.h"
-
-class GrCustomStage;
-class GrGpuGLProgram;
-
-// Programmable OpenGL or OpenGL ES 2.0
-class GrGpuGLShaders : public GrGpuGL {
-public:
-             GrGpuGLShaders(const GrGLContextInfo& ctxInfo);
-    virtual ~GrGpuGLShaders();
-
-    virtual void abandonResources() SK_OVERRIDE;
-
-    bool programUnitTest();
-
-protected:
-    // overrides from GrGpu
-    virtual void onResetContext() SK_OVERRIDE;
-    virtual bool flushGraphicsState(GrPrimitiveType type) SK_OVERRIDE;
-    virtual void setupGeometry(int* startVertex,
-                               int* startIndex,
-                               int vertexCount,
-                               int indexCount) SK_OVERRIDE;
-
-private:
-
-    // for readability of function impls
-    typedef GrGLProgram::ProgramDesc ProgramDesc;
-    typedef ProgramDesc::StageDesc   StageDesc;
-    typedef GrGLProgram::CachedData  CachedData;
-
-    class ProgramCache;
-
-    // sets the texture matrix uniform for currently bound program
-    void flushTextureMatrix(int stage);
-
-    // sets the texture domain uniform for currently bound program
-    void flushTextureDomain(int stage);
-
-    // sets the color specified by GrDrawState::setColor()
-    void flushColor(GrColor color);
-
-    // sets the color specified by GrDrawState::setCoverage()
-    void flushCoverage(GrColor color);
-
-    // sets the MVP matrix uniform for currently bound program
-    void flushViewMatrix();
-
-    // flushes the parameters to two point radial gradient
-    void flushRadial2(int stage);
-
-    // flushes the parameters for convolution
-    void flushConvolution(int stage);
-
-    // flushes the normalized texel size
-    void flushTexelSize(int stage);
-
-    // flushes the color matrix
-    void flushColorMatrix();
-
-    static void DeleteProgram(const GrGLInterface* gl,
-                              CachedData* programData);
-
-    void buildProgram(GrPrimitiveType typeBlend,
-                      BlendOptFlags blendOpts,
-                      GrBlendCoeff dstCoeff,
-                      GrCustomStage** customStages);
-
-    ProgramCache*               fProgramCache;
-    CachedData*                 fProgramData;
-
-    GrGLuint                    fHWProgramID;
-    GrColor                     fHWConstAttribColor;
-    GrColor                     fHWConstAttribCoverage;
-
-    GrGLProgram                 fCurrentProgram;
-    // If we get rid of fixed function subclass this should move
-    // to the GLCaps struct in parent class
-    GrGLint                     fMaxVertexAttribs;
-
-    typedef GrGpuGL INHERITED;
-};
-
-#endif
-
diff --git a/src/gpu/gl/GrGpuGLShaders.cpp b/src/gpu/gl/GrGpuGL_program.cpp
similarity index 92%
rename from src/gpu/gl/GrGpuGLShaders.cpp
rename to src/gpu/gl/GrGpuGL_program.cpp
index 802574c..2ac26d5 100644
--- a/src/gpu/gl/GrGpuGLShaders.cpp
+++ b/src/gpu/gl/GrGpuGL_program.cpp
@@ -5,12 +5,11 @@
  * found in the LICENSE file.
  */
 
-#include "GrGpuGLShaders.h"
+#include "GrGpuGL.h"
 
 #include "GrBinHashKey.h"
 #include "effects/GrConvolutionEffect.h"
 #include "GrCustomStage.h"
-#include "GrGLProgram.h"
 #include "GrGLProgramStage.h"
 #include "GrGLSL.h"
 #include "GrGpuVertex.h"
@@ -24,7 +23,7 @@
 
 #include "../GrTHashCache.h"
 
-class GrGpuGLShaders::ProgramCache : public ::GrNoncopyable {
+class GrGpuGL::ProgramCache : public ::GrNoncopyable {
 private:
     class Entry;
 
@@ -69,7 +68,7 @@
 
     ~ProgramCache() {
         for (int i = 0; i < fCount; ++i) {
-            GrGpuGLShaders::DeleteProgram(fGL.interface(),
+            GrGpuGL::DeleteProgram(fGL.interface(),
                                           &fEntries[i].fProgramData);
         }
     }
@@ -107,7 +106,7 @@
                     }
                 }
                 fHashCache.remove(entry->fKey, entry);
-                GrGpuGLShaders::DeleteProgram(fGL.interface(),
+                GrGpuGL::DeleteProgram(fGL.interface(),
                                               &entry->fProgramData);
             }
             entry->copyAndTakeOwnership(newEntry);
@@ -126,13 +125,7 @@
     }
 };
 
-void GrGpuGLShaders::abandonResources(){
-    INHERITED::abandonResources();
-    fProgramCache->abandon();
-    fHWProgramID = 0;
-}
-
-void GrGpuGLShaders::DeleteProgram(const GrGLInterface* gl,
+void GrGpuGL::DeleteProgram(const GrGLInterface* gl,
                                    CachedData* programData) {
     GR_GL_CALL(gl, DeleteShader(programData->fVShaderID));
     if (programData->fGShaderID) {
@@ -145,6 +138,25 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 
+void GrGpuGL::createProgramCache() {
+    fProgramData = NULL;
+    fProgramCache = new ProgramCache(this->glContextInfo());
+}
+
+void GrGpuGL::deleteProgramCache() {
+    delete fProgramCache;
+    fProgramCache = NULL;
+    fProgramData = NULL;
+}
+
+void GrGpuGL::abandonResources(){
+    INHERITED::abandonResources();
+    fProgramCache->abandon();
+    fHWProgramID = 0;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
 #define GL_CALL(X) GR_GL_CALL(this->glInterface(), X)
 
 namespace {
@@ -166,7 +178,7 @@
 
 }
 
-bool GrGpuGLShaders::programUnitTest() {
+bool GrGpuGL::programUnitTest() {
 
     GrGLSLGeneration glslGeneration = 
             GrGetGLSLGeneration(this->glBinding(), this->glInterface());
@@ -315,78 +327,7 @@
     return true;
 }
 
-GrGpuGLShaders::GrGpuGLShaders(const GrGLContextInfo& ctxInfo)
-    : GrGpuGL(ctxInfo) {
-
-    // Enable supported shader-related caps
-    if (kDesktop_GrGLBinding == this->glBinding()) {
-        fCaps.fDualSourceBlendingSupport =
-                            this->glVersion() >= GR_GL_VER(3,3) ||
-                            this->hasExtension("GL_ARB_blend_func_extended");
-        fCaps.fShaderDerivativeSupport = true;
-        // we don't support GL_ARB_geometry_shader4, just GL 3.2+ GS
-        fCaps.fGeometryShaderSupport = 
-                                this->glVersion() >= GR_GL_VER(3,2) &&
-                                this->glslGeneration() >= k150_GrGLSLGeneration;
-    } else {
-        fCaps.fShaderDerivativeSupport =
-                            this->hasExtension("GL_OES_standard_derivatives");
-    }
-
-    GR_GL_GetIntegerv(this->glInterface(),
-                      GR_GL_MAX_VERTEX_ATTRIBS,
-                      &fMaxVertexAttribs);
-
-    fProgramData = NULL;
-    fProgramCache = new ProgramCache(this->glContextInfo());
-
-#if 0
-    this->programUnitTest();
-#endif
-}
-
-GrGpuGLShaders::~GrGpuGLShaders() {
-
-    if (fProgramData && 0 != fHWProgramID) {
-        // detach the current program so there is no confusion on OpenGL's part
-        // that we want it to be deleted
-        SkASSERT(fHWProgramID == fProgramData->fProgramID);
-        GL_CALL(UseProgram(0));
-    }
-    delete fProgramCache;
-}
-
-void GrGpuGLShaders::onResetContext() {
-    INHERITED::onResetContext();
-
-    fHWGeometryState.fVertexOffset = ~0;
-
-    // Third party GL code may have left vertex attributes enabled. Some GL
-    // implementations (osmesa) may read vetex attributes that are not required
-    // by the current shader. Therefore, we have to ensure that only the
-    // attributes we require for the current draw are enabled or we may cause an
-    // invalid read.
-
-    // Disable all vertex layout bits so that next flush will assume all
-    // optional vertex attributes are disabled.
-    fHWGeometryState.fVertexLayout = 0;
-
-    // We always use the this attribute and assume it is always enabled.
-    int posAttrIdx = GrGLProgram::PositionAttributeIdx();
-    GL_CALL(EnableVertexAttribArray(posAttrIdx));
-    // Disable all other vertex attributes.
-    for  (int va = 0; va < fMaxVertexAttribs; ++va) {
-        if (va != posAttrIdx) {
-            GL_CALL(DisableVertexAttribArray(va));
-        }
-    }
-
-    fHWProgramID = 0;
-    fHWConstAttribColor = GrColor_ILLEGAL;
-    fHWConstAttribCoverage = GrColor_ILLEGAL;
-}
-
-void GrGpuGLShaders::flushViewMatrix() {
+void GrGpuGL::flushViewMatrix() {
     const GrMatrix& vm = this->getDrawState().getViewMatrix();
     if (!fProgramData->fViewMatrix.cheapEqualTo(vm)) {
 
@@ -421,7 +362,7 @@
     }
 }
 
-void GrGpuGLShaders::flushTextureDomain(int s) {
+void GrGpuGL::flushTextureDomain(int s) {
     const GrGLint& uni = fProgramData->fUniLocations.fStages[s].fTexDomUni;
     const GrDrawState& drawState = this->getDrawState();
     if (GrGLProgram::kUnusedUniform != uni) {
@@ -457,7 +398,7 @@
     }
 }
 
-void GrGpuGLShaders::flushTextureMatrix(int s) {
+void GrGpuGL::flushTextureMatrix(int s) {
     const GrGLint& uni = fProgramData->fUniLocations.fStages[s].fTextureMatrixUni;
     const GrDrawState& drawState = this->getDrawState();
     const GrGLTexture* texture =
@@ -494,7 +435,7 @@
     }
 }
 
-void GrGpuGLShaders::flushRadial2(int s) {
+void GrGpuGL::flushRadial2(int s) {
 
     const int &uni = fProgramData->fUniLocations.fStages[s].fRadial2Uni;
     const GrSamplerState& sampler = this->getDrawState().getSampler(s);
@@ -528,7 +469,7 @@
     }
 }
 
-void GrGpuGLShaders::flushConvolution(int s) {
+void GrGpuGL::flushConvolution(int s) {
     const GrSamplerState& sampler = this->getDrawState().getSampler(s);
     int kernelUni = fProgramData->fUniLocations.fStages[s].fKernelUni;
     if (GrGLProgram::kUnusedUniform != kernelUni) {
@@ -554,7 +495,7 @@
     }
 }
 
-void GrGpuGLShaders::flushTexelSize(int s) {
+void GrGpuGL::flushTexelSize(int s) {
     const int& uni = fProgramData->fUniLocations.fStages[s].fNormalizedTexelSizeUni;
     if (GrGLProgram::kUnusedUniform != uni) {
         const GrGLTexture* texture =
@@ -571,7 +512,7 @@
     }
 }
 
-void GrGpuGLShaders::flushColorMatrix() {
+void GrGpuGL::flushColorMatrix() {
     const ProgramDesc& desc = fCurrentProgram.getDesc();
     int matrixUni = fProgramData->fUniLocations.fColorMatrixUni;
     int vecUni = fProgramData->fUniLocations.fColorMatrixVecUni;
@@ -602,7 +543,7 @@
     GrColorUnpackA(color) * ONE_OVER_255 \
 }
 
-void GrGpuGLShaders::flushColor(GrColor color) {
+void GrGpuGL::flushColor(GrColor color) {
     const ProgramDesc& desc = fCurrentProgram.getDesc();
     const GrDrawState& drawState = this->getDrawState();
 
@@ -651,7 +592,7 @@
     }
 }
 
-void GrGpuGLShaders::flushCoverage(GrColor coverage) {
+void GrGpuGL::flushCoverage(GrColor coverage) {
     const ProgramDesc& desc = fCurrentProgram.getDesc();
     const GrDrawState& drawState = this->getDrawState();
 
@@ -693,7 +634,7 @@
     }
 }
 
-bool GrGpuGLShaders::flushGraphicsState(GrPrimitiveType type) {
+bool GrGpuGL::flushGraphicsState(GrPrimitiveType type) {
     if (!flushGLStateCommon(type)) {
         return false;
     }
@@ -787,7 +728,7 @@
     #error "unknown GR_TEXT_SCALAR type"
 #endif
 
-void GrGpuGLShaders::setupGeometry(int* startVertex,
+void GrGpuGL::setupGeometry(int* startVertex,
                                     int* startIndex,
                                     int vertexCount,
                                     int indexCount) {
@@ -944,7 +885,7 @@
 
 }
 
-void GrGpuGLShaders::buildProgram(GrPrimitiveType type,
+void GrGpuGL::buildProgram(GrPrimitiveType type,
                                   BlendOptFlags blendOpts,
                                   GrBlendCoeff dstCoeff,
                                   GrCustomStage** customStages) {