aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-10-04 15:42:56 +0000
committerGravatar commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-10-04 15:42:56 +0000
commit261dc569b6a53729bea6e4e7a0cf2afa980eb82d (patch)
tree842eeaddfcf42076cd96c8e3e53562668c7ecc32
parent57bb0c39aea034f1494089dde3e9a6e4304ac04c (diff)
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
-rw-r--r--gyp/gpu.gypi1
-rw-r--r--src/gpu/GrAAConvexPathRenderer.cpp16
-rw-r--r--src/gpu/GrAARectRenderer.cpp41
-rw-r--r--src/gpu/GrOvalRenderer.cpp58
-rw-r--r--src/gpu/effects/GrBezierEffect.cpp52
-rw-r--r--src/gpu/effects/GrCustomCoordsTextureEffect.cpp15
-rw-r--r--src/gpu/gl/GrGLEffect.h18
-rw-r--r--src/gpu/gl/GrGLProgram.cpp8
-rw-r--r--src/gpu/gl/GrGLProgramDesc.h12
-rw-r--r--src/gpu/gl/GrGLProgramEffects.cpp103
-rw-r--r--src/gpu/gl/GrGLProgramEffects.h112
-rw-r--r--src/gpu/gl/GrGLShaderBuilder.cpp221
-rw-r--r--src/gpu/gl/GrGLShaderBuilder.h289
-rw-r--r--src/gpu/gl/GrGLVertexEffect.h52
14 files changed, 541 insertions, 457 deletions
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<QuadEdgeEffect>::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<GrAlignedRectEffect>::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<GrRectEffect>::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<CircleEdgeEffect>();
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<EllipseEdgeEffect>();
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<DIEllipseEdgeEffect>();
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<GrCustomCoordsTextureEffect>().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<Transform, true>& 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<GrGLVertexEffect*>(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<Transform, true>& 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<Sampler, true>& samplers = fProgramEffects->fSamplers.push_back();
+ SkTArray<Sampler, true>& 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<TextureSampler> 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<GrGLEffect*> fGLEffects;
+ SkTArray<SkSTArray<4, Sampler, true> > 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<GrGLEffect*> fGLEffects;
SkTArray<SkSTArray<2, Transform, true> > fTransforms;
- SkTArray<SkSTArray<4, Sampler, true> > 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<GrGLVertexProgramEffects> fProgramEffects;
- GrGLShaderBuilder* fBuilder;
- SkAutoTDelete<GrGLProgramEffects> 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<VertexBuilder> 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