From 261dc569b6a53729bea6e4e7a0cf2afa980eb82d Mon Sep 17 00:00:00 2001 From: "commit-bot@chromium.org" Date: Fri, 4 Oct 2013 15:42:56 +0000 Subject: Move VertexBuilder to a GrGLFullShaderBuilder subclass Removes the VertexBuilder nested class from GrGLShaderBuilder in favor of a new GrGLFullShaderBuilder subclass, and adds an optional emitCode overload to GrGLEffect that takes a GrGLFullShaderBuilder. Makes setData virtual in GrGLEffectArray and adds a GrGLVertexEffectArray subclass that gets built using a GrGLFullShaderBuilder. Also adds a new GrGLVertexEffect subclass that makes the GrGLFullShaderBuilder overload required for emitCode, and updates GrGLEffects to inherit from GrGLVertexEffect where needed. R=bsalomon@google.com Author: cdalton@nvidia.com Review URL: https://codereview.chromium.org/25474006 git-svn-id: http://skia.googlecode.com/svn/trunk@11612 2bbb7eff-a529-9590-31e7-b0007b416f81 --- gyp/gpu.gypi | 1 + src/gpu/GrAAConvexPathRenderer.cpp | 16 +- src/gpu/GrAARectRenderer.cpp | 41 ++-- src/gpu/GrOvalRenderer.cpp | 58 ++--- src/gpu/effects/GrBezierEffect.cpp | 52 ++--- src/gpu/effects/GrCustomCoordsTextureEffect.cpp | 15 +- src/gpu/gl/GrGLEffect.h | 18 +- src/gpu/gl/GrGLProgram.cpp | 8 +- src/gpu/gl/GrGLProgramDesc.h | 12 + src/gpu/gl/GrGLProgramEffects.cpp | 103 +++++---- src/gpu/gl/GrGLProgramEffects.h | 112 ++++++--- src/gpu/gl/GrGLShaderBuilder.cpp | 221 ++++++++---------- src/gpu/gl/GrGLShaderBuilder.h | 289 +++++++++++++----------- src/gpu/gl/GrGLVertexEffect.h | 52 +++++ 14 files changed, 541 insertions(+), 457 deletions(-) create mode 100644 src/gpu/gl/GrGLVertexEffect.h diff --git a/gyp/gpu.gypi b/gyp/gpu.gypi index c93e7afb7d..e787118d88 100644 --- a/gyp/gpu.gypi +++ b/gyp/gpu.gypi @@ -156,6 +156,7 @@ '<(skia_src_path)/gpu/gl/GrGLDefaultInterface_none.cpp', '<(skia_src_path)/gpu/gl/GrGLDefines.h', '<(skia_src_path)/gpu/gl/GrGLEffect.h', + '<(skia_src_path)/gpu/gl/GrGLVertexEffect.h', '<(skia_src_path)/gpu/gl/GrGLExtensions.cpp', '<(skia_src_path)/gpu/gl/GrGLIndexBuffer.cpp', '<(skia_src_path)/gpu/gl/GrGLIndexBuffer.h', diff --git a/src/gpu/GrAAConvexPathRenderer.cpp b/src/gpu/GrAAConvexPathRenderer.cpp index 78f2045786..ebb2f6988f 100644 --- a/src/gpu/GrAAConvexPathRenderer.cpp +++ b/src/gpu/GrAAConvexPathRenderer.cpp @@ -20,6 +20,7 @@ #include "gl/GrGLEffect.h" #include "gl/GrGLSL.h" +#include "gl/GrGLVertexEffect.h" #include "effects/GrVertexEffect.h" @@ -521,29 +522,26 @@ public: return GrTBackendEffectFactory::getInstance(); } - class GLEffect : public GrGLEffect { + class GLEffect : public GrGLVertexEffect { public: GLEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&) : INHERITED (factory) {} - virtual void emitCode(GrGLShaderBuilder* builder, + virtual void emitCode(GrGLFullShaderBuilder* builder, const GrDrawEffect& drawEffect, EffectKey key, const char* outputColor, const char* inputColor, const TransformedCoordsArray&, const TextureSamplerArray& samplers) SK_OVERRIDE { - GrGLShaderBuilder::VertexBuilder* vertexBuilder = builder->getVertexBuilder(); - SkASSERT(NULL != vertexBuilder); - const char *vsName, *fsName; const SkString* attrName = - vertexBuilder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]); + builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]); builder->fsCodeAppendf("\t\tfloat edgeAlpha;\n"); SkAssertResult(builder->enableFeature( GrGLShaderBuilder::kStandardDerivatives_GLSLFeature)); - vertexBuilder->addVarying(kVec4f_GrSLType, "QuadEdge", &vsName, &fsName); + builder->addVarying(kVec4f_GrSLType, "QuadEdge", &vsName, &fsName); // keep the derivative instructions outside the conditional builder->fsCodeAppendf("\t\tvec2 duvdx = dFdx(%s.xy);\n", fsName); @@ -565,7 +563,7 @@ public: GrGLSLModulatef<4>(&modulate, inputColor, "edgeAlpha"); builder->fsCodeAppendf("\t%s = %s;\n", outputColor, modulate.c_str()); - vertexBuilder->vsCodeAppendf("\t%s = %s;\n", vsName, attrName->c_str()); + builder->vsCodeAppendf("\t%s = %s;\n", vsName, attrName->c_str()); } static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) { @@ -575,7 +573,7 @@ public: virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE {} private: - typedef GrGLEffect INHERITED; + typedef GrGLVertexEffect INHERITED; }; private: diff --git a/src/gpu/GrAARectRenderer.cpp b/src/gpu/GrAARectRenderer.cpp index 320b3d7cb0..b2052a8d28 100644 --- a/src/gpu/GrAARectRenderer.cpp +++ b/src/gpu/GrAARectRenderer.cpp @@ -8,6 +8,7 @@ #include "GrAARectRenderer.h" #include "GrGpu.h" #include "gl/GrGLEffect.h" +#include "gl/GrGLVertexEffect.h" #include "GrTBackendEffectFactory.h" #include "SkColorPriv.h" #include "effects/GrVertexEffect.h" @@ -39,29 +40,26 @@ public: return GrTBackendEffectFactory::getInstance(); } - class GLEffect : public GrGLEffect { + class GLEffect : public GrGLVertexEffect { public: GLEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&) : INHERITED (factory) {} - virtual void emitCode(GrGLShaderBuilder* builder, + virtual void emitCode(GrGLFullShaderBuilder* builder, const GrDrawEffect& drawEffect, EffectKey key, const char* outputColor, const char* inputColor, const TransformedCoordsArray&, const TextureSamplerArray& samplers) SK_OVERRIDE { - GrGLShaderBuilder::VertexBuilder* vertexBuilder = builder->getVertexBuilder(); - SkASSERT(NULL != vertexBuilder); - // setup the varying for the Axis aligned rect effect // xy -> interpolated offset // zw -> w/2+0.5, h/2+0.5 const char *vsRectName, *fsRectName; - vertexBuilder->addVarying(kVec4f_GrSLType, "Rect", &vsRectName, &fsRectName); + builder->addVarying(kVec4f_GrSLType, "Rect", &vsRectName, &fsRectName); const SkString* attr0Name = - vertexBuilder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]); - vertexBuilder->vsCodeAppendf("\t%s = %s;\n", vsRectName, attr0Name->c_str()); + builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]); + builder->vsCodeAppendf("\t%s = %s;\n", vsRectName, attr0Name->c_str()); // TODO: compute all these offsets, spans, and scales in the VS builder->fsCodeAppendf("\tfloat insetW = min(1.0, %s.z) - 0.5;\n", fsRectName); @@ -98,7 +96,7 @@ public: virtual void setData(const GrGLUniformManager& uman, const GrDrawEffect&) SK_OVERRIDE {} private: - typedef GrGLEffect INHERITED; + typedef GrGLVertexEffect INHERITED; }; @@ -160,37 +158,34 @@ public: return GrTBackendEffectFactory::getInstance(); } - class GLEffect : public GrGLEffect { + class GLEffect : public GrGLVertexEffect { public: GLEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&) : INHERITED (factory) {} - virtual void emitCode(GrGLShaderBuilder* builder, + virtual void emitCode(GrGLFullShaderBuilder* builder, const GrDrawEffect& drawEffect, EffectKey key, const char* outputColor, const char* inputColor, const TransformedCoordsArray&, const TextureSamplerArray& samplers) SK_OVERRIDE { - GrGLShaderBuilder::VertexBuilder* vertexBuilder = builder->getVertexBuilder(); - SkASSERT(NULL != vertexBuilder); - // setup the varying for the center point and the unit vector // that points down the height of the rect const char *vsRectEdgeName, *fsRectEdgeName; - vertexBuilder->addVarying(kVec4f_GrSLType, "RectEdge", - &vsRectEdgeName, &fsRectEdgeName); + builder->addVarying(kVec4f_GrSLType, "RectEdge", + &vsRectEdgeName, &fsRectEdgeName); const SkString* attr0Name = - vertexBuilder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]); - vertexBuilder->vsCodeAppendf("\t%s = %s;\n", vsRectEdgeName, attr0Name->c_str()); + builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]); + builder->vsCodeAppendf("\t%s = %s;\n", vsRectEdgeName, attr0Name->c_str()); // setup the varying for width/2+.5 and height/2+.5 const char *vsWidthHeightName, *fsWidthHeightName; - vertexBuilder->addVarying(kVec2f_GrSLType, "WidthHeight", - &vsWidthHeightName, &fsWidthHeightName); + builder->addVarying(kVec2f_GrSLType, "WidthHeight", + &vsWidthHeightName, &fsWidthHeightName); const SkString* attr1Name = - vertexBuilder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[1]); - vertexBuilder->vsCodeAppendf("\t%s = %s;\n", vsWidthHeightName, attr1Name->c_str()); + builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[1]); + builder->vsCodeAppendf("\t%s = %s;\n", vsWidthHeightName, attr1Name->c_str()); // TODO: compute all these offsets, spans, and scales in the VS builder->fsCodeAppendf("\tfloat insetW = min(1.0, %s.x) - 0.5;\n", fsWidthHeightName); @@ -234,7 +229,7 @@ public: virtual void setData(const GrGLUniformManager& uman, const GrDrawEffect&) SK_OVERRIDE {} private: - typedef GrGLEffect INHERITED; + typedef GrGLVertexEffect INHERITED; }; diff --git a/src/gpu/GrOvalRenderer.cpp b/src/gpu/GrOvalRenderer.cpp index 2c923f8f81..785126560a 100644 --- a/src/gpu/GrOvalRenderer.cpp +++ b/src/gpu/GrOvalRenderer.cpp @@ -10,6 +10,7 @@ #include "GrEffect.h" #include "gl/GrGLEffect.h" #include "gl/GrGLSL.h" +#include "gl/GrGLVertexEffect.h" #include "GrTBackendEffectFactory.h" #include "GrDrawState.h" @@ -88,28 +89,25 @@ public: inline bool isStroked() const { return fStroke; } - class GLEffect : public GrGLEffect { + class GLEffect : public GrGLVertexEffect { public: GLEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&) : INHERITED (factory) {} - virtual void emitCode(GrGLShaderBuilder* builder, + virtual void emitCode(GrGLFullShaderBuilder* builder, const GrDrawEffect& drawEffect, EffectKey key, const char* outputColor, const char* inputColor, const TransformedCoordsArray&, const TextureSamplerArray& samplers) SK_OVERRIDE { - GrGLShaderBuilder::VertexBuilder* vertexBuilder = builder->getVertexBuilder(); - SkASSERT(NULL != vertexBuilder); - const CircleEdgeEffect& circleEffect = drawEffect.castEffect(); const char *vsName, *fsName; - vertexBuilder->addVarying(kVec4f_GrSLType, "CircleEdge", &vsName, &fsName); + builder->addVarying(kVec4f_GrSLType, "CircleEdge", &vsName, &fsName); const SkString* attrName = - vertexBuilder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]); - vertexBuilder->vsCodeAppendf("\t%s = %s;\n", vsName, attrName->c_str()); + builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]); + builder->vsCodeAppendf("\t%s = %s;\n", vsName, attrName->c_str()); builder->fsCodeAppendf("\tfloat d = length(%s.xy);\n", fsName); builder->fsCodeAppendf("\tfloat edgeAlpha = clamp(%s.z - d, 0.0, 1.0);\n", fsName); @@ -132,7 +130,7 @@ public: virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE {} private: - typedef GrGLEffect INHERITED; + typedef GrGLVertexEffect INHERITED; }; @@ -203,35 +201,32 @@ public: inline bool isStroked() const { return fStroke; } - class GLEffect : public GrGLEffect { + class GLEffect : public GrGLVertexEffect { public: GLEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&) : INHERITED (factory) {} - virtual void emitCode(GrGLShaderBuilder* builder, + virtual void emitCode(GrGLFullShaderBuilder* builder, const GrDrawEffect& drawEffect, EffectKey key, const char* outputColor, const char* inputColor, const TransformedCoordsArray&, const TextureSamplerArray& samplers) SK_OVERRIDE { - GrGLShaderBuilder::VertexBuilder* vertexBuilder = builder->getVertexBuilder(); - SkASSERT(NULL != vertexBuilder); - const EllipseEdgeEffect& ellipseEffect = drawEffect.castEffect(); const char *vsOffsetName, *fsOffsetName; const char *vsRadiiName, *fsRadiiName; - vertexBuilder->addVarying(kVec2f_GrSLType, "EllipseOffsets", &vsOffsetName, &fsOffsetName); + builder->addVarying(kVec2f_GrSLType, "EllipseOffsets", &vsOffsetName, &fsOffsetName); const SkString* attr0Name = - vertexBuilder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]); - vertexBuilder->vsCodeAppendf("\t%s = %s;\n", vsOffsetName, attr0Name->c_str()); + builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]); + builder->vsCodeAppendf("\t%s = %s;\n", vsOffsetName, attr0Name->c_str()); - vertexBuilder->addVarying(kVec4f_GrSLType, "EllipseRadii", &vsRadiiName, &fsRadiiName); + builder->addVarying(kVec4f_GrSLType, "EllipseRadii", &vsRadiiName, &fsRadiiName); const SkString* attr1Name = - vertexBuilder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[1]); - vertexBuilder->vsCodeAppendf("\t%s = %s;\n", vsRadiiName, attr1Name->c_str()); + builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[1]); + builder->vsCodeAppendf("\t%s = %s;\n", vsRadiiName, attr1Name->c_str()); // for outer curve builder->fsCodeAppendf("\tvec2 scaledOffset = %s*%s.xy;\n", fsOffsetName, fsRadiiName); @@ -269,7 +264,7 @@ public: } private: - typedef GrGLEffect INHERITED; + typedef GrGLVertexEffect INHERITED; }; private: @@ -347,38 +342,35 @@ public: inline Mode getMode() const { return fMode; } - class GLEffect : public GrGLEffect { + class GLEffect : public GrGLVertexEffect { public: GLEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&) : INHERITED (factory) {} - virtual void emitCode(GrGLShaderBuilder* builder, + virtual void emitCode(GrGLFullShaderBuilder* builder, const GrDrawEffect& drawEffect, EffectKey key, const char* outputColor, const char* inputColor, const TransformedCoordsArray&, const TextureSamplerArray& samplers) SK_OVERRIDE { - GrGLShaderBuilder::VertexBuilder* vertexBuilder = builder->getVertexBuilder(); - SkASSERT(NULL != vertexBuilder); - const DIEllipseEdgeEffect& ellipseEffect = drawEffect.castEffect(); SkAssertResult(builder->enableFeature( GrGLShaderBuilder::kStandardDerivatives_GLSLFeature)); const char *vsOffsetName0, *fsOffsetName0; - vertexBuilder->addVarying(kVec2f_GrSLType, "EllipseOffsets0", + builder->addVarying(kVec2f_GrSLType, "EllipseOffsets0", &vsOffsetName0, &fsOffsetName0); const SkString* attr0Name = - vertexBuilder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]); - vertexBuilder->vsCodeAppendf("\t%s = %s;\n", vsOffsetName0, attr0Name->c_str()); + builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]); + builder->vsCodeAppendf("\t%s = %s;\n", vsOffsetName0, attr0Name->c_str()); const char *vsOffsetName1, *fsOffsetName1; - vertexBuilder->addVarying(kVec2f_GrSLType, "EllipseOffsets1", + builder->addVarying(kVec2f_GrSLType, "EllipseOffsets1", &vsOffsetName1, &fsOffsetName1); const SkString* attr1Name = - vertexBuilder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[1]); - vertexBuilder->vsCodeAppendf("\t%s = %s;\n", vsOffsetName1, attr1Name->c_str()); + builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[1]); + builder->vsCodeAppendf("\t%s = %s;\n", vsOffsetName1, attr1Name->c_str()); // for outer curve builder->fsCodeAppendf("\tvec2 scaledOffset = %s.xy;\n", fsOffsetName0); @@ -431,7 +423,7 @@ public: } private: - typedef GrGLEffect INHERITED; + typedef GrGLVertexEffect INHERITED; }; private: diff --git a/src/gpu/effects/GrBezierEffect.cpp b/src/gpu/effects/GrBezierEffect.cpp index 9adf59261b..4dca884734 100644 --- a/src/gpu/effects/GrBezierEffect.cpp +++ b/src/gpu/effects/GrBezierEffect.cpp @@ -9,13 +9,14 @@ #include "gl/GrGLEffect.h" #include "gl/GrGLSL.h" +#include "gl/GrGLVertexEffect.h" #include "GrTBackendEffectFactory.h" -class GrGLConicEffect : public GrGLEffect { +class GrGLConicEffect : public GrGLVertexEffect { public: GrGLConicEffect(const GrBackendEffectFactory&, const GrDrawEffect&); - virtual void emitCode(GrGLShaderBuilder* builder, + virtual void emitCode(GrGLFullShaderBuilder* builder, const GrDrawEffect& drawEffect, EffectKey key, const char* outputColor, @@ -30,7 +31,7 @@ public: private: GrBezierEdgeType fEdgeType; - typedef GrGLEffect INHERITED; + typedef GrGLVertexEffect INHERITED; }; GrGLConicEffect::GrGLConicEffect(const GrBackendEffectFactory& factory, @@ -40,23 +41,20 @@ GrGLConicEffect::GrGLConicEffect(const GrBackendEffectFactory& factory, fEdgeType = ce.getEdgeType(); } -void GrGLConicEffect::emitCode(GrGLShaderBuilder* builder, +void GrGLConicEffect::emitCode(GrGLFullShaderBuilder* builder, const GrDrawEffect& drawEffect, EffectKey key, const char* outputColor, const char* inputColor, const TransformedCoordsArray&, const TextureSamplerArray& samplers) { - GrGLShaderBuilder::VertexBuilder* vertexBuilder = builder->getVertexBuilder(); - SkASSERT(NULL != vertexBuilder); - const char *vsName, *fsName; - vertexBuilder->addVarying(kVec4f_GrSLType, "ConicCoeffs", + builder->addVarying(kVec4f_GrSLType, "ConicCoeffs", &vsName, &fsName); const SkString* attr0Name = - vertexBuilder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]); - vertexBuilder->vsCodeAppendf("\t%s = %s;\n", vsName, attr0Name->c_str()); + builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]); + builder->vsCodeAppendf("\t%s = %s;\n", vsName, attr0Name->c_str()); builder->fsCodeAppend("\t\tfloat edgeAlpha;\n"); @@ -156,11 +154,11 @@ GrEffectRef* GrConicEffect::TestCreate(SkRandom* random, // Quad ////////////////////////////////////////////////////////////////////////////// -class GrGLQuadEffect : public GrGLEffect { +class GrGLQuadEffect : public GrGLVertexEffect { public: GrGLQuadEffect(const GrBackendEffectFactory&, const GrDrawEffect&); - virtual void emitCode(GrGLShaderBuilder* builder, + virtual void emitCode(GrGLFullShaderBuilder* builder, const GrDrawEffect& drawEffect, EffectKey key, const char* outputColor, @@ -175,7 +173,7 @@ public: private: GrBezierEdgeType fEdgeType; - typedef GrGLEffect INHERITED; + typedef GrGLVertexEffect INHERITED; }; GrGLQuadEffect::GrGLQuadEffect(const GrBackendEffectFactory& factory, @@ -185,23 +183,20 @@ GrGLQuadEffect::GrGLQuadEffect(const GrBackendEffectFactory& factory, fEdgeType = ce.getEdgeType(); } -void GrGLQuadEffect::emitCode(GrGLShaderBuilder* builder, +void GrGLQuadEffect::emitCode(GrGLFullShaderBuilder* builder, const GrDrawEffect& drawEffect, EffectKey key, const char* outputColor, const char* inputColor, const TransformedCoordsArray&, const TextureSamplerArray& samplers) { - GrGLShaderBuilder::VertexBuilder* vertexBuilder = builder->getVertexBuilder(); - SkASSERT(NULL != vertexBuilder); - const char *vsName, *fsName; const SkString* attrName = - vertexBuilder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]); + builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]); builder->fsCodeAppendf("\t\tfloat edgeAlpha;\n"); - vertexBuilder->addVarying(kVec4f_GrSLType, "HairQuadEdge", &vsName, &fsName); + builder->addVarying(kVec4f_GrSLType, "HairQuadEdge", &vsName, &fsName); switch (fEdgeType) { case kHairAA_GrBezierEdgeType: { @@ -248,7 +243,7 @@ void GrGLQuadEffect::emitCode(GrGLShaderBuilder* builder, GrGLSLModulatef<4>(&modulate, inputColor, "edgeAlpha"); builder->fsCodeAppendf("\t%s = %s;\n", outputColor, modulate.c_str()); - vertexBuilder->vsCodeAppendf("\t%s = %s;\n", vsName, attrName->c_str()); + builder->vsCodeAppendf("\t%s = %s;\n", vsName, attrName->c_str()); } GrGLEffect::EffectKey GrGLQuadEffect::GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) { @@ -290,11 +285,11 @@ GrEffectRef* GrQuadEffect::TestCreate(SkRandom* random, // Cubic ////////////////////////////////////////////////////////////////////////////// -class GrGLCubicEffect : public GrGLEffect { +class GrGLCubicEffect : public GrGLVertexEffect { public: GrGLCubicEffect(const GrBackendEffectFactory&, const GrDrawEffect&); - virtual void emitCode(GrGLShaderBuilder* builder, + virtual void emitCode(GrGLFullShaderBuilder* builder, const GrDrawEffect& drawEffect, EffectKey key, const char* outputColor, @@ -309,7 +304,7 @@ public: private: GrBezierEdgeType fEdgeType; - typedef GrGLEffect INHERITED; + typedef GrGLVertexEffect INHERITED; }; GrGLCubicEffect::GrGLCubicEffect(const GrBackendEffectFactory& factory, @@ -319,23 +314,20 @@ GrGLCubicEffect::GrGLCubicEffect(const GrBackendEffectFactory& factory, fEdgeType = ce.getEdgeType(); } -void GrGLCubicEffect::emitCode(GrGLShaderBuilder* builder, +void GrGLCubicEffect::emitCode(GrGLFullShaderBuilder* builder, const GrDrawEffect& drawEffect, EffectKey key, const char* outputColor, const char* inputColor, const TransformedCoordsArray&, const TextureSamplerArray& samplers) { - GrGLShaderBuilder::VertexBuilder* vertexBuilder = builder->getVertexBuilder(); - SkASSERT(NULL != vertexBuilder); - const char *vsName, *fsName; - vertexBuilder->addVarying(kVec4f_GrSLType, "CubicCoeffs", + builder->addVarying(kVec4f_GrSLType, "CubicCoeffs", &vsName, &fsName); const SkString* attr0Name = - vertexBuilder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]); - vertexBuilder->vsCodeAppendf("\t%s = %s;\n", vsName, attr0Name->c_str()); + builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]); + builder->vsCodeAppendf("\t%s = %s;\n", vsName, attr0Name->c_str()); builder->fsCodeAppend("\t\tfloat edgeAlpha;\n"); diff --git a/src/gpu/effects/GrCustomCoordsTextureEffect.cpp b/src/gpu/effects/GrCustomCoordsTextureEffect.cpp index b14de8bd34..f85a927aba 100644 --- a/src/gpu/effects/GrCustomCoordsTextureEffect.cpp +++ b/src/gpu/effects/GrCustomCoordsTextureEffect.cpp @@ -9,34 +9,33 @@ #include "gl/GrGLEffect.h" #include "gl/GrGLSL.h" #include "gl/GrGLTexture.h" +#include "gl/GrGLVertexEffect.h" #include "GrTBackendEffectFactory.h" #include "GrTexture.h" -class GrGLCustomCoordsTextureEffect : public GrGLEffect { +class GrGLCustomCoordsTextureEffect : public GrGLVertexEffect { public: GrGLCustomCoordsTextureEffect(const GrBackendEffectFactory& factory, const GrDrawEffect& drawEffect) : INHERITED (factory) {} - virtual void emitCode(GrGLShaderBuilder* builder, + virtual void emitCode(GrGLFullShaderBuilder* builder, const GrDrawEffect& drawEffect, EffectKey key, const char* outputColor, const char* inputColor, const TransformedCoordsArray&, const TextureSamplerArray& samplers) SK_OVERRIDE { - GrGLShaderBuilder::VertexBuilder* vertexBuilder = builder->getVertexBuilder(); - SkASSERT(NULL != vertexBuilder); SkASSERT(1 == drawEffect.castEffect().numVertexAttribs()); SkString fsCoordName; const char* vsVaryingName; const char* fsVaryingNamePtr; - vertexBuilder->addVarying(kVec2f_GrSLType, "textureCoords", &vsVaryingName, &fsVaryingNamePtr); + builder->addVarying(kVec2f_GrSLType, "textureCoords", &vsVaryingName, &fsVaryingNamePtr); fsCoordName = fsVaryingNamePtr; const char* attrName = - vertexBuilder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0])->c_str(); - vertexBuilder->vsCodeAppendf("\t%s = %s;\n", vsVaryingName, attrName); + builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0])->c_str(); + builder->vsCodeAppendf("\t%s = %s;\n", vsVaryingName, attrName); builder->fsCodeAppendf("\t%s = ", outputColor); builder->fsAppendTextureLookupAndModulate(inputColor, @@ -50,7 +49,7 @@ public: const GrDrawEffect& drawEffect) SK_OVERRIDE {} private: - typedef GrGLEffect INHERITED; + typedef GrGLVertexEffect INHERITED; }; /////////////////////////////////////////////////////////////////////////////// diff --git a/src/gpu/gl/GrGLEffect.h b/src/gpu/gl/GrGLEffect.h index 52b1e921c1..b6807383e6 100644 --- a/src/gpu/gl/GrGLEffect.h +++ b/src/gpu/gl/GrGLEffect.h @@ -14,8 +14,6 @@ #include "GrGLShaderVar.h" #include "GrGLSL.h" -class GrGLTexture; - /** @file This file contains specializations for OpenGL of the shader stages declared in include/gpu/GrEffect.h. Objects of type GrGLEffect are responsible for emitting the @@ -34,6 +32,8 @@ class GrGLTexture; */ class GrDrawEffect; +class GrGLTexture; +class GrGLVertexEffect; class GrGLEffect { @@ -48,7 +48,10 @@ public: kEffectKeyBits = GrBackendEffectFactory::kEffectKeyBits, }; - GrGLEffect(const GrBackendEffectFactory& factory) : fFactory(factory) {} + GrGLEffect(const GrBackendEffectFactory& factory) + : fFactory(factory) + , fIsVertexEffect(false) { + } virtual ~GrGLEffect() {} @@ -93,8 +96,17 @@ public: static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&) { return 0; } + /** Used by the system when generating shader code, to see if this effect can be downcasted to + the internal GrGLVertexEffect type */ + bool isVertexEffect() const { return fIsVertexEffect; } + protected: const GrBackendEffectFactory& fFactory; + +private: + friend class GrGLVertexEffect; // to set fIsVertexEffect + + bool fIsVertexEffect; }; #endif diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp index 3691fe994b..4fe7a2b7c9 100644 --- a/src/gpu/gl/GrGLProgram.cpp +++ b/src/gpu/gl/GrGLProgram.cpp @@ -211,12 +211,8 @@ bool GrGLProgram::genProgram(const GrEffectStage* colorStages[], const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader(); - bool needsVertexShader = true; - - GrGLShaderBuilder builder(fGpu, fUniformManager, fDesc, needsVertexShader); - if (GrGLShaderBuilder::VertexBuilder* vertexBuilder = builder.getVertexBuilder()) { - fUniformHandles.fViewMatrixUni = vertexBuilder->getViewMatrixUniform(); - } + GrGLFullShaderBuilder builder(fGpu, fUniformManager, fDesc); + fUniformHandles.fViewMatrixUni = builder.getViewMatrixUniform(); // incoming color to current stage being processed. SkString inColor = builder.getInputColor(); diff --git a/src/gpu/gl/GrGLProgramDesc.h b/src/gpu/gl/GrGLProgramDesc.h index e160438e08..0c7c8cf629 100644 --- a/src/gpu/gl/GrGLProgramDesc.h +++ b/src/gpu/gl/GrGLProgramDesc.h @@ -113,6 +113,17 @@ private: kColorInputCnt }; + static GrSLConstantVec KnownColorInputValue(ColorInput ci) { + switch (ci) { + case GrGLProgramDesc::kTransBlack_ColorInput: + return kZeros_GrSLConstantVec; + case GrGLProgramDesc::kSolidWhite_ColorInput: + return kOnes_GrSLConstantVec; + default: + return kNone_GrSLConstantVec; + } + } + enum CoverageOutput { // modulate color and coverage, write result as the color output. kModulate_CoverageOutput, @@ -221,6 +232,7 @@ private: // code generation to GrGLShaderBuilder (and maybe add getters rather than friending). friend class GrGLProgram; friend class GrGLShaderBuilder; + friend class GrGLFullShaderBuilder; }; #endif diff --git a/src/gpu/gl/GrGLProgramEffects.cpp b/src/gpu/gl/GrGLProgramEffects.cpp index b6decf8607..d5826abe30 100644 --- a/src/gpu/gl/GrGLProgramEffects.cpp +++ b/src/gpu/gl/GrGLProgramEffects.cpp @@ -9,6 +9,7 @@ #include "GrDrawEffect.h" #include "gl/GrGLEffect.h" #include "gl/GrGLShaderBuilder.h" +#include "gl/GrGLVertexEffect.h" #include "gl/GrGpuGL.h" typedef GrGLProgramEffects::EffectKey EffectKey; @@ -157,9 +158,9 @@ void GrGLProgramEffects::initSamplers(const GrGLUniformManager& uniformManager, } } -void GrGLProgramEffects::setData(GrGpuGL* gpu, - const GrGLUniformManager& uniformManager, - const GrEffectStage* effectStages[]) { +void GrGLVertexProgramEffects::setData(GrGpuGL* gpu, + const GrGLUniformManager& uniformManager, + const GrEffectStage* effectStages[]) { int numEffects = fGLEffects.count(); SkASSERT(numEffects == fTransforms.count()); SkASSERT(numEffects == fSamplers.count()); @@ -171,9 +172,9 @@ void GrGLProgramEffects::setData(GrGpuGL* gpu, } } -void GrGLProgramEffects::setTransformData(const GrGLUniformManager& uniformManager, - const GrDrawEffect& drawEffect, - int effectIdx) { +void GrGLVertexProgramEffects::setTransformData(const GrGLUniformManager& uniformManager, + const GrDrawEffect& drawEffect, + int effectIdx) { SkTArray& transforms = fTransforms[effectIdx]; int numTransforms = transforms.count(); SkASSERT(numTransforms == (*drawEffect.effect())->numTransforms()); @@ -243,21 +244,18 @@ void GrGLProgramEffects::bindTextures(GrGpuGL* gpu, const GrEffectRef& effect, i //////////////////////////////////////////////////////////////////////////////// -GrGLProgramEffectsBuilder::GrGLProgramEffectsBuilder(GrGLShaderBuilder* builder, int reserveCount) - : fBuilder(builder) { - GrGLShaderBuilder::VertexBuilder* vertexBuilder = fBuilder->getVertexBuilder(); - SkASSERT(NULL != vertexBuilder); - fProgramEffects.reset(SkNEW_ARGS(GrGLProgramEffects, - (reserveCount, vertexBuilder->hasExplicitLocalCoords()))); +GrGLVertexProgramEffectsBuilder::GrGLVertexProgramEffectsBuilder(GrGLFullShaderBuilder* builder, + int reserveCount) + : fBuilder(builder) + , fProgramEffects(SkNEW_ARGS(GrGLVertexProgramEffects, + (reserveCount, fBuilder->hasExplicitLocalCoords()))) { } -void GrGLProgramEffectsBuilder::emitEffect(const GrEffectStage& stage, - EffectKey key, - const char* outColor, - const char* inColor, - int stageIndex) { - GrGLShaderBuilder::VertexBuilder* vertexBuilder = fBuilder->getVertexBuilder(); - SkASSERT(NULL != vertexBuilder); +void GrGLVertexProgramEffectsBuilder::emitEffect(const GrEffectStage& stage, + EffectKey key, + const char* outColor, + const char* inColor, + int stageIndex) { SkASSERT(NULL != fProgramEffects.get()); GrDrawEffect drawEffect(stage, fProgramEffects->fHasExplicitLocalCoords); @@ -267,7 +265,7 @@ void GrGLProgramEffectsBuilder::emitEffect(const GrEffectStage& stage, this->emitAttributes(stage); this->emitTransforms(effect, key, &coords); - this->emitSamplers(effect, &samplers); + INHERITED::emitSamplers(fBuilder, fProgramEffects.get(), effect, &samplers); GrGLEffect* glEffect = effect->getFactory().createGLInstance(drawEffect); fProgramEffects->fGLEffects.push_back(glEffect); @@ -275,38 +273,37 @@ void GrGLProgramEffectsBuilder::emitEffect(const GrEffectStage& stage, // Enclose custom code in a block to avoid namespace conflicts SkString openBrace; openBrace.printf("\t{ // Stage %d: %s\n", stageIndex, glEffect->name()); - vertexBuilder->vsCodeAppend(openBrace.c_str()); + fBuilder->vsCodeAppend(openBrace.c_str()); fBuilder->fsCodeAppend(openBrace.c_str()); - glEffect->emitCode(fBuilder, drawEffect, key, outColor, inColor, coords, samplers); + if (glEffect->isVertexEffect()) { + GrGLVertexEffect* vertexEffect = static_cast(glEffect); + vertexEffect->emitCode(fBuilder, drawEffect, key, outColor, inColor, coords, samplers); + } else { + glEffect->emitCode(fBuilder, drawEffect, key, outColor, inColor, coords, samplers); + } - vertexBuilder->vsCodeAppend("\t}\n"); + fBuilder->vsCodeAppend("\t}\n"); fBuilder->fsCodeAppend("\t}\n"); } -void GrGLProgramEffectsBuilder::emitAttributes(const GrEffectStage& stage) { - GrGLShaderBuilder::VertexBuilder* vertexBuilder = fBuilder->getVertexBuilder(); - SkASSERT(NULL != vertexBuilder); - +void GrGLVertexProgramEffectsBuilder::emitAttributes(const GrEffectStage& stage) { int numAttributes = stage.getVertexAttribIndexCount(); const int* attributeIndices = stage.getVertexAttribIndices(); for (int a = 0; a < numAttributes; ++a) { // TODO: Make addAttribute mangle the name. SkString attributeName("aAttr"); attributeName.appendS32(attributeIndices[a]); - vertexBuilder->addEffectAttribute(attributeIndices[a], - (*stage.getEffect())->vertexAttribType(a), - attributeName); + fBuilder->addEffectAttribute(attributeIndices[a], + (*stage.getEffect())->vertexAttribType(a), + attributeName); } } -void GrGLProgramEffectsBuilder::emitTransforms(const GrEffectRef& effect, - EffectKey effectKey, - TransformedCoordsArray* outCoords) { - GrGLShaderBuilder::VertexBuilder* vertexBuilder = fBuilder->getVertexBuilder(); - SkASSERT(NULL != vertexBuilder); - - typedef GrGLProgramEffects::Transform Transform; +void GrGLVertexProgramEffectsBuilder::emitTransforms(const GrEffectRef& effect, + EffectKey effectKey, + TransformedCoordsArray* outCoords) { + typedef GrGLVertexProgramEffects::Transform Transform; SkTArray& transforms = fProgramEffects->fTransforms.push_back(); EffectKey totalKey = GrBackendEffectFactory::GetTransformKey(effectKey); int numTransforms = effect->numTransforms(); @@ -361,30 +358,30 @@ void GrGLProgramEffectsBuilder::emitTransforms(const GrEffectRef& effect, } const char* vsVaryingName; const char* fsVaryingName; - vertexBuilder->addVarying(varyingType, varyingName, &vsVaryingName, &fsVaryingName); + fBuilder->addVarying(varyingType, varyingName, &vsVaryingName, &fsVaryingName); const GrGLShaderVar& coords = (kPositionCoords_Flag & key) ? - vertexBuilder->positionAttribute() : - vertexBuilder->localCoordsAttribute(); + fBuilder->positionAttribute() : + fBuilder->localCoordsAttribute(); // varying = matrix * coords (logically) switch (transforms[t].fType) { case kVoid_GrSLType: SkASSERT(kVec2f_GrSLType == varyingType); - vertexBuilder->vsCodeAppendf("\t%s = %s;\n", vsVaryingName, coords.c_str()); + fBuilder->vsCodeAppendf("\t%s = %s;\n", vsVaryingName, coords.c_str()); break; case kVec2f_GrSLType: SkASSERT(kVec2f_GrSLType == varyingType); - vertexBuilder->vsCodeAppendf("\t%s = %s + %s;\n", - vsVaryingName, uniName, coords.c_str()); + fBuilder->vsCodeAppendf("\t%s = %s + %s;\n", + vsVaryingName, uniName, coords.c_str()); break; case kMat33f_GrSLType: { SkASSERT(kVec2f_GrSLType == varyingType || kVec3f_GrSLType == varyingType); if (kVec2f_GrSLType == varyingType) { - vertexBuilder->vsCodeAppendf("\t%s = (%s * vec3(%s, 1)).xy;\n", - vsVaryingName, uniName, coords.c_str()); + fBuilder->vsCodeAppendf("\t%s = (%s * vec3(%s, 1)).xy;\n", + vsVaryingName, uniName, coords.c_str()); } else { - vertexBuilder->vsCodeAppendf("\t%s = %s * vec3(%s, 1);\n", - vsVaryingName, uniName, coords.c_str()); + fBuilder->vsCodeAppendf("\t%s = %s * vec3(%s, 1);\n", + vsVaryingName, uniName, coords.c_str()); } break; } @@ -395,18 +392,20 @@ void GrGLProgramEffectsBuilder::emitTransforms(const GrEffectRef& effect, } } -void GrGLProgramEffectsBuilder::emitSamplers(const GrEffectRef& effect, +void GrGLProgramEffectsBuilder::emitSamplers(GrGLShaderBuilder* builder, + GrGLProgramEffects* programEffects, + const GrEffectRef& effect, TextureSamplerArray* outSamplers) { typedef GrGLProgramEffects::Sampler Sampler; - SkTArray& samplers = fProgramEffects->fSamplers.push_back(); + SkTArray& samplers = programEffects->fSamplers.push_back(); int numTextures = effect->numTextures(); samplers.push_back_n(numTextures); SkString name; for (int t = 0; t < numTextures; ++t) { name.printf("Sampler%d", t); - samplers[t].fUniform = fBuilder->addUniform(GrGLShaderBuilder::kFragment_Visibility, - kSampler2D_GrSLType, - name.c_str()); + samplers[t].fUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility, + kSampler2D_GrSLType, + name.c_str()); SkNEW_APPEND_TO_TARRAY(outSamplers, TextureSampler, (samplers[t].fUniform, effect->textureAccess(t))); } diff --git a/src/gpu/gl/GrGLProgramEffects.h b/src/gpu/gl/GrGLProgramEffects.h index b74dc96c4b..f6f975ae4e 100644 --- a/src/gpu/gl/GrGLProgramEffects.h +++ b/src/gpu/gl/GrGLProgramEffects.h @@ -15,7 +15,9 @@ class GrEffectStage; class GrGLProgramEffectsBuilder; +class GrGLVertexProgramEffectsBuilder; class GrGLShaderBuilder; +class GrGLFullShaderBuilder; /** * This class encapsulates an array of GrGLEffects and their supporting data (coord transforms @@ -34,7 +36,7 @@ public: static EffectKey GenTransformKey(const GrDrawEffect&); static EffectKey GenTextureKey(const GrDrawEffect&, const GrGLCaps&); - ~GrGLProgramEffects(); + virtual ~GrGLProgramEffects(); /** * Assigns a texture unit to each sampler. It starts on *texUnitIdx and writes the next @@ -45,9 +47,9 @@ public: /** * Calls setData() on each effect, and sets their transformation matrices and texture bindings. */ - void setData(GrGpuGL*, - const GrGLUniformManager&, - const GrEffectStage* effectStages[]); + virtual void setData(GrGpuGL*, + const GrGLUniformManager&, + const GrEffectStage* effectStages[]) = 0; /** * Passed to GrGLEffects so they can add transformed coordinates to their shader code. @@ -94,13 +96,44 @@ public: typedef SkTArray TextureSamplerArray; -private: +protected: friend class GrGLProgramEffectsBuilder; - GrGLProgramEffects(int reserveCount, bool explicitLocalCoords) + GrGLProgramEffects(int reserveCount) : fGLEffects(reserveCount) + , fSamplers(reserveCount) { + } + + /** + * Helper for setData(). Binds all the textures for an effect. + */ + void bindTextures(GrGpuGL*, const GrEffectRef&, int effectIdx); + + struct Sampler { + SkDEBUGCODE(Sampler() : fTextureUnit(-1) {}) + UniformHandle fUniform; + int fTextureUnit; + }; + + SkTArray fGLEffects; + SkTArray > fSamplers; +}; + +/** + * This is a GrGLProgramEffects implementation that does coord transforms with the vertex shader. + */ +class GrGLVertexProgramEffects : public GrGLProgramEffects { +public: + virtual void setData(GrGpuGL*, + const GrGLUniformManager&, + const GrEffectStage* effectStages[]) SK_OVERRIDE; + +private: + friend class GrGLVertexProgramEffectsBuilder; + + GrGLVertexProgramEffects(int reserveCount, bool explicitLocalCoords) + : INHERITED(reserveCount) , fTransforms(reserveCount) - , fSamplers(reserveCount) , fHasExplicitLocalCoords(explicitLocalCoords) { } @@ -109,11 +142,6 @@ private: */ void setTransformData(const GrGLUniformManager&, const GrDrawEffect&, int effectIdx); - /** - * Helper for setData(). Binds all the textures for an effect. - */ - void bindTextures(GrGpuGL*, const GrEffectRef&, int effectIdx); - struct Transform { Transform() { fCurrentValue = SkMatrix::InvalidMatrix(); } UniformHandle fHandle; @@ -121,35 +149,51 @@ private: SkMatrix fCurrentValue; }; - struct Sampler { - SkDEBUGCODE(Sampler() : fTextureUnit(-1) {}) - UniformHandle fUniform; - int fTextureUnit; - }; - - SkTArray fGLEffects; SkTArray > fTransforms; - SkTArray > fSamplers; bool fHasExplicitLocalCoords; + + typedef GrGLProgramEffects INHERITED; }; //////////////////////////////////////////////////////////////////////////////// /** - * This class is used to construct a GrGLProgramEffects. + * This is an abstract base class for constructing different types of GrGLProgramEffects objects. */ class GrGLProgramEffectsBuilder { public: - GrGLProgramEffectsBuilder(GrGLShaderBuilder* builder, int reserveCount); - /** * Emits the effect's shader code, and stores the necessary uniforms internally. */ - void emitEffect(const GrEffectStage&, - GrGLProgramEffects::EffectKey, - const char* outColor, - const char* inColor, - int stageIndex); + virtual void emitEffect(const GrEffectStage&, + GrGLProgramEffects::EffectKey, + const char* outColor, + const char* inColor, + int stageIndex) = 0; + +protected: + /** + * Helper for emitEffect(). Emits uniforms for an effect's texture accesses and appends the + * necessary data to the TextureSamplerArray* object so effects can add texture lookups. + */ + static void emitSamplers(GrGLShaderBuilder*, + GrGLProgramEffects*, + const GrEffectRef&, + GrGLProgramEffects::TextureSamplerArray*); +}; + +/** + * This class is used to construct a GrGLVertexProgramEffects object. + */ +class GrGLVertexProgramEffectsBuilder : public GrGLProgramEffectsBuilder { +public: + GrGLVertexProgramEffectsBuilder(GrGLFullShaderBuilder*, int reserveCount); + + virtual void emitEffect(const GrEffectStage&, + GrGLProgramEffects::EffectKey, + const char* outColor, + const char* inColor, + int stageIndex) SK_OVERRIDE; /** * Finalizes the building process and returns the effect array. After this call, the builder @@ -174,16 +218,10 @@ private: GrGLProgramEffects::EffectKey, GrGLProgramEffects::TransformedCoordsArray*); - /** - * Helper for emitEffect(). Emits uniforms for an effect's texture accesses. The uniform info - * as well as texture access parameters are appended to the TextureSamplerArray* object, which - * is in turn passed to the effect's emitCode() function. - */ - void emitSamplers(const GrEffectRef&, - GrGLProgramEffects::TextureSamplerArray*); + GrGLFullShaderBuilder* fBuilder; + SkAutoTDelete fProgramEffects; - GrGLShaderBuilder* fBuilder; - SkAutoTDelete fProgramEffects; + typedef GrGLProgramEffectsBuilder INHERITED; }; #endif diff --git a/src/gpu/gl/GrGLShaderBuilder.cpp b/src/gpu/gl/GrGLShaderBuilder.cpp index c33f04ba30..089ece7c07 100644 --- a/src/gpu/gl/GrGLShaderBuilder.cpp +++ b/src/gpu/gl/GrGLShaderBuilder.cpp @@ -15,8 +15,8 @@ #include "SkRTConf.h" #include "SkTrace.h" -#define GL_CALL(X) GR_GL_CALL(fGpu->glInterface(), X) -#define GL_CALL_RET(R, X) GR_GL_CALL_RET(fGpu->glInterface(), R, X) +#define GL_CALL(X) GR_GL_CALL(this->gpu()->glInterface(), X) +#define GL_CALL_RET(R, X) GR_GL_CALL_RET(this->gpu()->glInterface(), R, X) // number of each input/output type in a single allocation block static const int kVarsPerBlock = 8; @@ -91,27 +91,22 @@ static const char kDstCopyColorName[] = "_dstColor"; GrGLShaderBuilder::GrGLShaderBuilder(GrGpuGL* gpu, GrGLUniformManager& uniformManager, - const GrGLProgramDesc& desc, - bool needsVertexShader) - : fUniforms(kVarsPerBlock) - , fGpu(gpu) + const GrGLProgramDesc& desc) + : fGpu(gpu) , fUniformManager(uniformManager) , fFSFeaturesAddedMask(0) , fFSInputs(kVarsPerBlock) , fFSOutputs(kMaxFSOutputs) + , fUniforms(kVarsPerBlock) , fSetupFragPosition(false) - , fKnownColorValue(kNone_GrSLConstantVec) - , fKnownCoverageValue(kNone_GrSLConstantVec) + , fKnownColorValue(GrGLProgramDesc::KnownColorInputValue(desc.getHeader().fColorInput)) + , fKnownCoverageValue(GrGLProgramDesc::KnownColorInputValue(desc.getHeader().fCoverageInput)) , fHasCustomColorOutput(false) , fHasSecondaryOutput(false) , fTopLeftFragPosRead(kTopLeftFragPosRead_FragPosKey == desc.getHeader().fFragPosKey) { const GrGLProgramDesc::KeyHeader& header = desc.getHeader(); - if (needsVertexShader) { - fVertexBuilder.reset(SkNEW_ARGS(VertexBuilder, (this, fGpu, desc))); - } - // Emit code to read the dst copy textue if necessary. if (kNoDstRead_DstReadKey != header.fDstReadKey && GrGLCaps::kNone_FBFetchType == fGpu->glCaps().fbFetchType()) { @@ -152,58 +147,18 @@ GrGLShaderBuilder::GrGLShaderBuilder(GrGpuGL* gpu, this->fsCodeAppend(";\n\n"); } - switch (header.fColorInput) { - case GrGLProgramDesc::kAttribute_ColorInput: { - SkASSERT(NULL != fVertexBuilder.get()); - fVertexBuilder->addAttribute(kVec4f_GrSLType, color_attribute_name()); - const char *vsName, *fsName; - fVertexBuilder->addVarying(kVec4f_GrSLType, "Color", &vsName, &fsName); - fVertexBuilder->vsCodeAppendf("\t%s = %s;\n", vsName, color_attribute_name()); - fInputColor = fsName; - break; - } - case GrGLProgramDesc::kUniform_ColorInput: { - const char* name; - fColorUniform = this->addUniform(GrGLShaderBuilder::kFragment_Visibility, - kVec4f_GrSLType, "Color", &name); - fInputColor = name; - break; - } - case GrGLProgramDesc::kTransBlack_ColorInput: - fKnownColorValue = kZeros_GrSLConstantVec; - break; - case GrGLProgramDesc::kSolidWhite_ColorInput: - fKnownColorValue = kOnes_GrSLConstantVec; - break; - default: - GrCrash("Unknown color type."); - } - - switch (header.fCoverageInput) { - case GrGLProgramDesc::kAttribute_ColorInput: { - SkASSERT(NULL != fVertexBuilder.get()); - fVertexBuilder->addAttribute(kVec4f_GrSLType, coverage_attribute_name()); - const char *vsName, *fsName; - fVertexBuilder->addVarying(kVec4f_GrSLType, "Coverage", &vsName, &fsName); - fVertexBuilder->vsCodeAppendf("\t%s = %s;\n", vsName, coverage_attribute_name()); - fInputCoverage = fsName; - break; - } - case GrGLProgramDesc::kUniform_ColorInput: { - const char* name; - fCoverageUniform = this->addUniform(GrGLShaderBuilder::kFragment_Visibility, - kVec4f_GrSLType, "Coverage", &name); - fInputCoverage = name; - break; - } - case GrGLProgramDesc::kTransBlack_ColorInput: - fKnownCoverageValue = kZeros_GrSLConstantVec; - break; - case GrGLProgramDesc::kSolidWhite_ColorInput: - fKnownCoverageValue = kOnes_GrSLConstantVec; - break; - default: - GrCrash("Unknown coverage type."); + if (GrGLProgramDesc::kUniform_ColorInput == header.fColorInput) { + const char* name; + fColorUniform = this->addUniform(GrGLShaderBuilder::kFragment_Visibility, + kVec4f_GrSLType, "Color", &name); + fInputColor = name; + } + + if (GrGLProgramDesc::kUniform_ColorInput == header.fCoverageInput) { + const char* name; + fCoverageUniform = this->addUniform(GrGLShaderBuilder::kFragment_Visibility, + kVec4f_GrSLType, "Coverage", &name); + fInputCoverage = name; } if (k110_GrGLSLGeneration != fGpu->glslGeneration()) { @@ -551,14 +506,12 @@ void GrGLShaderBuilder::appendUniformDecls(ShaderVisibility visibility, } } -GrGLProgramEffects* GrGLShaderBuilder::createAndEmitEffects( - const GrEffectStage* effectStages[], - const EffectKey effectKeys[], - int effectCnt, - SkString* fsInOutColor, - GrSLConstantVec* fsInOutColorKnownValue) { - - GrGLProgramEffectsBuilder programEffectsBuilder(this, effectCnt); +void GrGLShaderBuilder::createAndEmitEffects(GrGLProgramEffectsBuilder* programEffectsBuilder, + const GrEffectStage* effectStages[], + const EffectKey effectKeys[], + int effectCnt, + SkString* fsInOutColor, + GrSLConstantVec* fsInOutColorKnownValue) { bool effectEmitted = false; SkString inColor = *fsInOutColor; @@ -580,11 +533,11 @@ GrGLProgramEffects* GrGLShaderBuilder::createAndEmitEffects( this->nameVariable(&outColor, '\0', "output"); this->fsCodeAppendf("\tvec4 %s;\n", outColor.c_str()); - programEffectsBuilder.emitEffect(stage, - effectKeys[e], - outColor.c_str(), - inColor.isEmpty() ? NULL : inColor.c_str(), - fCodeStage.stageIndex()); + programEffectsBuilder->emitEffect(stage, + effectKeys[e], + outColor.c_str(), + inColor.isEmpty() ? NULL : inColor.c_str(), + fCodeStage.stageIndex()); inColor = outColor; *fsInOutColorKnownValue = kNone_GrSLConstantVec; @@ -594,8 +547,6 @@ GrGLProgramEffects* GrGLShaderBuilder::createAndEmitEffects( if (effectEmitted) { *fsInOutColor = outColor; } - - return programEffectsBuilder.finish(); } const char* GrGLShaderBuilder::getColorOutputName() const { @@ -706,10 +657,6 @@ bool attach_shader(const GrGLInterface* gli, } bool GrGLShaderBuilder::compileAndAttachShaders(GrGLuint programId) const { - if (NULL != fVertexBuilder.get() && !fVertexBuilder->compileAndAttachShaders(programId)) { - return false; - } - SkString fragShaderSrc(GrGetGLSLVersionDecl(this->ctxInfo())); fragShaderSrc.append(fFSExtensions); append_default_precision_qualifier(kDefaultFragmentPrecision, @@ -732,10 +679,6 @@ bool GrGLShaderBuilder::compileAndAttachShaders(GrGLuint programId) const { } void GrGLShaderBuilder::bindProgramLocations(GrGLuint programId) const { - if (NULL != fVertexBuilder.get()) { - fVertexBuilder->bindProgramLocations(programId); - } - if (fHasCustomColorOutput) { GL_CALL(BindFragDataLocation(programId, 0, declared_color_output_name())); } @@ -748,13 +691,12 @@ const GrGLContextInfo& GrGLShaderBuilder::ctxInfo() const { return fGpu->ctxInfo(); } -//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// -GrGLShaderBuilder::VertexBuilder::VertexBuilder(GrGLShaderBuilder* parent, - GrGpuGL* gpu, - const GrGLProgramDesc& desc) - : fParent(parent) - , fGpu(gpu) +GrGLFullShaderBuilder::GrGLFullShaderBuilder(GrGpuGL* gpu, + GrGLUniformManager& uniformManager, + const GrGLProgramDesc& desc) + : INHERITED(gpu, uniformManager, desc) , fDesc(desc) , fVSAttrs(kVarsPerBlock) , fVSOutputs(kVarsPerBlock) @@ -775,8 +717,8 @@ GrGLShaderBuilder::VertexBuilder::VertexBuilder(GrGLShaderBuilder* parent, } const char* viewMName; - fViewMatrixUniform = fParent->addUniform(GrGLShaderBuilder::kVertex_Visibility, - kMat33f_GrSLType, "ViewM", &viewMName); + fViewMatrixUniform = this->addUniform(GrGLShaderBuilder::kVertex_Visibility, + kMat33f_GrSLType, "ViewM", &viewMName); this->vsCodeAppendf("\tvec3 pos3 = %s * vec3(%s, 1);\n" "\tgl_Position = vec4(pos3.xy, 0, pos3.z);\n", @@ -790,10 +732,25 @@ GrGLShaderBuilder::VertexBuilder::VertexBuilder(GrGLShaderBuilder* parent, ) { this->vsCodeAppend("\tgl_PointSize = 1.0;\n"); } + + if (GrGLProgramDesc::kAttribute_ColorInput == header.fColorInput) { + this->addAttribute(kVec4f_GrSLType, color_attribute_name()); + const char *vsName, *fsName; + this->addVarying(kVec4f_GrSLType, "Color", &vsName, &fsName); + this->vsCodeAppendf("\t%s = %s;\n", vsName, color_attribute_name()); + this->setInputColor(fsName); + } + + if (GrGLProgramDesc::kAttribute_ColorInput == header.fCoverageInput) { + this->addAttribute(kVec4f_GrSLType, coverage_attribute_name()); + const char *vsName, *fsName; + this->addVarying(kVec4f_GrSLType, "Coverage", &vsName, &fsName); + this->vsCodeAppendf("\t%s = %s;\n", vsName, coverage_attribute_name()); + this->setInputCoverage(fsName); + } } -bool GrGLShaderBuilder::VertexBuilder::addAttribute(GrSLType type, - const char* name) { +bool GrGLFullShaderBuilder::addAttribute(GrSLType type, const char* name) { for (int i = 0; i < fVSAttrs.count(); ++i) { const GrGLShaderVar& attr = fVSAttrs[i]; // if attribute already added, don't add it again @@ -808,9 +765,9 @@ bool GrGLShaderBuilder::VertexBuilder::addAttribute(GrSLType type, return true; } -bool GrGLShaderBuilder::VertexBuilder::addEffectAttribute(int attributeIndex, - GrSLType type, - const SkString& name) { +bool GrGLFullShaderBuilder::addEffectAttribute(int attributeIndex, + GrSLType type, + const SkString& name) { if (!this->addAttribute(type, name.c_str())) { return false; } @@ -819,14 +776,14 @@ bool GrGLShaderBuilder::VertexBuilder::addEffectAttribute(int attributeIndex, return true; } -void GrGLShaderBuilder::VertexBuilder::addVarying(GrSLType type, - const char* name, - const char** vsOutName, - const char** fsInName) { +void GrGLFullShaderBuilder::addVarying(GrSLType type, + const char* name, + const char** vsOutName, + const char** fsInName) { fVSOutputs.push_back(); fVSOutputs.back().setType(type); fVSOutputs.back().setTypeModifier(GrGLShaderVar::kVaryingOut_TypeModifier); - fParent->nameVariable(fVSOutputs.back().accessName(), 'v', name); + this->nameVariable(fVSOutputs.back().accessName(), 'v', name); if (vsOutName) { *vsOutName = fVSOutputs.back().getName().c_str(); @@ -845,22 +802,20 @@ void GrGLShaderBuilder::VertexBuilder::addVarying(GrSLType type, fGSOutputs.push_back(); fGSOutputs.back().setType(type); fGSOutputs.back().setTypeModifier(GrGLShaderVar::kVaryingOut_TypeModifier); - fParent->nameVariable(fGSOutputs.back().accessName(), 'g', name); + this->nameVariable(fGSOutputs.back().accessName(), 'g', name); fsName = fGSOutputs.back().accessName(); } else #endif { fsName = fVSOutputs.back().accessName(); } - fParent->fsInputAppend().set(type, - GrGLShaderVar::kVaryingIn_TypeModifier, - *fsName); + this->fsInputAppend().set(type, GrGLShaderVar::kVaryingIn_TypeModifier, *fsName); if (fsInName) { *fsInName = fsName->c_str(); } } -const SkString* GrGLShaderBuilder::VertexBuilder::getEffectAttributeName(int attributeIndex) const { +const SkString* GrGLFullShaderBuilder::getEffectAttributeName(int attributeIndex) const { const AttributePair* attribEnd = fEffectAttributes.end(); for (const AttributePair* attrib = fEffectAttributes.begin(); attrib != attribEnd; ++attrib) { if (attrib->fIndex == attributeIndex) { @@ -871,26 +826,44 @@ const SkString* GrGLShaderBuilder::VertexBuilder::getEffectAttributeName(int att return NULL; } -bool GrGLShaderBuilder::VertexBuilder::compileAndAttachShaders(GrGLuint programId) const { - SkString vertShaderSrc(GrGetGLSLVersionDecl(fParent->ctxInfo())); - fParent->appendUniformDecls(kVertex_Visibility, &vertShaderSrc); - fParent->appendDecls(fVSAttrs, &vertShaderSrc); - fParent->appendDecls(fVSOutputs, &vertShaderSrc); +GrGLProgramEffects* GrGLFullShaderBuilder::createAndEmitEffects( + const GrEffectStage* effectStages[], + const EffectKey effectKeys[], + int effectCnt, + SkString* inOutFSColor, + GrSLConstantVec* fsInOutColorKnownValue) { + + GrGLVertexProgramEffectsBuilder programEffectsBuilder(this, effectCnt); + this->INHERITED::createAndEmitEffects(&programEffectsBuilder, + effectStages, + effectKeys, + effectCnt, + inOutFSColor, + fsInOutColorKnownValue); + return programEffectsBuilder.finish(); +} + +bool GrGLFullShaderBuilder::compileAndAttachShaders(GrGLuint programId) const { + const GrGLInterface* glInterface = this->gpu()->glInterface(); + SkString vertShaderSrc(GrGetGLSLVersionDecl(this->ctxInfo())); + this->appendUniformDecls(kVertex_Visibility, &vertShaderSrc); + this->appendDecls(fVSAttrs, &vertShaderSrc); + this->appendDecls(fVSOutputs, &vertShaderSrc); vertShaderSrc.append("void main() {\n"); vertShaderSrc.append(fVSCode); vertShaderSrc.append("}\n"); - if (!attach_shader(fGpu->glInterface(), programId, GR_GL_VERTEX_SHADER, vertShaderSrc)) { + if (!attach_shader(glInterface, programId, GR_GL_VERTEX_SHADER, vertShaderSrc)) { return false; } #if GR_GL_EXPERIMENTAL_GS if (fDesc.getHeader().fExperimentalGS) { - SkASSERT(fGpu->glslGeneration() >= k150_GrGLSLGeneration); - SkString geomShaderSrc(GrGetGLSLVersionDecl(fParent->ctxInfo())); + SkASSERT(this->ctxInfo().glslGeneration() >= k150_GrGLSLGeneration); + SkString geomShaderSrc(GrGetGLSLVersionDecl(this->ctxInfo())); geomShaderSrc.append("layout(triangles) in;\n" "layout(triangle_strip, max_vertices = 6) out;\n"); - fParent->appendDecls(fGSInputs, &geomShaderSrc); - fParent->appendDecls(fGSOutputs, &geomShaderSrc); + this->appendDecls(fGSInputs, &geomShaderSrc); + this->appendDecls(fGSOutputs, &geomShaderSrc); geomShaderSrc.append("void main() {\n"); geomShaderSrc.append("\tfor (int i = 0; i < 3; ++i) {\n" "\t\tgl_Position = gl_in[i].gl_Position;\n"); @@ -907,16 +880,18 @@ bool GrGLShaderBuilder::VertexBuilder::compileAndAttachShaders(GrGLuint programI "\t}\n" "\tEndPrimitive();\n"); geomShaderSrc.append("}\n"); - if (!attach_shader(fGpu->glInterface(), programId, GR_GL_GEOMETRY_SHADER, geomShaderSrc)) { + if (!attach_shader(glInterface, programId, GR_GL_GEOMETRY_SHADER, geomShaderSrc)) { return false; } } #endif - return true; + return this->INHERITED::compileAndAttachShaders(programId); } -void GrGLShaderBuilder::VertexBuilder::bindProgramLocations(GrGLuint programId) const { +void GrGLFullShaderBuilder::bindProgramLocations(GrGLuint programId) const { + this->INHERITED::bindProgramLocations(programId); + const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader(); // Bind the attrib locations to same values for all shaders diff --git a/src/gpu/gl/GrGLShaderBuilder.h b/src/gpu/gl/GrGLShaderBuilder.h index 4553ac3a0e..4c43fc36c3 100644 --- a/src/gpu/gl/GrGLShaderBuilder.h +++ b/src/gpu/gl/GrGLShaderBuilder.h @@ -33,6 +33,7 @@ public: typedef GrBackendEffectFactory::EffectKey EffectKey; typedef GrGLProgramEffects::TextureSampler TextureSampler; typedef GrGLProgramEffects::TransformedCoordsArray TransformedCoordsArray; + typedef GrGLUniformManager::BuilderUniform BuilderUniform; enum ShaderVisibility { kVertex_Visibility = 0x1, @@ -40,10 +41,8 @@ public: kFragment_Visibility = 0x4, }; - GrGLShaderBuilder(GrGpuGL*, - GrGLUniformManager&, - const GrGLProgramDesc&, - bool needsVertexShader); + GrGLShaderBuilder(GrGpuGL*, GrGLUniformManager&, const GrGLProgramDesc&); + virtual ~GrGLShaderBuilder() {} /** * Use of these features may require a GLSL extension to be enabled. Shaders may not compile @@ -104,9 +103,6 @@ public: const char* body, SkString* outName); - /** Add input/output variable declarations (i.e. 'varying') to the fragment shader. */ - GrGLShaderVar& fsInputAppend() { return fFSInputs.push_back(); } - typedef uint8_t DstReadKey; typedef uint8_t FragPosKey; @@ -174,10 +170,22 @@ public: * TODO: These are used by GrGLProgram to insert a mode color filter. Remove these when the * color filter is expressed as a GrEffect. */ - const SkString& getInputColor() const { return fInputColor; } - GrSLConstantVec getKnownColorValue() const { return fKnownColorValue; } - const SkString& getInputCoverage() const { return fInputCoverage; } - GrSLConstantVec getKnownCoverageValue() const { return fKnownCoverageValue; } + const SkString& getInputColor() const { + SkASSERT(fInputColor.isEmpty() != (kNone_GrSLConstantVec == fKnownColorValue)); + return fInputColor; + } + GrSLConstantVec getKnownColorValue() const { + SkASSERT(fInputColor.isEmpty() != (kNone_GrSLConstantVec == fKnownColorValue)); + return fKnownColorValue; + } + const SkString& getInputCoverage() const { + SkASSERT(fInputCoverage.isEmpty() != (kNone_GrSLConstantVec == fKnownCoverageValue)); + return fInputCoverage; + } + GrSLConstantVec getKnownCoverageValue() const { + SkASSERT(fInputCoverage.isEmpty() != (kNone_GrSLConstantVec == fKnownCoverageValue)); + return fKnownCoverageValue; + } /** * Adds code for effects and returns a GrGLProgramEffects* object. The caller is responsible for @@ -188,11 +196,11 @@ public: * output color. The handles to texture samplers for effectStage[i] are added to * effectSamplerHandles[i]. */ - GrGLProgramEffects* createAndEmitEffects(const GrEffectStage* effectStages[], - const EffectKey effectKeys[], - int effectCnt, - SkString* inOutFSColor, - GrSLConstantVec* fsInOutColorKnownValue); + virtual GrGLProgramEffects* createAndEmitEffects(const GrEffectStage* effectStages[], + const EffectKey effectKeys[], + int effectCnt, + SkString* inOutFSColor, + GrSLConstantVec* fsInOutColorKnownValue) = 0; const char* getColorOutputName() const; const char* enableSecondaryOutput(); @@ -210,106 +218,38 @@ public: return fDstCopySamplerUniform; } - /** Helper class used to build the vertex and geometry shaders. This functionality - is kept separate from the rest of GrGLShaderBuilder to allow for shaders programs - that only use the fragment shader. */ - class VertexBuilder { - public: - VertexBuilder(GrGLShaderBuilder* parent, GrGpuGL* gpu, const GrGLProgramDesc&); - - /** - * Called by GrGLEffects to add code to one of the shaders. - */ - void vsCodeAppendf(const char format[], ...) SK_PRINTF_LIKE(2, 3) { - va_list args; - va_start(args, format); - fVSCode.appendf(format, args); - va_end(args); - } - - void vsCodeAppend(const char* str) { fVSCode.append(str); } - - /** Add a vertex attribute to the current program that is passed in from the vertex data. - Returns false if the attribute was already there, true otherwise. */ - bool addAttribute(GrSLType type, const char* name); - - /** Add a varying variable to the current program to pass values between vertex and fragment - shaders. If the last two parameters are non-NULL, they are filled in with the name - generated. */ - void addVarying(GrSLType type, - const char* name, - const char** vsOutName = NULL, - const char** fsInName = NULL); - - /** Returns a vertex attribute that represents the vertex position in the VS. This is the - pre-matrix position and is commonly used by effects to compute texture coords via a matrix. - */ - const GrGLShaderVar& positionAttribute() const { return *fPositionVar; } - - /** Returns a vertex attribute that represents the local coords in the VS. This may be the same - as positionAttribute() or it may not be. It depends upon whether the rendering code - specified explicit local coords or not in the GrDrawState. */ - const GrGLShaderVar& localCoordsAttribute() const { return *fLocalCoordsVar; } - - /** - * Are explicit local coordinates provided as input to the vertex shader. - */ - bool hasExplicitLocalCoords() const { return (fLocalCoordsVar != fPositionVar); } - - bool addEffectAttribute(int attributeIndex, GrSLType type, const SkString& name); - const SkString* getEffectAttributeName(int attributeIndex) const; - - GrGLUniformManager::UniformHandle getViewMatrixUniform() const { - return fViewMatrixUniform; - } + bool finish(GrGLuint* outProgramId); - bool compileAndAttachShaders(GrGLuint programId) const; - void bindProgramLocations(GrGLuint programId) const; + const GrGLContextInfo& ctxInfo() const; - private: - GrGLShaderBuilder* fParent; - GrGpuGL* fGpu; - const GrGLProgramDesc& fDesc; - VarArray fVSAttrs; - VarArray fVSOutputs; - VarArray fGSInputs; - VarArray fGSOutputs; - - SkString fVSCode; - - struct AttributePair { - void set(int index, const SkString& name) { - fIndex = index; fName = name; - } - int fIndex; - SkString fName; - }; - SkSTArray<10, AttributePair, true> fEffectAttributes; +protected: + GrGpuGL* gpu() const { return fGpu; } - GrGLUniformManager::UniformHandle fViewMatrixUniform; + void setInputColor(const char* inputColor) { fInputColor = inputColor; } + void setInputCoverage(const char* inputCoverage) { fInputCoverage = inputCoverage; } - GrGLShaderVar* fPositionVar; - GrGLShaderVar* fLocalCoordsVar; - }; + /** Add input/output variable declarations (i.e. 'varying') to the fragment shader. */ + GrGLShaderVar& fsInputAppend() { return fFSInputs.push_back(); } - /** Gets the vertex builder that is used to construct the vertex and geometry shaders. - It may be NULL if this shader program is only meant to have a fragment shader. */ - VertexBuilder* getVertexBuilder() const { return fVertexBuilder.get(); } + // Generates a name for a variable. The generated string will be name prefixed by the prefix + // char (unless the prefix is '\0'). It also mangles the name to be stage-specific if we're + // generating stage code. + void nameVariable(SkString* out, char prefix, const char* name); - bool finish(GrGLuint* outProgramId); + // Helper for emitEffects(). + void createAndEmitEffects(GrGLProgramEffectsBuilder*, + const GrEffectStage* effectStages[], + const EffectKey effectKeys[], + int effectCnt, + SkString* inOutFSColor, + GrSLConstantVec* fsInOutColorKnownValue); - const GrGLContextInfo& ctxInfo() const; + virtual bool compileAndAttachShaders(GrGLuint programId) const; + virtual void bindProgramLocations(GrGLuint programId) const; -private: void appendDecls(const VarArray&, SkString*) const; void appendUniformDecls(ShaderVisibility, SkString*) const; - bool compileAndAttachShaders(GrGLuint programId) const; - void bindProgramLocations(GrGLuint programId) const; - - typedef GrGLUniformManager::BuilderUniform BuilderUniform; - GrGLUniformManager::BuilderUniformArray fUniforms; - private: class CodeStage : public SkNoncopyable { public: @@ -376,11 +316,6 @@ private: // track the enables separately for each shader. void addFSFeature(uint32_t featureBit, const char* extensionName); - // Generates a name for a variable. The generated string will be name prefixed by the prefix - // char (unless the prefix is '\0'). It also mangles the name to be stage-specific if we're - // generating stage code. - void nameVariable(SkString* out, char prefix, const char* name); - // Interpretation of DstReadKey when generating code enum { kNoDstRead_DstReadKey = 0, @@ -395,36 +330,124 @@ private: kBottomLeftFragPosRead_FragPosKey = 0x2,// Read frag pos relative to bottom-left. }; - GrGpuGL* fGpu; - GrGLUniformManager& fUniformManager; - uint32_t fFSFeaturesAddedMask; - SkString fFSFunctions; - SkString fFSExtensions; - VarArray fFSInputs; - VarArray fFSOutputs; + GrGpuGL* fGpu; + GrGLUniformManager& fUniformManager; + uint32_t fFSFeaturesAddedMask; + SkString fFSFunctions; + SkString fFSExtensions; + VarArray fFSInputs; + VarArray fFSOutputs; + GrGLUniformManager::BuilderUniformArray fUniforms; + + SkString fFSCode; + + bool fSetupFragPosition; + GrGLUniformManager::UniformHandle fDstCopySamplerUniform; + + SkString fInputColor; + GrSLConstantVec fKnownColorValue; + SkString fInputCoverage; + GrSLConstantVec fKnownCoverageValue; + + bool fHasCustomColorOutput; + bool fHasSecondaryOutput; + + GrGLUniformManager::UniformHandle fRTHeightUniform; + GrGLUniformManager::UniformHandle fDstCopyTopLeftUniform; + GrGLUniformManager::UniformHandle fDstCopyScaleUniform; + GrGLUniformManager::UniformHandle fColorUniform; + GrGLUniformManager::UniformHandle fCoverageUniform; + + bool fTopLeftFragPosRead; +}; + +//////////////////////////////////////////////////////////////////////////////// + +class GrGLFullShaderBuilder : public GrGLShaderBuilder { +public: + GrGLFullShaderBuilder(GrGpuGL*, GrGLUniformManager&, const GrGLProgramDesc&); + + /** + * Called by GrGLEffects to add code to one of the shaders. + */ + void vsCodeAppendf(const char format[], ...) SK_PRINTF_LIKE(2, 3) { + va_list args; + va_start(args, format); + fVSCode.appendf(format, args); + va_end(args); + } + + void vsCodeAppend(const char* str) { fVSCode.append(str); } - SkString fFSCode; + /** Add a vertex attribute to the current program that is passed in from the vertex data. + Returns false if the attribute was already there, true otherwise. */ + bool addAttribute(GrSLType type, const char* name); - bool fSetupFragPosition; - GrGLUniformManager::UniformHandle fDstCopySamplerUniform; + /** Add a varying variable to the current program to pass values between vertex and fragment + shaders. If the last two parameters are non-NULL, they are filled in with the name + generated. */ + void addVarying(GrSLType type, + const char* name, + const char** vsOutName = NULL, + const char** fsInName = NULL); + + /** Returns a vertex attribute that represents the vertex position in the VS. This is the + pre-matrix position and is commonly used by effects to compute texture coords via a matrix. + */ + const GrGLShaderVar& positionAttribute() const { return *fPositionVar; } + + /** Returns a vertex attribute that represents the local coords in the VS. This may be the same + as positionAttribute() or it may not be. It depends upon whether the rendering code + specified explicit local coords or not in the GrDrawState. */ + const GrGLShaderVar& localCoordsAttribute() const { return *fLocalCoordsVar; } + + /** + * Are explicit local coordinates provided as input to the vertex shader. + */ + bool hasExplicitLocalCoords() const { return (fLocalCoordsVar != fPositionVar); } - SkString fInputColor; - GrSLConstantVec fKnownColorValue; - SkString fInputCoverage; - GrSLConstantVec fKnownCoverageValue; + bool addEffectAttribute(int attributeIndex, GrSLType type, const SkString& name); + const SkString* getEffectAttributeName(int attributeIndex) const; - bool fHasCustomColorOutput; - bool fHasSecondaryOutput; + virtual GrGLProgramEffects* createAndEmitEffects( + const GrEffectStage* effectStages[], + const EffectKey effectKeys[], + int effectCnt, + SkString* inOutFSColor, + GrSLConstantVec* fsInOutColorKnownValue) SK_OVERRIDE; + + GrGLUniformManager::UniformHandle getViewMatrixUniform() const { + return fViewMatrixUniform; + } + +protected: + virtual bool compileAndAttachShaders(GrGLuint programId) const SK_OVERRIDE; + virtual void bindProgramLocations(GrGLuint programId) const SK_OVERRIDE; + +private: + const GrGLProgramDesc& fDesc; + VarArray fVSAttrs; + VarArray fVSOutputs; + VarArray fGSInputs; + VarArray fGSOutputs; + + SkString fVSCode; + + struct AttributePair { + void set(int index, const SkString& name) { + fIndex = index; fName = name; + } + int fIndex; + SkString fName; + }; + SkSTArray<10, AttributePair, true> fEffectAttributes; - GrGLUniformManager::UniformHandle fRTHeightUniform; - GrGLUniformManager::UniformHandle fDstCopyTopLeftUniform; - GrGLUniformManager::UniformHandle fDstCopyScaleUniform; - GrGLUniformManager::UniformHandle fColorUniform; - GrGLUniformManager::UniformHandle fCoverageUniform; + GrGLUniformManager::UniformHandle fViewMatrixUniform; - bool fTopLeftFragPosRead; + GrGLShaderVar* fPositionVar; + GrGLShaderVar* fLocalCoordsVar; - SkAutoTDelete fVertexBuilder; + typedef GrGLShaderBuilder INHERITED; }; #endif diff --git a/src/gpu/gl/GrGLVertexEffect.h b/src/gpu/gl/GrGLVertexEffect.h new file mode 100644 index 0000000000..1b4c7444b4 --- /dev/null +++ b/src/gpu/gl/GrGLVertexEffect.h @@ -0,0 +1,52 @@ +/* + * Copyright 2013 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef GrGLVertexEffect_DEFINED +#define GrGLVertexEffect_DEFINED + +#include "GrGLEffect.h" + +/** + * If a GL effect needs a GrGLFullShaderBuilder* object to emit vertex code, then it must inherit + * from this class. Since paths don't have vertices, this class is only meant to be used internally + * by skia, for special cases. + */ +class GrGLVertexEffect : public GrGLEffect { +public: + GrGLVertexEffect(const GrBackendEffectFactory& factory) + : INHERITED(factory) { fIsVertexEffect = true; } + + /** + * This is similar to emitCode() in the base class, except it takes a full shader builder. + * This allows the effect subclass to emit vertex code. + */ + virtual void emitCode(GrGLFullShaderBuilder* builder, + const GrDrawEffect& drawEffect, + EffectKey key, + const char* outputColor, + const char* inputColor, + const TransformedCoordsArray& coords, + const TextureSamplerArray& samplers) = 0; + + /** + * Provide a default override for base class's emitCode() function. + */ + virtual void emitCode(GrGLShaderBuilder* builder, + const GrDrawEffect& drawEffect, + EffectKey key, + const char* outputColor, + const char* inputColor, + const TransformedCoordsArray& coords, + const TextureSamplerArray& samplers) SK_OVERRIDE { + GrCrash("GrGLVertexEffect requires GrGLFullShaderBuilder* overload for emitCode()."); + } + +private: + typedef GrGLEffect INHERITED; +}; + +#endif -- cgit v1.2.3