diff options
-rw-r--r-- | gyp/gpu.gyp | 3 | ||||
-rw-r--r-- | src/effects/SkLightingImageFilter.cpp | 227 | ||||
-rw-r--r-- | src/gpu/effects/GrColorTableEffect.cpp | 6 | ||||
-rw-r--r-- | src/gpu/effects/GrConvolutionEffect.cpp | 37 | ||||
-rw-r--r-- | src/gpu/effects/GrGradientEffects.cpp | 51 | ||||
-rw-r--r-- | src/gpu/effects/GrMorphologyEffect.cpp | 26 | ||||
-rw-r--r-- | src/gpu/effects/GrSingleTextureEffect.cpp | 4 | ||||
-rw-r--r-- | src/gpu/effects/GrTextureDomainEffect.cpp | 36 | ||||
-rw-r--r-- | src/gpu/gl/GrGLProgram.cpp | 147 | ||||
-rw-r--r-- | src/gpu/gl/GrGLProgram.h | 64 | ||||
-rw-r--r-- | src/gpu/gl/GrGLProgramStage.cpp | 8 | ||||
-rw-r--r-- | src/gpu/gl/GrGLProgramStage.h | 8 | ||||
-rw-r--r-- | src/gpu/gl/GrGLShaderBuilder.cpp | 35 | ||||
-rw-r--r-- | src/gpu/gl/GrGLShaderBuilder.h | 41 | ||||
-rw-r--r-- | src/gpu/gl/GrGLUniformHandle.h | 16 | ||||
-rw-r--r-- | src/gpu/gl/GrGLUniformManager.cpp | 247 | ||||
-rw-r--r-- | src/gpu/gl/GrGLUniformManager.h | 76 | ||||
-rw-r--r-- | src/gpu/gl/GrGpuGL.h | 4 | ||||
-rw-r--r-- | src/gpu/gl/GrGpuGL_program.cpp | 54 |
19 files changed, 577 insertions, 513 deletions
diff --git a/gyp/gpu.gyp b/gyp/gpu.gyp index cff89d3676..6792db5856 100644 --- a/gyp/gpu.gyp +++ b/gyp/gpu.gyp @@ -332,6 +332,9 @@ '../src/gpu/gl/GrGLTexture.h', '../src/gpu/gl/GrGLUtil.cpp', '../src/gpu/gl/GrGLUtil.h', + '../src/gpu/gl/GrGLUniformManager.cpp', + '../src/gpu/gl/GrGLUniformManager.h', + '../src/gpu/gl/GrGLUniformHandle.h', '../src/gpu/gl/GrGLVertexBuffer.cpp', '../src/gpu/gl/GrGLVertexBuffer.h', '../src/gpu/gl/GrGpuGL.cpp', diff --git a/src/effects/SkLightingImageFilter.cpp b/src/effects/SkLightingImageFilter.cpp index 99a51d4bf6..21a553dd71 100644 --- a/src/effects/SkLightingImageFilter.cpp +++ b/src/effects/SkLightingImageFilter.cpp @@ -12,16 +12,15 @@ #include "GrProgramStageFactory.h" #include "effects/GrSingleTextureEffect.h" #include "gl/GrGLProgramStage.h" -#include "gl/GrGLSL.h" #include "gl/GrGLTexture.h" #include "GrCustomStage.h" class GrGLDiffuseLightingEffect; class GrGLSpecularLightingEffect; -// For brevity, and these definitions are likely to move to a different class soon. -typedef GrGLShaderBuilder::UniformHandle UniformHandle; -static const UniformHandle kInvalidUniformHandle = GrGLShaderBuilder::kInvalidUniformHandle; +// For brevity +typedef GrGLUniformManager::UniformHandle UniformHandle; +static const UniformHandle kInvalidUniformHandle = GrGLUniformManager::kInvalidUniformHandle; namespace { @@ -30,19 +29,21 @@ const SkScalar gTwoThirds = SkScalarDiv(SkIntToScalar(2), SkIntToScalar(3)); const SkScalar gOneHalf = SkFloatToScalar(0.5f); const SkScalar gOneQuarter = SkFloatToScalar(0.25f); -void setUniformPoint3(const GrGLInterface* gl, GrGLint location, const SkPoint3& point) { - float x = SkScalarToFloat(point.fX); - float y = SkScalarToFloat(point.fY); - float z = SkScalarToFloat(point.fZ); - GR_GL_CALL(gl, Uniform3f(location, x, y, z)); +void setUniformPoint3(const GrGLUniformManager& uman, UniformHandle uni, const SkPoint3& point) { + GR_STATIC_ASSERT(offsetof(SkPoint3, fX) + sizeof(float) == offsetof(SkPoint3, fY)); + GR_STATIC_ASSERT(offsetof(SkPoint3, fY) + sizeof(float) == offsetof(SkPoint3, fZ)); + uman.set3fv(uni, 0, 1, &point.fX); } -void setUniformNormal3(const GrGLInterface* gl, GrGLint location, const SkPoint3& point) { - setUniformPoint3(gl, location, SkPoint3(point.fX, -point.fY, point.fZ)); +void setUniformNormal3(const GrGLUniformManager& uman, UniformHandle uni, const SkPoint3& point) { + setUniformPoint3(uman, uni, SkPoint3(point.fX, -point.fY, point.fZ)); } -void setUniformPoint3FlipY(const GrGLInterface* gl, GrGLint location, const SkPoint3& point, int height) { - setUniformPoint3(gl, location, SkPoint3(point.fX, height-point.fY, point.fZ)); +void setUniformPoint3FlipY(const GrGLUniformManager& uman, + UniformHandle uni, + const SkPoint3& point, + int height) { + setUniformPoint3(uman, uni, SkPoint3(point.fX, height-point.fY, point.fZ)); } // Shift matrix components to the left, as we advance pixels to the right. @@ -370,15 +371,13 @@ public: virtual void emitLightColor(const GrGLShaderBuilder*, SkString* out, const char *surfaceToLight) const; - virtual void initUniforms(const GrGLShaderBuilder*, const GrGLInterface* gl, int programID); - virtual void setData(const GrGLInterface*, const GrRenderTarget* rt, const SkLight* light) const; + virtual void setData(const GrGLUniformManager&, const GrRenderTarget* rt, const SkLight* light) const; private: typedef SkRefCnt INHERITED; protected: UniformHandle fColorUni; - int fColorLocation; }; /////////////////////////////////////////////////////////////////////////////// @@ -387,18 +386,13 @@ class GrGLDistantLight : public GrGLLight { public: virtual ~GrGLDistantLight() {} virtual void setupVariables(GrGLShaderBuilder* builder, int stage) SK_OVERRIDE; - virtual void initUniforms(const GrGLShaderBuilder*, - const GrGLInterface* gl, - int programID) SK_OVERRIDE; - virtual void setData(const GrGLInterface* gl, const GrRenderTarget* rt, const SkLight* light) const SK_OVERRIDE; + virtual void setData(const GrGLUniformManager&, const GrRenderTarget* rt, const SkLight* light) const SK_OVERRIDE; virtual void emitSurfaceToLight(const GrGLShaderBuilder*, SkString* out, const char* z) const SK_OVERRIDE; - private: typedef GrGLLight INHERITED; UniformHandle fDirectionUni; - int fDirectionLocation; }; /////////////////////////////////////////////////////////////////////////////// @@ -407,20 +401,15 @@ class GrGLPointLight : public GrGLLight { public: virtual ~GrGLPointLight() {} virtual void setupVariables(GrGLShaderBuilder* builder, int stage) SK_OVERRIDE; - virtual void initUniforms(const GrGLShaderBuilder*, - const GrGLInterface*, - int programID) SK_OVERRIDE; - virtual void setData(const GrGLInterface* gl, const GrRenderTarget* rt, const SkLight* light) const SK_OVERRIDE; + virtual void setData(const GrGLUniformManager&, const GrRenderTarget* rt, const SkLight* light) const SK_OVERRIDE; virtual void emitVS(SkString* out) const SK_OVERRIDE; virtual void emitSurfaceToLight(const GrGLShaderBuilder*, SkString* out, const char* z) const SK_OVERRIDE; - private: typedef GrGLLight INHERITED; SkPoint3 fLocation; UniformHandle fLocationUni; - int fLocationLocation; }; /////////////////////////////////////////////////////////////////////////////// @@ -429,10 +418,7 @@ class GrGLSpotLight : public GrGLLight { public: virtual ~GrGLSpotLight() {} virtual void setupVariables(GrGLShaderBuilder* builder, int stage) SK_OVERRIDE; - virtual void initUniforms(const GrGLShaderBuilder* builder, - const GrGLInterface* gl, - int programID) SK_OVERRIDE; - virtual void setData(const GrGLInterface* gl, const GrRenderTarget* rt, const SkLight* light) const SK_OVERRIDE; + virtual void setData(const GrGLUniformManager&, const GrRenderTarget* rt, const SkLight* light) const SK_OVERRIDE; virtual void emitVS(SkString* out) const SK_OVERRIDE; virtual void emitFuncs(const GrGLShaderBuilder* builder, SkString* out) const; virtual void emitSurfaceToLight(const GrGLShaderBuilder* builder, @@ -446,17 +432,11 @@ private: typedef GrGLLight INHERITED; UniformHandle fLocationUni; - int fLocationLocation; UniformHandle fExponentUni; - int fExponentLocation; UniformHandle fCosOuterConeAngleUni; - int fCosOuterConeAngleLocation; UniformHandle fCosInnerConeAngleUni; - int fCosInnerConeAngleLocation; UniformHandle fConeScaleUni; - int fConeScaleLocation; UniformHandle fSUni; - int fSLocation; }; }; @@ -903,10 +883,7 @@ public: static inline StageKey GenKey(const GrCustomStage& s); - virtual void initUniforms(const GrGLShaderBuilder* builder, - const GrGLInterface*, - int programID) SK_OVERRIDE; - virtual void setData(const GrGLInterface*, + virtual void setData(const GrGLUniformManager&, const GrCustomStage&, const GrRenderTarget*, int stageNum) SK_OVERRIDE; @@ -915,9 +892,7 @@ private: typedef GrGLProgramStage INHERITED; UniformHandle fImageIncrementUni; - GrGLint fImageIncrementLocation; UniformHandle fSurfaceScaleUni; - GrGLint fSurfaceScaleLocation; GrGLLight* fLight; }; @@ -930,10 +905,7 @@ public: virtual void setupVariables(GrGLShaderBuilder* builder, int stage) SK_OVERRIDE; virtual void emitLightFunc(const GrGLShaderBuilder*, SkString* funcs) SK_OVERRIDE; - virtual void initUniforms(const GrGLShaderBuilder*, - const GrGLInterface*, - int programID) SK_OVERRIDE; - virtual void setData(const GrGLInterface*, + virtual void setData(const GrGLUniformManager&, const GrCustomStage&, const GrRenderTarget*, int stageNum) SK_OVERRIDE; @@ -942,7 +914,6 @@ private: typedef GrGLLightingEffect INHERITED; UniformHandle fKDUni; - GrGLint fKDLocation; }; /////////////////////////////////////////////////////////////////////////////// @@ -954,10 +925,7 @@ public: virtual void setupVariables(GrGLShaderBuilder* builder, int stage) SK_OVERRIDE; virtual void emitLightFunc(const GrGLShaderBuilder*, SkString* funcs) SK_OVERRIDE; - virtual void initUniforms(const GrGLShaderBuilder*, - const GrGLInterface*, - int programID) SK_OVERRIDE; - virtual void setData(const GrGLInterface*, + virtual void setData(const GrGLUniformManager&, const GrCustomStage&, const GrRenderTarget*, int stageNum) SK_OVERRIDE; @@ -966,9 +934,7 @@ private: typedef GrGLLightingEffect INHERITED; UniformHandle fKSUni; - GrGLint fKSLocation; UniformHandle fShininessUni; - GrGLint fShininessLocation; }; /////////////////////////////////////////////////////////////////////////////// @@ -1015,9 +981,7 @@ GrGLLightingEffect::GrGLLightingEffect(const GrProgramStageFactory& factory, const GrCustomStage& stage) : GrGLProgramStage(factory) , fImageIncrementUni(kInvalidUniformHandle) - , fImageIncrementLocation(0) - , fSurfaceScaleUni(kInvalidUniformHandle) - , fSurfaceScaleLocation(0) { + , fSurfaceScaleUni(kInvalidUniformHandle) { const GrLightingEffect& m = static_cast<const GrLightingEffect&>(stage); fLight = m.light()->createGLLight(); } @@ -1041,17 +1005,6 @@ void GrGLLightingEffect::emitVS(GrGLShaderBuilder* builder, fLight->emitVS(&builder->fVSCode); } -void GrGLLightingEffect::initUniforms(const GrGLShaderBuilder* builder, - const GrGLInterface* gl, - int programID) { - const char* imgInc = builder->getUniformCStr(fImageIncrementUni); - const char* surfScale = builder->getUniformCStr(fSurfaceScaleUni); - - GR_GL_CALL_RET(gl, fSurfaceScaleLocation, GetUniformLocation(programID, surfScale)); - GR_GL_CALL_RET(gl, fImageIncrementLocation, GetUniformLocation(programID, imgInc)); - fLight->initUniforms(builder, gl, programID); -} - void GrGLLightingEffect::emitFS(GrGLShaderBuilder* builder, const char* outputColor, const char* inputColor, @@ -1103,7 +1056,7 @@ GrGLProgramStage::StageKey GrGLLightingEffect::GenKey( return static_cast<const GrLightingEffect&>(s).light()->type(); } -void GrGLLightingEffect::setData(const GrGLInterface* gl, +void GrGLLightingEffect::setData(const GrGLUniformManager& uman, const GrCustomStage& data, const GrRenderTarget* rt, int stageNum) { @@ -1111,9 +1064,9 @@ void GrGLLightingEffect::setData(const GrGLInterface* gl, static_cast<const GrLightingEffect&>(data); GrGLTexture* texture = static_cast<GrGLTexture*>(data.texture(0)); float ySign = texture->orientation() == GrGLTexture::kTopDown_Orientation ? -1.0f : 1.0f; - GR_GL_CALL(gl, Uniform2f(fImageIncrementLocation, 1.0f / texture->width(), ySign / texture->height())); - GR_GL_CALL(gl, Uniform1f(fSurfaceScaleLocation, effect.surfaceScale())); - fLight->setData(gl, rt, effect.light()); + uman.set2f(fImageIncrementUni, 1.0f / texture->width(), ySign / texture->height()); + uman.set1f(fSurfaceScaleUni, effect.surfaceScale()); + fLight->setData(uman, rt, effect.light()); } /////////////////////////////////////////////////////////////////////////////// @@ -1123,8 +1076,7 @@ void GrGLLightingEffect::setData(const GrGLInterface* gl, GrGLDiffuseLightingEffect::GrGLDiffuseLightingEffect(const GrProgramStageFactory& factory, const GrCustomStage& stage) : INHERITED(factory, stage) - , fKDUni(kInvalidUniformHandle) - , fKDLocation(0) { + , fKDUni(kInvalidUniformHandle) { } void GrGLDiffuseLightingEffect::setupVariables(GrGLShaderBuilder* builder, int stage) { @@ -1133,14 +1085,6 @@ void GrGLDiffuseLightingEffect::setupVariables(GrGLShaderBuilder* builder, int s stage); } -void GrGLDiffuseLightingEffect::initUniforms(const GrGLShaderBuilder* builder, - const GrGLInterface* gl, - int programID) { - INHERITED::initUniforms(builder, gl, programID); - const char* kd = builder->getUniformCStr(fKDUni); - GR_GL_CALL_RET(gl, fKDLocation, GetUniformLocation(programID, kd)); -} - void GrGLDiffuseLightingEffect::emitLightFunc(const GrGLShaderBuilder* builder, SkString* funcs) { const char* kd = builder->getUniformCStr(fKDUni); funcs->appendf("vec4 light(vec3 normal, vec3 surfaceToLight, vec3 lightColor) {\n"); @@ -1149,14 +1093,14 @@ void GrGLDiffuseLightingEffect::emitLightFunc(const GrGLShaderBuilder* builder, funcs->appendf("}\n"); } -void GrGLDiffuseLightingEffect::setData(const GrGLInterface* gl, +void GrGLDiffuseLightingEffect::setData(const GrGLUniformManager& uman, const GrCustomStage& data, const GrRenderTarget* rt, int stageNum) { - INHERITED::setData(gl, data, rt, stageNum); + INHERITED::setData(uman, data, rt, stageNum); const GrDiffuseLightingEffect& effect = static_cast<const GrDiffuseLightingEffect&>(data); - GR_GL_CALL(gl, Uniform1f(fKDLocation, effect.kd())); + uman.set1f(fKDUni, effect.kd()); } /////////////////////////////////////////////////////////////////////////////// @@ -1185,9 +1129,7 @@ GrGLSpecularLightingEffect::GrGLSpecularLightingEffect(const GrProgramStageFacto const GrCustomStage& stage) : GrGLLightingEffect(factory, stage) , fKSUni(kInvalidUniformHandle) - , fKSLocation(0) - , fShininessUni(kInvalidUniformHandle) - , fShininessLocation(0) { + , fShininessUni(kInvalidUniformHandle) { } void GrGLSpecularLightingEffect::setupVariables(GrGLShaderBuilder* builder, int stage) { @@ -1198,16 +1140,6 @@ void GrGLSpecularLightingEffect::setupVariables(GrGLShaderBuilder* builder, int kFloat_GrSLType, "uShininess", stage); } -void GrGLSpecularLightingEffect::initUniforms(const GrGLShaderBuilder* builder, - const GrGLInterface* gl, - int programID) { - INHERITED::initUniforms(builder, gl, programID); - const char* ks = builder->getUniformCStr(fKSUni); - const char* shininess = builder->getUniformCStr(fShininessUni); - GR_GL_CALL_RET(gl, fKSLocation, GetUniformLocation(programID, ks)); - GR_GL_CALL_RET(gl, fShininessLocation, GetUniformLocation(programID, shininess)); -} - void GrGLSpecularLightingEffect::emitLightFunc(const GrGLShaderBuilder* builder, SkString* funcs) { funcs->appendf("vec4 light(vec3 normal, vec3 surfaceToLight, vec3 lightColor) {\n"); funcs->appendf("\tvec3 halfDir = vec3(normalize(surfaceToLight + vec3(0, 0, 1)));\n"); @@ -1219,15 +1151,14 @@ void GrGLSpecularLightingEffect::emitLightFunc(const GrGLShaderBuilder* builder, funcs->appendf("}\n"); } -void GrGLSpecularLightingEffect::setData(const GrGLInterface* gl, +void GrGLSpecularLightingEffect::setData(const GrGLUniformManager& uman, const GrCustomStage& data, const GrRenderTarget* rt, int stageNum) { - INHERITED::setData(gl, data, rt, stageNum); - const GrSpecularLightingEffect& effect = - static_cast<const GrSpecularLightingEffect&>(data); - GR_GL_CALL(gl, Uniform1f(fKSLocation, effect.ks())); - GR_GL_CALL(gl, Uniform1f(fShininessLocation, effect.shininess())); + INHERITED::setData(uman, data, rt, stageNum); + const GrSpecularLightingEffect& effect = static_cast<const GrSpecularLightingEffect&>(data); + uman.set1f(fKSUni, effect.ks()); + uman.set1f(fShininessUni, effect.shininess()); } /////////////////////////////////////////////////////////////////////////////// @@ -1244,15 +1175,10 @@ void GrGLLight::setupVariables(GrGLShaderBuilder* builder, int stage) { kVec3f_GrSLType, "uLightColor", stage); } -void GrGLLight::initUniforms(const GrGLShaderBuilder* builder, - const GrGLInterface* gl, - int programID) { - const char* color = builder->getUniformCStr(fColorUni); - GR_GL_CALL_RET(gl, fColorLocation, GetUniformLocation(programID, color)); -} - -void GrGLLight::setData(const GrGLInterface* gl, const GrRenderTarget* rt, const SkLight* light) const { - setUniformPoint3(gl, fColorLocation, light->color() * SkScalarInvert(SkIntToScalar(255))); +void GrGLLight::setData(const GrGLUniformManager& uman, + const GrRenderTarget* rt, + const SkLight* light) const { + setUniformPoint3(uman, fColorUni, light->color() * SkScalarInvert(SkIntToScalar(255))); } GrGLLight* SkDistantLight::createGLLight() const { @@ -1267,19 +1193,13 @@ void GrGLDistantLight::setupVariables(GrGLShaderBuilder* builder, int stage) { "uLightDirection", stage); } -void GrGLDistantLight::initUniforms(const GrGLShaderBuilder* builder, - const GrGLInterface* gl, - int programID) { - INHERITED::initUniforms(builder, gl, programID); - const char* dir = builder->getUniformCStr(fDirectionUni); - GR_GL_CALL_RET(gl, fDirectionLocation, GetUniformLocation(programID, dir)); -} - -void GrGLDistantLight::setData(const GrGLInterface* gl, const GrRenderTarget* rt, const SkLight* light) const { - INHERITED::setData(gl, rt, light); +void GrGLDistantLight::setData(const GrGLUniformManager& uman, + const GrRenderTarget* rt, + const SkLight* light) const { + INHERITED::setData(uman, rt, light); SkASSERT(light->type() == SkLight::kDistant_LightType); const SkDistantLight* distantLight = static_cast<const SkDistantLight*>(light); - setUniformNormal3(gl, fDirectionLocation, distantLight->direction()); + setUniformNormal3(uman, fDirectionUni, distantLight->direction()); } void GrGLDistantLight::emitSurfaceToLight(const GrGLShaderBuilder* builder, @@ -1297,28 +1217,23 @@ void GrGLPointLight::setupVariables(GrGLShaderBuilder* builder, int stage) { "uLightLocation", stage); } -void GrGLPointLight::initUniforms(const GrGLShaderBuilder* builder, - const GrGLInterface* gl, - int programID) { - INHERITED::initUniforms(builder, gl, programID); - const char* loc = builder->getUniformCStr(fLocationUni); - GR_GL_CALL_RET(gl, fLocationLocation, GetUniformLocation(programID, loc)); -} - -void GrGLPointLight::setData(const GrGLInterface* gl, const GrRenderTarget* rt, const SkLight* light) const { - INHERITED::setData(gl, rt, light); +void GrGLPointLight::setData(const GrGLUniformManager& uman, + const GrRenderTarget* rt, + const SkLight* light) const { + INHERITED::setData(uman, rt, light); SkASSERT(light->type() == SkLight::kPoint_LightType); const SkPointLight* pointLight = static_cast<const SkPointLight*>(light); - setUniformPoint3FlipY(gl, fLocationLocation, pointLight->location(), rt->height()); + setUniformPoint3FlipY(uman, fLocationUni, pointLight->location(), rt->height()); } void GrGLPointLight::emitVS(SkString* out) const { } -void GrGLPointLight::emitSurfaceToLight(const GrGLShaderBuilder* builder, SkString* out, const char* z) const { +void GrGLPointLight::emitSurfaceToLight(const GrGLShaderBuilder* builder, + SkString* out, + const char* z) const { const char* loc = builder->getUniformCStr(fLocationUni); - out->appendf( - "normalize(%s - vec3(gl_FragCoord.xy, %s))", loc, z); + out->appendf("normalize(%s - vec3(gl_FragCoord.xy, %s))", loc, z); } /////////////////////////////////////////////////////////////////////////////// @@ -1339,32 +1254,18 @@ void GrGLSpotLight::setupVariables(GrGLShaderBuilder* builder, int stage) { kVec3f_GrSLType, "uS", stage); } -void GrGLSpotLight::initUniforms(const GrGLShaderBuilder* builder, const GrGLInterface* gl, int programID) { - INHERITED::initUniforms(builder, gl, programID); - const char* location = builder->getUniformCStr(fLocationUni); - const char* exponent = builder->getUniformCStr(fExponentUni); - const char* cosInner = builder->getUniformCStr(fCosInnerConeAngleUni); - const char* cosOuter = builder->getUniformCStr(fCosOuterConeAngleUni); - const char* coneScale = builder->getUniformCStr(fConeScaleUni); - const char* s = builder->getUniformCStr(fSUni); - GR_GL_CALL_RET(gl, fLocationLocation, GetUniformLocation(programID, location)); - GR_GL_CALL_RET(gl, fExponentLocation, GetUniformLocation(programID, exponent)); - GR_GL_CALL_RET(gl, fCosInnerConeAngleLocation, GetUniformLocation(programID, cosInner)); - GR_GL_CALL_RET(gl, fCosOuterConeAngleLocation, GetUniformLocation(programID, cosOuter)); - GR_GL_CALL_RET(gl, fConeScaleLocation, GetUniformLocation(programID, coneScale)); - GR_GL_CALL_RET(gl, fSLocation, GetUniformLocation(programID, s)); -} - -void GrGLSpotLight::setData(const GrGLInterface* gl, const GrRenderTarget* rt, const SkLight* light) const { - INHERITED::setData(gl, rt, light); +void GrGLSpotLight::setData(const GrGLUniformManager& uman, + const GrRenderTarget* rt, + const SkLight* light) const { + INHERITED::setData(uman, rt, light); SkASSERT(light->type() == SkLight::kSpot_LightType); const SkSpotLight* spotLight = static_cast<const SkSpotLight *>(light); - setUniformPoint3FlipY(gl, fLocationLocation, spotLight->location(), rt->height()); - GR_GL_CALL(gl, Uniform1f(fExponentLocation, spotLight->specularExponent())); - GR_GL_CALL(gl, Uniform1f(fCosInnerConeAngleLocation, spotLight->cosInnerConeAngle())); - GR_GL_CALL(gl, Uniform1f(fCosOuterConeAngleLocation, spotLight->cosOuterConeAngle())); - GR_GL_CALL(gl, Uniform1f(fConeScaleLocation, spotLight->coneScale())); - setUniformNormal3(gl, fSLocation, spotLight->s()); + setUniformPoint3FlipY(uman, fLocationUni, spotLight->location(), rt->height()); + uman.set1f(fExponentUni, spotLight->specularExponent()); + uman.set1f(fCosInnerConeAngleUni, spotLight->cosInnerConeAngle()); + uman.set1f(fCosOuterConeAngleUni, spotLight->cosOuterConeAngle()); + uman.set1f(fConeScaleUni, spotLight->coneScale()); + setUniformNormal3(uman, fSUni, spotLight->s()); } void GrGLSpotLight::emitVS(SkString* out) const { diff --git a/src/gpu/effects/GrColorTableEffect.cpp b/src/gpu/effects/GrColorTableEffect.cpp index 8ea0dbffc2..f047a3e522 100644 --- a/src/gpu/effects/GrColorTableEffect.cpp +++ b/src/gpu/effects/GrColorTableEffect.cpp @@ -26,11 +26,7 @@ public: const char* inputColor, const char* samplerName) SK_OVERRIDE; - virtual void initUniforms(const GrGLShaderBuilder*, - const GrGLInterface*, - int programID) SK_OVERRIDE {} - - virtual void setData(const GrGLInterface*, + virtual void setData(const GrGLUniformManager&, const GrCustomStage&, const GrRenderTarget*, int stageNum) SK_OVERRIDE {} diff --git a/src/gpu/effects/GrConvolutionEffect.cpp b/src/gpu/effects/GrConvolutionEffect.cpp index a16313eac8..f01caa3901 100644 --- a/src/gpu/effects/GrConvolutionEffect.cpp +++ b/src/gpu/effects/GrConvolutionEffect.cpp @@ -11,9 +11,9 @@ #include "gl/GrGLTexture.h" #include "GrProgramStageFactory.h" -// For brevity, and these definitions are likely to move to a different class soon. -typedef GrGLShaderBuilder::UniformHandle UniformHandle; -static const UniformHandle kInvalidUniformHandle = GrGLShaderBuilder::kInvalidUniformHandle; +// For brevity +typedef GrGLUniformManager::UniformHandle UniformHandle; +static const UniformHandle kInvalidUniformHandle = GrGLUniformManager::kInvalidUniformHandle; class GrGLConvolutionEffect : public GrGLProgramStage { public: @@ -29,11 +29,7 @@ public: const char* inputColor, const char* samplerName) SK_OVERRIDE; - virtual void initUniforms(const GrGLShaderBuilder*, - const GrGLInterface*, - int programID) SK_OVERRIDE; - - virtual void setData(const GrGLInterface*, + virtual void setData(const GrGLUniformManager& uman, const GrCustomStage&, const GrRenderTarget*, int stageNum) SK_OVERRIDE; @@ -45,9 +41,7 @@ private: int fRadius; UniformHandle fKernelUni; - GrGLint fKernelLocation; UniformHandle fImageIncrementUni; - GrGLint fImageIncrementLocation; typedef GrGLProgramStage INHERITED; }; @@ -56,9 +50,7 @@ GrGLConvolutionEffect::GrGLConvolutionEffect(const GrProgramStageFactory& factor const GrCustomStage& stage) : GrGLProgramStage(factory) , fKernelUni(kInvalidUniformHandle) - , fKernelLocation(0) - , fImageIncrementUni(kInvalidUniformHandle) - , fImageIncrementLocation(0) { + , fImageIncrementUni(kInvalidUniformHandle) { const GrConvolutionEffect& c = static_cast<const GrConvolutionEffect&>(stage); fRadius = c.radius(); @@ -71,9 +63,6 @@ void GrGLConvolutionEffect::setupVariables(GrGLShaderBuilder* builder, kVec2f_GrSLType, "uImageIncrement", stage); fKernelUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, kFloat_GrSLType, "uKernel", stage, this->width()); - - fImageIncrementLocation = kUseUniform; - fKernelLocation = kUseUniform; } void GrGLConvolutionEffect::emitVS(GrGLShaderBuilder* builder, @@ -114,16 +103,7 @@ void GrGLConvolutionEffect::emitFS(GrGLShaderBuilder* builder, } } -void GrGLConvolutionEffect::initUniforms(const GrGLShaderBuilder* builder, - const GrGLInterface* gl, - int programID) { - const char* kernel = builder->getUniformCStr(fKernelUni); - const char* imgInc = builder->getUniformCStr(fImageIncrementUni); - GR_GL_CALL_RET(gl, fImageIncrementLocation, GetUniformLocation(programID, imgInc)); - GR_GL_CALL_RET(gl, fKernelLocation, GetUniformLocation(programID, kernel)); -} - -void GrGLConvolutionEffect::setData(const GrGLInterface* gl, +void GrGLConvolutionEffect::setData(const GrGLUniformManager& uman, const GrCustomStage& data, const GrRenderTarget*, int stageNum) { @@ -143,9 +123,8 @@ void GrGLConvolutionEffect::setData(const GrGLInterface* gl, default: GrCrash("Unknown filter direction."); } - GR_GL_CALL(gl, Uniform2fv(fImageIncrementLocation, 1, imageIncrement)); - - GR_GL_CALL(gl, Uniform1fv(fKernelLocation, this->width(), conv.kernel())); + uman.set2fv(fImageIncrementUni, 0, 1, imageIncrement); + uman.set1fv(fKernelUni, 0, this->width(), conv.kernel()); } GrGLProgramStage::StageKey GrGLConvolutionEffect::GenKey( diff --git a/src/gpu/effects/GrGradientEffects.cpp b/src/gpu/effects/GrGradientEffects.cpp index 34bff09fa6..3769e21e59 100644 --- a/src/gpu/effects/GrGradientEffects.cpp +++ b/src/gpu/effects/GrGradientEffects.cpp @@ -202,9 +202,9 @@ const GrProgramStageFactory& GrRadialGradient::getFactory() const { ///////////////////////////////////////////////////////////////////// -// For brevity, and these definitions are likely to move to a different class soon. -typedef GrGLShaderBuilder::UniformHandle UniformHandle; -static const UniformHandle kInvalidUniformHandle = GrGLShaderBuilder::kInvalidUniformHandle; +// For brevity +typedef GrGLUniformManager::UniformHandle UniformHandle; +static const UniformHandle kInvalidUniformHandle = GrGLUniformManager::kInvalidUniformHandle; class GrGLRadial2Gradient : public GrGLGradientStage { @@ -222,10 +222,7 @@ public: const char* outputColor, const char* inputColor, const char* samplerName) SK_OVERRIDE; - virtual void initUniforms(const GrGLShaderBuilder* builder, - const GrGLInterface*, - int programID) SK_OVERRIDE; - virtual void setData(const GrGLInterface*, + virtual void setData(const GrGLUniformManager&, const GrCustomStage&, const GrRenderTarget*, int stageNum) SK_OVERRIDE; @@ -237,9 +234,7 @@ public: protected: UniformHandle fVSParamUni; - GrGLint fVSParamLocation; UniformHandle fFSParamUni; - GrGLint fFSParamLocation; const char* fVSVaryingName; const char* fFSVaryingName; @@ -287,9 +282,6 @@ void GrGLRadial2Gradient::setupVariables(GrGLShaderBuilder* builder, int stage) fFSParamUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, kFloat_GrSLType, "uRadial2FSParams", stage, 6); - fVSParamLocation = GrGLProgramStage::kUseUniform; - fFSParamLocation = GrGLProgramStage::kUseUniform; - // For radial gradients without perspective we can pass the linear // part of the quadratic as a varying. if (builder->fVaryingDims == builder->fCoordDims) { @@ -385,16 +377,7 @@ void GrGLRadial2Gradient::emitFS(GrGLShaderBuilder* builder, this->emitColorLookup(builder, t.c_str(), outputColor, samplerName); } -void GrGLRadial2Gradient::initUniforms(const GrGLShaderBuilder* builder, - const GrGLInterface* gl, - int programID) { - const char* vsParam = builder->getUniformCStr(fVSParamUni); - const char* fsParam = builder->getUniformCStr(fFSParamUni); - GR_GL_CALL_RET(gl, fVSParamLocation, GetUniformLocation(programID, vsParam)); - GR_GL_CALL_RET(gl, fFSParamLocation, GetUniformLocation(programID, fsParam)); -} - -void GrGLRadial2Gradient::setData(const GrGLInterface* gl, +void GrGLRadial2Gradient::setData(const GrGLUniformManager& uman, const GrCustomStage& baseData, const GrRenderTarget*, int stageNum) { @@ -423,8 +406,8 @@ void GrGLRadial2Gradient::setData(const GrGLInterface* gl, data.isPosRoot() ? 1.f : -1.f }; - GR_GL_CALL(gl, Uniform1fv(fVSParamLocation, 6, values)); - GR_GL_CALL(gl, Uniform1fv(fFSParamLocation, 6, values)); + uman.set1fv(fVSParamUni, 0, 6, values); + uman.set1fv(fFSParamUni, 0, 6, values); fCachedCenter = centerX1; fCachedRadius = radius0; fCachedPosRoot = data.isPosRoot(); @@ -492,10 +475,7 @@ public: const char* outputColor, const char* inputColor, const char* samplerName) SK_OVERRIDE; - virtual void initUniforms(const GrGLShaderBuilder* builder, - const GrGLInterface*, - int programID) SK_OVERRIDE; - virtual void setData(const GrGLInterface*, + virtual void setData(const GrGLUniformManager&, const GrCustomStage&, const GrRenderTarget*, int stageNum) SK_OVERRIDE; @@ -713,16 +693,7 @@ void GrGLConical2Gradient::emitFS(GrGLShaderBuilder* builder, } } -void GrGLConical2Gradient::initUniforms(const GrGLShaderBuilder* builder, - const GrGLInterface* gl, - int programID) { - const char* vsParam = builder->getUniformCStr(fVSParamUni); - const char* fsParam = builder->getUniformCStr(fFSParamUni); - GR_GL_CALL_RET(gl, fVSParamLocation, GetUniformLocation(programID, vsParam)); - GR_GL_CALL_RET(gl, fFSParamLocation, GetUniformLocation(programID, fsParam)); -} - -void GrGLConical2Gradient::setData(const GrGLInterface* gl, +void GrGLConical2Gradient::setData(const GrGLUniformManager& uman, const GrCustomStage& baseData, const GrRenderTarget*, int stageNum) { @@ -753,8 +724,8 @@ void GrGLConical2Gradient::setData(const GrGLInterface* gl, GrScalarToFloat(diffRadius) }; - GR_GL_CALL(gl, Uniform1fv(fVSParamLocation, 6, values)); - GR_GL_CALL(gl, Uniform1fv(fFSParamLocation, 6, values)); + uman.set1fv(fVSParamUni, 0, 6, values); + uman.set1fv(fFSParamUni, 0, 6, values); fCachedCenter = centerX1; fCachedRadius = radius0; fCachedDiffRadius = diffRadius; diff --git a/src/gpu/effects/GrMorphologyEffect.cpp b/src/gpu/effects/GrMorphologyEffect.cpp index 6699989f04..22c986ab68 100644 --- a/src/gpu/effects/GrMorphologyEffect.cpp +++ b/src/gpu/effects/GrMorphologyEffect.cpp @@ -29,10 +29,7 @@ public: static inline StageKey GenKey(const GrCustomStage& s); - virtual void initUniforms(const GrGLShaderBuilder*, - const GrGLInterface*, - int programID) SK_OVERRIDE; - virtual void setData(const GrGLInterface*, + virtual void setData(const GrGLUniformManager&, const GrCustomStage&, const GrRenderTarget*, int stageNum) SK_OVERRIDE; @@ -40,10 +37,9 @@ public: private: int width() const { return GrMorphologyEffect::WidthFromRadius(fRadius); } - int fRadius; - GrMorphologyEffect::MorphologyType fType; - GrGLShaderBuilder::UniformHandle fImageIncrementUni; - GrGLint fImageIncrementLocation; + int fRadius; + GrMorphologyEffect::MorphologyType fType; + GrGLUniformManager::UniformHandle fImageIncrementUni; typedef GrGLProgramStage INHERITED; }; @@ -51,8 +47,7 @@ private: GrGLMorphologyEffect ::GrGLMorphologyEffect(const GrProgramStageFactory& factory, const GrCustomStage& stage) : GrGLProgramStage(factory) - , fImageIncrementUni(GrGLShaderBuilder::kInvalidUniformHandle) - , fImageIncrementLocation(0) { + , fImageIncrementUni(GrGLUniformManager::kInvalidUniformHandle) { const GrMorphologyEffect& m = static_cast<const GrMorphologyEffect&>(stage); fRadius = m.radius(); fType = m.type(); @@ -71,13 +66,6 @@ void GrGLMorphologyEffect::emitVS(GrGLShaderBuilder* builder, code->appendf("\t\t%s -= vec2(%d, %d) * %s;\n", vertexCoords, fRadius, fRadius, imgInc); } -void GrGLMorphologyEffect::initUniforms(const GrGLShaderBuilder* builder, - const GrGLInterface* gl, - int programID) { - const char* imgInc = builder->getUniformCStr(fImageIncrementUni); - GR_GL_CALL_RET(gl, fImageIncrementLocation, GetUniformLocation(programID, imgInc)); -} - void GrGLMorphologyEffect ::emitFS(GrGLShaderBuilder* builder, const char* outputColor, const char* inputColor, @@ -119,7 +107,7 @@ GrGLProgramStage::StageKey GrGLMorphologyEffect::GenKey( return key; } -void GrGLMorphologyEffect ::setData(const GrGLInterface* gl, +void GrGLMorphologyEffect ::setData(const GrGLUniformManager& uman, const GrCustomStage& data, const GrRenderTarget*, int stageNum) { @@ -140,7 +128,7 @@ void GrGLMorphologyEffect ::setData(const GrGLInterface* gl, default: GrCrash("Unknown filter direction."); } - GR_GL_CALL(gl, Uniform2fv(fImageIncrementLocation, 1, imageIncrement)); + uman.set2fv(fImageIncrementUni, 0, 1, imageIncrement); } /////////////////////////////////////////////////////////////////////////////// diff --git a/src/gpu/effects/GrSingleTextureEffect.cpp b/src/gpu/effects/GrSingleTextureEffect.cpp index d8b90a15fc..350d9e6bc5 100644 --- a/src/gpu/effects/GrSingleTextureEffect.cpp +++ b/src/gpu/effects/GrSingleTextureEffect.cpp @@ -12,10 +12,6 @@ #include "GrProgramStageFactory.h" #include "GrTexture.h" -// For brevity, and these definitions are likely to move to a different class soon. -typedef GrGLShaderBuilder::UniformHandle UniformHandle; -static const UniformHandle kInvalidUniformHandle = GrGLShaderBuilder::kInvalidUniformHandle; - class GrGLSingleTextureEffect : public GrGLProgramStage { public: GrGLSingleTextureEffect(const GrProgramStageFactory& factory, diff --git a/src/gpu/effects/GrTextureDomainEffect.cpp b/src/gpu/effects/GrTextureDomainEffect.cpp index e949c4c085..ca8561ce48 100644 --- a/src/gpu/effects/GrTextureDomainEffect.cpp +++ b/src/gpu/effects/GrTextureDomainEffect.cpp @@ -9,10 +9,6 @@ #include "gl/GrGLProgramStage.h" #include "GrProgramStageFactory.h" -// For brevity, and these definitions are likely to move to a different class soon. -typedef GrGLShaderBuilder::UniformHandle UniformHandle; -static const UniformHandle kInvalidUniformHandle = GrGLShaderBuilder::kInvalidUniformHandle; - class GrGLTextureDomainEffect : public GrGLProgramStage { public: GrGLTextureDomainEffect(const GrProgramStageFactory& factory, @@ -27,11 +23,7 @@ public: const char* inputColor, const char* samplerName) SK_OVERRIDE; - virtual void initUniforms(const GrGLShaderBuilder* builder, - const GrGLInterface*, - int programID) SK_OVERRIDE; - - virtual void setData(const GrGLInterface*, + virtual void setData(const GrGLUniformManager&, const GrCustomStage&, const GrRenderTarget*, int stageNum) SK_OVERRIDE; @@ -39,8 +31,7 @@ public: static inline StageKey GenKey(const GrCustomStage&) { return 0; } private: - UniformHandle fNameUni; - int fNameLocation; + GrGLUniformManager::UniformHandle fNameUni; typedef GrGLProgramStage INHERITED; }; @@ -48,15 +39,13 @@ private: GrGLTextureDomainEffect::GrGLTextureDomainEffect(const GrProgramStageFactory& factory, const GrCustomStage& stage) : GrGLProgramStage(factory) - , fNameUni(kInvalidUniformHandle) - , fNameLocation(0) { + , fNameUni(GrGLUniformManager::kInvalidUniformHandle) { } void GrGLTextureDomainEffect::setupVariables(GrGLShaderBuilder* builder, int stage) { fNameUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, kVec4f_GrSLType, "uTexDom", stage); - fNameLocation = kUseUniform; }; void GrGLTextureDomainEffect::emitFS(GrGLShaderBuilder* builder, @@ -75,17 +64,10 @@ void GrGLTextureDomainEffect::emitFS(GrGLShaderBuilder* builder, builder->emitDefaultFetch(outputColor, samplerName); } -void GrGLTextureDomainEffect::initUniforms(const GrGLShaderBuilder* builder, - const GrGLInterface* gl, int programID) { - GR_GL_CALL_RET(gl, fNameLocation, - GetUniformLocation(programID, builder->getUniformCStr(fNameUni))); - GrAssert(kUnusedUniform != fNameLocation); -} - -void GrGLTextureDomainEffect::setData(const GrGLInterface* gl, - const GrCustomStage& data, - const GrRenderTarget*, - int stageNum) { +void GrGLTextureDomainEffect::setData(const GrGLUniformManager& uman, + const GrCustomStage& data, + const GrRenderTarget*, + int stageNum) { const GrTextureDomainEffect& effect = static_cast<const GrTextureDomainEffect&>(data); const GrRect& domain = effect.domain(); @@ -104,8 +86,7 @@ void GrGLTextureDomainEffect::setData(const GrGLInterface* gl, // of elements so that values = (l, t, r, b). SkTSwap(values[1], values[3]); } - - GR_GL_CALL(gl, Uniform4fv(fNameLocation, 1, values)); + uman.set4fv(fNameUni, 0, 1, values); } @@ -114,7 +95,6 @@ void GrGLTextureDomainEffect::setData(const GrGLInterface* gl, GrTextureDomainEffect::GrTextureDomainEffect(GrTexture* texture, GrRect domain) : GrSingleTextureEffect(texture) , fTextureDomain(domain) { - } GrTextureDomainEffect::~GrTextureDomainEffect() { diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp index 8c1f4f7afd..3a39d0c194 100644 --- a/src/gpu/gl/GrGLProgram.cpp +++ b/src/gpu/gl/GrGLProgram.cpp @@ -21,16 +21,6 @@ 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 { - /// Used to mark a StageUniLocation field that should be bound - /// to a uniform during getUniformLocationsAndInitCache(). - kUseUniform = 2000 -}; - -} // namespace - #define PRINT_SHADERS 0 typedef GrGLProgram::Desc::StageDesc StageDesc; @@ -104,15 +94,27 @@ GrGLProgram* GrGLProgram::Create(const GrGLContextInfo& gl, GrGLProgram::GrGLProgram(const GrGLContextInfo& gl, const Desc& desc, - GrCustomStage** customStages) : fContextInfo(gl) { + GrCustomStage** customStages) +: fContextInfo(gl) +, fUniformManager(gl) { fDesc = desc; fVShaderID = 0; fGShaderID = 0; fFShaderID = 0; fProgramID = 0; + + fViewMatrix = GrMatrix::InvalidMatrix(); + fViewportSize.set(-1, -1); + fColor = GrColor_ILLEGAL; + fColorFilterColor = GrColor_ILLEGAL; + for (int s = 0; s < GrDrawState::kNumStages; ++s) { fProgramStage[s] = NULL; + fTextureMatrices[s] = GrMatrix::InvalidMatrix(); + // this is arbitrary, just initialize to something + fTextureOrientation[s] = GrGLTexture::kBottomUp_Orientation; } + this->genProgram(customStages); } @@ -399,9 +401,8 @@ void GrGLProgram::genInputColor(GrGLShaderBuilder* builder, SkString* inColor) { *inColor = fsName; } break; case GrGLProgram::Desc::kUniform_ColorInput: - builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, - kVec4f_GrSLType, COL_UNI_NAME); - fUniLocations.fColorUni = kUseUniform; + fUniforms.fColorUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, + kVec4f_GrSLType, COL_UNI_NAME); *inColor = COL_UNI_NAME; break; case GrGLProgram::Desc::kTransBlack_ColorInput: @@ -416,9 +417,8 @@ void GrGLProgram::genInputColor(GrGLShaderBuilder* builder, SkString* inColor) { } void GrGLProgram::genUniformCoverage(GrGLShaderBuilder* builder, SkString* inOutCoverage) { - builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, - kVec4f_GrSLType, COV_UNI_NAME); - fUniLocations.fCoverageUni = kUseUniform; + fUniforms.fCoverageUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, + kVec4f_GrSLType, COV_UNI_NAME); if (inOutCoverage->size()) { builder->fFSCode.appendf("\tvec4 uniCoverage = %s * %s;\n", COV_UNI_NAME, inOutCoverage->c_str()); @@ -589,15 +589,12 @@ bool GrGLProgram::compileShaders(const GrGLShaderBuilder& builder) { return true; } - bool GrGLProgram::genProgram(GrCustomStage** customStages) { GrAssert(0 == fProgramID); - GrGLShaderBuilder builder(fContextInfo); + GrGLShaderBuilder builder(fContextInfo, fUniformManager); const uint32_t& layout = fDesc.fVertexLayout; - fUniLocations.reset(); - #if GR_GL_EXPERIMENTAL_GS builder.fUsesGS = fDesc.fExperimentalGS; #endif @@ -658,9 +655,8 @@ bool GrGLProgram::genProgram(GrCustomStage** customStages) { builder.fFSOutputs.push_back(colorOutput); } - builder.addUniform(GrGLShaderBuilder::kVertex_ShaderType, - kMat33f_GrSLType, VIEW_MATRIX_NAME); - fUniLocations.fViewMatrixUni = kUseUniform; + fUniforms.fViewMatrixUni = builder.addUniform(GrGLShaderBuilder::kVertex_ShaderType, + kMat33f_GrSLType, VIEW_MATRIX_NAME); builder.fVSAttrs.push_back().set(kVec2f_GrSLType, GrGLShaderVar::kAttribute_TypeModifier, @@ -748,9 +744,8 @@ bool GrGLProgram::genProgram(GrCustomStage** customStages) { } } if (needColorFilterUniform) { - builder.addUniform(GrGLShaderBuilder::kFragment_ShaderType, - kVec4f_GrSLType, COL_FILTER_UNI_NAME); - fUniLocations.fColorFilterUni = kUseUniform; + fUniforms.fColorFilterUni = builder.addUniform(GrGLShaderBuilder::kFragment_ShaderType, + kVec4f_GrSLType, COL_FILTER_UNI_NAME); } bool wroteFragColorZero = false; if (SkXfermode::kZero_Coeff == uniformCoeff && @@ -768,12 +763,10 @@ bool GrGLProgram::genProgram(GrCustomStage** customStages) { inColor = "filteredColor"; } if (applyColorMatrix) { - builder.addUniform(GrGLShaderBuilder::kFragment_ShaderType, - kMat44f_GrSLType, COL_MATRIX_UNI_NAME); - builder.addUniform(GrGLShaderBuilder::kFragment_ShaderType, - kVec4f_GrSLType, COL_MATRIX_VEC_UNI_NAME); - fUniLocations.fColorMatrixUni = kUseUniform; - fUniLocations.fColorMatrixVecUni = kUseUniform; + fUniforms.fColorMatrixUni = builder.addUniform(GrGLShaderBuilder::kFragment_ShaderType, + kMat44f_GrSLType, COL_MATRIX_UNI_NAME); + fUniforms.fColorMatrixVecUni = builder.addUniform(GrGLShaderBuilder::kFragment_ShaderType, + kVec4f_GrSLType, COL_MATRIX_VEC_UNI_NAME); builder.fFSCode.append("\tvec4 matrixedColor;\n"); const char* color = adjustInColor(inColor); addColorMatrix(&builder.fFSCode, "matrixedColor", color); @@ -927,7 +920,8 @@ bool GrGLProgram::genProgram(GrCustomStage** customStages) { return false; } - this->getUniformLocationsAndInitCache(builder); + builder.finished(fProgramID); + this->initSamplerUniforms(); return true; } @@ -993,78 +987,14 @@ bool GrGLProgram::bindOutputsAttribsAndLinkProgram(SkString texCoordAttrNames[], return true; } -void GrGLProgram::getUniformLocationsAndInitCache(const GrGLShaderBuilder& builder) { - - if (kUseUniform == fUniLocations.fViewMatrixUni) { - GL_CALL_RET(fUniLocations.fViewMatrixUni, GetUniformLocation(fProgramID, VIEW_MATRIX_NAME)); - GrAssert(kUnusedUniform != fUniLocations.fViewMatrixUni); - } - if (kUseUniform == fUniLocations.fColorUni) { - GL_CALL_RET(fUniLocations.fColorUni, GetUniformLocation(fProgramID, COL_UNI_NAME)); - GrAssert(kUnusedUniform != fUniLocations.fColorUni); - } - if (kUseUniform == fUniLocations.fColorFilterUni) { - GL_CALL_RET(fUniLocations.fColorFilterUni, - GetUniformLocation(fProgramID, COL_FILTER_UNI_NAME)); - GrAssert(kUnusedUniform != fUniLocations.fColorFilterUni); - } - - if (kUseUniform == fUniLocations.fColorMatrixUni) { - GL_CALL_RET(fUniLocations.fColorMatrixUni, - GetUniformLocation(fProgramID, COL_MATRIX_UNI_NAME)); - } - - if (kUseUniform == fUniLocations.fColorMatrixVecUni) { - GL_CALL_RET(fUniLocations.fColorMatrixVecUni, - GetUniformLocation(fProgramID, COL_MATRIX_VEC_UNI_NAME)); - } - - if (kUseUniform == fUniLocations.fCoverageUni) { - GL_CALL_RET(fUniLocations.fCoverageUni,GetUniformLocation(fProgramID, COV_UNI_NAME)); - GrAssert(kUnusedUniform != fUniLocations.fCoverageUni); - } - - for (int s = 0; s < GrDrawState::kNumStages; ++s) { - StageUniLocations& locations = fUniLocations.fStages[s]; - if (fDesc.fStages[s].isEnabled()) { - if (kUseUniform == locations.fTextureMatrixUni) { - SkString texMName; - tex_matrix_name(s, &texMName); - GL_CALL_RET(locations.fTextureMatrixUni, - GetUniformLocation(fProgramID, texMName.c_str())); - //color filter table effect does not consumer coords gen'ed by matrix. - //GrAssert(kUnusedUniform != locations.fTextureMatrixUni); - } - - if (kUseUniform == locations.fSamplerUni) { - SkString samplerName; - sampler_name(s, &samplerName); - GL_CALL_RET(locations.fSamplerUni, - GetUniformLocation(fProgramID,samplerName.c_str())); - GrAssert(kUnusedUniform != locations.fSamplerUni); - } - - if (NULL != fProgramStage[s]) { - fProgramStage[s]->initUniforms(&builder, fContextInfo.interface(), fProgramID); - } - } - } +void GrGLProgram::initSamplerUniforms() { GL_CALL(UseProgram(fProgramID)); - // init sampler unis and set bogus values for state tracking for (int s = 0; s < GrDrawState::kNumStages; ++s) { - if (kUnusedUniform != fUniLocations.fStages[s].fSamplerUni) { - GL_CALL(Uniform1i(fUniLocations.fStages[s].fSamplerUni, s)); + if (GrGLUniformManager::kInvalidUniformHandle != fUniforms.fStages[s].fSamplerUni) { + fUniformManager.setSampler(fUniforms.fStages[s].fSamplerUni, s); } - fTextureMatrices[s] = GrMatrix::InvalidMatrix(); - // this is arbitrary, just initialize to something - fTextureOrientation[s] = GrGLTexture::kBottomUp_Orientation; - // Must not reset fStageOverride[] here. } - fViewMatrix = GrMatrix::InvalidMatrix(); - fViewportSize.set(-1, -1); - fColor = GrColor_ILLEGAL; - fColorFilterColor = GrColor_ILLEGAL; } /////////////////////////////////////////////////////////////////////////////// @@ -1078,7 +1008,7 @@ void GrGLProgram::genStageCode(int stageNum, GrAssert(stageNum >= 0 && stageNum <= GrDrawState::kNumStages); const GrGLProgram::StageDesc& desc = fDesc.fStages[stageNum]; - StageUniLocations& locations = fUniLocations.fStages[stageNum]; + StageUniforms& uniforms = fUniforms.fStages[stageNum]; GrGLProgramStage* customStage = fProgramStage[stageNum]; GrAssert((desc.fInConfigFlags & StageDesc::kInConfigBitMask) == desc.fInConfigFlags); @@ -1093,13 +1023,11 @@ void GrGLProgram::genStageCode(int stageNum, } else { SkString texMatName; tex_matrix_name(stageNum, &texMatName); - GrGLShaderBuilder::UniformHandle m = - segments->addUniform(GrGLShaderBuilder::kVertex_ShaderType, - kMat33f_GrSLType, texMatName.c_str()); - const GrGLShaderVar& mat = segments->getUniformVariable(m); + uniforms.fTextureMatrixUni = segments->addUniform(GrGLShaderBuilder::kVertex_ShaderType, + kMat33f_GrSLType, texMatName.c_str()); + const GrGLShaderVar& mat = segments->getUniformVariable(uniforms.fTextureMatrixUni); // Can't use texMatName.c_str() because it's on the stack! matName = mat.getName().c_str(); - locations.fTextureMatrixUni = kUseUniform; if (desc.fOptFlags & StageDesc::kNoPerspective_OptFlagBit) { segments->fVaryingDims = segments->fCoordDims; @@ -1116,9 +1044,8 @@ void GrGLProgram::genStageCode(int stageNum, SkString samplerName; sampler_name(stageNum, &samplerName); - segments->addUniform(GrGLShaderBuilder::kFragment_ShaderType, - kSampler2D_GrSLType, samplerName.c_str()); - locations.fSamplerUni = kUseUniform; + uniforms.fSamplerUni = segments->addUniform(GrGLShaderBuilder::kFragment_ShaderType, + kSampler2D_GrSLType, samplerName.c_str()); const char *varyingVSName, *varyingFSName; segments->addVarying(GrSLFloatVectorType(segments->fVaryingDims), diff --git a/src/gpu/gl/GrGLProgram.h b/src/gpu/gl/GrGLProgram.h index 6b6454d4df..02cb6ef55a 100644 --- a/src/gpu/gl/GrGLProgram.h +++ b/src/gpu/gl/GrGLProgram.h @@ -13,7 +13,7 @@ #include "GrGLContextInfo.h" #include "GrGLSL.h" #include "GrGLTexture.h" -//#include "GrGpu.h" +#include "GrGLUniformManager.h" #include "SkString.h" #include "SkXfermode.h" @@ -75,10 +75,6 @@ public: return 7 + GrDrawState::kMaxTexCoords + 3 * stage; } - enum { - kUnusedUniform = -1, - }; - // Parameters that affect code generation // These structs should be kept compact; they are the input to an // expensive hash key generator. @@ -259,6 +255,8 @@ private: void genGeometryShader(GrGLShaderBuilder* segments) const; + typedef GrGLUniformManager::UniformHandle UniformHandle; + void genUniformCoverage(GrGLShaderBuilder* segments, SkString* inOutCoverage); // generates code to compute coverage based on edge AA. @@ -269,42 +267,37 @@ private: bool bindColorOut, bool bindDualSrcOut); - // Binds uniforms; initializes cache to invalid values. - void getUniformLocationsAndInitCache(const GrGLShaderBuilder& builder); + // Sets the texture units for samplers + void initSamplerUniforms(); bool compileShaders(const GrGLShaderBuilder& builder); const char* adjustInColor(const SkString& inColor) const; - struct StageUniLocations { - GrGLint fTextureMatrixUni; - GrGLint fSamplerUni; - GrGLint fTexDomUni; - void reset() { - fTextureMatrixUni = kUnusedUniform; - fSamplerUni = kUnusedUniform; - fTexDomUni = kUnusedUniform; + struct StageUniforms { + UniformHandle fTextureMatrixUni; + UniformHandle fSamplerUni; + StageUniforms() { + fTextureMatrixUni = GrGLUniformManager::kInvalidUniformHandle; + fSamplerUni = GrGLUniformManager::kInvalidUniformHandle; } }; - struct UniLocations { - GrGLint fViewMatrixUni; - GrGLint fColorUni; - GrGLint fCoverageUni; - GrGLint fColorFilterUni; - GrGLint fColorMatrixUni; - GrGLint fColorMatrixVecUni; - StageUniLocations fStages[GrDrawState::kNumStages]; - void reset() { - fViewMatrixUni = kUnusedUniform; - fColorUni = kUnusedUniform; - fCoverageUni = kUnusedUniform; - fColorFilterUni = kUnusedUniform; - fColorMatrixUni = kUnusedUniform; - fColorMatrixVecUni = kUnusedUniform; - for (int s = 0; s < GrDrawState::kNumStages; ++s) { - fStages[s].reset(); - } + struct Uniforms { + UniformHandle fViewMatrixUni; + UniformHandle fColorUni; + UniformHandle fCoverageUni; + UniformHandle fColorFilterUni; + UniformHandle fColorMatrixUni; + UniformHandle fColorMatrixVecUni; + StageUniforms fStages[GrDrawState::kNumStages]; + Uniforms() { + fViewMatrixUni = GrGLUniformManager::kInvalidUniformHandle; + fColorUni = GrGLUniformManager::kInvalidUniformHandle; + fCoverageUni = GrGLUniformManager::kInvalidUniformHandle; + fColorFilterUni = GrGLUniformManager::kInvalidUniformHandle; + fColorMatrixUni = GrGLUniformManager::kInvalidUniformHandle; + fColorMatrixVecUni = GrGLUniformManager::kInvalidUniformHandle; } }; @@ -313,8 +306,6 @@ private: GrGLuint fGShaderID; GrGLuint fFShaderID; GrGLuint fProgramID; - // shader uniform locations (-1 if shader doesn't use them) - UniLocations fUniLocations; // The matrix sent to GL is determined by both the client's matrix and // the size of the viewport. @@ -336,6 +327,9 @@ private: Desc fDesc; const GrGLContextInfo& fContextInfo; + GrGLUniformManager fUniformManager; + Uniforms fUniforms; + friend class GrGpuGL; // TODO: remove this by adding getters and moving functionality. typedef GrRefCnt INHERITED; diff --git a/src/gpu/gl/GrGLProgramStage.cpp b/src/gpu/gl/GrGLProgramStage.cpp index fe103ad866..caf123b3d7 100644 --- a/src/gpu/gl/GrGLProgramStage.cpp +++ b/src/gpu/gl/GrGLProgramStage.cpp @@ -21,13 +21,7 @@ void GrGLProgramStage::setupVariables(GrGLShaderBuilder*, int stage) { } -void GrGLProgramStage::initUniforms(const GrGLShaderBuilder*, - const GrGLInterface*, - int progID) { - -} - -void GrGLProgramStage::setData(const GrGLInterface*, +void GrGLProgramStage::setData(const GrGLUniformManager&, const GrCustomStage&, const GrRenderTarget*, int stageNum) { diff --git a/src/gpu/gl/GrGLProgramStage.h b/src/gpu/gl/GrGLProgramStage.h index 6350ae34b8..5b2ff50881 100644 --- a/src/gpu/gl/GrGLProgramStage.h +++ b/src/gpu/gl/GrGLProgramStage.h @@ -73,17 +73,11 @@ public: const char* inputColor, const char* samplerName) = 0; - /** Binds uniforms; we must have already bound the program and - determined its GL program ID. */ - virtual void initUniforms(const GrGLShaderBuilder* builder, - const GrGLInterface* gl, - int programID); - /** A GrGLCustomStage instance can be reused with any GrCustomStage that produces the same stage key; this function reads data from a stage and uploads any uniform variables required by the shaders created in emit*(). */ - virtual void setData(const GrGLInterface* gl, + virtual void setData(const GrGLUniformManager&, const GrCustomStage& stage, const GrRenderTarget* renderTarget, int stageNum); diff --git a/src/gpu/gl/GrGLShaderBuilder.cpp b/src/gpu/gl/GrGLShaderBuilder.cpp index 7fa804a7e5..f56f102855 100644 --- a/src/gpu/gl/GrGLShaderBuilder.cpp +++ b/src/gpu/gl/GrGLShaderBuilder.cpp @@ -7,6 +7,7 @@ #include "gl/GrGLShaderBuilder.h" #include "gl/GrGLProgram.h" +#include "gl/GrGLUniformHandle.h" // number of each input/output type in a single allocation block static const int kVarsPerBlock = 8; @@ -17,12 +18,15 @@ static const int kMaxFSOutputs = 2; // ES2 FS only guarantees mediump and lowp support static const GrGLShaderVar::Precision kDefaultFragmentPrecision = GrGLShaderVar::kMedium_Precision; +typedef GrGLUniformManager::UniformHandle UniformHandle; +/////////////////////////////////////////////////////////////////////////////// + // Architectural assumption: always 2-d input coords. // Likely to become non-constant and non-static, perhaps even // varying by stage, if we use 1D textures for gradients! //const int GrGLShaderBuilder::fCoordDims = 2; -GrGLShaderBuilder::GrGLShaderBuilder(const GrGLContextInfo& ctx) +GrGLShaderBuilder::GrGLShaderBuilder(const GrGLContextInfo& ctx, GrGLUniformManager& uniformManager) : fUniforms(kVarsPerBlock) , fVSAttrs(kVarsPerBlock) , fVSOutputs(kVarsPerBlock) @@ -33,8 +37,8 @@ GrGLShaderBuilder::GrGLShaderBuilder(const GrGLContextInfo& ctx) , fUsesGS(false) , fVaryingDims(0) , fComplexCoord(false) - , fContext(ctx) { - + , fContext(ctx) + , fUniformManager(uniformManager) { } void GrGLShaderBuilder::computeSwizzle(uint32_t configFlags) { @@ -115,23 +119,23 @@ void GrGLShaderBuilder::emitDefaultFetch(const char* outColor, fFSCode.appendf("%s%s;\n", fSwizzle.c_str(), fModulate.c_str()); } -namespace { -inline int handle_to_index(GrGLShaderBuilder::UniformHandle h) { return ~h; } -inline GrGLShaderBuilder::UniformHandle index_to_handle(int i) { return ~i; } -} - -GrGLShaderBuilder::UniformHandle GrGLShaderBuilder::addUniform(uint32_t visibility, - GrSLType type, - const char* name, - int stageNum, - int count) { +GrGLUniformManager::UniformHandle GrGLShaderBuilder::addUniform(uint32_t visibility, + GrSLType type, + const char* name, + int stageNum, + int count) { GrAssert(name && strlen(name)); static const uint32_t kVisibilityMask = kVertex_ShaderType | kFragment_ShaderType; GrAssert(0 == (~kVisibilityMask & visibility)); GrAssert(0 != visibility); - Uniform& uni = fUniforms.push_back(); + BuilderUniform& uni = fUniforms.push_back(); UniformHandle h = index_to_handle(fUniforms.count() - 1); + GR_DEBUGCODE(UniformHandle h2 =) + fUniformManager.appendUniform(type, count); + // We expect the uniform manager to initially have no uniforms and that all uniforms are added + // by this function. Therefore, the handles should match. + GrAssert(h2 == h); uni.fVariable.setType(type); uni.fVariable.setTypeModifier(GrGLShaderVar::kUniform_TypeModifier); uni.fVariable.setName(name); @@ -280,3 +284,6 @@ void GrGLShaderBuilder::getShader(ShaderType type, SkString* shaderStr) const { } } +void GrGLShaderBuilder::finished(GrGLuint programID) { + fUniformManager.getUniformLocations(programID, fUniforms); +} diff --git a/src/gpu/gl/GrGLShaderBuilder.h b/src/gpu/gl/GrGLShaderBuilder.h index 892fcbee47..347bcda344 100644 --- a/src/gpu/gl/GrGLShaderBuilder.h +++ b/src/gpu/gl/GrGLShaderBuilder.h @@ -11,28 +11,25 @@ #include "GrAllocator.h" #include "gl/GrGLShaderVar.h" #include "gl/GrGLSL.h" +#include "gl/GrGLUniformManager.h" class GrGLContextInfo; + /** Contains all the incremental state of a shader as it is being built,as well as helpers to manipulate that state. - TODO: migrate CompileShaders() here? */ - class GrGLShaderBuilder { public: - typedef int UniformHandle; - static const UniformHandle kInvalidUniformHandle = 0; - enum ShaderType { kVertex_ShaderType = 0x1, kGeometry_ShaderType = 0x2, kFragment_ShaderType = 0x4, }; - GrGLShaderBuilder(const GrGLContextInfo&); + GrGLShaderBuilder(const GrGLContextInfo&, GrGLUniformManager&); void computeSwizzle(uint32_t configFlags); void computeModulate(const char* fsInColor); @@ -64,18 +61,18 @@ public: from which shaders the uniform should be accessible. At least one bit must be set. Geometry shader uniforms are not supported at this time. */ - UniformHandle addUniform(uint32_t visibility, - GrSLType type, - const char* name, - int stageNum = -1, - int count = GrGLShaderVar::kNonArray); + GrGLUniformManager::UniformHandle addUniform(uint32_t visibility, + GrSLType type, + const char* name, + int stageNum = -1, + int count = GrGLShaderVar::kNonArray); - const GrGLShaderVar& getUniformVariable(UniformHandle) const; + const GrGLShaderVar& getUniformVariable(GrGLUniformManager::UniformHandle) const; /** * Shorcut for getUniformVariable(u).c_str() */ - const char* getUniformCStr(UniformHandle u) const { + const char* getUniformCStr(GrGLUniformManager::UniformHandle u) const { return this->getUniformVariable(u).c_str(); } @@ -99,19 +96,20 @@ public: /** Called after building is complete to get the final shader string. */ void getShader(ShaderType, SkString*) const; + /** + * TODO: Make this do all the compiling, linking, etc. Hide this from the custom stages + */ + void finished(GrGLuint programID); + private: - typedef GrTAllocator<GrGLShaderVar> VarArray; - struct Uniform { - GrGLShaderVar fVariable; - uint32_t fVisibility; - }; + typedef GrTAllocator<GrGLShaderVar> VarArray; - typedef GrTAllocator<Uniform> UniformArray; void appendDecls(const VarArray&, SkString*) const; void appendUniformDecls(ShaderType, SkString*) const; - UniformArray fUniforms; + typedef GrGLUniformManager::BuilderUniform BuilderUniform; + GrGLUniformManager::BuilderUniformArray fUniforms; // TODO: Everything below here private. public: @@ -149,7 +147,8 @@ public: //@} private: - const GrGLContextInfo& fContext; + const GrGLContextInfo& fContext; + GrGLUniformManager& fUniformManager; }; #endif diff --git a/src/gpu/gl/GrGLUniformHandle.h b/src/gpu/gl/GrGLUniformHandle.h new file mode 100644 index 0000000000..231dd31c20 --- /dev/null +++ b/src/gpu/gl/GrGLUniformHandle.h @@ -0,0 +1,16 @@ +/* + * Copyright 2012 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef GrUniformHandle_DEFINED +#define GrUniformHandle_DEFINED + +namespace { +inline int handle_to_index(GrGLUniformManager::UniformHandle h) { return ~h; } +inline GrGLUniformManager::UniformHandle index_to_handle(int i) { return ~i; } +} + +#endif diff --git a/src/gpu/gl/GrGLUniformManager.cpp b/src/gpu/gl/GrGLUniformManager.cpp new file mode 100644 index 0000000000..1625ebbfab --- /dev/null +++ b/src/gpu/gl/GrGLUniformManager.cpp @@ -0,0 +1,247 @@ +/* + * Copyright 2012 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "gl/GrGLShaderBuilder.h" +#include "gl/GrGLProgram.h" +#include "gl/GrGLUniformHandle.h" + +#define ASSERT_ARRAY_UPLOAD_IN_BOUNDS(UNI, OFFSET, COUNT) \ + GrAssert(offset + arrayCount <= uni.fArrayCount || \ + (0 == offset && 1 == arrayCount && GrGLShaderVar::kNonArray == uni.fArrayCount)) + +GrGLUniformManager::UniformHandle GrGLUniformManager::appendUniform(GrSLType type, int arrayCount) { + int idx = fUniforms.count(); + Uniform& uni = fUniforms.push_back(); + GrAssert(GrGLShaderVar::kNonArray == arrayCount || arrayCount > 0); + uni.fArrayCount = arrayCount; + uni.fType = type; + uni.fVSLocation = kUnusedUniform; + uni.fFSLocation = kUnusedUniform; + return index_to_handle(idx); +} + +void GrGLUniformManager::setSampler(UniformHandle u, GrGLint texUnit) const { + const Uniform& uni = fUniforms[handle_to_index(u)]; + GrAssert(uni.fType == kSampler2D_GrSLType); + GrAssert(GrGLShaderVar::kNonArray == uni.fArrayCount); + GrAssert(kUnusedUniform != uni.fFSLocation || kUnusedUniform != uni.fVSLocation); + if (kUnusedUniform != uni.fFSLocation) { + GR_GL_CALL(fContext.interface(), Uniform1i(uni.fFSLocation, texUnit)); + } + if (kUnusedUniform != uni.fVSLocation && uni.fVSLocation != uni.fFSLocation) { + GR_GL_CALL(fContext.interface(), Uniform1i(uni.fVSLocation, texUnit)); + } +} + +void GrGLUniformManager::set1f(UniformHandle u, GrGLfloat v0) const { + const Uniform& uni = fUniforms[handle_to_index(u)]; + GrAssert(uni.fType == kFloat_GrSLType); + GrAssert(GrGLShaderVar::kNonArray == uni.fArrayCount); + GrAssert(kUnusedUniform != uni.fFSLocation || kUnusedUniform != uni.fVSLocation); + if (kUnusedUniform != uni.fFSLocation) { + GR_GL_CALL(fContext.interface(), Uniform1f(uni.fFSLocation, v0)); + } + if (kUnusedUniform != uni.fVSLocation && uni.fVSLocation != uni.fFSLocation) { + GR_GL_CALL(fContext.interface(), Uniform1f(uni.fVSLocation, v0)); + } +} + +void GrGLUniformManager::set1fv(UniformHandle u, + int offset, + int arrayCount, + const GrGLfloat v[]) const { + const Uniform& uni = fUniforms[handle_to_index(u)]; + GrAssert(uni.fType == kFloat_GrSLType); + GrAssert(arrayCount > 0); + ASSERT_ARRAY_UPLOAD_IN_BOUNDS(uni, offset, arrayCount); + // This assert fires in some instances of the two-pt gradient for its VSParams. + // Once the uniform manager is responsible for inserting the duplicate uniform + // arrays in VS and FS driver bug workaround, this can be enabled. + //GrAssert(kUnusedUniform != uni.fFSLocation || kUnusedUniform != uni.fVSLocation); + if (kUnusedUniform != uni.fFSLocation) { + GR_GL_CALL(fContext.interface(), Uniform1fv(uni.fFSLocation + offset, arrayCount, v)); + } + if (kUnusedUniform != uni.fVSLocation && uni.fVSLocation != uni.fFSLocation) { + GR_GL_CALL(fContext.interface(), Uniform1fv(uni.fVSLocation + offset, arrayCount, v)); + } +} + +void GrGLUniformManager::set2f(UniformHandle u, GrGLfloat v0, GrGLfloat v1) const { + const Uniform& uni = fUniforms[handle_to_index(u)]; + GrAssert(uni.fType == kVec2f_GrSLType); + GrAssert(GrGLShaderVar::kNonArray == uni.fArrayCount); + GrAssert(kUnusedUniform != uni.fFSLocation || kUnusedUniform != uni.fVSLocation); + if (kUnusedUniform != uni.fFSLocation) { + GR_GL_CALL(fContext.interface(), Uniform2f(uni.fFSLocation, v0, v1)); + } + if (kUnusedUniform != uni.fVSLocation && uni.fVSLocation != uni.fFSLocation) { + GR_GL_CALL(fContext.interface(), Uniform2f(uni.fVSLocation, v0, v1)); + } +} + +void GrGLUniformManager::set2fv(UniformHandle u, + int offset, + int arrayCount, + const GrGLfloat v[]) const { + const Uniform& uni = fUniforms[handle_to_index(u)]; + GrAssert(uni.fType == kVec2f_GrSLType); + GrAssert(arrayCount > 0); + ASSERT_ARRAY_UPLOAD_IN_BOUNDS(uni, offset, arrayCount); + GrAssert(kUnusedUniform != uni.fFSLocation || kUnusedUniform != uni.fVSLocation); + if (kUnusedUniform != uni.fFSLocation) { + GR_GL_CALL(fContext.interface(), Uniform2fv(uni.fFSLocation + offset, arrayCount, v)); + } + if (kUnusedUniform != uni.fVSLocation && uni.fVSLocation != uni.fFSLocation) { + GR_GL_CALL(fContext.interface(), Uniform2fv(uni.fVSLocation + offset, arrayCount, v)); + } +} + +void GrGLUniformManager::set3f(UniformHandle u, GrGLfloat v0, GrGLfloat v1, GrGLfloat v2) const { + const Uniform& uni = fUniforms[handle_to_index(u)]; + GrAssert(uni.fType == kVec3f_GrSLType); + GrAssert(GrGLShaderVar::kNonArray == uni.fArrayCount); + GrAssert(kUnusedUniform != uni.fFSLocation || kUnusedUniform != uni.fVSLocation); + if (kUnusedUniform != uni.fFSLocation) { + GR_GL_CALL(fContext.interface(), Uniform3f(uni.fFSLocation, v0, v1, v2)); + } + if (kUnusedUniform != uni.fVSLocation && uni.fVSLocation != uni.fFSLocation) { + GR_GL_CALL(fContext.interface(), Uniform3f(uni.fVSLocation, v0, v1, v2)); + } +} + +void GrGLUniformManager::set3fv(UniformHandle u, + int offset, + int arrayCount, + const GrGLfloat v[]) const { + const Uniform& uni = fUniforms[handle_to_index(u)]; + GrAssert(uni.fType == kVec3f_GrSLType); + GrAssert(arrayCount > 0); + ASSERT_ARRAY_UPLOAD_IN_BOUNDS(uni, offset, arrayCount); + GrAssert(kUnusedUniform != uni.fFSLocation || kUnusedUniform != uni.fVSLocation); + if (kUnusedUniform != uni.fFSLocation) { + GR_GL_CALL(fContext.interface(), Uniform3fv(uni.fFSLocation + offset, arrayCount, v)); + } + if (kUnusedUniform != uni.fVSLocation && uni.fVSLocation != uni.fFSLocation) { + GR_GL_CALL(fContext.interface(), Uniform3fv(uni.fVSLocation + offset, arrayCount, v)); + } +} + +void GrGLUniformManager::set4f(UniformHandle u, + GrGLfloat v0, + GrGLfloat v1, + GrGLfloat v2, + GrGLfloat v3) const { + const Uniform& uni = fUniforms[handle_to_index(u)]; + GrAssert(uni.fType == kVec4f_GrSLType); + GrAssert(GrGLShaderVar::kNonArray == uni.fArrayCount); + GrAssert(kUnusedUniform != uni.fFSLocation || kUnusedUniform != uni.fVSLocation); + if (kUnusedUniform != uni.fFSLocation) { + GR_GL_CALL(fContext.interface(), Uniform4f(uni.fFSLocation, v0, v1, v2, v3)); + } + if (kUnusedUniform != uni.fVSLocation && uni.fVSLocation != uni.fFSLocation) { + GR_GL_CALL(fContext.interface(), Uniform4f(uni.fVSLocation, v0, v1, v2, v3)); + } +} + +void GrGLUniformManager::set4fv(UniformHandle u, + int offset, + int arrayCount, + const GrGLfloat v[]) const { + const Uniform& uni = fUniforms[handle_to_index(u)]; + GrAssert(uni.fType == kVec4f_GrSLType); + GrAssert(arrayCount > 0); + GrAssert(kUnusedUniform != uni.fFSLocation || kUnusedUniform != uni.fVSLocation); + if (kUnusedUniform != uni.fFSLocation) { + GR_GL_CALL(fContext.interface(), Uniform4fv(uni.fFSLocation + offset, arrayCount, v)); + } + if (kUnusedUniform != uni.fVSLocation && uni.fVSLocation != uni.fFSLocation) { + GR_GL_CALL(fContext.interface(), Uniform4fv(uni.fVSLocation + offset, arrayCount, v)); + } +} + +void GrGLUniformManager::setMatrix3f(UniformHandle u, const GrGLfloat matrix[]) const { + const Uniform& uni = fUniforms[handle_to_index(u)]; + GrAssert(uni.fType == kMat33f_GrSLType); + GrAssert(GrGLShaderVar::kNonArray == uni.fArrayCount); + GrAssert(kUnusedUniform != uni.fFSLocation || kUnusedUniform != uni.fVSLocation); + if (kUnusedUniform != uni.fFSLocation) { + GR_GL_CALL(fContext.interface(), UniformMatrix3fv(uni.fFSLocation, 1, false, matrix)); + } + if (kUnusedUniform != uni.fVSLocation && uni.fVSLocation != uni.fFSLocation) { + GR_GL_CALL(fContext.interface(), UniformMatrix3fv(uni.fVSLocation, 1, false, matrix)); + } +} + +void GrGLUniformManager::setMatrix4f(UniformHandle u, const GrGLfloat matrix[]) const { + const Uniform& uni = fUniforms[handle_to_index(u)]; + GrAssert(uni.fType == kMat44f_GrSLType); + GrAssert(GrGLShaderVar::kNonArray == uni.fArrayCount); + GrAssert(kUnusedUniform != uni.fFSLocation || kUnusedUniform != uni.fVSLocation); + if (kUnusedUniform != uni.fFSLocation) { + GR_GL_CALL(fContext.interface(), UniformMatrix4fv(uni.fFSLocation, 1, false, matrix)); + } + if (kUnusedUniform != uni.fVSLocation && uni.fVSLocation != uni.fFSLocation) { + GR_GL_CALL(fContext.interface(), UniformMatrix4fv(uni.fVSLocation, 1, false, matrix)); + } +} + +void GrGLUniformManager::setMatrix3fv(UniformHandle u, + int offset, + int arrayCount, + const GrGLfloat matrices[]) const { + const Uniform& uni = fUniforms[handle_to_index(u)]; + GrAssert(uni.fType == kMat33f_GrSLType); + GrAssert(arrayCount > 0); + ASSERT_ARRAY_UPLOAD_IN_BOUNDS(uni, offset, arrayCount); + GrAssert(kUnusedUniform != uni.fFSLocation || kUnusedUniform != uni.fVSLocation); + if (kUnusedUniform != uni.fFSLocation) { + GR_GL_CALL(fContext.interface(), + UniformMatrix3fv(uni.fFSLocation + offset, arrayCount, false, matrices)); + } + if (kUnusedUniform != uni.fVSLocation && uni.fVSLocation != uni.fFSLocation) { + GR_GL_CALL(fContext.interface(), + UniformMatrix3fv(uni.fVSLocation + offset, arrayCount, false, matrices)); + } +} + +void GrGLUniformManager::setMatrix4fv(UniformHandle u, + int offset, + int arrayCount, + const GrGLfloat matrices[]) const { + const Uniform& uni = fUniforms[handle_to_index(u)]; + GrAssert(uni.fType == kMat44f_GrSLType); + GrAssert(arrayCount > 0); + ASSERT_ARRAY_UPLOAD_IN_BOUNDS(uni, offset, arrayCount); + GrAssert(kUnusedUniform != uni.fFSLocation || kUnusedUniform != uni.fVSLocation); + if (kUnusedUniform != uni.fFSLocation) { + GR_GL_CALL(fContext.interface(), + UniformMatrix4fv(uni.fFSLocation + offset, arrayCount, false, matrices)); + } + if (kUnusedUniform != uni.fVSLocation && uni.fVSLocation != uni.fFSLocation) { + GR_GL_CALL(fContext.interface(), + UniformMatrix4fv(uni.fVSLocation + offset, arrayCount, false, matrices)); + } +} + +void GrGLUniformManager::getUniformLocations(GrGLuint programID, const BuilderUniformArray& uniforms) { + GrAssert(uniforms.count() == fUniforms.count()); + int count = fUniforms.count(); + for (int i = 0; i < count; ++i) { + GrAssert(uniforms[i].fVariable.getType() == fUniforms[i].fType); + GrAssert(uniforms[i].fVariable.getArrayCount() == fUniforms[i].fArrayCount); + GrGLint location; + // TODO: Move the Xoom uniform array in both FS and VS bug workaround here. + GR_GL_CALL_RET(fContext.interface(), location, + GetUniformLocation(programID, uniforms[i].fVariable.c_str())); + if (GrGLShaderBuilder::kVertex_ShaderType & uniforms[i].fVisibility) { + fUniforms[i].fVSLocation = location; + } + if (GrGLShaderBuilder::kFragment_ShaderType & uniforms[i].fVisibility) { + fUniforms[i].fFSLocation = location; + } + } +} diff --git a/src/gpu/gl/GrGLUniformManager.h b/src/gpu/gl/GrGLUniformManager.h new file mode 100644 index 0000000000..aea96f0b38 --- /dev/null +++ b/src/gpu/gl/GrGLUniformManager.h @@ -0,0 +1,76 @@ +/* + * Copyright 2012 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef GrGLUniformManager_DEFINED +#define GrGLUniformManager_DEFINED + +#include "gl/GrGLShaderVar.h" +#include "gl/GrGLSL.h" + +#include "SkTArray.h" + +class GrGLContextInfo; + +/** Manages a program's uniforms. +*/ +class GrGLUniformManager { +public: + // Opaque handle to a uniform + typedef int UniformHandle; + static const UniformHandle kInvalidUniformHandle = 0; + + GrGLUniformManager(const GrGLContextInfo& context) : fContext(context) {} + + UniformHandle appendUniform(GrSLType type, int arrayCount = GrGLShaderVar::kNonArray); + + /** Functions for uploading uniform values. The varities ending in v can be used to upload to an + * array of uniforms. offset + arrayCount must be <= the array count of the uniform. + */ + void setSampler(UniformHandle, GrGLint texUnit) const; + void set1f(UniformHandle, GrGLfloat v0) const; + void set1fv(UniformHandle, int offset, int arrayCount, const GrGLfloat v[]) const; + void set2f(UniformHandle, GrGLfloat, GrGLfloat) const; + void set2fv(UniformHandle, int offset, int arrayCount, const GrGLfloat v[]) const; + void set3f(UniformHandle, GrGLfloat, GrGLfloat, GrGLfloat) const; + void set3fv(UniformHandle, int offset, int arrayCount, const GrGLfloat v[]) const; + void set4f(UniformHandle, GrGLfloat, GrGLfloat, GrGLfloat, GrGLfloat) const; + void set4fv(UniformHandle, int offset, int arrayCount, const GrGLfloat v[]) const; + // matrices are column-major, the first three upload a single matrix, the latter three upload + // arrayCount matrices into a uniform array. + void setMatrix3f(UniformHandle, const GrGLfloat matrix[]) const; + void setMatrix4f(UniformHandle, const GrGLfloat matrix[]) const; + void setMatrix3fv(UniformHandle, int offset, int arrayCount, const GrGLfloat matrices[]) const; + void setMatrix4fv(UniformHandle, int offset, int arrayCount, const GrGLfloat matrices[]) const; + + struct BuilderUniform { + GrGLShaderVar fVariable; + uint32_t fVisibility; + }; + typedef SkTArray<BuilderUniform, true> BuilderUniformArray; + + /** + * Called by the GrGLShaderBuilder to get GL locations for all uniforms. + */ + void getUniformLocations(GrGLuint programID, const BuilderUniformArray& uniforms); + +private: + enum { + kUnusedUniform = -1, + }; + + struct Uniform { + GrGLint fVSLocation; + GrGLint fFSLocation; + GrSLType fType; + int fArrayCount; + }; + + SkTArray<Uniform, true> fUniforms; + const GrGLContextInfo& fContext; +}; + +#endif diff --git a/src/gpu/gl/GrGpuGL.h b/src/gpu/gl/GrGpuGL.h index fb78ad2973..b3e8cf8698 100644 --- a/src/gpu/gl/GrGpuGL.h +++ b/src/gpu/gl/GrGpuGL.h @@ -219,8 +219,8 @@ private: void flushBoundTextureAndParams(int stage); void flushBoundTextureAndParams(int stage, GrGLTexture* nextTexture); - // sets the texture matrix and domain for the currently bound program - void flushTextureMatrixAndDomain(int stage); + // sets the texture matrix for the currently bound program + void flushTextureMatrix(int stage); // sets the color specified by GrDrawState::setColor() void flushColor(GrColor color); diff --git a/src/gpu/gl/GrGpuGL_program.cpp b/src/gpu/gl/GrGpuGL_program.cpp index 56a893dc3a..f4044fcabe 100644 --- a/src/gpu/gl/GrGpuGL_program.cpp +++ b/src/gpu/gl/GrGpuGL_program.cpp @@ -11,6 +11,9 @@ #include "GrGLProgramStage.h" #include "GrGpuVertex.h" +typedef GrGLUniformManager::UniformHandle UniformHandle; +static const UniformHandle kInvalidUniformHandle = GrGLUniformManager::kInvalidUniformHandle; + #define SKIP_CACHE_CHECK true #define GR_UINT32_MAX static_cast<uint32_t>(-1) @@ -147,11 +150,7 @@ void GrGpuGL::flushViewMatrix(DrawType type) { GrScalarToFloat(m[GrMatrix::kMTransY]), GrScalarToFloat(m[GrMatrix::kMPersp2]) }; - - GrAssert(GrGLProgram::kUnusedUniform != - fCurrentProgram->fUniLocations.fViewMatrixUni); - GL_CALL(UniformMatrix3fv(fCurrentProgram->fUniLocations.fViewMatrixUni, - 1, false, mt)); + fCurrentProgram->fUniformManager.setMatrix3f(fCurrentProgram->fUniforms.fViewMatrixUni, mt); fCurrentProgram->fViewMatrix = vm; fCurrentProgram->fViewportSize = viewportSize; } @@ -194,7 +193,7 @@ bool GrGpuGL::TextureMatrixIsIdentity(const GrGLTexture* texture, /////////////////////////////////////////////////////////////////////////////// -void GrGpuGL::flushTextureMatrixAndDomain(int s) { +void GrGpuGL::flushTextureMatrix(int s) { const GrDrawState& drawState = this->getDrawState(); const GrGLTexture* texture = static_cast<const GrGLTexture*>(drawState.getTexture(s)); @@ -203,13 +202,12 @@ void GrGpuGL::flushTextureMatrixAndDomain(int s) { bool orientationChange = fCurrentProgram->fTextureOrientation[s] != texture->orientation(); - const GrGLint& matrixUni = - fCurrentProgram->fUniLocations.fStages[s].fTextureMatrixUni; + UniformHandle matrixUni = fCurrentProgram->fUniforms.fStages[s].fTextureMatrixUni; const GrMatrix& hwMatrix = fCurrentProgram->fTextureMatrices[s]; const GrMatrix& samplerMatrix = drawState.getSampler(s).getMatrix(); - if (GrGLProgram::kUnusedUniform != matrixUni && + if (kInvalidUniformHandle != matrixUni && (orientationChange || !hwMatrix.cheapEqualTo(samplerMatrix))) { GrMatrix m = samplerMatrix; @@ -229,7 +227,7 @@ void GrGpuGL::flushTextureMatrixAndDomain(int s) { GrScalarToFloat(m[GrMatrix::kMPersp2]) }; - GL_CALL(UniformMatrix3fv(matrixUni, 1, false, mt)); + fCurrentProgram->fUniformManager.setMatrix3f(matrixUni, mt); fCurrentProgram->fTextureMatrices[s] = samplerMatrix; } @@ -239,10 +237,9 @@ void GrGpuGL::flushTextureMatrixAndDomain(int s) { void GrGpuGL::flushColorMatrix() { - int matrixUni = fCurrentProgram->fUniLocations.fColorMatrixUni; - int vecUni = fCurrentProgram->fUniLocations.fColorMatrixVecUni; - if (GrGLProgram::kUnusedUniform != matrixUni - && GrGLProgram::kUnusedUniform != vecUni) { + UniformHandle matrixUni = fCurrentProgram->fUniforms.fColorMatrixUni; + UniformHandle vecUni = fCurrentProgram->fUniforms.fColorMatrixVecUni; + if (kInvalidUniformHandle != matrixUni && kInvalidUniformHandle != vecUni) { const float* m = this->getDrawState().getColorMatrix(); GrGLfloat mt[] = { m[0], m[5], m[10], m[15], @@ -254,8 +251,8 @@ void GrGpuGL::flushColorMatrix() { GrGLfloat vec[] = { m[4] * scale, m[9] * scale, m[14] * scale, m[19] * scale, }; - GL_CALL(UniformMatrix4fv(matrixUni, 1, false, mt)); - GL_CALL(Uniform4fv(vecUni, 1, vec)); + fCurrentProgram->fUniformManager.setMatrix4f(matrixUni, mt); + fCurrentProgram->fUniformManager.set4fv(vecUni, 0, 1, vec); } } @@ -293,9 +290,9 @@ void GrGpuGL::flushColor(GrColor color) { // OpenGL ES doesn't support unsigned byte varieties of // glUniform float c[] = GR_COLOR_TO_VEC4(color); - GrAssert(GrGLProgram::kUnusedUniform != - fCurrentProgram->fUniLocations.fColorUni); - GL_CALL(Uniform4fv(fCurrentProgram->fUniLocations.fColorUni, 1, c)); + GrAssert(kInvalidUniformHandle != fCurrentProgram->fUniforms.fColorUni); + fCurrentProgram->fUniformManager.set4fv(fCurrentProgram->fUniforms.fColorUni, + 0, 1, c); fCurrentProgram->fColor = color; } break; @@ -306,12 +303,11 @@ void GrGpuGL::flushColor(GrColor color) { GrCrash("Unknown color type."); } } - if (fCurrentProgram->fUniLocations.fColorFilterUni - != GrGLProgram::kUnusedUniform - && fCurrentProgram->fColorFilterColor - != drawState.getColorFilterColor()) { + UniformHandle filterColorUni = fCurrentProgram->fUniforms.fColorFilterUni; + if (kInvalidUniformHandle != filterColorUni && + fCurrentProgram->fColorFilterColor != drawState.getColorFilterColor()) { float c[] = GR_COLOR_TO_VEC4(drawState.getColorFilterColor()); - GL_CALL(Uniform4fv(fCurrentProgram->fUniLocations.fColorFilterUni, 1, c)); + fCurrentProgram->fUniformManager.set4fv(filterColorUni, 0, 1, c); fCurrentProgram->fColorFilterColor = drawState.getColorFilterColor(); } } @@ -342,9 +338,9 @@ void GrGpuGL::flushCoverage(GrColor coverage) { // OpenGL ES doesn't support unsigned byte varieties of // glUniform float c[] = GR_COLOR_TO_VEC4(coverage); - GrAssert(GrGLProgram::kUnusedUniform != - fCurrentProgram->fUniLocations.fCoverageUni); - GL_CALL(Uniform4fv(fCurrentProgram->fUniLocations.fCoverageUni, 1, c)); + GrAssert(kInvalidUniformHandle != fCurrentProgram->fUniforms.fCoverageUni); + fCurrentProgram->fUniformManager.set4fv(fCurrentProgram->fUniforms.fCoverageUni, + 0, 1, c); fCurrentProgram->fCoverage = coverage; } break; @@ -418,13 +414,13 @@ bool GrGpuGL::flushGraphicsState(DrawType type) { #endif this->flushBoundTextureAndParams(s); - this->flushTextureMatrixAndDomain(s); + this->flushTextureMatrix(s); if (NULL != fCurrentProgram->fProgramStage[s]) { const GrSamplerState& sampler = this->getDrawState().getSampler(s); const GrGLTexture* texture = static_cast<const GrGLTexture*>( this->getDrawState().getTexture(s)); - fCurrentProgram->fProgramStage[s]->setData(this->glInterface(), + fCurrentProgram->fProgramStage[s]->setData(fCurrentProgram->fUniformManager, *sampler.getCustomStage(), drawState.getRenderTarget(), s); } |