aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar joshualitt <joshualitt@chromium.org>2014-12-03 06:24:10 -0800
committerGravatar Commit bot <commit-bot@chromium.org>2014-12-03 06:24:10 -0800
commit2dd1ae016d7f297b433c3ea3a771ef8e01657c1f (patch)
tree96aa03d4b4b1802490cb5b769627b75f3de4a470
parent960fb50a1a7ac76fd51e22983812f26bfffa6d1e (diff)
First step to moving vertex attributes to the geometryProcessor
-rw-r--r--expectations/gm/ignored-tests.txt3
-rw-r--r--gm/beziereffects.cpp21
-rw-r--r--gm/convexpolyeffect.cpp12
-rw-r--r--include/gpu/GrTypesPriv.h66
-rw-r--r--src/gpu/GrAAConvexPathRenderer.cpp52
-rwxr-xr-xsrc/gpu/GrAADistanceFieldPathRenderer.cpp44
-rw-r--r--src/gpu/GrAAHairLinePathRenderer.cpp35
-rw-r--r--src/gpu/GrAAHairLinePathRenderer.h3
-rw-r--r--src/gpu/GrAARectRenderer.cpp25
-rwxr-xr-xsrc/gpu/GrBitmapTextContext.cpp38
-rwxr-xr-xsrc/gpu/GrContext.cpp29
-rw-r--r--src/gpu/GrDefaultGeoProcFactory.cpp235
-rw-r--r--src/gpu/GrDefaultGeoProcFactory.h6
-rw-r--r--src/gpu/GrDefaultPathRenderer.cpp8
-rwxr-xr-xsrc/gpu/GrDistanceFieldTextContext.cpp31
-rw-r--r--src/gpu/GrDrawState.cpp148
-rw-r--r--src/gpu/GrDrawState.h74
-rw-r--r--src/gpu/GrDrawTarget.cpp7
-rw-r--r--src/gpu/GrGeometryProcessor.h65
-rw-r--r--src/gpu/GrInOrderDrawBuffer.cpp10
-rw-r--r--src/gpu/GrOptDrawState.cpp98
-rw-r--r--src/gpu/GrOptDrawState.h30
-rw-r--r--src/gpu/GrOvalRenderer.cpp224
-rw-r--r--src/gpu/GrProgramDesc.h32
-rw-r--r--src/gpu/effects/GrBezierEffect.cpp72
-rw-r--r--src/gpu/effects/GrBezierEffect.h18
-rw-r--r--src/gpu/effects/GrCustomCoordsTextureEffect.cpp53
-rw-r--r--src/gpu/effects/GrCustomCoordsTextureEffect.h14
-rw-r--r--src/gpu/effects/GrDashingEffect.cpp90
-rwxr-xr-xsrc/gpu/effects/GrDistanceFieldTextureEffect.cpp87
-rw-r--r--src/gpu/effects/GrDistanceFieldTextureEffect.h26
-rw-r--r--src/gpu/gl/GrGLGeometryProcessor.h14
-rw-r--r--src/gpu/gl/GrGLProgram.cpp13
-rw-r--r--src/gpu/gl/GrGLProgramDesc.cpp42
-rw-r--r--src/gpu/gl/GrGpuGL.cpp2
-rw-r--r--src/gpu/gl/GrGpuGL_program.cpp31
-rw-r--r--src/gpu/gl/builders/GrGLProgramBuilder.cpp159
-rw-r--r--src/gpu/gl/builders/GrGLProgramBuilder.h37
-rw-r--r--src/gpu/gl/builders/GrGLVertexShaderBuilder.cpp110
-rw-r--r--src/gpu/gl/builders/GrGLVertexShaderBuilder.h38
-rw-r--r--tests/GLProgramsTest.cpp79
41 files changed, 858 insertions, 1323 deletions
diff --git a/expectations/gm/ignored-tests.txt b/expectations/gm/ignored-tests.txt
index eec9c974fc..9337e7563b 100644
--- a/expectations/gm/ignored-tests.txt
+++ b/expectations/gm/ignored-tests.txt
@@ -66,3 +66,6 @@ drawbitmapmatrix
#junov skbug.com/3176
pictureimagefilter
+
+#joshualitt
+bezier_cubic_effects
diff --git a/gm/beziereffects.cpp b/gm/beziereffects.cpp
index 3de47d3be2..f875607792 100644
--- a/gm/beziereffects.cpp
+++ b/gm/beziereffects.cpp
@@ -21,15 +21,6 @@
#include "effects/GrBezierEffect.h"
-// Position & KLM line eq values. These are the vertex attributes for Bezier curves. The last value
-// of the Vec4f is ignored.
-namespace {
-extern const GrVertexAttrib kAttribs[] = {
- {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding},
- {kVec4f_GrVertexAttribType, sizeof(SkPoint), kGeometryProcessor_GrVertexAttribBinding}
-};
-}
-
static inline SkScalar eval_line(const SkPoint& p, const SkScalar lineEq[3], SkScalar sign) {
return sign * (lineEq[0] * p.fX + lineEq[1] * p.fY + lineEq[2]);
}
@@ -159,9 +150,9 @@ protected:
SkASSERT(tt.target());
GrDrawState ds;
- ds.setVertexAttribs<kAttribs>(2, sizeof(Vertex));
- GrDrawTarget::AutoReleaseGeometry geo(tt.target(), 4, ds.getVertexStride(), 0);
+ GrDrawTarget::AutoReleaseGeometry geo(tt.target(), 4, gp->getVertexStride(), 0);
+ SkASSERT(gp->getVertexStride() == sizeof(Vertex));
Vertex* verts = reinterpret_cast<Vertex*>(geo.vertices());
verts[0].fPosition.setRectFan(bounds.fLeft, bounds.fTop,
@@ -316,9 +307,9 @@ protected:
SkASSERT(tt.target());
GrDrawState ds;
- ds.setVertexAttribs<kAttribs>(2, sizeof(Vertex));
- GrDrawTarget::AutoReleaseGeometry geo(tt.target(), 4, ds.getVertexStride(), 0);
+ GrDrawTarget::AutoReleaseGeometry geo(tt.target(), 4, gp->getVertexStride(), 0);
+ SkASSERT(gp->getVertexStride() == sizeof(Vertex));
Vertex* verts = reinterpret_cast<Vertex*>(geo.vertices());
verts[0].fPosition.setRectFan(bounds.fLeft, bounds.fTop,
@@ -504,9 +495,9 @@ protected:
SkASSERT(tt.target());
GrDrawState ds;
- ds.setVertexAttribs<kAttribs>(2, sizeof(Vertex));
- GrDrawTarget::AutoReleaseGeometry geo(tt.target(), 4, ds.getVertexStride(), 0);
+ GrDrawTarget::AutoReleaseGeometry geo(tt.target(), 4, gp->getVertexStride(), 0);
+ SkASSERT(gp->getVertexStride() == sizeof(Vertex));
Vertex* verts = reinterpret_cast<Vertex*>(geo.vertices());
verts[0].fPosition.setRectFan(bounds.fLeft, bounds.fTop,
diff --git a/gm/convexpolyeffect.cpp b/gm/convexpolyeffect.cpp
index 8ee4a5db6f..1e5c6017ca 100644
--- a/gm/convexpolyeffect.cpp
+++ b/gm/convexpolyeffect.cpp
@@ -133,13 +133,15 @@ protected:
}
GrDrawState ds;
- ds.setGeometryProcessor(GrDefaultGeoProcFactory::Create(false))->unref();
+ const GrGeometryProcessor* gp = GrDefaultGeoProcFactory::Create();
+ ds.setGeometryProcessor(gp)->unref();
ds.addCoverageProcessor(fp);
ds.setIdentityViewMatrix();
ds.setRenderTarget(rt);
ds.setColor(0xff000000);
- GrDrawTarget::AutoReleaseGeometry geo(tt.target(), 4, ds.getVertexStride(), 0);
+ GrDrawTarget::AutoReleaseGeometry geo(tt.target(), 4, gp->getVertexStride(), 0);
+ SkASSERT(gp->getVertexStride() == sizeof(SkPoint));
SkPoint* verts = reinterpret_cast<SkPoint*>(geo.vertices());
SkRect bounds = p.getBounds();
@@ -189,13 +191,15 @@ protected:
}
GrDrawState ds;
- ds.setGeometryProcessor(GrDefaultGeoProcFactory::Create(false))->unref();
+ const GrGeometryProcessor* gp = GrDefaultGeoProcFactory::Create();
+ ds.setGeometryProcessor(gp)->unref();
ds.addCoverageProcessor(fp);
ds.setIdentityViewMatrix();
ds.setRenderTarget(rt);
ds.setColor(0xff000000);
- GrDrawTarget::AutoReleaseGeometry geo(tt.target(), 4, ds.getVertexStride(), 0);
+ GrDrawTarget::AutoReleaseGeometry geo(tt.target(), 4, gp->getVertexStride(), 0);
+ SkASSERT(gp->getVertexStride() == sizeof(SkPoint));
SkPoint* verts = reinterpret_cast<SkPoint*>(geo.vertices());
SkRect bounds = rect;
diff --git a/include/gpu/GrTypesPriv.h b/include/gpu/GrTypesPriv.h
index 75c987f148..0ff4e5709e 100644
--- a/include/gpu/GrTypesPriv.h
+++ b/include/gpu/GrTypesPriv.h
@@ -120,58 +120,24 @@ static inline size_t GrVertexAttribTypeSize(GrVertexAttribType type) {
}
/**
- * Semantic bindings for vertex attributes. kEffect means that the attribute is input to a
- * GrProcessor. Each binding other than kEffect may not appear more than once in the current set of
- * attributes. kPosition must be appear for exactly one attribute.
+ * converts a GrVertexAttribType to a GrSLType
*/
-enum GrVertexAttribBinding {
- kPosition_GrVertexAttribBinding, // required, must have vector count of 2
- kLocalCoord_GrVertexAttribBinding, // must have vector count of 2
- kColor_GrVertexAttribBinding, // must have vector count of 4
- kCoverage_GrVertexAttribBinding, // must have a single byte
-
- kLastFixedFunction_GrVertexAttribBinding = kCoverage_GrVertexAttribBinding,
-
- kGeometryProcessor_GrVertexAttribBinding, // vector length must agree with
- // GrProcessor::vertexAttribType() for each effect input to
- // which the attribute is mapped by GrDrawState::setEffect()
- kLast_GrVertexAttribBinding = kGeometryProcessor_GrVertexAttribBinding
-};
-
-static const int kGrVertexAttribBindingCnt = kLast_GrVertexAttribBinding + 1;
-static const int kGrFixedFunctionVertexAttribBindingCnt =
- kLastFixedFunction_GrVertexAttribBinding + 1;
-
-static inline int GrFixedFunctionVertexAttribVectorCount(GrVertexAttribBinding binding) {
- SkASSERT(binding >= 0 && binding < kGrFixedFunctionVertexAttribBindingCnt);
- static const int kVecCounts[] = { 2, 2, 4, 1 };
-
- return kVecCounts[binding];
-
- GR_STATIC_ASSERT(0 == kPosition_GrVertexAttribBinding);
- GR_STATIC_ASSERT(1 == kLocalCoord_GrVertexAttribBinding);
- GR_STATIC_ASSERT(2 == kColor_GrVertexAttribBinding);
- GR_STATIC_ASSERT(3 == kCoverage_GrVertexAttribBinding);
- GR_STATIC_ASSERT(kGrFixedFunctionVertexAttribBindingCnt == SK_ARRAY_COUNT(kVecCounts));
-}
-
-struct GrVertexAttrib {
- inline void set(GrVertexAttribType type, size_t offset, GrVertexAttribBinding binding) {
- fType = type;
- fOffset = offset;
- fBinding = binding;
+static inline GrSLType GrVertexAttribTypeToSLType(GrVertexAttribType type) {
+ switch (type) {
+ default:
+ SkFAIL("Unsupported type conversion");
+ case kUByte_GrVertexAttribType:
+ case kFloat_GrVertexAttribType:
+ return kFloat_GrSLType;
+ case kVec2f_GrVertexAttribType:
+ return kVec2f_GrSLType;
+ case kVec3f_GrVertexAttribType:
+ return kVec3f_GrSLType;
+ case kVec4ub_GrVertexAttribType:
+ case kVec4f_GrVertexAttribType:
+ return kVec4f_GrSLType;
}
- bool operator==(const GrVertexAttrib& other) const {
- return fType == other.fType && fOffset == other.fOffset && fBinding == other.fBinding;
- };
- bool operator!=(const GrVertexAttrib& other) const { return !(*this == other); }
-
- GrVertexAttribType fType;
- size_t fOffset;
- GrVertexAttribBinding fBinding;
-};
-
-template <int N> class GrVertexAttribArray : public SkSTArray<N, GrVertexAttrib, true> {};
+}
//////////////////////////////////////////////////////////////////////////////
diff --git a/src/gpu/GrAAConvexPathRenderer.cpp b/src/gpu/GrAAConvexPathRenderer.cpp
index 934eb04ed8..b5ad44adc0 100644
--- a/src/gpu/GrAAConvexPathRenderer.cpp
+++ b/src/gpu/GrAAConvexPathRenderer.cpp
@@ -518,7 +518,8 @@ public:
static const char* Name() { return "QuadEdge"; }
- const GrShaderVar& inQuadEdge() const { return fInQuadEdge; }
+ const GrAttribute* inPosition() const { return fInPosition; }
+ const GrAttribute* inQuadEdge() const { return fInQuadEdge; }
virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERRIDE {
return GrTBackendGeometryProcessorFactory<QuadEdgeEffect>::getInstance();
@@ -530,8 +531,20 @@ public:
: INHERITED (factory) {}
virtual void emitCode(const EmitArgs& args) SK_OVERRIDE {
+ const QuadEdgeEffect& qe = args.fGP.cast<QuadEdgeEffect>();
+ GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
+
GrGLVertToFrag v(kVec4f_GrSLType);
args.fPB->addVarying("QuadEdge", &v);
+ vsBuilder->codeAppendf("%s = %s;", v.vsOut(), qe.inQuadEdge()->fName);
+
+ // setup coord outputs
+ vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(), qe.inPosition()->fName);
+ vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(), qe.inPosition()->fName);
+
+ // setup position varying
+ vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(),
+ vsBuilder->uViewM(), qe.inPosition()->fName);
GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
@@ -555,17 +568,7 @@ public:
fsBuilder->codeAppendf("edgeAlpha = "
"clamp(0.5 - edgeAlpha / length(gF), 0.0, 1.0);}");
-
- fsBuilder->codeAppendf("%s = %s;", args.fOutput,
- (GrGLSLExpr4(args.fInput) * GrGLSLExpr1("edgeAlpha")).c_str());
-
- const GrShaderVar& inQuadEdge = args.fGP.cast<QuadEdgeEffect>().inQuadEdge();
- GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
- vsBuilder->codeAppendf("\t%s = %s;\n", v.vsOut(), inQuadEdge.c_str());
-
- // setup position varying
- vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(),
- vsBuilder->uViewM(), vsBuilder->inPosition());
+ fsBuilder->codeAppendf("%s = vec4(edgeAlpha);", args.fOutputCoverage);
}
static inline void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder*) {}
@@ -577,10 +580,9 @@ public:
};
private:
- QuadEdgeEffect()
- : fInQuadEdge(this->addVertexAttrib(GrShaderVar("inQuadEdge",
- kVec4f_GrSLType,
- GrShaderVar::kAttribute_TypeModifier))) {
+ QuadEdgeEffect() {
+ fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVertexAttribType));
+ fInQuadEdge = &this->addVertexAttrib(GrAttribute("inQuadEdge", kVec4f_GrVertexAttribType));
}
virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE {
@@ -591,7 +593,8 @@ private:
inout->mulByUnknownAlpha();
}
- const GrShaderVar& fInQuadEdge;
+ const GrAttribute* fInPosition;
+ const GrAttribute* fInQuadEdge;
GR_DECLARE_GEOMETRY_PROCESSOR_TEST;
@@ -619,16 +622,6 @@ bool GrAAConvexPathRenderer::canDrawPath(const GrDrawTarget* target,
stroke.isFillStyle() && !path.isInverseFillType() && path.isConvex());
}
-namespace {
-
-// position + edge
-extern const GrVertexAttrib gPathAttribs[] = {
- {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding},
- {kVec4f_GrVertexAttribType, sizeof(SkPoint), kGeometryProcessor_GrVertexAttribBinding}
-};
-
-};
-
bool GrAAConvexPathRenderer::onDrawPath(GrDrawTarget* target,
GrDrawState* drawState,
const SkPath& origPath,
@@ -678,12 +671,11 @@ bool GrAAConvexPathRenderer::onDrawPath(GrDrawTarget* target,
// Our computed verts should all be within one pixel of the segment control points.
devBounds.outset(SK_Scalar1, SK_Scalar1);
- drawState->setVertexAttribs<gPathAttribs>(SK_ARRAY_COUNT(gPathAttribs), sizeof(QuadVertex));
-
GrGeometryProcessor* quadProcessor = QuadEdgeEffect::Create();
drawState->setGeometryProcessor(quadProcessor)->unref();
- GrDrawTarget::AutoReleaseGeometry arg(target, vCount, drawState->getVertexStride(), iCount);
+ GrDrawTarget::AutoReleaseGeometry arg(target, vCount, quadProcessor->getVertexStride(), iCount);
+ SkASSERT(quadProcessor->getVertexStride() == sizeof(QuadVertex));
if (!arg.succeeded()) {
return false;
}
diff --git a/src/gpu/GrAADistanceFieldPathRenderer.cpp b/src/gpu/GrAADistanceFieldPathRenderer.cpp
index 5e0410fd75..6ac504a948 100755
--- a/src/gpu/GrAADistanceFieldPathRenderer.cpp
+++ b/src/gpu/GrAADistanceFieldPathRenderer.cpp
@@ -103,13 +103,6 @@ GrAADistanceFieldPathRenderer::onGetStencilSupport(const GrDrawTarget*,
////////////////////////////////////////////////////////////////////////////////
-// position + texture coord
-extern const GrVertexAttrib gSDFPathVertexAttribs[] = {
- { kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding },
- { kVec2f_GrVertexAttribType, sizeof(SkPoint), kGeometryProcessor_GrVertexAttribBinding }
-};
-static const size_t kSDFPathVASize = 2 * sizeof(SkPoint);
-
bool GrAADistanceFieldPathRenderer::onDrawPath(GrDrawTarget* target,
GrDrawState* drawState,
const SkPath& path,
@@ -322,12 +315,25 @@ bool GrAADistanceFieldPathRenderer::internalDrawPath(GrDrawTarget* target,
GrDrawTarget::DrawToken drawToken = target->getCurrentDrawToken();
pathData->fPlot->setDrawToken(drawToken);
- // make me some vertices
- drawState->setVertexAttribs<gSDFPathVertexAttribs>(SK_ARRAY_COUNT(gSDFPathVertexAttribs),
- kSDFPathVASize);
+ // set up any flags
+ uint32_t flags = 0;
+ const SkMatrix& vm = drawState->getViewMatrix();
+ flags |= vm.isSimilarity() ? kSimilarity_DistanceFieldEffectFlag : 0;
+
+ GrTextureParams params(SkShader::kRepeat_TileMode, GrTextureParams::kBilerp_FilterMode);
+ if (flags != fEffectFlags) {
+ fCachedGeometryProcessor.reset(GrDistanceFieldNoGammaTextureEffect::Create(texture,
+ params,
+ flags));
+ fEffectFlags = flags;
+ }
+ drawState->setGeometryProcessor(fCachedGeometryProcessor.get());
+
void* vertices = NULL;
- bool success = target->reserveVertexAndIndexSpace(4, drawState->getVertexStride(), 0, &vertices,
- NULL);
+ bool success = target->reserveVertexAndIndexSpace(4,
+ fCachedGeometryProcessor->getVertexStride(),
+ 0, &vertices, NULL);
+ SkASSERT(fCachedGeometryProcessor->getVertexStride() == 2 * sizeof(SkPoint));
GrAlwaysAssert(success);
SkScalar dx = pathData->fBounds.fLeft;
@@ -361,20 +367,6 @@ bool GrAADistanceFieldPathRenderer::internalDrawPath(GrDrawTarget* target,
SkFixedToFloat(texture->texturePriv().normalizeFixedY(ty + th)),
vertSize);
- // set up any flags
- uint32_t flags = 0;
- const SkMatrix& vm = drawState->getViewMatrix();
- flags |= vm.isSimilarity() ? kSimilarity_DistanceFieldEffectFlag : 0;
-
- GrTextureParams params(SkShader::kRepeat_TileMode, GrTextureParams::kBilerp_FilterMode);
- if (flags != fEffectFlags) {
- fCachedGeometryProcessor.reset(GrDistanceFieldNoGammaTextureEffect::Create(texture,
- params,
- flags));
- fEffectFlags = flags;
- }
- drawState->setGeometryProcessor(fCachedGeometryProcessor.get());
-
vm.mapRect(&r);
target->setIndexSourceToBuffer(fContext->getQuadIndexBuffer());
target->drawIndexedInstances(drawState, kTriangles_GrPrimitiveType, 1, 4, 6, &r);
diff --git a/src/gpu/GrAAHairLinePathRenderer.cpp b/src/gpu/GrAAHairLinePathRenderer.cpp
index 0d16cf8ea2..7168c83884 100644
--- a/src/gpu/GrAAHairLinePathRenderer.cpp
+++ b/src/gpu/GrAAHairLinePathRenderer.cpp
@@ -642,14 +642,6 @@ void add_line(const SkPoint p[2],
///////////////////////////////////////////////////////////////////////////////
-namespace {
-// position + edge
-extern const GrVertexAttrib gHairlineBezierAttribs[] = {
- {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding},
- {kVec4f_GrVertexAttribType, sizeof(SkPoint), kGeometryProcessor_GrVertexAttribBinding}
-};
-};
-
bool GrAAHairLinePathRenderer::createLineGeom(GrDrawTarget* target,
GrDrawState* drawState,
GrDrawTarget::AutoReleaseGeometry* arg,
@@ -661,10 +653,9 @@ bool GrAAHairLinePathRenderer::createLineGeom(GrDrawTarget* target,
int vertCnt = kLineSegNumVertices * lineCnt;
- GrDefaultGeoProcFactory::SetAttribs(drawState, GrDefaultGeoProcFactory::kPosition_GPType |
- GrDefaultGeoProcFactory::kCoverage_GPType);
-
- if (!arg->set(target, vertCnt, drawState->getVertexStride(), 0)) {
+ size_t vstride = drawState->getGeometryProcessor()->getVertexStride();
+ SkASSERT(vstride == sizeof(LineVertex));
+ if (!arg->set(target, vertCnt, vstride, 0)) {
return false;
}
@@ -701,15 +692,13 @@ bool GrAAHairLinePathRenderer::createBezierGeom(GrDrawTarget* target,
const PtArray& conics,
int conicCnt,
const IntArray& qSubdivs,
- const FloatArray& cWeights) {
+ const FloatArray& cWeights,
+ size_t vertexStride) {
const SkMatrix& viewM = drawState->getViewMatrix();
int vertCnt = kQuadNumVertices * quadCnt + kQuadNumVertices * conicCnt;
- int vAttribCnt = SK_ARRAY_COUNT(gHairlineBezierAttribs);
- drawState->setVertexAttribs<gHairlineBezierAttribs>(vAttribCnt, sizeof(BezierVertex));
-
- if (!arg->set(target, vertCnt, drawState->getVertexStride(), 0)) {
+ if (!arg->set(target, vertCnt, vertexStride, 0)) {
return false;
}
@@ -846,6 +835,11 @@ bool GrAAHairLinePathRenderer::onDrawPath(GrDrawTarget* target,
GrDrawTarget::AutoReleaseGeometry arg;
SkRect devBounds;
+ uint32_t gpFlags = GrDefaultGeoProcFactory::kPosition_GPType |
+ GrDefaultGeoProcFactory::kCoverage_GPType;
+ GrDrawState::AutoRestoreEffects are(drawState);
+ drawState->setGeometryProcessor(GrDefaultGeoProcFactory::Create(gpFlags))->unref();
+
if (!this->createLineGeom(target,
drawState,
&arg,
@@ -868,8 +862,6 @@ bool GrAAHairLinePathRenderer::onDrawPath(GrDrawTarget* target,
kLineSegNumVertices * lineCnt));
{
- GrDrawState::AutoRestoreEffects are(drawState);
- drawState->setGeometryProcessor(GrDefaultGeoProcFactory::Create(false))->unref();
target->setIndexSourceToBuffer(fLinesIndexBuffer);
int lines = 0;
while (lines < lineCnt) {
@@ -901,7 +893,8 @@ bool GrAAHairLinePathRenderer::onDrawPath(GrDrawTarget* target,
conics,
conicCnt,
qSubdivs,
- cWeights)) {
+ cWeights,
+ sizeof(BezierVertex))) {
return false;
}
@@ -923,6 +916,7 @@ bool GrAAHairLinePathRenderer::onDrawPath(GrDrawTarget* target,
SkASSERT(hairQuadProcessor);
GrDrawState::AutoRestoreEffects are(drawState);
target->setIndexSourceToBuffer(fQuadsIndexBuffer);
+
drawState->setGeometryProcessor(hairQuadProcessor)->unref();
int quads = 0;
while (quads < quadCnt) {
@@ -943,6 +937,7 @@ bool GrAAHairLinePathRenderer::onDrawPath(GrDrawTarget* target,
GrGeometryProcessor* hairConicProcessor = GrConicEffect::Create(
kHairlineAA_GrProcessorEdgeType, *target->caps());
SkASSERT(hairConicProcessor);
+
drawState->setGeometryProcessor(hairConicProcessor)->unref();
int conics = 0;
while (conics < conicCnt) {
diff --git a/src/gpu/GrAAHairLinePathRenderer.h b/src/gpu/GrAAHairLinePathRenderer.h
index c5f64f5e8f..2f44860c6c 100644
--- a/src/gpu/GrAAHairLinePathRenderer.h
+++ b/src/gpu/GrAAHairLinePathRenderer.h
@@ -57,7 +57,8 @@ private:
const PtArray& conics,
int conicCnt,
const IntArray& qSubdivs,
- const FloatArray& cWeights);
+ const FloatArray& cWeights,
+ size_t vertexStride);
const GrIndexBuffer* fLinesIndexBuffer;
const GrIndexBuffer* fQuadsIndexBuffer;
diff --git a/src/gpu/GrAARectRenderer.cpp b/src/gpu/GrAARectRenderer.cpp
index edb59d04d8..95fe8c9b7f 100644
--- a/src/gpu/GrAARectRenderer.cpp
+++ b/src/gpu/GrAARectRenderer.cpp
@@ -27,18 +27,17 @@ enum CoverageAttribType {
}
static CoverageAttribType set_rect_attribs(GrDrawState* drawState) {
+ uint32_t flags = GrDefaultGeoProcFactory::kColor_GPType;
if (drawState->canTweakAlphaForCoverage()) {
- drawState->setGeometryProcessor(
- GrDefaultGeoProcFactory::CreateAndSetAttribs(
- drawState,
- GrDefaultGeoProcFactory::kColor_GPType))->unref();
+ drawState->setGeometryProcessor(GrDefaultGeoProcFactory::Create(flags))->unref();
+ SkASSERT(drawState->getGeometryProcessor()->getVertexStride() ==
+ sizeof(GrDefaultGeoProcFactory::PositionColorAttr));
return kUseColor_CoverageAttribType;
} else {
- drawState->setGeometryProcessor(
- GrDefaultGeoProcFactory::CreateAndSetAttribs(
- drawState,
- GrDefaultGeoProcFactory::kColor_GPType |
- GrDefaultGeoProcFactory::kCoverage_GPType))->unref();
+ flags |= GrDefaultGeoProcFactory::kCoverage_GPType;
+ drawState->setGeometryProcessor(GrDefaultGeoProcFactory::Create(flags))->unref();
+ SkASSERT(drawState->getGeometryProcessor()->getVertexStride() ==
+ sizeof(GrDefaultGeoProcFactory::PositionColorCoverageAttr));
return kUseCoverage_CoverageAttribType;
}
}
@@ -190,7 +189,8 @@ void GrAARectRenderer::geometryFillAARect(GrDrawTarget* target,
drawState->setHint(GrDrawState::kVertexColorsAreOpaque_Hint, true);
}
- GrDrawTarget::AutoReleaseGeometry geo(target, 8, drawState->getVertexStride(), 0);
+ size_t vstride = drawState->getGeometryProcessor()->getVertexStride();
+ GrDrawTarget::AutoReleaseGeometry geo(target, 8, vstride, 0);
if (!geo.succeeded()) {
SkDebugf("Failed to get space for vertices!\n");
return;
@@ -209,7 +209,6 @@ void GrAARectRenderer::geometryFillAARect(GrDrawTarget* target,
}
intptr_t verts = reinterpret_cast<intptr_t>(geo.vertices());
- size_t vstride = drawState->getVertexStride();
SkPoint* fan0Pos = reinterpret_cast<SkPoint*>(verts);
SkPoint* fan1Pos = reinterpret_cast<SkPoint*>(verts + 4 * vstride);
@@ -395,7 +394,8 @@ void GrAARectRenderer::geometryStrokeAARect(GrDrawTarget* target,
int outerVertexNum = miterStroke ? 4 : 8;
int totalVertexNum = (outerVertexNum + innerVertexNum) * 2;
- GrDrawTarget::AutoReleaseGeometry geo(target, totalVertexNum, drawState->getVertexStride(), 0);
+ size_t vstride = drawState->getGeometryProcessor()->getVertexStride();
+ GrDrawTarget::AutoReleaseGeometry geo(target, totalVertexNum, vstride, 0);
if (!geo.succeeded()) {
SkDebugf("Failed to get space for vertices!\n");
return;
@@ -407,7 +407,6 @@ void GrAARectRenderer::geometryStrokeAARect(GrDrawTarget* target,
}
intptr_t verts = reinterpret_cast<intptr_t>(geo.vertices());
- size_t vstride = drawState->getVertexStride();
// We create vertices for four nested rectangles. There are two ramps from 0 to full
// coverage, one on the exterior of the stroke and the other on the interior.
diff --git a/src/gpu/GrBitmapTextContext.cpp b/src/gpu/GrBitmapTextContext.cpp
index 2ff410e5cf..3b0bddb8e7 100755
--- a/src/gpu/GrBitmapTextContext.cpp
+++ b/src/gpu/GrBitmapTextContext.cpp
@@ -35,24 +35,11 @@ SK_CONF_DECLARE(bool, c_DumpFontCache, "gpu.dumpFontCache", false,
"Dump the contents of the font cache before every purge.");
namespace {
-// position + texture coord
-extern const GrVertexAttrib gLCDVertexAttribs[] = {
- {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding},
- {kVec2f_GrVertexAttribType, sizeof(SkPoint), kGeometryProcessor_GrVertexAttribBinding}
-};
-
static const size_t kLCDTextVASize = 2 * sizeof(SkPoint);
// position + local coord
static const size_t kColorTextVASize = 2 * sizeof(SkPoint);
-// position + color + texture coord
-extern const GrVertexAttrib gGrayVertexAttribs[] = {
- {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding},
- {kVec4ub_GrVertexAttribType, sizeof(SkPoint), kColor_GrVertexAttribBinding},
- {kVec2f_GrVertexAttribType, sizeof(SkPoint) + sizeof(GrColor), kGeometryProcessor_GrVertexAttribBinding}
-};
-
static const size_t kGrayTextVASize = 2 * sizeof(SkPoint) + sizeof(GrColor);
static const int kVerticesPerGlyph = 4;
@@ -354,19 +341,6 @@ static size_t get_vertex_stride(GrMaskFormat maskFormat) {
}
}
-static void set_vertex_attributes(GrDrawState* drawState, GrMaskFormat maskFormat) {
- if (kA8_GrMaskFormat == maskFormat) {
- drawState->setVertexAttribs<gGrayVertexAttribs>(
- SK_ARRAY_COUNT(gGrayVertexAttribs), kGrayTextVASize);
- } else if (kARGB_GrMaskFormat == maskFormat) {
- GrDefaultGeoProcFactory::SetAttribs(drawState,
- GrDefaultGeoProcFactory::kLocalCoord_GPType);
- } else {
- drawState->setVertexAttribs<gLCDVertexAttribs>(
- SK_ARRAY_COUNT(gLCDVertexAttribs), kLCDTextVASize);
- }
-}
-
static void* alloc_vertices(GrDrawTarget* drawTarget,
int numVertices,
GrMaskFormat maskFormat) {
@@ -552,16 +526,15 @@ void GrBitmapTextContext::flush() {
GrDrawState drawState;
drawState.setFromPaint(fPaint, SkMatrix::I(), fContext->getRenderTarget());
- set_vertex_attributes(&drawState, fCurrMaskFormat);
-
// setup our sampler state for our text texture/atlas
SkASSERT(SkIsAlign4(fCurrVertex));
SkASSERT(fCurrTexture);
- GrTextureParams params(SkShader::kRepeat_TileMode, GrTextureParams::kNone_FilterMode);
// This effect could be stored with one of the cache objects (atlas?)
+ GrTextureParams params(SkShader::kRepeat_TileMode, GrTextureParams::kNone_FilterMode);
if (kARGB_GrMaskFormat == fCurrMaskFormat) {
- drawState.setGeometryProcessor(GrDefaultGeoProcFactory::Create(true))->unref();
+ uint32_t flags = GrDefaultGeoProcFactory::kLocalCoord_GPType;
+ drawState.setGeometryProcessor(GrDefaultGeoProcFactory::Create(flags))->unref();
GrFragmentProcessor* fragProcessor = GrSimpleTextureEffect::Create(fCurrTexture,
SkMatrix::I(),
params);
@@ -569,11 +542,12 @@ void GrBitmapTextContext::flush() {
} else {
uint32_t textureUniqueID = fCurrTexture->getUniqueID();
if (textureUniqueID != fEffectTextureUniqueID) {
+ bool hasColor = kA8_GrMaskFormat == fCurrMaskFormat;
fCachedGeometryProcessor.reset(GrCustomCoordsTextureEffect::Create(fCurrTexture,
- params));
+ params,
+ hasColor));
fEffectTextureUniqueID = textureUniqueID;
}
-
drawState.setGeometryProcessor(fCachedGeometryProcessor.get());
}
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index 852afe01ba..e947a16dd6 100755
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -313,13 +313,13 @@ GrTexture* GrContext::createResizedTexture(const GrSurfaceDesc& desc,
GrTextureParams::kNone_FilterMode);
drawState.addColorTextureProcessor(clampedTexture, SkMatrix::I(), params);
- drawState.setGeometryProcessor(
- GrDefaultGeoProcFactory::CreateAndSetAttribs(
- &drawState,
- GrDefaultGeoProcFactory::kPosition_GPType |
- GrDefaultGeoProcFactory::kLocalCoord_GPType))->unref();
+ uint32_t flags = GrDefaultGeoProcFactory::kPosition_GPType |
+ GrDefaultGeoProcFactory::kLocalCoord_GPType;
+ const GrGeometryProcessor* gp = GrDefaultGeoProcFactory::Create(flags);
+ drawState.setGeometryProcessor(gp)->unref();
- GrDrawTarget::AutoReleaseGeometry arg(fDrawBuffer, 4, drawState.getVertexStride(), 0);
+ GrDrawTarget::AutoReleaseGeometry arg(fDrawBuffer, 4, gp->getVertexStride(), 0);
+ SkASSERT(gp->getVertexStride() == 2 * sizeof(SkPoint));
if (arg.succeeded()) {
SkPoint* verts = (SkPoint*) arg.vertices();
@@ -753,12 +753,13 @@ void GrContext::drawRect(const GrPaint& paint,
// unitSquareVertexBuffer()
static const int worstCaseVertCount = 10;
- drawState.setDefaultVertexAttribs();
- drawState.setGeometryProcessor(GrDefaultGeoProcFactory::Create(false))->unref();
+ const GrGeometryProcessor* gp = GrDefaultGeoProcFactory::Create();
+ drawState.setGeometryProcessor(gp)->unref();
GrDrawTarget::AutoReleaseGeometry geo(target,
worstCaseVertCount,
- drawState.getVertexStride(),
+ gp->getVertexStride(),
0);
+ SkASSERT(gp->getVertexStride() == sizeof(SkPoint));
if (!geo.succeeded()) {
SkDebugf("Failed to get space for vertices!\n");
@@ -828,8 +829,7 @@ static void set_vertex_attributes(GrDrawState* drawState,
*colorOffset = sizeof(SkPoint);
flags |= GrDefaultGeoProcFactory::kColor_GPType;
}
- drawState->setGeometryProcessor(GrDefaultGeoProcFactory::CreateAndSetAttribs(drawState,
- flags))->unref();
+ drawState->setGeometryProcessor(GrDefaultGeoProcFactory::Create(flags))->unref();
}
void GrContext::drawVertices(const GrPaint& paint,
@@ -854,7 +854,9 @@ void GrContext::drawVertices(const GrPaint& paint,
int colorOffset = -1, texOffset = -1;
set_vertex_attributes(&drawState, texCoords, colors, &colorOffset, &texOffset);
- size_t vertexStride = drawState.getVertexStride();
+ size_t vertexStride = drawState.getGeometryProcessor()->getVertexStride();
+ SkASSERT(vertexStride == sizeof(SkPoint) + (SkToBool(texCoords) ? sizeof(SkPoint) : 0)
+ + (SkToBool(colors) ? sizeof(GrColor) : 0));
if (!geo.set(target, vertexCount, vertexStride, indexCount)) {
SkDebugf("Failed to get space for vertices!\n");
return;
@@ -1546,9 +1548,6 @@ GrDrawTarget* GrContext::prepareToDraw(GrDrawState* ds,
SkDebugf("Partial pixel coverage will be incorrectly blended.\n");
}
#endif
- // Clear any vertex attributes configured for the previous use of the
- // GrDrawState which can effect which blend optimizations are in effect.
- ds->setDefaultVertexAttribs();
} else {
ds->reset(fViewMatrix);
ds->setRenderTarget(fRenderTarget.get());
diff --git a/src/gpu/GrDefaultGeoProcFactory.cpp b/src/gpu/GrDefaultGeoProcFactory.cpp
index 332e73324c..ab28a579e7 100644
--- a/src/gpu/GrDefaultGeoProcFactory.cpp
+++ b/src/gpu/GrDefaultGeoProcFactory.cpp
@@ -7,22 +7,59 @@
#include "GrDefaultGeoProcFactory.h"
-#include "gl/builders/GrGLProgramBuilder.h"
-#include "gl/GrGLGeometryProcessor.h"
#include "GrDrawState.h"
#include "GrInvariantOutput.h"
#include "GrTBackendProcessorFactory.h"
+#include "gl/GrGLGeometryProcessor.h"
+#include "gl/builders/GrGLProgramBuilder.h"
/*
* The default Geometry Processor simply takes position and multiplies it by the uniform view
* matrix. It also leaves coverage untouched. Behind the scenes, we may add per vertex color or
* local coords.
*/
+typedef GrDefaultGeoProcFactory Flag;
+
class DefaultGeoProc : public GrGeometryProcessor {
public:
- static GrGeometryProcessor* Create(bool hasCoverage) {
- GR_CREATE_STATIC_PROCESSOR(gDefaultGeoProc, DefaultGeoProc, (hasCoverage));
- return SkRef(gDefaultGeoProc);
+ static GrGeometryProcessor* Create(uint32_t gpTypeFlags) {
+ switch (gpTypeFlags) {
+ case Flag::kColor_GPType | Flag::kCoverage_GPType | Flag::kLocalCoord_GPType: {
+ GR_CREATE_STATIC_PROCESSOR(gDefaultGeoProcColLocCov, DefaultGeoProc, (gpTypeFlags));
+ return SkRef(gDefaultGeoProcColLocCov);
+ }
+ case Flag::kColor_GPType | Flag::kLocalCoord_GPType: {
+ GR_CREATE_STATIC_PROCESSOR(gDefaultGeoProcColLoc, DefaultGeoProc, (gpTypeFlags));
+ return SkRef(gDefaultGeoProcColLoc);
+ }
+ case Flag::kColor_GPType | Flag::kCoverage_GPType: {
+ GR_CREATE_STATIC_PROCESSOR(gDefaultGeoProcColCov, DefaultGeoProc, (gpTypeFlags));
+ return SkRef(gDefaultGeoProcColCov);
+ }
+ case Flag::kColor_GPType: {
+ GR_CREATE_STATIC_PROCESSOR(gDefaultGeoProcCol, DefaultGeoProc, (gpTypeFlags));
+ return SkRef(gDefaultGeoProcCol);
+ }
+ case Flag::kLocalCoord_GPType | Flag::kCoverage_GPType: {
+ GR_CREATE_STATIC_PROCESSOR(gDefaultGeoProcLocCov, DefaultGeoProc, (gpTypeFlags));
+ return SkRef(gDefaultGeoProcLocCov);
+ }
+ case Flag::kLocalCoord_GPType: {
+ GR_CREATE_STATIC_PROCESSOR(gDefaultGeoProcLoc, DefaultGeoProc, (gpTypeFlags));
+ return SkRef(gDefaultGeoProcLoc);
+ }
+ case Flag::kCoverage_GPType: {
+ GR_CREATE_STATIC_PROCESSOR(gDefaultGeoProcCov, DefaultGeoProc, (gpTypeFlags));
+ return SkRef(gDefaultGeoProcCov);
+ }
+ case Flag::kPosition_GPType: {
+ GR_CREATE_STATIC_PROCESSOR(gDefaultGeoProc, DefaultGeoProc, (gpTypeFlags));
+ return SkRef(gDefaultGeoProc);
+ }
+ default:
+ SkFAIL("Incomplete Switch");
+ return NULL;
+ }
}
static const char* Name() { return "DefaultGeometryProcessor"; }
@@ -31,24 +68,51 @@ public:
return GrTBackendGeometryProcessorFactory<DefaultGeoProc>::getInstance();
}
+ const GrAttribute* inPosition() const { return fInPosition; }
+ const GrAttribute* inColor() const { return fInColor; }
+ const GrAttribute* inLocalCoords() const { return fInLocalCoords; }
+ const GrAttribute* inCoverage() const { return fInCoverage; }
+
class GLProcessor : public GrGLGeometryProcessor {
public:
GLProcessor(const GrBackendProcessorFactory& factory, const GrProcessor&)
: INHERITED (factory) {}
virtual void emitCode(const EmitArgs& args) SK_OVERRIDE {
+ const DefaultGeoProc& gp = args.fGP.cast<DefaultGeoProc>();
GrGLVertexBuilder* vs = args.fPB->getVertexShaderBuilder();
+ vs->codeAppendf("%s = %s;", vs->positionCoords(), gp.inPosition()->fName);
+
+ // Setup pass through color
+ if (gp.inColor()) {
+ args.fPB->addPassThroughAttribute(gp.inColor(), args.fOutputColor);
+ }
+
+ // Setup local coords if needed
+ if (gp.inLocalCoords()) {
+ vs->codeAppendf("%s = %s;", vs->localCoords(), gp.inLocalCoords()->fName);
+ } else {
+ vs->codeAppendf("%s = %s;", vs->localCoords(), gp.inPosition()->fName);
+ }
+
// setup position varying
vs->codeAppendf("%s = %s * vec3(%s, 1);", vs->glPosition(), vs->uViewM(),
- vs->inPosition());
+ gp.inPosition()->fName);
- // output coverage in FS(pass through)
+ // Setup coverage as pass through
GrGLGPFragmentBuilder* fs = args.fPB->getFragmentShaderBuilder();
- fs->codeAppendf("%s = %s;", args.fOutput, GrGLSLExpr4(args.fInput).c_str());
+ fs->codeAppendf("float alpha = 1.0;");
+ if (gp.inCoverage()) {
+ args.fPB->addPassThroughAttribute(gp.inCoverage(), "alpha");
+ }
+ fs->codeAppendf("%s = vec4(alpha);", args.fOutputCoverage);
}
- static inline void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder*) {}
+ static inline void GenKey(const GrProcessor& gp, const GrGLCaps&, GrProcessorKeyBuilder* b) {
+ const DefaultGeoProc& def = gp.cast<DefaultGeoProc>();
+ b->add32(def.fFlags);
+ }
virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE {}
@@ -57,23 +121,52 @@ public:
};
private:
- DefaultGeoProc(bool hasCoverageAttribute) : fHasCoverageAttribute(hasCoverageAttribute) {}
+ DefaultGeoProc(uint32_t gpTypeFlags)
+ : fInPosition(NULL)
+ , fInColor(NULL)
+ , fInLocalCoords(NULL)
+ , fInCoverage(NULL)
+ , fFlags(gpTypeFlags) {
+ bool hasColor = SkToBool(gpTypeFlags & GrDefaultGeoProcFactory::kColor_GPType);
+ bool hasLocalCoord = SkToBool(gpTypeFlags & GrDefaultGeoProcFactory::kLocalCoord_GPType);
+ bool hasCoverage = SkToBool(gpTypeFlags & GrDefaultGeoProcFactory::kCoverage_GPType);
+ fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVertexAttribType));
+ if (hasColor) {
+ fInColor = &this->addVertexAttrib(GrAttribute("inColor", kVec4ub_GrVertexAttribType));
+ this->setHasVertexColor();
+ }
+ if (hasLocalCoord) {
+ fInLocalCoords = &this->addVertexAttrib(GrAttribute("inLocalCoord",
+ kVec2f_GrVertexAttribType));
+ this->setHasLocalCoords();
+ }
+ if (hasCoverage) {
+ fInCoverage = &this->addVertexAttrib(GrAttribute("inCoverage",
+ kFloat_GrVertexAttribType));
+ this->setHasVertexCoverage();
+ }
+ }
virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE {
- return true;
+ const DefaultGeoProc& gp = other.cast<DefaultGeoProc>();
+ return gp.fFlags == this->fFlags;
}
virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVERRIDE {
- if (fHasCoverageAttribute) {
+ if (fInCoverage) {
inout->mulByUnknownAlpha();
} else {
inout->mulByKnownAlpha(255);
}
}
- GR_DECLARE_GEOMETRY_PROCESSOR_TEST;
+ const GrAttribute* fInPosition;
+ const GrAttribute* fInColor;
+ const GrAttribute* fInLocalCoords;
+ const GrAttribute* fInCoverage;
+ uint32_t fFlags;
- bool fHasCoverageAttribute;
+ GR_DECLARE_GEOMETRY_PROCESSOR_TEST;
typedef GrFragmentProcessor INHERITED;
};
@@ -84,112 +177,20 @@ GrGeometryProcessor* DefaultGeoProc::TestCreate(SkRandom* random,
GrContext*,
const GrDrawTargetCaps& caps,
GrTexture*[]) {
- return DefaultGeoProc::Create(random->nextBool());
-}
-
-// We use these arrays to customize our default GP. We only need 4 because we omit coverage if
-// coverage is not requested in the flags to the create function.
-GrVertexAttrib kDefaultPositionGeoProc[] = {
- { kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding },
- { kFloat_GrVertexAttribType, sizeof(SkPoint), kCoverage_GrVertexAttribBinding },
-};
-
-GrVertexAttrib kDefaultPosColorGeoProc[] = {
- { kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding },
- { kVec4ub_GrVertexAttribType, sizeof(SkPoint), kColor_GrVertexAttribBinding },
- { kFloat_GrVertexAttribType, sizeof(SkPoint) + sizeof(GrColor), kCoverage_GrVertexAttribBinding },
-};
-
-GrVertexAttrib kDefaultPosLocalCoordGeoProc[] = {
- { kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding },
- { kVec2f_GrVertexAttribType, sizeof(SkPoint), kLocalCoord_GrVertexAttribBinding },
- { kFloat_GrVertexAttribType, 2 * sizeof(SkPoint), kCoverage_GrVertexAttribBinding },
-};
-
-GrVertexAttrib kDefaultPosColLocalCoordGeoProc[] = {
- { kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding },
- { kVec4ub_GrVertexAttribType, sizeof(SkPoint), kColor_GrVertexAttribBinding },
- { kVec2f_GrVertexAttribType, sizeof(SkPoint) + sizeof(GrColor), kLocalCoord_GrVertexAttribBinding },
- { kFloat_GrVertexAttribType, 2 * sizeof(SkPoint) + sizeof(GrColor), kCoverage_GrVertexAttribBinding },
-};
-
-static size_t get_size(GrDefaultGeoProcFactory::GPType flag) {
- switch (flag) {
- case GrDefaultGeoProcFactory::kPosition_GPType:
- return GrVertexAttribTypeSize(kVec2f_GrVertexAttribType);
- case GrDefaultGeoProcFactory::kColor_GPType:
- return GrVertexAttribTypeSize(kVec4ub_GrVertexAttribType);
- case GrDefaultGeoProcFactory::kLocalCoord_GPType:
- return GrVertexAttribTypeSize(kVec2f_GrVertexAttribType);
- case GrDefaultGeoProcFactory::kCoverage_GPType:
- return GrVertexAttribTypeSize(kFloat_GrVertexAttribType);
- default:
- SkFAIL("Should never get here");
- return 0;
+ uint32_t flags = 0;
+ if (random->nextBool()) {
+ flags |= GrDefaultGeoProcFactory::kColor_GPType;
}
-}
-
-void GrDefaultGeoProcFactory::SetAttribs(GrDrawState* ds, uint32_t gpTypeFlags) {
- SkASSERT(ds);
- // always atleast position in the GP
- size_t size = get_size(kPosition_GPType);
- int count = 1;
-
- bool hasColor = SkToBool(gpTypeFlags & kColor_GPType);
- bool hasLocalCoord = SkToBool(gpTypeFlags & kLocalCoord_GPType);
- bool hasCoverage = SkToBool(gpTypeFlags & kCoverage_GPType);
-
- if (hasColor) {
- size += get_size(kColor_GPType);
- count++;
- if (hasLocalCoord) {
- size += get_size(kLocalCoord_GPType);
- count++;
- if (hasCoverage) {
- size += get_size(kCoverage_GPType);
- count++;
- ds->setVertexAttribs<kDefaultPosColLocalCoordGeoProc>(count, size);
- } else {
- ds->setVertexAttribs<kDefaultPosColLocalCoordGeoProc>(count, size);
-
- }
- } else {
- if (hasCoverage) {
- size += get_size(kCoverage_GPType);
- count++;
- ds->setVertexAttribs<kDefaultPosColorGeoProc>(count, size);
- } else {
- ds->setVertexAttribs<kDefaultPosColorGeoProc>(count, size);
- }
- }
- } else if (hasLocalCoord) {
- size += get_size(kLocalCoord_GPType);
- count++;
- if (hasCoverage) {
- size += get_size(kCoverage_GPType);
- count++;
- ds->setVertexAttribs<kDefaultPosLocalCoordGeoProc>(count, size);
- } else {
- ds->setVertexAttribs<kDefaultPosLocalCoordGeoProc>(count, size);
- }
- } else if (hasCoverage) {
- size += get_size(kCoverage_GPType);
- count++;
- ds->setVertexAttribs<kDefaultPositionGeoProc>(count, size);
- } else {
- // Just position
- ds->setVertexAttribs<kDefaultPositionGeoProc>(count, size);
+ if (random->nextBool()) {
+ flags |= GrDefaultGeoProcFactory::kCoverage_GPType;
+ }
+ if (random->nextBool()) {
+ flags |= GrDefaultGeoProcFactory::kLocalCoord_GPType;
}
-}
-
-const GrGeometryProcessor*
-GrDefaultGeoProcFactory::CreateAndSetAttribs(GrDrawState* ds, uint32_t gpTypeFlags) {
- SetAttribs(ds, gpTypeFlags);
- bool hasCoverage = SkToBool(gpTypeFlags & kCoverage_GPType);
- return DefaultGeoProc::Create(hasCoverage);
+ return DefaultGeoProc::Create(flags);
}
-const GrGeometryProcessor* GrDefaultGeoProcFactory::Create(bool hasAttributeCoverage) {
- return DefaultGeoProc::Create(hasAttributeCoverage);
+const GrGeometryProcessor* GrDefaultGeoProcFactory::Create(uint32_t gpTypeFlags) {
+ return DefaultGeoProc::Create(gpTypeFlags);
}
diff --git a/src/gpu/GrDefaultGeoProcFactory.h b/src/gpu/GrDefaultGeoProcFactory.h
index 99d85b64d6..a39c76da19 100644
--- a/src/gpu/GrDefaultGeoProcFactory.h
+++ b/src/gpu/GrDefaultGeoProcFactory.h
@@ -17,8 +17,6 @@ class GrDrawState;
* view matrix and wire through color, coverage, UV coords if requested. Right now this is only
* used in the creation of optimized draw states because adding default GPs to the drawstate can
* interfere with batching due to updating the drawstate.
- * TODO When we track geometry state separately from the draw state, we should be able use a default
- * GP with every draw call
*/
class GrDefaultGeoProcFactory {
public:
@@ -82,9 +80,7 @@ public:
*
* You must unref the return from Create.
*/
- static void SetAttribs(GrDrawState*, uint32_t GPTypeFlags = 0);
- static const GrGeometryProcessor* CreateAndSetAttribs(GrDrawState*, uint32_t GPTypeFlags = 0);
- static const GrGeometryProcessor* Create(bool hasAttributeCoverage);
+ static const GrGeometryProcessor* Create(uint32_t gpTypeFlags = 0);
};
#endif
diff --git a/src/gpu/GrDefaultPathRenderer.cpp b/src/gpu/GrDefaultPathRenderer.cpp
index 3b31e876a2..4d9026f086 100644
--- a/src/gpu/GrDefaultPathRenderer.cpp
+++ b/src/gpu/GrDefaultPathRenderer.cpp
@@ -233,10 +233,12 @@ bool GrDefaultPathRenderer::createGeom(GrDrawTarget* target,
}
}
- drawState->setDefaultVertexAttribs();
- if (!arg->set(target, maxPts, drawState->getVertexStride(), maxIdxs)) {
+ // TODO this is really wierd, I just need default vertex stride, can I think of a better way?
+ SkAutoTUnref<const GrGeometryProcessor> gp(GrDefaultGeoProcFactory::Create());
+ if (!arg->set(target, maxPts, gp->getVertexStride(), maxIdxs)) {
return false;
}
+ SkASSERT(gp->getVertexStride() == sizeof(SkPoint));
uint16_t* idxBase = reinterpret_cast<uint16_t*>(arg->indices());
uint16_t* idx = idxBase;
@@ -497,7 +499,7 @@ bool GrDefaultPathRenderer::internalDrawPath(GrDrawTarget* target,
drawState->enableState(GrDrawState::kNoColorWrites_StateBit);
}
GrDrawState::AutoRestoreEffects are(drawState);
- drawState->setGeometryProcessor(GrDefaultGeoProcFactory::Create(false))->unref();
+ drawState->setGeometryProcessor(GrDefaultGeoProcFactory::Create())->unref();
if (indexCnt) {
target->drawIndexed(drawState,
primType,
diff --git a/src/gpu/GrDistanceFieldTextContext.cpp b/src/gpu/GrDistanceFieldTextContext.cpp
index a012bc28b7..99aed573b6 100755
--- a/src/gpu/GrDistanceFieldTextContext.cpp
+++ b/src/gpu/GrDistanceFieldTextContext.cpp
@@ -38,27 +38,11 @@ static const int kMediumDFFontSize = 78;
static const int kMediumDFFontLimit = 78;
static const int kLargeDFFontSize = 192;
-namespace {
-// position + texture coord
-extern const GrVertexAttrib gTextVertexAttribs[] = {
- {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding},
- {kVec2f_GrVertexAttribType, sizeof(SkPoint) , kGeometryProcessor_GrVertexAttribBinding}
-};
-
static const size_t kTextVASize = 2 * sizeof(SkPoint);
-
-// position + color + texture coord
-extern const GrVertexAttrib gTextVertexWithColorAttribs[] = {
- {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding},
- {kVec4ub_GrVertexAttribType, sizeof(SkPoint), kColor_GrVertexAttribBinding},
- {kVec2f_GrVertexAttribType, sizeof(SkPoint) + sizeof(GrColor), kGeometryProcessor_GrVertexAttribBinding}
-};
-
static const size_t kTextVAColorSize = 2 * sizeof(SkPoint) + sizeof(GrColor);
static const int kVerticesPerGlyph = 4;
static const int kIndicesPerGlyph = 6;
-};
GrDistanceFieldTextContext::GrDistanceFieldTextContext(GrContext* context,
const SkDeviceProperties& properties,
@@ -432,6 +416,7 @@ void GrDistanceFieldTextContext::setupCoverageEffect(const SkColor& filteredColo
colorNoPreMul,
flags));
} else {
+ flags |= kColorAttr_DistanceFieldEffectFlag;
#ifdef SK_GAMMA_APPLY_TO_A8
U8CPU lum = SkColorSpaceLuminance::computeLuminance(fDeviceProperties.gamma(),
filteredColor);
@@ -618,18 +603,6 @@ HAS_ATLAS:
return true;
}
-// We use color vertices if we aren't drawing LCD text
-static void set_vertex_attributes(GrDrawState* drawState, bool useColorVerts) {
- // set up attributes
- if (useColorVerts) {
- drawState->setVertexAttribs<gTextVertexWithColorAttribs>(
- SK_ARRAY_COUNT(gTextVertexWithColorAttribs), kTextVAColorSize);
- } else {
- drawState->setVertexAttribs<gTextVertexAttribs>(
- SK_ARRAY_COUNT(gTextVertexAttribs), kTextVASize);
- }
-}
-
void GrDistanceFieldTextContext::flush() {
if (NULL == fDrawTarget) {
return;
@@ -638,8 +611,6 @@ void GrDistanceFieldTextContext::flush() {
if (fCurrVertex > 0) {
GrDrawState drawState;
drawState.setFromPaint(fPaint, fContext->getMatrix(), fContext->getRenderTarget());
- bool useColorVerts = !fUseLCDText;
- set_vertex_attributes(&drawState, useColorVerts);
// setup our sampler state for our text texture/atlas
SkASSERT(SkIsAlign4(fCurrVertex));
diff --git a/src/gpu/GrDrawState.cpp b/src/gpu/GrDrawState.cpp
index 7538cdb340..ff58c4899a 100644
--- a/src/gpu/GrDrawState.cpp
+++ b/src/gpu/GrDrawState.cpp
@@ -28,9 +28,6 @@ bool GrDrawState::isEqual(const GrDrawState& that) const {
this->fDstBlend != that.fDstBlend ||
this->fBlendConstant != that.fBlendConstant ||
this->fFlagBits != that.fFlagBits ||
- this->fVACount != that.fVACount ||
- this->fVAStride != that.fVAStride ||
- memcmp(this->fVAPtr, that.fVAPtr, this->fVACount * sizeof(GrVertexAttrib)) ||
this->fStencilSettings != that.fStencilSettings ||
this->fDrawFace != that.fDrawFace) {
return false;
@@ -65,10 +62,6 @@ bool GrDrawState::isEqual(const GrDrawState& that) const {
}
}
- SkASSERT(0 == memcmp(this->fFixedFunctionVertexAttribIndices,
- that.fFixedFunctionVertexAttribIndices,
- sizeof(this->fFixedFunctionVertexAttribIndices)));
-
return true;
}
@@ -95,9 +88,6 @@ GrDrawState& GrDrawState::operator=(const GrDrawState& that) {
fDstBlend = that.fDstBlend;
fBlendConstant = that.fBlendConstant;
fFlagBits = that.fFlagBits;
- fVACount = that.fVACount;
- fVAPtr = that.fVAPtr;
- fVAStride = that.fVAStride;
fStencilSettings = that.fStencilSettings;
fCoverage = that.fCoverage;
fDrawFace = that.fDrawFace;
@@ -115,10 +105,6 @@ GrDrawState& GrDrawState::operator=(const GrDrawState& that) {
if (fCoverageProcInfoValid) {
fCoverageProcInfo = that.fCoverageProcInfo;
}
-
- memcpy(fFixedFunctionVertexAttribIndices,
- that.fFixedFunctionVertexAttribIndices,
- sizeof(fFixedFunctionVertexAttribIndices));
return *this;
}
@@ -130,9 +116,6 @@ void GrDrawState::onReset(const SkMatrix* initialViewMatrix) {
fColorStages.reset();
fCoverageStages.reset();
-
- this->setDefaultVertexAttribs();
-
fColor = 0xffffffff;
if (NULL == initialViewMatrix) {
fViewMatrix.reset();
@@ -212,126 +195,6 @@ void GrDrawState::setFromPaint(const GrPaint& paint, const SkMatrix& vm, GrRende
////////////////////////////////////////////////////////////////////////////////
-bool GrDrawState::validateVertexAttribs() const {
- // check consistency of effects and attributes
- GrSLType slTypes[kMaxVertexAttribCnt];
- for (int i = 0; i < kMaxVertexAttribCnt; ++i) {
- slTypes[i] = static_cast<GrSLType>(-1);
- }
-
- if (this->hasGeometryProcessor()) {
- const GrGeometryProcessor* gp = this->getGeometryProcessor();
- // make sure that any attribute indices have the correct binding type, that the attrib
- // type and effect's shader lang type are compatible, and that attributes shared by
- // multiple effects use the same shader lang type.
- const GrGeometryProcessor::VertexAttribArray& s = gp->getVertexAttribs();
-
- int effectIndex = 0;
- for (int index = 0; index < fVACount; index++) {
- if (kGeometryProcessor_GrVertexAttribBinding != fVAPtr[index].fBinding) {
- // we only care about effect bindings
- continue;
- }
- SkASSERT(effectIndex < s.count());
- GrSLType effectSLType = s[effectIndex].getType();
- GrVertexAttribType attribType = fVAPtr[index].fType;
- int slVecCount = GrSLTypeVectorCount(effectSLType);
- int attribVecCount = GrVertexAttribTypeVectorCount(attribType);
- if (slVecCount != attribVecCount ||
- (static_cast<GrSLType>(-1) != slTypes[index] && slTypes[index] != effectSLType)) {
- return false;
- }
- slTypes[index] = effectSLType;
- effectIndex++;
- }
- // Make sure all attributes are consumed and we were able to find everything
- SkASSERT(s.count() == effectIndex);
- }
-
- return true;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-static void validate_vertex_attribs(const GrVertexAttrib* attribs, int count, size_t stride) {
- // this works as long as we're 4 byte-aligned
-#ifdef SK_DEBUG
- uint32_t overlapCheck = 0;
- SkASSERT(count <= GrDrawState::kMaxVertexAttribCnt);
- for (int index = 0; index < count; ++index) {
- size_t attribSize = GrVertexAttribTypeSize(attribs[index].fType);
- size_t attribOffset = attribs[index].fOffset;
- SkASSERT(attribOffset + attribSize <= stride);
- size_t dwordCount = attribSize >> 2;
- uint32_t mask = (1 << dwordCount)-1;
- size_t offsetShift = attribOffset >> 2;
- SkASSERT(!(overlapCheck & (mask << offsetShift)));
- overlapCheck |= (mask << offsetShift);
- }
-#endif
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-void GrDrawState::internalSetVertexAttribs(const GrVertexAttrib* attribs, int count,
- size_t stride) {
- SkASSERT(count <= kMaxVertexAttribCnt);
-
- fVAPtr = attribs;
- fVACount = count;
- fVAStride = stride;
- validate_vertex_attribs(fVAPtr, fVACount, fVAStride);
-
- // Set all the indices to -1
- memset(fFixedFunctionVertexAttribIndices,
- 0xff,
- sizeof(fFixedFunctionVertexAttribIndices));
-#ifdef SK_DEBUG
- uint32_t overlapCheck = 0;
-#endif
- for (int i = 0; i < count; ++i) {
- if (attribs[i].fBinding < kGrFixedFunctionVertexAttribBindingCnt) {
- // The fixed function attribs can only be specified once
- SkASSERT(-1 == fFixedFunctionVertexAttribIndices[attribs[i].fBinding]);
- SkASSERT(GrFixedFunctionVertexAttribVectorCount(attribs[i].fBinding) ==
- GrVertexAttribTypeVectorCount(attribs[i].fType));
- fFixedFunctionVertexAttribIndices[attribs[i].fBinding] = i;
- }
-#ifdef SK_DEBUG
- size_t dwordCount = GrVertexAttribTypeSize(attribs[i].fType) >> 2;
- uint32_t mask = (1 << dwordCount)-1;
- size_t offsetShift = attribs[i].fOffset >> 2;
- SkASSERT(!(overlapCheck & (mask << offsetShift)));
- overlapCheck |= (mask << offsetShift);
-#endif
- }
- fColorProcInfoValid = false;
- fCoverageProcInfoValid = false;
- // Positions must be specified.
- SkASSERT(-1 != fFixedFunctionVertexAttribIndices[kPosition_GrVertexAttribBinding]);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-void GrDrawState::setDefaultVertexAttribs() {
- static const GrVertexAttrib kPositionAttrib =
- {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding};
-
- fVAPtr = &kPositionAttrib;
- fVACount = 1;
- fVAStride = GrVertexAttribTypeSize(kVec2f_GrVertexAttribType);
-
- // set all the fixed function indices to -1 except position.
- memset(fFixedFunctionVertexAttribIndices,
- 0xff,
- sizeof(fFixedFunctionVertexAttribIndices));
- fFixedFunctionVertexAttribIndices[kPosition_GrVertexAttribBinding] = 0;
- fColorProcInfoValid = false;
- fCoverageProcInfoValid = false;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
bool GrDrawState::couldApplyCoverage(const GrDrawTargetCaps& caps) const {
if (caps.dualSourceBlendingSupport()) {
return true;
@@ -361,17 +224,6 @@ bool GrDrawState::hasSolidCoverage() const {
return fCoverageProcInfo.isSolidWhite();
}
-//////////////////////////////////////////////////////////////////////////////
-
-GrDrawState::AutoVertexAttribRestore::AutoVertexAttribRestore(GrDrawState* drawState) {
- SkASSERT(drawState);
- fDrawState = drawState;
- fVAPtr = drawState->fVAPtr;
- fVACount = drawState->fVACount;
- fVAStride = drawState->fVAStride;
- fDrawState->setDefaultVertexAttribs();
-}
-
//////////////////////////////////////////////////////////////////////////////s
bool GrDrawState::willEffectReadDstColor() const {
diff --git a/src/gpu/GrDrawState.h b/src/gpu/GrDrawState.h
index a049f1d807..a236d1a559 100644
--- a/src/gpu/GrDrawState.h
+++ b/src/gpu/GrDrawState.h
@@ -70,74 +70,17 @@ public:
/// @name Vertex Attributes
////
- enum {
- kMaxVertexAttribCnt = kLast_GrVertexAttribBinding + 4,
- };
-
- const GrVertexAttrib* getVertexAttribs() const { return fVAPtr; }
- int getVertexAttribCount() const { return fVACount; }
-
- size_t getVertexStride() const { return fVAStride; }
-
+ // TODO when we move this info off of GrGeometryProcessor, delete these
bool hasLocalCoordAttribute() const {
- return -1 != fFixedFunctionVertexAttribIndices[kLocalCoord_GrVertexAttribBinding];
+ return this->hasGeometryProcessor() && this->getGeometryProcessor()->hasLocalCoords();
}
bool hasColorVertexAttribute() const {
- return -1 != fFixedFunctionVertexAttribIndices[kColor_GrVertexAttribBinding];
+ return this->hasGeometryProcessor() && this->getGeometryProcessor()->hasVertexColor();
}
bool hasCoverageVertexAttribute() const {
- return -1 != fFixedFunctionVertexAttribIndices[kCoverage_GrVertexAttribBinding];
+ return this->hasGeometryProcessor() && this->getGeometryProcessor()->hasVertexCoverage();
}
- const int* getFixedFunctionVertexAttribIndices() const {
- return fFixedFunctionVertexAttribIndices;
- }
-
- bool validateVertexAttribs() const;
-
- /**
- * The format of vertices is represented as an array of GrVertexAttribs, with each representing
- * the type of the attribute, its offset, and semantic binding (see GrVertexAttrib in
- * GrTypesPriv.h).
- *
- * The mapping of attributes with kEffect bindings to GrProcessor inputs is specified when
- * setEffect is called.
- */
-
- /**
- * Sets vertex attributes for next draw. The object driving the templatization
- * should be a global GrVertexAttrib array that is never changed.
- *
- * @param count the number of attributes being set, limited to kMaxVertexAttribCnt.
- * @param stride the number of bytes between successive vertex data.
- */
- template <const GrVertexAttrib A[]> void setVertexAttribs(int count, size_t stride) {
- this->internalSetVertexAttribs(A, count, stride);
- }
-
- /**
- * Sets default vertex attributes for next draw. The default is a single attribute:
- * {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribType}
- */
- void setDefaultVertexAttribs();
-
- /**
- * Helper to save/restore vertex attribs
- */
- class AutoVertexAttribRestore {
- public:
- AutoVertexAttribRestore(GrDrawState* drawState);
-
- ~AutoVertexAttribRestore() { fDrawState->internalSetVertexAttribs(fVAPtr, fVACount,
- fVAStride); }
-
- private:
- GrDrawState* fDrawState;
- const GrVertexAttrib* fVAPtr;
- int fVACount;
- size_t fVAStride;
- };
-
/// @}
/**
@@ -765,8 +708,6 @@ private:
// This is used to assert that this condition holds.
SkDEBUGCODE(int fBlockEffectRemovalCnt;)
- void internalSetVertexAttribs(const GrVertexAttrib attribs[], int count, size_t stride);
-
typedef SkSTArray<4, GrFragmentStage> FragmentStageArray;
SkAutoTUnref<GrRenderTarget> fRenderTarget;
@@ -774,9 +715,6 @@ private:
SkMatrix fViewMatrix;
GrColor fBlendConstant;
uint32_t fFlagBits;
- const GrVertexAttrib* fVAPtr;
- int fVACount;
- size_t fVAStride;
GrStencilSettings fStencilSettings;
uint8_t fCoverage;
DrawFace fDrawFace;
@@ -787,10 +725,6 @@ private:
FragmentStageArray fCoverageStages;
uint32_t fHints;
- // This is simply a different representation of info in fVertexAttribs and thus does
- // not need to be compared in op==.
- int fFixedFunctionVertexAttribIndices[kGrFixedFunctionVertexAttribBindingCnt];
-
mutable GrProcOptInfo fColorProcInfo;
mutable GrProcOptInfo fCoverageProcInfo;
mutable bool fColorProcInfoValid;
diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp
index c385f27100..7728ea5497 100644
--- a/src/gpu/GrDrawTarget.cpp
+++ b/src/gpu/GrDrawTarget.cpp
@@ -375,7 +375,6 @@ bool GrDrawTarget::checkDraw(const GrDrawState& drawState,
}
}
- SkASSERT(drawState.validateVertexAttribs());
#endif
if (NULL == drawState.getRenderTarget()) {
return false;
@@ -472,7 +471,7 @@ void GrDrawTarget::drawIndexed(GrDrawState* ds,
if (!this->setupDstReadIfNecessary(ds, &dstCopy, devBounds)) {
return;
}
- this->setDrawBuffers(&info, ds->getVertexStride());
+ this->setDrawBuffers(&info, ds->getGeometryProcessor()->getVertexStride());
this->onDraw(*ds, info, scissorState, dstCopy.texture() ? &dstCopy : NULL);
}
@@ -515,7 +514,7 @@ void GrDrawTarget::drawNonIndexed(GrDrawState* ds,
return;
}
- this->setDrawBuffers(&info, ds->getVertexStride());
+ this->setDrawBuffers(&info, ds->getGeometryProcessor()->getVertexStride());
this->onDraw(*ds, info, scissorState, dstCopy.texture() ? &dstCopy : NULL);
}
@@ -779,7 +778,7 @@ void GrDrawTarget::drawIndexedInstances(GrDrawState* ds,
info.fStartIndex,
info.fVertexCount,
info.fIndexCount)) {
- this->setDrawBuffers(&info, ds->getVertexStride());
+ this->setDrawBuffers(&info, ds->getGeometryProcessor()->getVertexStride());
this->onDraw(*ds, info, scissorState, dstCopy.texture() ? &dstCopy : NULL);
}
info.fStartVertex += info.fVertexCount;
diff --git a/src/gpu/GrGeometryProcessor.h b/src/gpu/GrGeometryProcessor.h
index 6d27f0b4f1..17344d2bb4 100644
--- a/src/gpu/GrGeometryProcessor.h
+++ b/src/gpu/GrGeometryProcessor.h
@@ -13,7 +13,7 @@
#include "GrShaderVar.h"
/**
- * A GrGeomteryProcessor is used to perform computation in the vertex shader and
+ * A GrGeometryProcessor is used to perform computation in the vertex shader and
* add support for custom vertex attributes. A GrGemeotryProcessor is typically
* tied to the code that does a specific type of high-level primitive rendering
* (e.g. anti-aliased circle rendering). The GrGeometryProcessor used for a draw is
@@ -25,19 +25,38 @@
class GrGeometryProcessor : public GrProcessor {
public:
GrGeometryProcessor()
- : fWillUseGeoShader(false) {}
+ : fVertexStride(0)
+ , fWillUseGeoShader(false)
+ , fHasVertexColor(false)
+ , fHasVertexCoverage(false)
+ , fHasLocalCoords(false) {}
virtual const GrBackendGeometryProcessorFactory& getFactory() const = 0;
/*
- * This only has a max because GLProgramsTest needs to generate test arrays, and these have to
- * be static
- * TODO make this truly dynamic
+ * This is a safeguard to prevent GPs from going beyond platform specific attribute limits.
+ * This number can almost certainly be raised if required.
*/
- static const int kMaxVertexAttribs = 2;
- typedef SkTArray<GrShaderVar, true> VertexAttribArray;
+ static const int kMaxVertexAttribs = 6;
- const VertexAttribArray& getVertexAttribs() const { return fVertexAttribs; }
+ struct GrAttribute {
+ GrAttribute(const char* name, GrVertexAttribType type)
+ : fName(name)
+ , fType(type)
+ , fOffset(SkAlign4(GrVertexAttribTypeSize(type))) {}
+ const char* fName;
+ GrVertexAttribType fType;
+ size_t fOffset;
+ };
+
+ typedef SkTArray<GrAttribute, true> VertexAttribArray;
+
+ const VertexAttribArray& getAttribs() const { return fAttribs; }
+
+ // Returns the vertex stride of the GP. A common use case is to request geometry from a
+ // drawtarget based off of the stride, and to populate this memory using an implicit array of
+ // structs. In this case, it is best to assert the vertexstride == sizeof(VertexStruct).
+ size_t getVertexStride() const { return fVertexStride; }
bool willUseGeoShader() const { return fWillUseGeoShader; }
@@ -54,24 +73,40 @@ public:
return this->onIsEqual(that);
}
+ // TODO this is a total hack until the gp can own whether or not it uses uniform
+ // color / coverage
+ bool hasVertexColor() const { return fHasVertexColor; }
+ bool hasVertexCoverage() const { return fHasVertexCoverage; }
+ bool hasLocalCoords() const { return fHasLocalCoords; }
+
protected:
/**
- * Subclasses call this from their constructor to register vertex attributes (at most
- * kMaxVertexAttribs). This must only be called from the constructor because GrProcessors are
- * immutable.
+ * Subclasses call this from their constructor to register vertex attributes. Attributes
+ * will be padded to the nearest 4 bytes for performance reasons.
+ * TODO After deferred geometry, we should do all of this inline in GenerateGeometry alongside
+ * the struct used to actually populate the attributes
*/
- const GrShaderVar& addVertexAttrib(const GrShaderVar& var) {
- SkASSERT(fVertexAttribs.count() < kMaxVertexAttribs);
- return fVertexAttribs.push_back(var);
+ const GrAttribute& addVertexAttrib(const GrAttribute& attribute) {
+ fVertexStride += attribute.fOffset;
+ return fAttribs.push_back(attribute);
}
void setWillUseGeoShader() { fWillUseGeoShader = true; }
+ // TODO hack see above
+ void setHasVertexColor() { fHasVertexColor = true; }
+ void setHasVertexCoverage() { fHasVertexCoverage = true; }
+ void setHasLocalCoords() { fHasLocalCoords = true; }
+
private:
virtual bool onIsEqual(const GrGeometryProcessor&) const = 0;
- SkSTArray<kMaxVertexAttribs, GrShaderVar, true> fVertexAttribs;
+ SkSTArray<kMaxVertexAttribs, GrAttribute, true> fAttribs;
+ size_t fVertexStride;
bool fWillUseGeoShader;
+ bool fHasVertexColor;
+ bool fHasVertexCoverage;
+ bool fHasLocalCoords;
typedef GrProcessor INHERITED;
};
diff --git a/src/gpu/GrInOrderDrawBuffer.cpp b/src/gpu/GrInOrderDrawBuffer.cpp
index 6b98e13439..5533174853 100644
--- a/src/gpu/GrInOrderDrawBuffer.cpp
+++ b/src/gpu/GrInOrderDrawBuffer.cpp
@@ -66,8 +66,7 @@ static void set_vertex_attributes(GrDrawState* drawState, bool hasLocalCoords, G
uint32_t flags = GrDefaultGeoProcFactory::kPosition_GPType |
GrDefaultGeoProcFactory::kColor_GPType;
flags |= hasLocalCoords ? GrDefaultGeoProcFactory::kLocalCoord_GPType : 0;
- drawState->setGeometryProcessor(GrDefaultGeoProcFactory::CreateAndSetAttribs(drawState,
- flags))->unref();
+ drawState->setGeometryProcessor(GrDefaultGeoProcFactory::Create(flags))->unref();
if (0xFF == GrColorUnpackA(color)) {
drawState->setHint(GrDrawState::kVertexColorsAreOpaque_Hint, true);
}
@@ -119,7 +118,10 @@ void GrInOrderDrawBuffer::onDrawRect(GrDrawState* ds,
GrColor color = ds->getColor();
set_vertex_attributes(ds, SkToBool(localRect), color);
- AutoReleaseGeometry geo(this, 4, ds->getVertexStride(), 0);
+ size_t vstride = ds->getGeometryProcessor()->getVertexStride();
+ SkASSERT(vstride == sizeof(SkPoint) + sizeof(GrColor) + (SkToBool(localRect) ? sizeof(SkPoint) :
+ 0));
+ AutoReleaseGeometry geo(this, 4, vstride, 0);
if (!geo.succeeded()) {
SkDebugf("Failed to get space for vertices!\n");
return;
@@ -136,8 +138,6 @@ void GrInOrderDrawBuffer::onDrawRect(GrDrawState* ds,
return;
}
- size_t vstride = ds->getVertexStride();
-
geo.positions()->setRectFan(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, vstride);
matrix.mapPointsWithStride(geo.positions(), vstride, 4);
diff --git a/src/gpu/GrOptDrawState.cpp b/src/gpu/GrOptDrawState.cpp
index a494b171de..41a34c4ed2 100644
--- a/src/gpu/GrOptDrawState.cpp
+++ b/src/gpu/GrOptDrawState.cpp
@@ -7,7 +7,6 @@
#include "GrOptDrawState.h"
-#include "GrDefaultGeoProcFactory.h"
#include "GrDrawState.h"
#include "GrDrawTargetCaps.h"
#include "GrGpu.h"
@@ -30,9 +29,6 @@ GrOptDrawState::GrOptDrawState(const GrDrawState& drawState,
// Set the fields that don't default init and return. The lack of a render target will
// indicate that this can be skipped.
fFlags = 0;
- fVAPtr = NULL;
- fVACount = 0;
- fVAStride = 0;
fDrawFace = GrDrawState::kInvalid_DrawFace;
fSrcBlend = kZero_GrBlendCoeff;
fDstBlend = kZero_GrBlendCoeff;
@@ -46,9 +42,6 @@ GrOptDrawState::GrOptDrawState(const GrDrawState& drawState,
fScissorState = scissorState;
fViewMatrix = drawState.getViewMatrix();
fBlendConstant = drawState.getBlendConstant();
- fVAPtr = drawState.getVertexAttribs();
- fVACount = drawState.getVertexAttribCount();
- fVAStride = drawState.getVertexStride();
fStencilSettings = drawState.getStencil();
fDrawFace = drawState.getDrawFace();
fSrcBlend = optSrcCoeff;
@@ -72,18 +65,21 @@ GrOptDrawState::GrOptDrawState(const GrDrawState& drawState,
fFlags |= kDither_Flag;
}
- memcpy(descInfo.fFixedFunctionVertexAttribIndices,
- drawState.getFixedFunctionVertexAttribIndices(),
- sizeof(descInfo.fFixedFunctionVertexAttribIndices));
+ descInfo.fHasVertexColor = drawState.hasGeometryProcessor() &&
+ drawState.getGeometryProcessor()->hasVertexColor();
- uint8_t fixedFunctionVAToRemove = 0;
+ descInfo.fHasVertexCoverage = drawState.hasGeometryProcessor() &&
+ drawState.getGeometryProcessor()->hasVertexCoverage();
+
+ bool hasLocalCoords = drawState.hasGeometryProcessor() &&
+ drawState.getGeometryProcessor()->hasLocalCoords();
const GrProcOptInfo& colorPOI = drawState.colorProcInfo();
int firstColorStageIdx = colorPOI.firstEffectiveStageIndex();
descInfo.fInputColorIsUsed = colorPOI.inputColorIsUsed();
fColor = colorPOI.inputColorToEffectiveStage();
if (colorPOI.removeVertexAttrib()) {
- fixedFunctionVAToRemove |= 0x1 << kColor_GrVertexAttribBinding;
+ descInfo.fHasVertexColor = false;
}
// TODO: Once we can handle single or four channel input into coverage stages then we can use
@@ -93,12 +89,10 @@ GrOptDrawState::GrOptDrawState(const GrDrawState& drawState,
fCoverage = drawState.getCoverage();
this->adjustProgramForBlendOpt(drawState, blendOpt, &descInfo, &firstColorStageIdx,
- &firstCoverageStageIdx, &fixedFunctionVAToRemove);
- // Should not be setting any more FFVA to be removed at this point
- if (0 != fixedFunctionVAToRemove) {
- this->removeFixedFunctionVertexAttribs(fixedFunctionVAToRemove, &descInfo);
- }
- this->getStageStats(drawState, firstColorStageIdx, firstCoverageStageIdx, &descInfo);
+ &firstCoverageStageIdx);
+
+ this->getStageStats(drawState, firstColorStageIdx, firstCoverageStageIdx, hasLocalCoords,
+ &descInfo);
// Copy GeometryProcesssor from DS or ODS
SkASSERT(GrGpu::IsPathRenderingDrawType(drawType) ||
@@ -107,18 +101,16 @@ GrOptDrawState::GrOptDrawState(const GrDrawState& drawState,
fGeometryProcessor.reset(drawState.getGeometryProcessor());
// Copy Stages from DS to ODS
- bool explicitLocalCoords = descInfo.hasLocalCoordAttribute();
-
for (int i = firstColorStageIdx; i < drawState.numColorStages(); ++i) {
SkNEW_APPEND_TO_TARRAY(&fFragmentStages,
GrPendingFragmentStage,
- (drawState.fColorStages[i], explicitLocalCoords));
+ (drawState.fColorStages[i], hasLocalCoords));
}
fNumColorStages = fFragmentStages.count();
for (int i = firstCoverageStageIdx; i < drawState.numCoverageStages(); ++i) {
SkNEW_APPEND_TO_TARRAY(&fFragmentStages,
GrPendingFragmentStage,
- (drawState.fCoverageStages[i], explicitLocalCoords));
+ (drawState.fCoverageStages[i], hasLocalCoords));
}
this->setOutputStateInfo(drawState, blendOpt, *gpu->caps(), &descInfo);
@@ -166,8 +158,7 @@ void GrOptDrawState::adjustProgramForBlendOpt(const GrDrawState& ds,
GrDrawState::BlendOpt blendOpt,
GrProgramDesc::DescInfo* descInfo,
int* firstColorStageIdx,
- int* firstCoverageStageIdx,
- uint8_t* fixedFunctionVAToRemove) {
+ int* firstCoverageStageIdx) {
switch (blendOpt) {
case GrDrawState::kNone_BlendOpt:
case GrDrawState::kSkipDraw_BlendOpt:
@@ -177,7 +168,7 @@ void GrOptDrawState::adjustProgramForBlendOpt(const GrDrawState& ds,
fColor = 0xffffffff;
descInfo->fInputColorIsUsed = true;
*firstColorStageIdx = ds.numColorStages();
- *fixedFunctionVAToRemove |= 0x1 << kColor_GrVertexAttribBinding;
+ descInfo->fHasVertexColor = false;
break;
case GrDrawState::kEmitTransBlack_BlendOpt:
fColor = 0;
@@ -186,48 +177,12 @@ void GrOptDrawState::adjustProgramForBlendOpt(const GrDrawState& ds,
descInfo->fInputCoverageIsUsed = true;
*firstColorStageIdx = ds.numColorStages();
*firstCoverageStageIdx = ds.numCoverageStages();
- *fixedFunctionVAToRemove |= (0x1 << kColor_GrVertexAttribBinding |
- 0x1 << kCoverage_GrVertexAttribBinding);
+ descInfo->fHasVertexColor = false;
+ descInfo->fHasVertexCoverage = false;
break;
}
}
-void GrOptDrawState::removeFixedFunctionVertexAttribs(uint8_t removeVAFlag,
- GrProgramDesc::DescInfo* descInfo) {
- int numToRemove = 0;
- uint8_t maskCheck = 0x1;
- // Count the number of vertex attributes that we will actually remove
- for (int i = 0; i < kGrFixedFunctionVertexAttribBindingCnt; ++i) {
- if ((maskCheck & removeVAFlag) && -1 != descInfo->fFixedFunctionVertexAttribIndices[i]) {
- ++numToRemove;
- }
- maskCheck <<= 1;
- }
-
- fOptVA.reset(fVACount - numToRemove);
-
- GrVertexAttrib* dst = fOptVA.get();
- const GrVertexAttrib* src = fVAPtr;
-
- for (int i = 0, newIdx = 0; i < fVACount; ++i, ++src) {
- const GrVertexAttrib& currAttrib = *src;
- if (currAttrib.fBinding < kGrFixedFunctionVertexAttribBindingCnt) {
- uint8_t maskCheck = 0x1 << currAttrib.fBinding;
- if (maskCheck & removeVAFlag) {
- SkASSERT(-1 != descInfo->fFixedFunctionVertexAttribIndices[currAttrib.fBinding]);
- descInfo->fFixedFunctionVertexAttribIndices[currAttrib.fBinding] = -1;
- continue;
- }
- descInfo->fFixedFunctionVertexAttribIndices[currAttrib.fBinding] = newIdx;
- }
- memcpy(dst, src, sizeof(GrVertexAttrib));
- ++newIdx;
- ++dst;
- }
- fVACount -= numToRemove;
- fVAPtr = fOptVA.get();
-}
-
static void get_stage_stats(const GrFragmentStage& stage, bool* readsDst, bool* readsFragPosition) {
if (stage.getProcessor()->willReadDstColor()) {
*readsDst = true;
@@ -238,10 +193,11 @@ static void get_stage_stats(const GrFragmentStage& stage, bool* readsDst, bool*
}
void GrOptDrawState::getStageStats(const GrDrawState& ds, int firstColorStageIdx,
- int firstCoverageStageIdx, GrProgramDesc::DescInfo* descInfo) {
+ int firstCoverageStageIdx, bool hasLocalCoords,
+ GrProgramDesc::DescInfo* descInfo) {
// We will need a local coord attrib if there is one currently set on the optState and we are
// actually generating some effect code
- descInfo->fRequiresLocalCoordAttrib = descInfo->hasLocalCoordAttribute() &&
+ descInfo->fRequiresLocalCoordAttrib = hasLocalCoords &&
ds.numTotalStages() - firstColorStageIdx - firstCoverageStageIdx > 0;
descInfo->fReadsDst = false;
@@ -267,8 +223,8 @@ bool GrOptDrawState::operator== (const GrOptDrawState& that) const {
if (this->fDesc != that.fDesc) {
return false;
}
- bool usingVertexColors = that.fDesc.header().fColorAttributeIndex != -1;
- if (!usingVertexColors && this->fColor != that.fColor) {
+ bool hasVertexColors = this->fDesc.header().fColorInput == GrProgramDesc::kAttribute_ColorInput;
+ if (!hasVertexColors && this->fColor != that.fColor) {
return false;
}
@@ -279,17 +235,15 @@ bool GrOptDrawState::operator== (const GrOptDrawState& that) const {
this->fDstBlend != that.fDstBlend ||
this->fBlendConstant != that.fBlendConstant ||
this->fFlags != that.fFlags ||
- this->fVACount != that.fVACount ||
- this->fVAStride != that.fVAStride ||
- memcmp(this->fVAPtr, that.fVAPtr, this->fVACount * sizeof(GrVertexAttrib)) ||
this->fStencilSettings != that.fStencilSettings ||
this->fDrawFace != that.fDrawFace ||
this->fDstCopy.texture() != that.fDstCopy.texture()) {
return false;
}
- bool usingVertexCoverage = this->fDesc.header().fCoverageAttributeIndex != -1;
- if (!usingVertexCoverage && this->fCoverage != that.fCoverage) {
+ bool hasVertexCoverage =
+ this->fDesc.header().fCoverageInput == GrProgramDesc::kAttribute_ColorInput;
+ if (!hasVertexCoverage && this->fCoverage != that.fCoverage) {
return false;
}
diff --git a/src/gpu/GrOptDrawState.h b/src/gpu/GrOptDrawState.h
index bf4f78e5ef..542172fd64 100644
--- a/src/gpu/GrOptDrawState.h
+++ b/src/gpu/GrOptDrawState.h
@@ -36,19 +36,6 @@ public:
bool operator== (const GrOptDrawState& that) const;
bool operator!= (const GrOptDrawState& that) const { return !(*this == that); }
- ///////////////////////////////////////////////////////////////////////////
- /// @name Vertex Attributes
- ////
-
- enum {
- kMaxVertexAttribCnt = kLast_GrVertexAttribBinding + 4,
- };
-
- const GrVertexAttrib* getVertexAttribs() const { return fVAPtr; }
- int getVertexAttribCount() const { return fVACount; }
-
- size_t getVertexStride() const { return fVAStride; }
-
/// @}
///////////////////////////////////////////////////////////////////////////
@@ -213,26 +200,18 @@ private:
int* firstCoverageStageIdx);
/**
- * This function takes in a flag and removes the corresponding fixed function vertex attributes.
- * The flags are in the same order as GrVertexAttribBinding array. If bit i of removeVAFlags is
- * set, then vertex attributes with binding (GrVertexAttribute)i will be removed.
- */
- void removeFixedFunctionVertexAttribs(uint8_t removeVAFlags, GrProgramDesc::DescInfo*);
-
- /**
* Alter the program desc and inputs (attribs and processors) based on the blend optimization.
*/
void adjustProgramForBlendOpt(const GrDrawState& ds, GrDrawState::BlendOpt,
GrProgramDesc::DescInfo*,
- int* firstColorStageIdx, int* firstCoverageStageIdx,
- uint8_t* fixedFunctionVAToRemove);
+ int* firstColorStageIdx, int* firstCoverageStageIdx);
/**
* Loop over the effect stages to determine various info like what data they will read and what
* shaders they require.
*/
void getStageStats(const GrDrawState& ds, int firstColorStageIdx, int firstCoverageStageIdx,
- GrProgramDesc::DescInfo*);
+ bool hasLocalCoords, GrProgramDesc::DescInfo*);
/**
* Calculates the primary and secondary output types of the shader. For certain output types
@@ -256,9 +235,6 @@ private:
GrColor fColor;
SkMatrix fViewMatrix;
GrColor fBlendConstant;
- const GrVertexAttrib* fVAPtr;
- int fVACount;
- size_t fVAStride;
GrStencilSettings fStencilSettings;
uint8_t fCoverage;
GrDrawState::DrawFace fDrawFace;
@@ -272,8 +248,6 @@ private:
// This function is equivalent to the offset into fFragmentStages where coverage stages begin.
int fNumColorStages;
- SkAutoSTArray<4, GrVertexAttrib> fOptVA;
-
GrProgramDesc fDesc;
typedef SkRefCnt INHERITED;
diff --git a/src/gpu/GrOvalRenderer.cpp b/src/gpu/GrOvalRenderer.cpp
index 42844ee9ea..a9dda840aa 100644
--- a/src/gpu/GrOvalRenderer.cpp
+++ b/src/gpu/GrOvalRenderer.cpp
@@ -76,7 +76,8 @@ public:
}
}
- const GrShaderVar& inCircleEdge() const { return fInCircleEdge; }
+ const GrAttribute* inPosition() const { return fInPosition; }
+ const GrAttribute* inCircleEdge() const { return fInCircleEdge; }
virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERRIDE {
return GrTBackendGeometryProcessorFactory<CircleEdgeEffect>::getInstance();
@@ -94,28 +95,31 @@ public:
: INHERITED (factory) {}
virtual void emitCode(const EmitArgs& args) SK_OVERRIDE {
- const CircleEdgeEffect& circleEffect = args.fGP.cast<CircleEdgeEffect>();
+ const CircleEdgeEffect& ce = args.fGP.cast<CircleEdgeEffect>();
+ GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
+
GrGLVertToFrag v(kVec4f_GrSLType);
args.fPB->addVarying("CircleEdge", &v);
+ vsBuilder->codeAppendf("%s = %s;", v.vsOut(), ce.inCircleEdge()->fName);
- GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();;
- vsBuilder->codeAppendf("%s = %s;", v.vsOut(), circleEffect.inCircleEdge().c_str());
+ // setup coord outputs
+ vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(), ce.inPosition()->fName);
+ vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(), ce.inPosition()->fName);
// setup position varying
vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(),
- vsBuilder->uViewM(), vsBuilder->inPosition());
+ vsBuilder->uViewM(), ce.inPosition()->fName);
GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
fsBuilder->codeAppendf("float d = length(%s.xy);", v.fsIn());
fsBuilder->codeAppendf("float edgeAlpha = clamp(%s.z - d, 0.0, 1.0);", v.fsIn());
- if (circleEffect.isStroked()) {
+ if (ce.isStroked()) {
fsBuilder->codeAppendf("float innerAlpha = clamp(d - %s.w, 0.0, 1.0);",
v.fsIn());
fsBuilder->codeAppend("edgeAlpha *= innerAlpha;");
}
- fsBuilder->codeAppendf("%s = %s;\n", args.fOutput,
- (GrGLSLExpr4(args.fInput) * GrGLSLExpr1("edgeAlpha")).c_str());
+ fsBuilder->codeAppendf("%s = vec4(edgeAlpha);", args.fOutputCoverage);
}
static void GenKey(const GrProcessor& processor, const GrGLCaps&,
@@ -132,11 +136,10 @@ public:
private:
- CircleEdgeEffect(bool stroke)
- : fInCircleEdge(this->addVertexAttrib(
- GrShaderVar("inCircleEdge",
- kVec4f_GrSLType,
- GrShaderVar::kAttribute_TypeModifier))) {
+ CircleEdgeEffect(bool stroke) {
+ fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVertexAttribType));
+ fInCircleEdge = &this->addVertexAttrib(GrAttribute("inCircleEdge",
+ kVec4f_GrVertexAttribType));
fStroke = stroke;
}
@@ -149,7 +152,8 @@ private:
inout->mulByUnknownAlpha();
}
- const GrShaderVar& fInCircleEdge;
+ const GrAttribute* fInPosition;
+ const GrAttribute* fInCircleEdge;
bool fStroke;
GR_DECLARE_GEOMETRY_PROCESSOR_TEST;
@@ -199,8 +203,10 @@ public:
static const char* Name() { return "EllipseEdge"; }
- const GrShaderVar& inEllipseOffset() const { return fInEllipseOffset; }
- const GrShaderVar& inEllipseRadii() const { return fInEllipseRadii; }
+
+ const GrAttribute* inPosition() const { return fInPosition; }
+ const GrAttribute* inEllipseOffset() const { return fInEllipseOffset; }
+ const GrAttribute* inEllipseRadii() const { return fInEllipseRadii; }
inline bool isStroked() const { return fStroke; }
@@ -210,23 +216,27 @@ public:
: INHERITED (factory) {}
virtual void emitCode(const EmitArgs& args) SK_OVERRIDE {
- const EllipseEdgeEffect& ellipseEffect = args.fGP.cast<EllipseEdgeEffect>();
+ const EllipseEdgeEffect& ee = args.fGP.cast<EllipseEdgeEffect>();
+
+ GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
GrGLVertToFrag ellipseOffsets(kVec2f_GrSLType);
args.fPB->addVarying("EllipseOffsets", &ellipseOffsets);
-
- GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
vsBuilder->codeAppendf("%s = %s;", ellipseOffsets.vsOut(),
- ellipseEffect.inEllipseOffset().c_str());
+ ee.inEllipseOffset()->fName);
GrGLVertToFrag ellipseRadii(kVec4f_GrSLType);
args.fPB->addVarying("EllipseRadii", &ellipseRadii);
vsBuilder->codeAppendf("%s = %s;", ellipseRadii.vsOut(),
- ellipseEffect.inEllipseRadii().c_str());
+ ee.inEllipseRadii()->fName);
+
+ // setup coord outputs
+ vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(), ee.inPosition()->fName);
+ vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(), ee.inPosition()->fName);
// setup position varying
vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(),
- vsBuilder->uViewM(), vsBuilder->inPosition());
+ vsBuilder->uViewM(), ee.inPosition()->fName);
// for outer curve
GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
@@ -242,7 +252,7 @@ public:
fsBuilder->codeAppend("float edgeAlpha = clamp(0.5-test*invlen, 0.0, 1.0);");
// for inner curve
- if (ellipseEffect.isStroked()) {
+ if (ee.isStroked()) {
fsBuilder->codeAppendf("scaledOffset = %s*%s.zw;",
ellipseOffsets.fsIn(), ellipseRadii.fsIn());
fsBuilder->codeAppend("test = dot(scaledOffset, scaledOffset) - 1.0;");
@@ -252,8 +262,7 @@ public:
fsBuilder->codeAppend("edgeAlpha *= clamp(0.5+test*invlen, 0.0, 1.0);");
}
- fsBuilder->codeAppendf("%s = %s;", args.fOutput,
- (GrGLSLExpr4(args.fInput) * GrGLSLExpr1("edgeAlpha")).c_str());
+ fsBuilder->codeAppendf("%s = vec4(edgeAlpha);", args.fOutputCoverage);
}
static void GenKey(const GrProcessor& processor, const GrGLCaps&,
@@ -270,15 +279,12 @@ public:
};
private:
- EllipseEdgeEffect(bool stroke)
- : fInEllipseOffset(this->addVertexAttrib(
- GrShaderVar("inEllipseOffset",
- kVec2f_GrSLType,
- GrShaderVar::kAttribute_TypeModifier)))
- , fInEllipseRadii(this->addVertexAttrib(
- GrShaderVar("inEllipseRadii",
- kVec4f_GrSLType,
- GrShaderVar::kAttribute_TypeModifier))) {
+ EllipseEdgeEffect(bool stroke) {
+ fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVertexAttribType));
+ fInEllipseOffset = &this->addVertexAttrib(GrAttribute("inEllipseOffset",
+ kVec2f_GrVertexAttribType));
+ fInEllipseRadii = &this->addVertexAttrib(GrAttribute("inEllipseRadii",
+ kVec4f_GrVertexAttribType));
fStroke = stroke;
}
@@ -291,8 +297,9 @@ private:
inout->mulByUnknownAlpha();
}
- const GrShaderVar& fInEllipseOffset;
- const GrShaderVar& fInEllipseRadii;
+ const GrAttribute* fInPosition;
+ const GrAttribute* fInEllipseOffset;
+ const GrAttribute* fInEllipseRadii;
bool fStroke;
GR_DECLARE_GEOMETRY_PROCESSOR_TEST;
@@ -349,8 +356,9 @@ public:
static const char* Name() { return "DIEllipseEdge"; }
- const GrShaderVar& inEllipseOffsets0() const { return fInEllipseOffsets0; }
- const GrShaderVar& inEllipseOffsets1() const { return fInEllipseOffsets1; }
+ const GrAttribute* inPosition() const { return fInPosition; }
+ const GrAttribute* inEllipseOffsets0() const { return fInEllipseOffsets0; }
+ const GrAttribute* inEllipseOffsets1() const { return fInEllipseOffsets1; }
inline Mode getMode() const { return fMode; }
@@ -360,23 +368,27 @@ public:
: INHERITED (factory) {}
virtual void emitCode(const EmitArgs& args) SK_OVERRIDE {
- const DIEllipseEdgeEffect& ellipseEffect = args.fGP.cast<DIEllipseEdgeEffect>();
+ const DIEllipseEdgeEffect& ee = args.fGP.cast<DIEllipseEdgeEffect>();
+
+ GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
GrGLVertToFrag offsets0(kVec2f_GrSLType);
args.fPB->addVarying("EllipseOffsets0", &offsets0);
-
- GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
vsBuilder->codeAppendf("%s = %s;", offsets0.vsOut(),
- ellipseEffect.inEllipseOffsets0().c_str());
+ ee.inEllipseOffsets0()->fName);
GrGLVertToFrag offsets1(kVec2f_GrSLType);
args.fPB->addVarying("EllipseOffsets1", &offsets1);
vsBuilder->codeAppendf("%s = %s;", offsets1.vsOut(),
- ellipseEffect.inEllipseOffsets1().c_str());
+ ee.inEllipseOffsets1()->fName);
+
+ // setup coord outputs
+ vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(), ee.inPosition()->fName);
+ vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(), ee.inPosition()->fName);
// setup position varying
vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(),
- vsBuilder->uViewM(), vsBuilder->inPosition());
+ vsBuilder->uViewM(), ee.inPosition()->fName);
GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
SkAssertResult(fsBuilder->enableFeature(
@@ -394,7 +406,7 @@ public:
// avoid calling inversesqrt on zero.
fsBuilder->codeAppend("grad_dot = max(grad_dot, 1.0e-4);");
fsBuilder->codeAppend("float invlen = inversesqrt(grad_dot);");
- if (kHairline == ellipseEffect.getMode()) {
+ if (kHairline == ee.getMode()) {
// can probably do this with one step
fsBuilder->codeAppend("float edgeAlpha = clamp(1.0-test*invlen, 0.0, 1.0);");
fsBuilder->codeAppend("edgeAlpha *= clamp(1.0+test*invlen, 0.0, 1.0);");
@@ -403,7 +415,7 @@ public:
}
// for inner curve
- if (kStroke == ellipseEffect.getMode()) {
+ if (kStroke == ee.getMode()) {
fsBuilder->codeAppendf("scaledOffset = %s.xy;", offsets1.fsIn());
fsBuilder->codeAppend("test = dot(scaledOffset, scaledOffset) - 1.0;");
fsBuilder->codeAppendf("duvdx = dFdx(%s);", offsets1.fsIn());
@@ -416,8 +428,7 @@ public:
fsBuilder->codeAppend("edgeAlpha *= clamp(0.5+test*invlen, 0.0, 1.0);");
}
- fsBuilder->codeAppendf("%s = %s;", args.fOutput,
- (GrGLSLExpr4(args.fInput) * GrGLSLExpr1("edgeAlpha")).c_str());
+ fsBuilder->codeAppendf("%s = vec4(edgeAlpha);", args.fOutputCoverage);
}
static void GenKey(const GrProcessor& processor, const GrGLCaps&,
@@ -435,15 +446,12 @@ public:
};
private:
- DIEllipseEdgeEffect(Mode mode)
- : fInEllipseOffsets0(this->addVertexAttrib(
- GrShaderVar("inEllipseOffsets0",
- kVec2f_GrSLType,
- GrShaderVar::kAttribute_TypeModifier)))
- , fInEllipseOffsets1(this->addVertexAttrib(
- GrShaderVar("inEllipseOffsets1",
- kVec2f_GrSLType,
- GrShaderVar::kAttribute_TypeModifier))) {
+ DIEllipseEdgeEffect(Mode mode) {
+ fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVertexAttribType));
+ fInEllipseOffsets0 = &this->addVertexAttrib(GrAttribute("inEllipseOffsets0",
+ kVec2f_GrVertexAttribType));
+ fInEllipseOffsets1 = &this->addVertexAttrib(GrAttribute("inEllipseOffsets1",
+ kVec2f_GrVertexAttribType));
fMode = mode;
}
@@ -456,8 +464,9 @@ private:
inout->mulByUnknownAlpha();
}
- const GrShaderVar& fInEllipseOffsets0;
- const GrShaderVar& fInEllipseOffsets1;
+ const GrAttribute* fInPosition;
+ const GrAttribute* fInEllipseOffsets0;
+ const GrAttribute* fInEllipseOffsets1;
Mode fMode;
GR_DECLARE_GEOMETRY_PROCESSOR_TEST;
@@ -517,12 +526,6 @@ bool GrOvalRenderer::drawOval(GrDrawTarget* target,
///////////////////////////////////////////////////////////////////////////////
-// position + edge
-extern const GrVertexAttrib gCircleVertexAttribs[] = {
- {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding},
- {kVec4f_GrVertexAttribType, sizeof(SkPoint), kGeometryProcessor_GrVertexAttribBinding}
-};
-
void GrOvalRenderer::drawCircle(GrDrawTarget* target,
GrDrawState* drawState,
const GrContext* context,
@@ -541,17 +544,6 @@ void GrOvalRenderer::drawCircle(GrDrawTarget* target,
return;
}
- drawState->setVertexAttribs<gCircleVertexAttribs>(SK_ARRAY_COUNT(gCircleVertexAttribs),
- sizeof(CircleVertex));
-
- GrDrawTarget::AutoReleaseGeometry geo(target, 4, drawState->getVertexStride(), 0);
- if (!geo.succeeded()) {
- SkDebugf("Failed to get space for vertices!\n");
- return;
- }
-
- CircleVertex* verts = reinterpret_cast<CircleVertex*>(geo.vertices());
-
SkStrokeRec::Style style = stroke.getStyle();
bool isStrokeOnly = SkStrokeRec::kStroke_Style == style ||
SkStrokeRec::kHairline_Style == style;
@@ -576,6 +568,15 @@ void GrOvalRenderer::drawCircle(GrDrawTarget* target,
GrGeometryProcessor* gp = CircleEdgeEffect::Create(isStrokeOnly && innerRadius > 0);
drawState->setGeometryProcessor(gp)->unref();
+ GrDrawTarget::AutoReleaseGeometry geo(target, 4, gp->getVertexStride(), 0);
+ SkASSERT(gp->getVertexStride() == sizeof(CircleVertex));
+ if (!geo.succeeded()) {
+ SkDebugf("Failed to get space for vertices!\n");
+ return;
+ }
+
+ CircleVertex* verts = reinterpret_cast<CircleVertex*>(geo.vertices());
+
// The radii are outset for two reasons. First, it allows the shader to simply perform
// clamp(distance-to-center - radius, 0, 1). Second, the outer radius is used to compute the
// verts of the bounding box that is rendered and the outset ensures the box will cover all
@@ -617,20 +618,6 @@ void GrOvalRenderer::drawCircle(GrDrawTarget* target,
///////////////////////////////////////////////////////////////////////////////
-// position + offset + 1/radii
-extern const GrVertexAttrib gEllipseVertexAttribs[] = {
- {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding},
- {kVec2f_GrVertexAttribType, sizeof(SkPoint), kGeometryProcessor_GrVertexAttribBinding},
- {kVec4f_GrVertexAttribType, 2*sizeof(SkPoint), kGeometryProcessor_GrVertexAttribBinding}
-};
-
-// position + offsets
-extern const GrVertexAttrib gDIEllipseVertexAttribs[] = {
- {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding},
- {kVec2f_GrVertexAttribType, sizeof(SkPoint), kGeometryProcessor_GrVertexAttribBinding},
- {kVec2f_GrVertexAttribType, 2*sizeof(SkPoint), kGeometryProcessor_GrVertexAttribBinding},
-};
-
bool GrOvalRenderer::drawEllipse(GrDrawTarget* target,
GrDrawState* drawState,
const GrContext* context,
@@ -704,10 +691,13 @@ bool GrOvalRenderer::drawEllipse(GrDrawTarget* target,
return false;
}
- drawState->setVertexAttribs<gEllipseVertexAttribs>(SK_ARRAY_COUNT(gEllipseVertexAttribs),
- sizeof(EllipseVertex));
+ GrGeometryProcessor* gp = EllipseEdgeEffect::Create(isStrokeOnly &&
+ innerXRadius > 0 && innerYRadius > 0);
- GrDrawTarget::AutoReleaseGeometry geo(target, 4, drawState->getVertexStride(), 0);
+ drawState->setGeometryProcessor(gp)->unref();
+
+ GrDrawTarget::AutoReleaseGeometry geo(target, 4, gp->getVertexStride(), 0);
+ SkASSERT(gp->getVertexStride() == sizeof(EllipseVertex));
if (!geo.succeeded()) {
SkDebugf("Failed to get space for vertices!\n");
return false;
@@ -715,11 +705,6 @@ bool GrOvalRenderer::drawEllipse(GrDrawTarget* target,
EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(geo.vertices());
- GrGeometryProcessor* gp = EllipseEdgeEffect::Create(isStrokeOnly &&
- innerXRadius > 0 && innerYRadius > 0);
-
- drawState->setGeometryProcessor(gp)->unref();
-
// Compute the reciprocals of the radii here to save time in the shader
SkScalar xRadRecip = SkScalarInvert(xRadius);
SkScalar yRadRecip = SkScalarInvert(yRadius);
@@ -824,10 +809,12 @@ bool GrOvalRenderer::drawDIEllipse(GrDrawTarget* target,
SkScalar innerRatioX = SkScalarDiv(xRadius, innerXRadius);
SkScalar innerRatioY = SkScalarDiv(yRadius, innerYRadius);
- drawState->setVertexAttribs<gDIEllipseVertexAttribs>(SK_ARRAY_COUNT(gDIEllipseVertexAttribs),
- sizeof(DIEllipseVertex));
+ GrGeometryProcessor* gp = DIEllipseEdgeEffect::Create(mode);
+
+ drawState->setGeometryProcessor(gp)->unref();
- GrDrawTarget::AutoReleaseGeometry geo(target, 4, drawState->getVertexStride(), 0);
+ GrDrawTarget::AutoReleaseGeometry geo(target, 4, gp->getVertexStride(), 0);
+ SkASSERT(gp->getVertexStride() == sizeof(DIEllipseVertex));
if (!geo.succeeded()) {
SkDebugf("Failed to get space for vertices!\n");
return false;
@@ -835,10 +822,6 @@ bool GrOvalRenderer::drawDIEllipse(GrDrawTarget* target,
DIEllipseVertex* verts = reinterpret_cast<DIEllipseVertex*>(geo.vertices());
- GrGeometryProcessor* gp = DIEllipseEdgeEffect::Create(mode);
-
- drawState->setGeometryProcessor(gp)->unref();
-
// This expands the outer rect so that after CTM we end up with a half-pixel border
SkScalar a = vm[SkMatrix::kMScaleX];
SkScalar b = vm[SkMatrix::kMSkewX];
@@ -1072,16 +1055,6 @@ bool GrOvalRenderer::drawRRect(GrDrawTarget* target,
// if the corners are circles, use the circle renderer
if ((!hasStroke || scaledStroke.fX == scaledStroke.fY) && xRadius == yRadius) {
- drawState->setVertexAttribs<gCircleVertexAttribs>(SK_ARRAY_COUNT(gCircleVertexAttribs),
- sizeof(CircleVertex));
-
- GrDrawTarget::AutoReleaseGeometry geo(target, 16, drawState->getVertexStride(), 0);
- if (!geo.succeeded()) {
- SkDebugf("Failed to get space for vertices!\n");
- return false;
- }
- CircleVertex* verts = reinterpret_cast<CircleVertex*>(geo.vertices());
-
SkScalar innerRadius = 0.0f;
SkScalar outerRadius = xRadius;
SkScalar halfWidth = 0;
@@ -1104,6 +1077,14 @@ bool GrOvalRenderer::drawRRect(GrDrawTarget* target,
GrGeometryProcessor* effect = CircleEdgeEffect::Create(isStrokeOnly);
drawState->setGeometryProcessor(effect)->unref();
+ GrDrawTarget::AutoReleaseGeometry geo(target, 16, effect->getVertexStride(), 0);
+ SkASSERT(effect->getVertexStride() == sizeof(CircleVertex));
+ if (!geo.succeeded()) {
+ SkDebugf("Failed to get space for vertices!\n");
+ return false;
+ }
+ CircleVertex* verts = reinterpret_cast<CircleVertex*>(geo.vertices());
+
// The radii are outset for two reasons. First, it allows the shader to simply perform
// clamp(distance-to-center - radius, 0, 1). Second, the outer radius is used to compute the
// verts of the bounding box that is rendered and the outset ensures the box will cover all
@@ -1161,9 +1142,6 @@ bool GrOvalRenderer::drawRRect(GrDrawTarget* target,
// otherwise we use the ellipse renderer
} else {
- drawState->setVertexAttribs<gEllipseVertexAttribs>(SK_ARRAY_COUNT(gEllipseVertexAttribs),
- sizeof(EllipseVertex));
-
SkScalar innerXRadius = 0.0f;
SkScalar innerYRadius = 0.0f;
if (hasStroke) {
@@ -1198,15 +1176,17 @@ bool GrOvalRenderer::drawRRect(GrDrawTarget* target,
isStrokeOnly = (isStrokeOnly && innerXRadius >= 0 && innerYRadius >= 0);
- GrDrawTarget::AutoReleaseGeometry geo(target, 16, drawState->getVertexStride(), 0);
+ GrGeometryProcessor* effect = EllipseEdgeEffect::Create(isStrokeOnly);
+ drawState->setGeometryProcessor(effect)->unref();
+
+ GrDrawTarget::AutoReleaseGeometry geo(target, 16, effect->getVertexStride(), 0);
+ SkASSERT(effect->getVertexStride() == sizeof(EllipseVertex));
if (!geo.succeeded()) {
SkDebugf("Failed to get space for vertices!\n");
return false;
}
- EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(geo.vertices());
- GrGeometryProcessor* effect = EllipseEdgeEffect::Create(isStrokeOnly);
- drawState->setGeometryProcessor(effect)->unref();
+ EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(geo.vertices());
// Compute the reciprocals of the radii here to save time in the shader
SkScalar xRadRecip = SkScalarInvert(xRadius);
diff --git a/src/gpu/GrProgramDesc.h b/src/gpu/GrProgramDesc.h
index 788842d7be..655254f892 100644
--- a/src/gpu/GrProgramDesc.h
+++ b/src/gpu/GrProgramDesc.h
@@ -111,11 +111,6 @@ public:
PrimaryOutputType fPrimaryOutputType : 8;
SecondaryOutputType fSecondaryOutputType : 8;
- int8_t fPositionAttributeIndex;
- int8_t fLocalCoordAttributeIndex;
- int8_t fColorAttributeIndex;
- int8_t fCoverageAttributeIndex;
-
SkBool8 fHasGeometryProcessor;
int8_t fColorEffectCnt;
int8_t fCoverageEffectCnt;
@@ -141,29 +136,10 @@ public:
// A struct to communicate descriptor information to the program descriptor builder
struct DescInfo {
- int positionAttributeIndex() const {
- return fFixedFunctionVertexAttribIndices[kPosition_GrVertexAttribBinding];
- }
- int localCoordAttributeIndex() const {
- return fFixedFunctionVertexAttribIndices[kLocalCoord_GrVertexAttribBinding];
- }
- int colorVertexAttributeIndex() const {
- return fFixedFunctionVertexAttribIndices[kColor_GrVertexAttribBinding];
- }
- int coverageVertexAttributeIndex() const {
- return fFixedFunctionVertexAttribIndices[kCoverage_GrVertexAttribBinding];
- }
- bool hasLocalCoordAttribute() const {
- return -1 != fFixedFunctionVertexAttribIndices[kLocalCoord_GrVertexAttribBinding];
- }
- bool hasColorVertexAttribute() const {
- return -1 != fFixedFunctionVertexAttribIndices[kColor_GrVertexAttribBinding];
- }
- bool hasCoverageVertexAttribute() const {
- return -1 != fFixedFunctionVertexAttribIndices[kCoverage_GrVertexAttribBinding];
- }
-
- int fFixedFunctionVertexAttribIndices[kGrFixedFunctionVertexAttribBindingCnt];
+ // TODO when GPs control uniform / attribute handling of color / coverage, then we can
+ // clean this up
+ bool fHasVertexColor;
+ bool fHasVertexCoverage;
// These flags are needed to protect the code from creating an unused uniform color/coverage
// which will cause shader compiler errors.
diff --git a/src/gpu/effects/GrBezierEffect.cpp b/src/gpu/effects/GrBezierEffect.cpp
index 26049b398b..f38a136992 100644
--- a/src/gpu/effects/GrBezierEffect.cpp
+++ b/src/gpu/effects/GrBezierEffect.cpp
@@ -37,16 +37,20 @@ GrGLConicEffect::GrGLConicEffect(const GrBackendProcessorFactory& factory,
}
void GrGLConicEffect::emitCode(const EmitArgs& args) {
+ GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
+ const GrConicEffect& gp = args.fGP.cast<GrConicEffect>();
+
GrGLVertToFrag v(kVec4f_GrSLType);
args.fPB->addVarying("ConicCoeffs", &v);
+ vsBuilder->codeAppendf("%s = %s;", v.vsOut(), gp.inConicCoeffs()->fName);
- const GrShaderVar& inConicCoeffs = args.fGP.cast<GrConicEffect>().inConicCoeffs();
- GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
- vsBuilder->codeAppendf("%s = %s;", v.vsOut(), inConicCoeffs.c_str());
+ // setup coord outputs
+ vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(), gp.inPosition()->fName);
+ vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(), gp.inPosition()->fName);
// setup position varying
vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), vsBuilder->uViewM(),
- vsBuilder->inPosition());
+ gp.inPosition()->fName);
GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
fsBuilder->codeAppend("float edgeAlpha;");
@@ -105,8 +109,7 @@ void GrGLConicEffect::emitCode(const EmitArgs& args) {
SkFAIL("Shouldn't get here");
}
- fsBuilder->codeAppendf("%s = %s;", args.fOutput,
- (GrGLSLExpr4(args.fInput) * GrGLSLExpr1("edgeAlpha")).c_str());
+ fsBuilder->codeAppendf("%s = vec4(edgeAlpha);", args.fOutputCoverage);
}
void GrGLConicEffect::GenKey(const GrProcessor& processor, const GrGLCaps&,
@@ -125,10 +128,10 @@ const GrBackendGeometryProcessorFactory& GrConicEffect::getFactory() const {
}
GrConicEffect::GrConicEffect(GrPrimitiveEdgeType edgeType)
- : fEdgeType(edgeType)
- , fInConicCoeffs(this->addVertexAttrib(GrShaderVar("inConicCoeffs",
- kVec4f_GrSLType,
- GrShaderVar::kAttribute_TypeModifier))) {
+ : fEdgeType(edgeType) {
+ fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVertexAttribType));
+ fInConicCoeffs = &this->addVertexAttrib(GrAttribute("inConicCoeffs",
+ kVec4f_GrVertexAttribType));
}
bool GrConicEffect::onIsEqual(const GrGeometryProcessor& other) const {
@@ -181,16 +184,20 @@ GrGLQuadEffect::GrGLQuadEffect(const GrBackendProcessorFactory& factory,
}
void GrGLQuadEffect::emitCode(const EmitArgs& args) {
+ GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
+ const GrQuadEffect& gp = args.fGP.cast<GrQuadEffect>();
+
GrGLVertToFrag v(kVec4f_GrSLType);
args.fPB->addVarying("HairQuadEdge", &v);
+ vsBuilder->codeAppendf("%s = %s;", v.vsOut(), gp.inHairQuadEdge()->fName);
- GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
- const GrShaderVar& inHairQuadEdge = args.fGP.cast<GrQuadEffect>().inHairQuadEdge();
- vsBuilder->codeAppendf("%s = %s;", v.vsOut(), inHairQuadEdge.c_str());
+ // setup coord outputs
+ vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(), gp.inPosition()->fName);
+ vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(), gp.inPosition()->fName);
// setup position varying
vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), vsBuilder->uViewM(),
- vsBuilder->inPosition());
+ gp.inPosition()->fName);
GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
fsBuilder->codeAppendf("float edgeAlpha;");
@@ -235,8 +242,7 @@ void GrGLQuadEffect::emitCode(const EmitArgs& args) {
SkFAIL("Shouldn't get here");
}
- fsBuilder->codeAppendf("%s = %s;", args.fOutput,
- (GrGLSLExpr4(args.fInput) * GrGLSLExpr1("edgeAlpha")).c_str());
+ fsBuilder->codeAppendf("%s = vec4(edgeAlpha);", args.fOutputCoverage);
}
void GrGLQuadEffect::GenKey(const GrProcessor& processor, const GrGLCaps&,
@@ -255,10 +261,10 @@ const GrBackendGeometryProcessorFactory& GrQuadEffect::getFactory() const {
}
GrQuadEffect::GrQuadEffect(GrPrimitiveEdgeType edgeType)
- : fEdgeType(edgeType)
- , fInHairQuadEdge(this->addVertexAttrib(GrShaderVar("inCubicCoeffs",
- kVec4f_GrSLType,
- GrShaderVar::kAttribute_TypeModifier))) {
+ : fEdgeType(edgeType) {
+ fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVertexAttribType));
+ fInHairQuadEdge = &this->addVertexAttrib(GrAttribute("inHairQuadEdge",
+ kVec4f_GrVertexAttribType));
}
bool GrQuadEffect::onIsEqual(const GrGeometryProcessor& other) const {
@@ -311,16 +317,20 @@ GrGLCubicEffect::GrGLCubicEffect(const GrBackendProcessorFactory& factory,
}
void GrGLCubicEffect::emitCode(const EmitArgs& args) {
+ GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
+ const GrCubicEffect& gp = args.fGP.cast<GrCubicEffect>();
+
GrGLVertToFrag v(kVec4f_GrSLType);
- args.fPB->addVarying("CubicCoeffs", &v, GrGLShaderVar::kHigh_Precision);
+ args.fPB->addVarying("CubicCoeffs", &v);
+ vsBuilder->codeAppendf("%s = %s;", v.vsOut(), gp.inCubicCoeffs()->fName);
- GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
- const GrShaderVar& inCubicCoeffs = args.fGP.cast<GrCubicEffect>().inCubicCoeffs();
- vsBuilder->codeAppendf("%s = %s;", v.vsOut(), inCubicCoeffs.c_str());
+ // setup coord outputs
+ vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(), gp.inPosition()->fName);
+ vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(), gp.inPosition()->fName);
// setup position varying
vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), vsBuilder->uViewM(),
- vsBuilder->inPosition());
+ gp.inPosition()->fName);
GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
@@ -405,8 +415,8 @@ void GrGLCubicEffect::emitCode(const EmitArgs& args) {
SkFAIL("Shouldn't get here");
}
- fsBuilder->codeAppendf("%s = %s;", args.fOutput,
- (GrGLSLExpr4(args.fInput) * GrGLSLExpr1(edgeAlpha.c_str())).c_str());
+
+ fsBuilder->codeAppendf("%s = vec4(%s);", args.fOutputCoverage, edgeAlpha.c_str());
}
void GrGLCubicEffect::GenKey(const GrProcessor& processor, const GrGLCaps&,
@@ -425,10 +435,10 @@ const GrBackendGeometryProcessorFactory& GrCubicEffect::getFactory() const {
}
GrCubicEffect::GrCubicEffect(GrPrimitiveEdgeType edgeType)
- : fEdgeType(edgeType)
- , fInCubicCoeffs(this->addVertexAttrib(GrShaderVar("inCubicCoeffs",
- kVec4f_GrSLType,
- GrShaderVar::kAttribute_TypeModifier))) {
+ : fEdgeType(edgeType) {
+ fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVertexAttribType));
+ fInCubicCoeffs = &this->addVertexAttrib(GrAttribute("inCubicCoeffs",
+ kVec4f_GrVertexAttribType));
}
bool GrCubicEffect::onIsEqual(const GrGeometryProcessor& other) const {
diff --git a/src/gpu/effects/GrBezierEffect.h b/src/gpu/effects/GrBezierEffect.h
index 9b71f7d395..27f2fa1aa2 100644
--- a/src/gpu/effects/GrBezierEffect.h
+++ b/src/gpu/effects/GrBezierEffect.h
@@ -88,7 +88,8 @@ public:
static const char* Name() { return "Conic"; }
- inline const GrShaderVar& inConicCoeffs() const { return fInConicCoeffs; }
+ inline const GrAttribute* inPosition() const { return fInPosition; }
+ inline const GrAttribute* inConicCoeffs() const { return fInConicCoeffs; }
inline bool isAntiAliased() const { return GrProcessorEdgeTypeIsAA(fEdgeType); }
inline bool isFilled() const { return GrProcessorEdgeTypeIsFill(fEdgeType); }
inline GrPrimitiveEdgeType getEdgeType() const { return fEdgeType; }
@@ -107,7 +108,8 @@ private:
}
GrPrimitiveEdgeType fEdgeType;
- const GrShaderVar& fInConicCoeffs;
+ const GrAttribute* fInPosition;
+ const GrAttribute* fInConicCoeffs;
GR_DECLARE_GEOMETRY_PROCESSOR_TEST;
@@ -157,7 +159,8 @@ public:
static const char* Name() { return "Quad"; }
- inline const GrShaderVar& inHairQuadEdge() const { return fInHairQuadEdge; }
+ inline const GrAttribute* inPosition() const { return fInPosition; }
+ inline const GrAttribute* inHairQuadEdge() const { return fInHairQuadEdge; }
inline bool isAntiAliased() const { return GrProcessorEdgeTypeIsAA(fEdgeType); }
inline bool isFilled() const { return GrProcessorEdgeTypeIsFill(fEdgeType); }
inline GrPrimitiveEdgeType getEdgeType() const { return fEdgeType; }
@@ -176,7 +179,8 @@ private:
}
GrPrimitiveEdgeType fEdgeType;
- const GrShaderVar& fInHairQuadEdge;
+ const GrAttribute* fInPosition;
+ const GrAttribute* fInHairQuadEdge;
GR_DECLARE_GEOMETRY_PROCESSOR_TEST;
@@ -228,7 +232,8 @@ public:
static const char* Name() { return "Cubic"; }
- inline const GrShaderVar& inCubicCoeffs() const { return fInCubicCoeffs; }
+ inline const GrAttribute* inPosition() const { return fInPosition; }
+ inline const GrAttribute* inCubicCoeffs() const { return fInCubicCoeffs; }
inline bool isAntiAliased() const { return GrProcessorEdgeTypeIsAA(fEdgeType); }
inline bool isFilled() const { return GrProcessorEdgeTypeIsFill(fEdgeType); }
inline GrPrimitiveEdgeType getEdgeType() const { return fEdgeType; }
@@ -247,7 +252,8 @@ private:
}
GrPrimitiveEdgeType fEdgeType;
- const GrShaderVar& fInCubicCoeffs;
+ const GrAttribute* fInPosition;
+ const GrAttribute* fInCubicCoeffs;
GR_DECLARE_GEOMETRY_PROCESSOR_TEST;
diff --git a/src/gpu/effects/GrCustomCoordsTextureEffect.cpp b/src/gpu/effects/GrCustomCoordsTextureEffect.cpp
index f61a37bb6f..45c3008889 100644
--- a/src/gpu/effects/GrCustomCoordsTextureEffect.cpp
+++ b/src/gpu/effects/GrCustomCoordsTextureEffect.cpp
@@ -21,33 +21,44 @@ public:
: INHERITED (factory) {}
virtual void emitCode(const EmitArgs& args) SK_OVERRIDE {
- const GrCustomCoordsTextureEffect& customCoordsTextureEffect =
+ const GrCustomCoordsTextureEffect& cte =
args.fGP.cast<GrCustomCoordsTextureEffect>();
- SkASSERT(1 == customCoordsTextureEffect.getVertexAttribs().count());
+
+ GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
GrGLVertToFrag v(kVec2f_GrSLType);
args.fPB->addVarying("TextureCoords", &v);
+ vsBuilder->codeAppendf("%s = %s;", v.vsOut(), cte.inTextureCoords()->fName);
- GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
- const GrShaderVar& inTextureCoords = customCoordsTextureEffect.inTextureCoords();
- vsBuilder->codeAppendf("%s = %s;", v.vsOut(), inTextureCoords.c_str());
+ if (cte.inColor()) {
+ args.fPB->addPassThroughAttribute(cte.inColor(), args.fOutputColor);
+ }
+
+ // setup output coords
+ vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(), cte.inPosition()->fName);
+ vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(), cte.inPosition()->fName);
// setup position varying
vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(),
- vsBuilder->uViewM(), vsBuilder->inPosition());
+ vsBuilder->uViewM(), cte.inPosition()->fName);
GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
- fsBuilder->codeAppendf("%s = ", args.fOutput);
- fsBuilder->appendTextureLookupAndModulate(args.fInput,
- args.fSamplers[0],
- v.fsIn(),
- kVec2f_GrSLType);
+ fsBuilder->codeAppendf("%s = ", args.fOutputCoverage);
+ fsBuilder->appendTextureLookup(args.fSamplers[0], v.fsIn(), kVec2f_GrSLType);
fsBuilder->codeAppend(";");
}
virtual void setData(const GrGLProgramDataManager&,
const GrProcessor&) SK_OVERRIDE {}
+ static inline void GenKey(const GrProcessor& proc, const GrGLCaps&,
+ GrProcessorKeyBuilder* b) {
+ const GrCustomCoordsTextureEffect& gp = proc.cast<GrCustomCoordsTextureEffect>();
+
+ b->add32(SkToBool(gp.inColor()));
+ }
+
+
private:
typedef GrGLGeometryProcessor INHERITED;
};
@@ -55,16 +66,22 @@ private:
///////////////////////////////////////////////////////////////////////////////
GrCustomCoordsTextureEffect::GrCustomCoordsTextureEffect(GrTexture* texture,
- const GrTextureParams& params)
- : fTextureAccess(texture, params)
- , fInTextureCoords(this->addVertexAttrib(GrShaderVar("inTextureCoords",
- kVec2f_GrSLType,
- GrShaderVar::kAttribute_TypeModifier))) {
+ const GrTextureParams& params,
+ bool hasColor)
+ : fTextureAccess(texture, params), fInColor(NULL) {
+ fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVertexAttribType));
+ if (hasColor) {
+ fInColor = &this->addVertexAttrib(GrAttribute("inColor", kVec4ub_GrVertexAttribType));
+ this->setHasVertexColor();
+ }
+ fInTextureCoords = &this->addVertexAttrib(GrAttribute("inTextureCoords",
+ kVec2f_GrVertexAttribType));
this->addTextureAccess(&fTextureAccess);
}
bool GrCustomCoordsTextureEffect::onIsEqual(const GrGeometryProcessor& other) const {
- return true;
+ const GrCustomCoordsTextureEffect& gp = other.cast<GrCustomCoordsTextureEffect>();
+ return SkToBool(this->inColor()) == SkToBool(gp.inColor());
}
void GrCustomCoordsTextureEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const {
@@ -103,5 +120,5 @@ GrGeometryProcessor* GrCustomCoordsTextureEffect::TestCreate(SkRandom* random,
GrTextureParams params(tileModes, random->nextBool() ? GrTextureParams::kBilerp_FilterMode :
GrTextureParams::kNone_FilterMode);
- return GrCustomCoordsTextureEffect::Create(textures[texIdx], params);
+ return GrCustomCoordsTextureEffect::Create(textures[texIdx], params, random->nextBool());
}
diff --git a/src/gpu/effects/GrCustomCoordsTextureEffect.h b/src/gpu/effects/GrCustomCoordsTextureEffect.h
index 103e20916c..89fc9355f6 100644
--- a/src/gpu/effects/GrCustomCoordsTextureEffect.h
+++ b/src/gpu/effects/GrCustomCoordsTextureEffect.h
@@ -21,29 +21,33 @@ class GrInvariantOutput;
*/
class GrCustomCoordsTextureEffect : public GrGeometryProcessor {
public:
- static GrGeometryProcessor* Create(GrTexture* tex, const GrTextureParams& p) {
- return SkNEW_ARGS(GrCustomCoordsTextureEffect, (tex, p));
+ static GrGeometryProcessor* Create(GrTexture* tex, const GrTextureParams& p, bool hasColor) {
+ return SkNEW_ARGS(GrCustomCoordsTextureEffect, (tex, p, hasColor));
}
virtual ~GrCustomCoordsTextureEffect() {}
static const char* Name() { return "Texture"; }
- const GrShaderVar& inTextureCoords() const { return fInTextureCoords; }
+ const GrAttribute* inPosition() const { return fInPosition; }
+ const GrAttribute* inColor() const { return fInColor; }
+ const GrAttribute* inTextureCoords() const { return fInTextureCoords; }
typedef GrGLCustomCoordsTextureEffect GLProcessor;
virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERRIDE;
private:
- GrCustomCoordsTextureEffect(GrTexture* texture, const GrTextureParams& params);
+ GrCustomCoordsTextureEffect(GrTexture* texture, const GrTextureParams& params, bool hasColor);
virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE;
virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVERRIDE;
GrTextureAccess fTextureAccess;
- const GrShaderVar& fInTextureCoords;
+ const GrAttribute* fInPosition;
+ const GrAttribute* fInColor;
+ const GrAttribute* fInTextureCoords;
GR_DECLARE_GEOMETRY_PROCESSOR_TEST;
diff --git a/src/gpu/effects/GrDashingEffect.cpp b/src/gpu/effects/GrDashingEffect.cpp
index 71d92cbb84..95760e62e5 100644
--- a/src/gpu/effects/GrDashingEffect.cpp
+++ b/src/gpu/effects/GrDashingEffect.cpp
@@ -65,18 +65,12 @@ static bool can_fast_path_dash(const SkPoint pts[2], const GrStrokeInfo& strokeI
}
namespace {
-
struct DashLineVertex {
SkPoint fPos;
SkPoint fDashPos;
};
-
-extern const GrVertexAttrib gDashLineVertexAttribs[] = {
- { kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding },
- { kVec2f_GrVertexAttribType, sizeof(SkPoint), kGeometryProcessor_GrVertexAttribBinding },
};
-};
static void calc_dash_scaling(SkScalar* parallelScale, SkScalar* perpScale,
const SkMatrix& viewMatrix, const SkPoint pts[2]) {
SkVector vecSrc = pts[1] - pts[0];
@@ -341,6 +335,8 @@ bool GrDashingEffect::DrawDashLine(GrGpu* gpu, GrDrawTarget* target, GrDrawState
}
devIntervals[0] = lineLength;
}
+
+ const GrGeometryProcessor* gp;
bool fullDash = devIntervals[1] > 0.f || useAA;
if (fullDash) {
SkPathEffect::DashInfo devInfo;
@@ -352,20 +348,14 @@ bool GrDashingEffect::DrawDashLine(GrGpu* gpu, GrDrawTarget* target, GrDrawState
bool isRoundCap = SkPaint::kRound_Cap == cap;
GrDashingEffect::DashCap capType = isRoundCap ? GrDashingEffect::kRound_DashCap :
GrDashingEffect::kNonRound_DashCap;
- drawState->setGeometryProcessor(
- GrDashingEffect::Create(edgeType, devInfo, strokeWidth, capType))->unref();
-
- // Set up the vertex data for the line and start/end dashes
- drawState->setVertexAttribs<gDashLineVertexAttribs>(SK_ARRAY_COUNT(gDashLineVertexAttribs),
- sizeof(DashLineVertex));
+ gp = GrDashingEffect::Create(edgeType, devInfo, strokeWidth, capType);
} else {
// Set up the vertex data for the line and start/end dashes
- drawState->setGeometryProcessor(
- GrDefaultGeoProcFactory::CreateAndSetAttribs(
- drawState,
- GrDefaultGeoProcFactory::kPosition_GPType))->unref();
+ gp = GrDefaultGeoProcFactory::Create(GrDefaultGeoProcFactory::kPosition_GPType);
}
+ drawState->setGeometryProcessor(gp)->unref();
+
int totalRectCnt = 0;
totalRectCnt += !lineDone ? 1 : 0;
@@ -374,7 +364,7 @@ bool GrDashingEffect::DrawDashLine(GrGpu* gpu, GrDrawTarget* target, GrDrawState
GrDrawTarget::AutoReleaseGeometry geo(target,
totalRectCnt * 4,
- drawState->getVertexStride(), 0);
+ gp->getVertexStride(), 0);
if (!geo.succeeded()) {
SkDebugf("Failed to get space for vertices!\n");
return false;
@@ -401,10 +391,12 @@ bool GrDashingEffect::DrawDashLine(GrGpu* gpu, GrDrawTarget* target, GrDrawState
bounds.outset(bloatX + strokeAdj, bloatY + halfSrcStroke);
if (fullDash) {
DashLineVertex* verts = reinterpret_cast<DashLineVertex*>(geo.vertices());
+ SkASSERT(gp->getVertexStride() == sizeof(DashLineVertex));
setup_dashed_rect(bounds, verts, curVIdx, combinedMatrix, startOffset, devBloat,
lineLength, halfDevStroke);
} else {
SkPoint* verts = reinterpret_cast<SkPoint*>(geo.vertices());
+ SkASSERT(gp->getVertexStride() == sizeof(SkPoint));
setup_dashed_rect_pos(bounds, curVIdx, combinedMatrix, verts);
}
curVIdx += 4;
@@ -415,10 +407,12 @@ bool GrDashingEffect::DrawDashLine(GrGpu* gpu, GrDrawTarget* target, GrDrawState
startRect.outset(bloatX, bloatY);
if (fullDash) {
DashLineVertex* verts = reinterpret_cast<DashLineVertex*>(geo.vertices());
+ SkASSERT(gp->getVertexStride() == sizeof(DashLineVertex));
setup_dashed_rect(startRect, verts, curVIdx, combinedMatrix, startOffset, devBloat,
devIntervals[0], halfDevStroke);
} else {
SkPoint* verts = reinterpret_cast<SkPoint*>(geo.vertices());
+ SkASSERT(gp->getVertexStride() == sizeof(SkPoint));
setup_dashed_rect_pos(startRect, curVIdx, combinedMatrix, verts);
}
@@ -430,10 +424,12 @@ bool GrDashingEffect::DrawDashLine(GrGpu* gpu, GrDrawTarget* target, GrDrawState
endRect.outset(bloatX, bloatY);
if (fullDash) {
DashLineVertex* verts = reinterpret_cast<DashLineVertex*>(geo.vertices());
+ SkASSERT(gp->getVertexStride() == sizeof(DashLineVertex));
setup_dashed_rect(endRect, verts, curVIdx, combinedMatrix, startOffset, devBloat,
devIntervals[0], halfDevStroke);
} else {
SkPoint* verts = reinterpret_cast<SkPoint*>(geo.vertices());
+ SkASSERT(gp->getVertexStride() == sizeof(SkPoint));
setup_dashed_rect_pos(endRect, curVIdx, combinedMatrix, verts);
}
@@ -469,7 +465,9 @@ public:
static const char* Name() { return "DashingCircleEffect"; }
- const GrShaderVar& inCoord() const { return fInCoord; }
+ const GrAttribute* inPosition() const { return fInPosition; }
+
+ const GrAttribute* inCoord() const { return fInCoord; }
GrPrimitiveEdgeType getEdgeType() const { return fEdgeType; }
@@ -490,8 +488,9 @@ private:
virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVERRIDE;
- GrPrimitiveEdgeType fEdgeType;
- const GrShaderVar& fInCoord;
+ GrPrimitiveEdgeType fEdgeType;
+ const GrAttribute* fInPosition;
+ const GrAttribute* fInCoord;
SkScalar fIntervalLength;
SkScalar fRadius;
SkScalar fCenterX;
@@ -539,15 +538,19 @@ void GLDashingCircleEffect::emitCode(const EmitArgs& args) {
"params",
&paramName);
+ GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
+
GrGLVertToFrag v(kVec2f_GrSLType);
args.fPB->addVarying("Coord", &v);
+ vsBuilder->codeAppendf("%s = %s;", v.vsOut(), dce.inCoord()->fName);
- GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
- vsBuilder->codeAppendf("\t%s = %s;\n", v.vsOut(), dce.inCoord().c_str());
+ // setup coord outputs
+ vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(), dce.inPosition()->fName);
+ vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(), dce.inPosition()->fName);
// setup position varying
vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), vsBuilder->uViewM(),
- vsBuilder->inPosition());
+ dce.inPosition()->fName);
// transforms all points so that we can compare them to our test circle
GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
@@ -564,8 +567,7 @@ void GLDashingCircleEffect::emitCode(const EmitArgs& args) {
fsBuilder->codeAppendf("\t\tfloat alpha = 1.0;\n");
fsBuilder->codeAppendf("\t\talpha *= dist < %s.x + 0.5 ? 1.0 : 0.0;\n", paramName);
}
- fsBuilder->codeAppendf("\t\t%s = %s;\n", args.fOutput,
- (GrGLSLExpr4(args.fInput) * GrGLSLExpr1("alpha")).c_str());
+ fsBuilder->codeAppendf("%s = vec4(alpha);", args.fOutputCoverage);
}
void GLDashingCircleEffect::setData(const GrGLProgramDataManager& pdman
@@ -611,10 +613,9 @@ const GrBackendGeometryProcessorFactory& DashingCircleEffect::getFactory() const
DashingCircleEffect::DashingCircleEffect(GrPrimitiveEdgeType edgeType, const DashInfo& info,
SkScalar radius)
- : fEdgeType(edgeType)
- , fInCoord(this->addVertexAttrib(GrShaderVar("inCoord",
- kVec2f_GrSLType,
- GrShaderVar::kAttribute_TypeModifier))) {
+ : fEdgeType(edgeType) {
+ fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVertexAttribType));
+ fInCoord = &this->addVertexAttrib(GrAttribute("inCoord", kVec2f_GrVertexAttribType));
SkScalar onLen = info.fIntervals[0];
SkScalar offLen = info.fIntervals[1];
fIntervalLength = onLen + offLen;
@@ -675,7 +676,9 @@ public:
static const char* Name() { return "DashingEffect"; }
- const GrShaderVar& inCoord() const { return fInCoord; }
+ const GrAttribute* inPosition() const { return fInPosition; }
+
+ const GrAttribute* inCoord() const { return fInCoord; }
GrPrimitiveEdgeType getEdgeType() const { return fEdgeType; }
@@ -694,8 +697,9 @@ private:
virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVERRIDE;
- GrPrimitiveEdgeType fEdgeType;
- const GrShaderVar& fInCoord;
+ GrPrimitiveEdgeType fEdgeType;
+ const GrAttribute* fInPosition;
+ const GrAttribute* fInCoord;
SkRect fRect;
SkScalar fIntervalLength;
@@ -747,14 +751,20 @@ void GLDashingLineEffect::emitCode(const EmitArgs& args) {
"interval",
&intervalName);
+
+ GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
+
GrGLVertToFrag v(kVec2f_GrSLType);
args.fPB->addVarying("Coord", &v);
- GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
- vsBuilder->codeAppendf("\t%s = %s;\n", v.vsOut(), de.inCoord().c_str());
+ vsBuilder->codeAppendf("%s = %s;", v.vsOut(), de.inCoord()->fName);
+
+ // setup coord outputs
+ vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(), de.inPosition()->fName);
+ vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(), de.inPosition()->fName);
// setup position varying
vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), vsBuilder->uViewM(),
- vsBuilder->inPosition());
+ de.inPosition()->fName);
// transforms all points so that we can compare them to our test rect
GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
@@ -778,8 +788,7 @@ void GLDashingLineEffect::emitCode(const EmitArgs& args) {
fsBuilder->codeAppendf("\t\talpha *= (fragPosShifted.x - %s.x) > -0.5 ? 1.0 : 0.0;\n", rectName);
fsBuilder->codeAppendf("\t\talpha *= (%s.z - fragPosShifted.x) >= -0.5 ? 1.0 : 0.0;\n", rectName);
}
- fsBuilder->codeAppendf("\t\t%s = %s;\n", args.fOutput,
- (GrGLSLExpr4(args.fInput) * GrGLSLExpr1("alpha")).c_str());
+ fsBuilder->codeAppendf("%s = vec4(alpha);", args.fOutputCoverage);
}
void GLDashingLineEffect::setData(const GrGLProgramDataManager& pdman,
@@ -826,10 +835,9 @@ const GrBackendGeometryProcessorFactory& DashingLineEffect::getFactory() const {
DashingLineEffect::DashingLineEffect(GrPrimitiveEdgeType edgeType, const DashInfo& info,
SkScalar strokeWidth)
- : fEdgeType(edgeType)
- , fInCoord(this->addVertexAttrib(GrShaderVar("inCoord",
- kVec2f_GrSLType,
- GrShaderVar::kAttribute_TypeModifier))) {
+ : fEdgeType(edgeType) {
+ fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVertexAttribType));
+ fInCoord = &this->addVertexAttrib(GrAttribute("inCoord", kVec2f_GrVertexAttribType));
SkScalar onLen = info.fIntervals[0];
SkScalar offLen = info.fIntervals[1];
SkScalar halfOffLen = SkScalarHalf(offLen);
diff --git a/src/gpu/effects/GrDistanceFieldTextureEffect.cpp b/src/gpu/effects/GrDistanceFieldTextureEffect.cpp
index bc4146d891..5e1bc9968c 100755
--- a/src/gpu/effects/GrDistanceFieldTextureEffect.cpp
+++ b/src/gpu/effects/GrDistanceFieldTextureEffect.cpp
@@ -34,21 +34,30 @@ public:
virtual void emitCode(const EmitArgs& args) SK_OVERRIDE {
const GrDistanceFieldTextureEffect& dfTexEffect =
args.fGP.cast<GrDistanceFieldTextureEffect>();
- SkASSERT(1 == dfTexEffect.getVertexAttribs().count());
GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
SkAssertResult(fsBuilder->enableFeature(
GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
+ GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
GrGLVertToFrag v(kVec2f_GrSLType);
args.fPB->addVarying("TextureCoords", &v);
+ vsBuilder->codeAppendf("%s = %s;", v.vsOut(), dfTexEffect.inTextureCoords()->fName);
- GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
- vsBuilder->codeAppendf("\t%s = %s;\n", v.vsOut(), dfTexEffect.inTextureCoords().c_str());
+ // setup color attribute
+ if(dfTexEffect.inColor()) {
+ args.fPB->addPassThroughAttribute(dfTexEffect.inColor(), args.fOutputColor);
+ }
// setup position varying
vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(),
- vsBuilder->uViewM(), vsBuilder->inPosition());
+ vsBuilder->uViewM(), dfTexEffect.inPosition()->fName);
+
+ // setup output coords
+ vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(),
+ dfTexEffect.inPosition()->fName);
+ vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(),
+ dfTexEffect.inPosition()->fName);
const char* textureSizeUniName = NULL;
fTextureSizeUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility,
@@ -111,8 +120,7 @@ public:
fsBuilder->codeAppend("\tval = gammaColor.r;\n");
#endif
- fsBuilder->codeAppendf("\t%s = %s;\n", args.fOutput,
- (GrGLSLExpr4(args.fInput) * GrGLSLExpr1("val")).c_str());
+ fsBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage);
}
virtual void setData(const GrGLProgramDataManager& pdman,
@@ -171,10 +179,15 @@ GrDistanceFieldTextureEffect::GrDistanceFieldTextureEffect(GrTexture* texture,
, fLuminance(luminance)
#endif
, fFlags(flags & kNonLCD_DistanceFieldEffectMask)
- , fInTextureCoords(this->addVertexAttrib(GrShaderVar("inTextureCoords",
- kVec2f_GrSLType,
- GrShaderVar::kAttribute_TypeModifier))) {
+ , fInColor(NULL) {
SkASSERT(!(flags & ~kNonLCD_DistanceFieldEffectMask));
+ fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVertexAttribType));
+ if (flags & kColorAttr_DistanceFieldEffectFlag) {
+ fInColor = &this->addVertexAttrib(GrAttribute("inColor", kVec4ub_GrVertexAttribType));
+ this->setHasVertexColor();
+ }
+ fInTextureCoords = &this->addVertexAttrib(GrAttribute("inTextureCoords",
+ kVec2f_GrVertexAttribType));
this->addTextureAccess(&fTextureAccess);
#ifdef SK_GAMMA_APPLY_TO_A8
this->addTextureAccess(&fGammaTextureAccess);
@@ -249,21 +262,31 @@ public:
virtual void emitCode(const EmitArgs& args) SK_OVERRIDE {
const GrDistanceFieldNoGammaTextureEffect& dfTexEffect =
args.fGP.cast<GrDistanceFieldNoGammaTextureEffect>();
- SkASSERT(1 == dfTexEffect.getVertexAttribs().count());
GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
SkAssertResult(fsBuilder->enableFeature(
GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
+ GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
GrGLVertToFrag v(kVec2f_GrSLType);
args.fPB->addVarying("TextureCoords", &v);
- GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
- vsBuilder->codeAppendf("%s = %s;", v.vsOut(), dfTexEffect.inTextureCoords().c_str());
+ // setup color attribute
+ if(dfTexEffect.inColor()) {
+ args.fPB->addPassThroughAttribute(dfTexEffect.inColor(), args.fOutputColor);
+ }
+
+ vsBuilder->codeAppendf("%s = %s;", v.vsOut(), dfTexEffect.inTextureCoords()->fName);
+
+ // setup coord outputs
+ vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(),
+ dfTexEffect.inPosition()->fName);
+ vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(),
+ dfTexEffect.inPosition()->fName);
// setup position varying
vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(),
- vsBuilder->uViewM(), vsBuilder->inPosition());
+ vsBuilder->uViewM(), dfTexEffect.inPosition()->fName);
const char* textureSizeUniName = NULL;
fTextureSizeUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility,
@@ -311,8 +334,7 @@ public:
}
fsBuilder->codeAppend("float val = smoothstep(-afwidth, afwidth, distance);");
- fsBuilder->codeAppendf("%s = %s;", args.fOutput,
- (GrGLSLExpr4(args.fInput) * GrGLSLExpr1("val")).c_str());
+ fsBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage);
}
virtual void setData(const GrGLProgramDataManager& pdman,
@@ -351,10 +373,15 @@ GrDistanceFieldNoGammaTextureEffect::GrDistanceFieldNoGammaTextureEffect(GrTextu
uint32_t flags)
: fTextureAccess(texture, params)
, fFlags(flags & kNonLCD_DistanceFieldEffectMask)
- , fInTextureCoords(this->addVertexAttrib(GrShaderVar("inTextureCoords",
- kVec2f_GrSLType,
- GrShaderVar::kAttribute_TypeModifier))) {
+ , fInColor(NULL) {
SkASSERT(!(flags & ~kNonLCD_DistanceFieldEffectMask));
+ fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVertexAttribType));
+ if (flags & kColorAttr_DistanceFieldEffectFlag) {
+ fInColor = &this->addVertexAttrib(GrAttribute("inColor", kVec4ub_GrVertexAttribType));
+ this->setHasVertexColor();
+ }
+ fInTextureCoords = &this->addVertexAttrib(GrAttribute("inTextureCoords",
+ kVec2f_GrVertexAttribType));
this->addTextureAccess(&fTextureAccess);
}
@@ -411,17 +438,21 @@ public:
virtual void emitCode(const EmitArgs& args) SK_OVERRIDE {
const GrDistanceFieldLCDTextureEffect& dfTexEffect =
args.fGP.cast<GrDistanceFieldLCDTextureEffect>();
- SkASSERT(1 == dfTexEffect.getVertexAttribs().count());
+ GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
GrGLVertToFrag v(kVec2f_GrSLType);
args.fPB->addVarying("TextureCoords", &v);
+ vsBuilder->codeAppendf("%s = %s;", v.vsOut(), dfTexEffect.inTextureCoords()->fName);
- GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
- vsBuilder->codeAppendf("\t%s = %s;\n", v.vsOut(), dfTexEffect.inTextureCoords().c_str());
+ // setup coord outputs
+ vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(),
+ dfTexEffect.inPosition()->fName);
+ vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(),
+ dfTexEffect.inPosition()->fName);
// setup position varying
vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(),
- vsBuilder->uViewM(), vsBuilder->inPosition());
+ vsBuilder->uViewM(), dfTexEffect.inPosition()->fName);
const char* textureSizeUniName = NULL;
// width, height, 1/(3*width)
@@ -528,8 +559,7 @@ public:
fsBuilder->codeAppend(";\n");
fsBuilder->codeAppend("\tval.z = gammaColor.r;\n");
- fsBuilder->codeAppendf("\t%s = %s;\n", args.fOutput,
- (GrGLSLExpr4(args.fInput) * GrGLSLExpr4("val")).c_str());
+ fsBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage);
}
virtual void setData(const GrGLProgramDataManager& pdman,
@@ -591,12 +621,11 @@ GrDistanceFieldLCDTextureEffect::GrDistanceFieldLCDTextureEffect(
: fTextureAccess(texture, params)
, fGammaTextureAccess(gamma, gParams)
, fTextColor(textColor)
- , fFlags(flags & kLCD_DistanceFieldEffectMask)
- , fInTextureCoords(this->addVertexAttrib(GrShaderVar("inTextureCoords",
- kVec2f_GrSLType,
- GrShaderVar::kAttribute_TypeModifier))) {
+ , fFlags(flags & kLCD_DistanceFieldEffectMask){
SkASSERT(!(flags & ~kLCD_DistanceFieldEffectMask) && (flags & kUseLCD_DistanceFieldEffectFlag));
-
+ fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVertexAttribType));
+ fInTextureCoords = &this->addVertexAttrib(GrAttribute("inTextureCoords",
+ kVec2f_GrVertexAttribType));
this->addTextureAccess(&fTextureAccess);
this->addTextureAccess(&fGammaTextureAccess);
}
diff --git a/src/gpu/effects/GrDistanceFieldTextureEffect.h b/src/gpu/effects/GrDistanceFieldTextureEffect.h
index bcc40889fd..a074d69f63 100644
--- a/src/gpu/effects/GrDistanceFieldTextureEffect.h
+++ b/src/gpu/effects/GrDistanceFieldTextureEffect.h
@@ -22,13 +22,15 @@ enum GrDistanceFieldEffectFlags {
kUseLCD_DistanceFieldEffectFlag = 0x04, // use lcd text
kBGR_DistanceFieldEffectFlag = 0x08, // lcd display has bgr order
kPortrait_DistanceFieldEffectFlag = 0x10, // lcd display is in portrait mode (not used yet)
+ kColorAttr_DistanceFieldEffectFlag = 0x20, // color vertex attribute
kInvalid_DistanceFieldEffectFlag = 0x80, // invalid state (for initialization)
kUniformScale_DistanceFieldEffectMask = kSimilarity_DistanceFieldEffectFlag |
kRectToRect_DistanceFieldEffectFlag,
// The subset of the flags relevant to GrDistanceFieldTextureEffect
- kNonLCD_DistanceFieldEffectMask = kSimilarity_DistanceFieldEffectFlag,
+ kNonLCD_DistanceFieldEffectMask = kSimilarity_DistanceFieldEffectFlag |
+ kColorAttr_DistanceFieldEffectFlag,
// The subset of the flags relevant to GrDistanceFieldLCDTextureEffect
kLCD_DistanceFieldEffectMask = kSimilarity_DistanceFieldEffectFlag |
kRectToRect_DistanceFieldEffectFlag |
@@ -62,7 +64,9 @@ public:
static const char* Name() { return "DistanceFieldTexture"; }
- const GrShaderVar& inTextureCoords() const { return fInTextureCoords; }
+ const GrAttribute* inPosition() const { return fInPosition; }
+ const GrAttribute* inColor() const { return fInColor; }
+ const GrAttribute* inTextureCoords() const { return fInTextureCoords; }
#ifdef SK_GAMMA_APPLY_TO_A8
float getLuminance() const { return fLuminance; }
#endif
@@ -89,7 +93,9 @@ private:
float fLuminance;
#endif
uint32_t fFlags;
- const GrShaderVar& fInTextureCoords;
+ const GrAttribute* fInPosition;
+ const GrAttribute* fInColor;
+ const GrAttribute* fInTextureCoords;
GR_DECLARE_GEOMETRY_PROCESSOR_TEST;
@@ -114,7 +120,9 @@ public:
static const char* Name() { return "DistanceFieldTexture"; }
- const GrShaderVar& inTextureCoords() const { return fInTextureCoords; }
+ const GrAttribute* inPosition() const { return fInPosition; }
+ const GrAttribute* inColor() const { return fInColor; }
+ const GrAttribute* inTextureCoords() const { return fInTextureCoords; }
uint32_t getFlags() const { return fFlags; }
typedef GrGLDistanceFieldNoGammaTextureEffect GLProcessor;
@@ -131,7 +139,9 @@ private:
GrTextureAccess fTextureAccess;
uint32_t fFlags;
- const GrShaderVar& fInTextureCoords;
+ const GrAttribute* fInPosition;
+ const GrAttribute* fInColor;
+ const GrAttribute* fInTextureCoords;
GR_DECLARE_GEOMETRY_PROCESSOR_TEST;
@@ -157,7 +167,8 @@ public:
static const char* Name() { return "DistanceFieldLCDTexture"; }
- const GrShaderVar& inTextureCoords() const { return fInTextureCoords; }
+ const GrAttribute* inPosition() const { return fInPosition; }
+ const GrAttribute* inTextureCoords() const { return fInTextureCoords; }
GrColor getTextColor() const { return fTextColor; }
uint32_t getFlags() const { return fFlags; }
@@ -179,7 +190,8 @@ private:
GrTextureAccess fGammaTextureAccess;
GrColor fTextColor;
uint32_t fFlags;
- const GrShaderVar& fInTextureCoords;
+ const GrAttribute* fInPosition;
+ const GrAttribute* fInTextureCoords;
GR_DECLARE_GEOMETRY_PROCESSOR_TEST;
diff --git a/src/gpu/gl/GrGLGeometryProcessor.h b/src/gpu/gl/GrGLGeometryProcessor.h
index 06b4aa9d47..c3bee95266 100644
--- a/src/gpu/gl/GrGLGeometryProcessor.h
+++ b/src/gpu/gl/GrGLGeometryProcessor.h
@@ -25,14 +25,18 @@ public:
struct EmitArgs {
EmitArgs(GrGLGPBuilder* pb,
const GrGeometryProcessor& gp,
- const char* output,
- const char* input,
+ const char* outputColor,
+ const char* outputCoverage,
const TextureSamplerArray& samplers)
- : fPB(pb), fGP(gp), fOutput(output), fInput(input), fSamplers(samplers) {}
+ : fPB(pb)
+ , fGP(gp)
+ , fOutputColor(outputColor)
+ , fOutputCoverage(outputCoverage)
+ , fSamplers(samplers) {}
GrGLGPBuilder* fPB;
const GrGeometryProcessor& fGP;
- const char* fOutput;
- const char* fInput;
+ const char* fOutputColor;
+ const char* fOutputCoverage;
const TextureSamplerArray& fSamplers;
};
/**
diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp
index 3249793d62..63cb9da20b 100644
--- a/src/gpu/gl/GrGLProgram.cpp
+++ b/src/gpu/gl/GrGLProgram.cpp
@@ -25,16 +25,13 @@
/**
* Retrieves the final matrix that a transform needs to apply to its source coords.
*/
-static SkMatrix get_transform_matrix(const GrPendingFragmentStage& stage,
- bool useExplicitLocalCoords,
- int transformIdx) {
+static SkMatrix get_transform_matrix(const GrPendingFragmentStage& stage, int transformIdx) {
const GrCoordTransform& coordTransform = stage.getProcessor()->coordTransform(transformIdx);
SkMatrix combined;
if (kLocal_GrCoordSet == coordTransform.sourceCoords()) {
// If we have explicit local coords then we shouldn't need a coord change.
- const SkMatrix& ccm =
- useExplicitLocalCoords ? SkMatrix::I() : stage.getCoordChangeMatrix();
+ const SkMatrix& ccm = stage.getCoordChangeMatrix();
combined.setConcat(coordTransform.getMatrix(), ccm);
} else {
combined = coordTransform.getMatrix();
@@ -187,7 +184,7 @@ void GrGLProgram::setTransformData(const GrPendingFragmentStage& processor,
SkASSERT(numTransforms == processor.getProcessor()->numTransforms());
for (int t = 0; t < numTransforms; ++t) {
SkASSERT(transforms[t].fHandle.isValid());
- const SkMatrix& matrix = get_transform_matrix(processor, ip->fLocalCoordAttrib, t);
+ const SkMatrix& matrix = get_transform_matrix(processor, t);
if (!transforms[t].fCurrentValue.cheapEqualTo(matrix)) {
fProgramDataManager.setSkMatrix(transforms[t].fHandle.convertToUniformHandle(), matrix);
transforms[t].fCurrentValue = matrix;
@@ -335,7 +332,7 @@ void GrGLNvprProgram::setTransformData(const GrPendingFragmentStage& proc,
SkASSERT(numTransforms == proc.getProcessor()->numTransforms());
for (int t = 0; t < numTransforms; ++t) {
SkASSERT(transforms[t].fHandle.isValid());
- const SkMatrix& transform = get_transform_matrix(proc, false, t);
+ const SkMatrix& transform = get_transform_matrix(proc, t);
if (transforms[t].fCurrentValue.cheapEqualTo(transform)) {
continue;
}
@@ -376,7 +373,7 @@ GrGLLegacyNvprProgram::setTransformData(const GrPendingFragmentStage& proc,
int texCoordIndex = ip->fTransforms[0].fHandle.handle();
int numTransforms = proc.getProcessor()->numTransforms();
for (int t = 0; t < numTransforms; ++t) {
- const SkMatrix& transform = get_transform_matrix(proc, false, t);
+ const SkMatrix& transform = get_transform_matrix(proc, t);
GrGLPathRendering::PathTexGenComponents components =
GrGLPathRendering::kST_PathTexGenComponents;
if (proc.isPerspectiveCoordTransform(t)) {
diff --git a/src/gpu/gl/GrGLProgramDesc.cpp b/src/gpu/gl/GrGLProgramDesc.cpp
index 6a2d388692..74f669f2e3 100644
--- a/src/gpu/gl/GrGLProgramDesc.cpp
+++ b/src/gpu/gl/GrGLProgramDesc.cpp
@@ -63,9 +63,9 @@ static bool swizzle_requires_alpha_remapping(const GrGLCaps& caps,
static uint32_t gen_attrib_key(const GrGeometryProcessor& proc) {
uint32_t key = 0;
- const GrGeometryProcessor::VertexAttribArray& vars = proc.getVertexAttribs();
+ const GrGeometryProcessor::VertexAttribArray& vars = proc.getAttribs();
int numAttributes = vars.count();
- SkASSERT(numAttributes <= 2);
+ SkASSERT(numAttributes <= GrGeometryProcessor::kMaxVertexAttribs);
for (int a = 0; a < numAttributes; ++a) {
uint32_t value = 1 << a;
key |= value;
@@ -206,11 +206,7 @@ bool GrGLProgramDescBuilder::Build(const GrOptDrawState& optState,
header->fUseNvpr = false;
}
- bool hasUniformColor = inputColorIsUsed &&
- (isPathRendering || !descInfo.hasColorVertexAttribute());
-
- bool hasUniformCoverage = inputCoverageIsUsed &&
- (isPathRendering || !descInfo.hasCoverageVertexAttribute());
+ bool hasUniformColor = inputColorIsUsed && (isPathRendering || !descInfo.fHasVertexColor);
if (!inputColorIsUsed) {
header->fColorInput = GrProgramDesc::kAllOnes_ColorInput;
@@ -221,12 +217,13 @@ bool GrGLProgramDescBuilder::Build(const GrOptDrawState& optState,
SkASSERT(!header->fUseNvpr);
}
- bool covIsSolidWhite = !descInfo.hasCoverageVertexAttribute() &&
- 0xffffffff == optState.getCoverageColor();
+ bool hasVertexCoverage = !isPathRendering && descInfo.fHasVertexCoverage;
+
+ bool covIsSolidWhite = !hasVertexCoverage && 0xffffffff == optState.getCoverageColor();
if (covIsSolidWhite || !inputCoverageIsUsed) {
header->fCoverageInput = GrProgramDesc::kAllOnes_ColorInput;
- } else if (hasUniformCoverage) {
+ } else if (!hasVertexCoverage) {
header->fCoverageInput = GrProgramDesc::kUniform_ColorInput;
} else {
header->fCoverageInput = GrProgramDesc::kAttribute_ColorInput;
@@ -255,31 +252,6 @@ bool GrGLProgramDescBuilder::Build(const GrOptDrawState& optState,
header->fFragPosKey = 0;
}
- // Record attribute indices
- header->fPositionAttributeIndex = descInfo.positionAttributeIndex();
- header->fLocalCoordAttributeIndex = descInfo.localCoordAttributeIndex();
-
- // For constant color and coverage we need an attribute with an index beyond those already set
- int availableAttributeIndex = optState.getVertexAttribCount();
- if (descInfo.hasColorVertexAttribute()) {
- header->fColorAttributeIndex = descInfo.colorVertexAttributeIndex();
- } else if (GrProgramDesc::kAttribute_ColorInput == header->fColorInput) {
- SkASSERT(availableAttributeIndex < GrDrawState::kMaxVertexAttribCnt);
- header->fColorAttributeIndex = availableAttributeIndex;
- availableAttributeIndex++;
- } else {
- header->fColorAttributeIndex = -1;
- }
-
- if (descInfo.hasCoverageVertexAttribute()) {
- header->fCoverageAttributeIndex = descInfo.coverageVertexAttributeIndex();
- } else if (GrProgramDesc::kAttribute_ColorInput == header->fCoverageInput) {
- SkASSERT(availableAttributeIndex < GrDrawState::kMaxVertexAttribCnt);
- header->fCoverageAttributeIndex = availableAttributeIndex;
- } else {
- header->fCoverageAttributeIndex = -1;
- }
-
header->fPrimaryOutputType = descInfo.fPrimaryOutputType;
header->fSecondaryOutputType = descInfo.fSecondaryOutputType;
diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp
index 32da5d7798..df35d2c78c 100644
--- a/src/gpu/gl/GrGpuGL.cpp
+++ b/src/gpu/gl/GrGpuGL.cpp
@@ -146,7 +146,7 @@ GrGpuGL::GrGpuGL(const GrGLContext& ctx, GrContext* context)
fProgramCache = SkNEW_ARGS(ProgramCache, (this));
- SkASSERT(this->glCaps().maxVertexAttributes() >= GrDrawState::kMaxVertexAttribCnt);
+ SkASSERT(this->glCaps().maxVertexAttributes() >= GrGeometryProcessor::kMaxVertexAttribs);
fLastSuccessfulStencilFmtIdx = 0;
fHWProgramID = 0;
diff --git a/src/gpu/gl/GrGpuGL_program.cpp b/src/gpu/gl/GrGpuGL_program.cpp
index e2c59b927f..cb8810cc79 100644
--- a/src/gpu/gl/GrGpuGL_program.cpp
+++ b/src/gpu/gl/GrGpuGL_program.cpp
@@ -250,16 +250,11 @@ bool GrGpuGL::flushGraphicsState(const GrOptDrawState& optState, DrawType type)
void GrGpuGL::setupGeometry(const GrOptDrawState& optState,
const GrDrawTarget::DrawInfo& info,
size_t* indexOffsetInBytes) {
- GrGLsizei stride = static_cast<GrGLsizei>(optState.getVertexStride());
-
- size_t vertexOffsetInBytes = stride * info.startVertex();
-
GrGLVertexBuffer* vbuf;
vbuf = (GrGLVertexBuffer*) info.vertexBuffer();
SkASSERT(vbuf);
SkASSERT(!vbuf->isMapped());
- vertexOffsetInBytes += vbuf->baseOffset();
GrGLIndexBuffer* ibuf = NULL;
if (info.isIndexed()) {
@@ -276,23 +271,31 @@ void GrGpuGL::setupGeometry(const GrOptDrawState& optState,
fHWGeometryState.bindArrayAndBuffersToDraw(this, vbuf, ibuf);
if (fCurrentProgram->hasVertexShader()) {
- int vertexAttribCount = optState.getVertexAttribCount();
+ const GrGeometryProcessor* gp = optState.getGeometryProcessor();
+
+ GrGLsizei stride = static_cast<GrGLsizei>(gp->getVertexStride());
+
+ size_t vertexOffsetInBytes = stride * info.startVertex();
+
+ vertexOffsetInBytes += vbuf->baseOffset();
+
+ const SkTArray<GrGeometryProcessor::GrAttribute, true>& attribs = gp->getAttribs();
+ int vaCount = attribs.count();
uint32_t usedAttribArraysMask = 0;
- const GrVertexAttrib* vertexAttrib = optState.getVertexAttribs();
+ size_t offset = 0;
- for (int vertexAttribIndex = 0; vertexAttribIndex < vertexAttribCount;
- ++vertexAttribIndex, ++vertexAttrib) {
- usedAttribArraysMask |= (1 << vertexAttribIndex);
- GrVertexAttribType attribType = vertexAttrib->fType;
+ for (int attribIndex = 0; attribIndex < vaCount; attribIndex++) {
+ usedAttribArraysMask |= (1 << attribIndex);
+ GrVertexAttribType attribType = attribs[attribIndex].fType;
attribState->set(this,
- vertexAttribIndex,
+ attribIndex,
vbuf,
GrGLAttribTypeToLayout(attribType).fCount,
GrGLAttribTypeToLayout(attribType).fType,
GrGLAttribTypeToLayout(attribType).fNormalized,
stride,
- reinterpret_cast<GrGLvoid*>(
- vertexOffsetInBytes + vertexAttrib->fOffset));
+ reinterpret_cast<GrGLvoid*>(vertexOffsetInBytes + offset));
+ offset += attribs[attribIndex].fOffset;
}
attribState->disableUnusedArrays(this, usedAttribArraysMask);
}
diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.cpp b/src/gpu/gl/builders/GrGLProgramBuilder.cpp
index 16cc5d4964..64150a4fda 100644
--- a/src/gpu/gl/builders/GrGLProgramBuilder.cpp
+++ b/src/gpu/gl/builders/GrGLProgramBuilder.cpp
@@ -52,37 +52,15 @@ GrGLProgram* GrGLProgramBuilder::CreateProgram(const GrOptDrawState& optState,
GrGLSLExpr1 inputCoverage;
pb->setupUniformColorAndCoverageIfNeeded(&inputColor, &inputCoverage);
- // if we have a vertex shader(we don't only if we are using NVPR or NVPR ES), then we may have
- // to setup a few more things like builtin vertex attributes
- bool hasVertexShader = !(header.fUseNvpr &&
- gpu->glPathRendering()->texturingMode() ==
- GrGLPathRendering::FixedFunction_TexturingMode);
-
- if (hasVertexShader) {
- pb->fVS.setupUniformViewMatrix();
- pb->fVS.setupPositionAndLocalCoords();
-
- if (header.fEmitsPointSize) {
- pb->fVS.codeAppend("gl_PointSize = 1.0;");
- }
- if (GrProgramDesc::kAttribute_ColorInput == header.fColorInput) {
- pb->fVS.setupBuiltinVertexAttribute("Color", &inputColor);
- }
- if (GrProgramDesc::kAttribute_ColorInput == header.fCoverageInput) {
- pb->fVS.setupBuiltinVertexAttribute("Coverage", &inputCoverage);
- }
- }
-
// TODO: Once all stages can handle taking a float or vec4 and correctly handling them we can
// remove this cast to a vec4.
- GrGLSLExpr4 inputCoverageVec4 = GrGLSLExpr4::VectorCast(inputCoverage);
+ GrGLSLExpr4 inputCoverageVec4;
+ if (inputCoverage.isValid()) {
+ inputCoverageVec4 = GrGLSLExpr4::VectorCast(inputCoverage);
+ }
pb->emitAndInstallProcs(&inputColor, &inputCoverageVec4);
- if (hasVertexShader) {
- pb->fVS.transformToNormalizedDeviceSpace();
- }
-
// write the secondary color output if necessary
if (GrProgramDesc::kNone_SecondaryOutputType != header.fSecondaryOutputType) {
pb->fFS.enableSecondaryOutput(inputColor, inputCoverageVec4);
@@ -145,6 +123,15 @@ void GrGLProgramBuilder::addVarying(const char* name,
}
}
+void GrGLProgramBuilder::addPassThroughAttribute(const GrGeometryProcessor::GrAttribute* input,
+ const char* output) {
+ GrSLType type = GrVertexAttribTypeToSLType(input->fType);
+ GrGLVertToFrag v(type);
+ this->addVarying(input->fName, &v);
+ fVS.codeAppendf("%s = %s;", v.vsOut(), input->fName);
+ fFS.codeAppendf("%s = %s;", output, v.fsIn());
+}
+
void GrGLProgramBuilder::nameVariable(SkString* out, char prefix, const char* name) {
if ('\0' == prefix) {
*out = name;
@@ -242,50 +229,84 @@ void GrGLProgramBuilder::setupUniformColorAndCoverageIfNeeded(GrGLSLExpr4* input
}
}
-void GrGLProgramBuilder::emitAndInstallProcs(GrGLSLExpr4* inputColor,
- GrGLSLExpr4* inputCoverage) {
- fFragmentProcessors.reset(SkNEW(GrGLInstalledFragProcs));
- int numProcs = fOptState.numFragmentStages();
- this->emitAndInstallFragProcs(0, fOptState.numColorStages(), inputColor);
+void GrGLProgramBuilder::emitAndInstallProcs(GrGLSLExpr4* inputColor, GrGLSLExpr4* inputCoverage) {
if (fOptState.hasGeometryProcessor()) {
+ fVS.setupUniformViewMatrix();
+
+ const GrProgramDesc::KeyHeader& header = this->header();
+ if (header.fEmitsPointSize) {
+ fVS.codeAppend("gl_PointSize = 1.0;");
+ }
+
+ // Setup position
+ // TODO it'd be possible to remove these from the vertexshader builder and have them
+ // be outputs from the emit call. We don't do this because emitargs is constant. It would
+ // be easy to change this though
+ fVS.codeAppendf("vec3 %s;", fVS.glPosition());
+ fVS.codeAppendf("vec2 %s;", fVS.positionCoords());
+ fVS.codeAppendf("vec2 %s;", fVS.localCoords());
+
const GrGeometryProcessor& gp = *fOptState.getGeometryProcessor();
fVS.emitAttributes(gp);
- GrGLSLExpr4 output;
- this->emitAndInstallProc<GrGeometryProcessor>(gp, 0, *inputCoverage, &output);
- *inputCoverage = output;
+ GrGLSLExpr4 outputColor;
+ GrGLSLExpr4 outputCoverage;
+ this->emitAndInstallProc(gp, &outputColor, &outputCoverage);
+
+ // We may override color and coverage here if we have unform color or coverage. This is
+ // obviously not ideal.
+ // TODO lets the GP itself do the override
+ if (GrProgramDesc::kAttribute_ColorInput == header.fColorInput) {
+ *inputColor = outputColor;
+ }
+ if (GrProgramDesc::kUniform_ColorInput != header.fCoverageInput) {
+ *inputCoverage = outputCoverage;
+ }
}
+
+ fFragmentProcessors.reset(SkNEW(GrGLInstalledFragProcs));
+ int numProcs = fOptState.numFragmentStages();
+ this->emitAndInstallFragProcs(0, fOptState.numColorStages(), inputColor);
this->emitAndInstallFragProcs(fOptState.numColorStages(), numProcs, inputCoverage);
+
+ if (fOptState.hasGeometryProcessor()) {
+ fVS.transformToNormalizedDeviceSpace();
+ }
}
-void GrGLProgramBuilder::emitAndInstallFragProcs(int procOffset, int numProcs, GrGLSLExpr4* inOut) {
+void GrGLProgramBuilder::emitAndInstallFragProcs(int procOffset,
+ int numProcs,
+ GrGLSLExpr4* inOut) {
for (int e = procOffset; e < numProcs; ++e) {
GrGLSLExpr4 output;
const GrPendingFragmentStage& stage = fOptState.getFragmentStage(e);
- this->emitAndInstallProc<GrPendingFragmentStage>(stage, e, *inOut, &output);
+ this->emitAndInstallProc(stage, e, *inOut, &output);
*inOut = output;
}
}
+void GrGLProgramBuilder::nameExpression(GrGLSLExpr4* output, const char* baseName) {
+ // create var to hold stage result. If we already have a valid output name, just use that
+ // otherwise create a new mangled one. This name is only valid if we are reordering stages
+ // and have to tell stage exactly where to put its output.
+ SkString outName;
+ if (output->isValid()) {
+ outName = output->c_str();
+ } else {
+ this->nameVariable(&outName, '\0', baseName);
+ }
+ fFS.codeAppendf("vec4 %s;", outName.c_str());
+ *output = outName;
+}
+
// TODO Processors cannot output zeros because an empty string is all 1s
// the fix is to allow effects to take the GrGLSLExpr4 directly
-template <class Proc>
-void GrGLProgramBuilder::emitAndInstallProc(const Proc& proc,
+void GrGLProgramBuilder::emitAndInstallProc(const GrPendingFragmentStage& proc,
int index,
const GrGLSLExpr4& input,
GrGLSLExpr4* output) {
// Program builders have a bit of state we need to clear with each effect
AutoStageAdvance adv(this);
-
- // create var to hold stage result. If we already have a valid output name, just use that
- // otherwise create a new mangled one.
- SkString outColorName;
- if (output->isValid()) {
- outColorName = output->c_str();
- } else {
- this->nameVariable(&outColorName, '\0', "output");
- }
- fFS.codeAppendf("vec4 %s;", outColorName.c_str());
- *output = outColorName;
+ this->nameExpression(output, "output");
// Enclose custom code in a block to avoid namespace conflicts
SkString openBrace;
@@ -297,10 +318,28 @@ void GrGLProgramBuilder::emitAndInstallProc(const Proc& proc,
fFS.codeAppend("}");
}
+void GrGLProgramBuilder::emitAndInstallProc(const GrGeometryProcessor& proc,
+ GrGLSLExpr4* outputColor,
+ GrGLSLExpr4* outputCoverage) {
+ // Program builders have a bit of state we need to clear with each effect
+ AutoStageAdvance adv(this);
+ this->nameExpression(outputColor, "outputColor");
+ this->nameExpression(outputCoverage, "outputCoverage");
+
+ // Enclose custom code in a block to avoid namespace conflicts
+ SkString openBrace;
+ openBrace.printf("{ // Stage %d, %s\n", fStageIndex, proc.name());
+ fFS.codeAppend(openBrace.c_str());
+
+ this->emitAndInstallProc(proc, outputColor->c_str(), outputCoverage->c_str());
+
+ fFS.codeAppend("}");
+}
+
void GrGLProgramBuilder::emitAndInstallProc(const GrPendingFragmentStage& fs,
const char* outColor,
const char* inColor) {
- GrGLInstalledFragProc* ifp = SkNEW_ARGS(GrGLInstalledFragProc, (fVS.hasLocalCoords()));
+ GrGLInstalledFragProc* ifp = SkNEW(GrGLInstalledFragProc);
const GrFragmentProcessor& fp = *fs.getProcessor();
ifp->fGLProc.reset(fp.getFactory().createGLInstance(fp));
@@ -321,8 +360,8 @@ void GrGLProgramBuilder::emitAndInstallProc(const GrPendingFragmentStage& fs,
}
void GrGLProgramBuilder::emitAndInstallProc(const GrGeometryProcessor& gp,
- const char* outCoverage,
- const char* inCoverage) {
+ const char* outColor,
+ const char* outCoverage) {
SkASSERT(!fGeometryProcessor);
fGeometryProcessor = SkNEW(GrGLInstalledGeoProc);
@@ -331,7 +370,7 @@ void GrGLProgramBuilder::emitAndInstallProc(const GrGeometryProcessor& gp,
SkSTArray<4, GrGLProcessor::TextureSampler> samplers(gp.numTextures());
this->emitSamplers(gp, &samplers, fGeometryProcessor);
- GrGLGeometryProcessor::EmitArgs args(this, gp, outCoverage, inCoverage, samplers);
+ GrGLGeometryProcessor::EmitArgs args(this, gp, outColor, outCoverage, samplers);
fGeometryProcessor->fGLProc->emitCode(args);
// We have to check that effects and the code they emit are consistent, ie if an effect
@@ -377,9 +416,10 @@ void GrGLProgramBuilder::emitTransforms(const GrPendingFragmentStage& stage,
suffixedVaryingName.appendf("_%i", t);
varyingName = suffixedVaryingName.c_str();
}
- const char* coords = kPosition_GrCoordSet == processor->coordTransform(t).sourceCoords() ?
- fVS.positionAttribute().c_str() :
- fVS.localCoordsAttribute().c_str();
+
+ bool useLocalCoords = kLocal_GrCoordSet == processor->coordTransform(t).sourceCoords();
+ const char* coords = useLocalCoords ? fVS.localCoords() : fVS.positionCoords();
+
GrGLVertToFrag v(varyingType);
this->addCoordVarying(varyingName, &v, uniName, coords);
@@ -419,6 +459,7 @@ GrGLProgram* GrGLProgramBuilder::finalize() {
this->cleanupProgram(programID, shadersToDelete);
return NULL;
}
+
if (!(GrGLProgramDescBuilder::GetHeader(fDesc).fUseNvpr &&
fGpu->glPathRendering()->texturingMode() ==
GrGLPathRendering::FixedFunction_TexturingMode)) {
@@ -426,7 +467,11 @@ GrGLProgram* GrGLProgramBuilder::finalize() {
this->cleanupProgram(programID, shadersToDelete);
return NULL;
}
- fVS.bindVertexAttributes(programID);
+
+ // Non fixed function NVPR actually requires a vertex shader to compile
+ if (fOptState.hasGeometryProcessor()) {
+ fVS.bindVertexAttributes(programID);
+ }
}
bool usingBindUniform = fGpu->glInterface()->fFunctions.fBindUniformLocation != NULL;
if (usingBindUniform) {
diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.h b/src/gpu/gl/builders/GrGLProgramBuilder.h
index 7a4646d03f..76f7ae97c3 100644
--- a/src/gpu/gl/builders/GrGLProgramBuilder.h
+++ b/src/gpu/gl/builders/GrGLProgramBuilder.h
@@ -126,10 +126,25 @@ struct GrGLGeoToFrag : public GrGLVarying {
/* a specialization of the above for GPs. Lets the user add uniforms, varyings, and VS / FS code */
class GrGLGPBuilder : public virtual GrGLUniformBuilder {
public:
+ /*
+ * addVarying allows fine grained control for setting up varyings between stages. If you just
+ * need to take an attribute and pass it through to an output value in a fragment shader, use
+ * addPassThroughAttribute.
+ * TODO convert most uses of addVarying to addPassThroughAttribute
+ */
virtual void addVarying(const char* name,
GrGLVarying*,
GrGLShaderVar::Precision fsPrecision=GrGLShaderVar::kDefault_Precision) = 0;
+ /*
+ * This call can be used by GP to pass an attribute through all shaders directly to 'output' in
+ * the fragment shader. Though this call effects both the vertex shader and fragment shader,
+ * it expects 'output' to be defined in the fragment shader before this call is made.
+ * TODO it might be nicer behavior to have a flag to declare output inside this call
+ */
+ virtual void addPassThroughAttribute(const GrGeometryProcessor::GrAttribute*,
+ const char* output) = 0;
+
// TODO rename getFragmentBuilder
virtual GrGLGPFragmentBuilder* getFragmentShaderBuilder() = 0;
virtual GrGLVertexBuilder* getVertexShaderBuilder() = 0;
@@ -205,6 +220,10 @@ public:
GrGLVarying*,
GrGLShaderVar::Precision fsPrecision=GrGLShaderVar::kDefault_Precision) SK_OVERRIDE;
+ virtual void addPassThroughAttribute(const GrGeometryProcessor::GrAttribute*,
+ const char* output) SK_OVERRIDE;
+
+
// Handles for program uniforms (other than per-effect uniforms)
struct BuiltinUniformHandles {
UniformHandle fViewMatrixUni;
@@ -242,22 +261,29 @@ protected:
// generating stage code.
void nameVariable(SkString* out, char prefix, const char* name);
void setupUniformColorAndCoverageIfNeeded(GrGLSLExpr4* inputColor, GrGLSLExpr1* inputCoverage);
+ // Generates a possibly mangled name for a stage variable and writes it to the fragment shader.
+ // If GrGLSLExpr4 has a valid name then it will use that instead
+ void nameExpression(GrGLSLExpr4*, const char* baseName);
void emitAndInstallProcs(GrGLSLExpr4* inputColor,
GrGLSLExpr4* inputCoverage);
void emitAndInstallFragProcs(int procOffset, int numProcs, GrGLSLExpr4* inOut);
- template <class Proc>
- void emitAndInstallProc(const Proc&,
+ void emitAndInstallProc(const GrPendingFragmentStage&,
int index,
const GrGLSLExpr4& input,
GrGLSLExpr4* output);
+ void emitAndInstallProc(const GrGeometryProcessor&,
+ GrGLSLExpr4* outputColor,
+ GrGLSLExpr4* outputCoverage);
+
// these emit functions help to keep the createAndEmitProcessors template general
void emitAndInstallProc(const GrPendingFragmentStage&,
const char* outColor,
const char* inColor);
void emitAndInstallProc(const GrGeometryProcessor&,
- const char* outCoverage,
- const char* inCoverage);
+ const char* outColor,
+ const char* outCoverage);
+
void verify(const GrGeometryProcessor&);
void verify(const GrFragmentProcessor&);
void emitSamplers(const GrProcessor&,
@@ -372,7 +398,7 @@ struct GrGLInstalledGeoProc : public GrGLInstalledProc {
};
struct GrGLInstalledFragProc : public GrGLInstalledProc {
- GrGLInstalledFragProc(bool useLocalCoords) : fGLProc(NULL), fLocalCoordAttrib(useLocalCoords) {}
+ GrGLInstalledFragProc() : fGLProc(NULL) {}
class ShaderVarHandle {
public:
bool isValid() const { return fHandle > -1; }
@@ -397,7 +423,6 @@ struct GrGLInstalledFragProc : public GrGLInstalledProc {
SkAutoTDelete<GrGLFragmentProcessor> fGLProc;
SkSTArray<2, Transform, true> fTransforms;
- bool fLocalCoordAttrib;
};
struct GrGLInstalledFragProcs : public SkRefCnt {
diff --git a/src/gpu/gl/builders/GrGLVertexShaderBuilder.cpp b/src/gpu/gl/builders/GrGLVertexShaderBuilder.cpp
index 7af5ce9843..63cd352dd2 100644
--- a/src/gpu/gl/builders/GrGLVertexShaderBuilder.cpp
+++ b/src/gpu/gl/builders/GrGLVertexShaderBuilder.cpp
@@ -13,15 +13,9 @@
#define GL_CALL(X) GR_GL_CALL(fProgramBuilder->gpu()->glInterface(), X)
#define GL_CALL_RET(R, X) GR_GL_CALL_RET(fProgramBuilder->gpu()->glInterface(), R, X)
-static const char* color_attribute_name() { return "inColor"; }
-static const char* coverage_attribute_name() { return "inCoverage"; }
-
GrGLVertexBuilder::GrGLVertexBuilder(GrGLProgramBuilder* program)
: INHERITED(program)
- , fPositionVar(NULL)
- , fLocalCoordsVar(NULL)
- , fRtAdjustName(NULL)
- , fEffectAttribOffset(0) {
+ , fRtAdjustName(NULL) {
}
void GrGLVertexBuilder::addVarying(const char* name, GrGLVarying* v) {
@@ -39,58 +33,13 @@ void GrGLVertexBuilder::setupUniformViewMatrix() {
this->uViewM());
}
-void GrGLVertexBuilder::setupPositionAndLocalCoords() {
- // Setup position
- this->codeAppendf("vec3 %s;", this->glPosition());
-
- // setup position and local coords attribute
- fPositionVar = &fInputs.push_back();
- fPositionVar->set(kVec2f_GrSLType,
- GrGLShaderVar::kAttribute_TypeModifier,
- this->inPosition());
- if (-1 != fProgramBuilder->header().fLocalCoordAttributeIndex) {
- fLocalCoordsVar = &fInputs.push_back();
- fLocalCoordsVar->set(kVec2f_GrSLType,
- GrGLShaderVar::kAttribute_TypeModifier,
- "inLocalCoords");
- } else {
- fLocalCoordsVar = fPositionVar;
- }
- fEffectAttribOffset = fInputs.count();
-}
-
-void GrGLVertexBuilder::setupBuiltinVertexAttribute(const char* inName, GrGLSLExpr1* out) {
- GrGLVertToFrag v(kFloat_GrSLType);
- fProgramBuilder->addVarying(inName, &v);
- SkString name(inName);
- name.prepend("in");
- this->addAttribute(GrShaderVar(name.c_str(),
- kFloat_GrSLType,
- GrShaderVar::kAttribute_TypeModifier));
- this->codeAppendf("%s = %s;", v.vsOut(), name.c_str());
- *out = v.fsIn();
- fEffectAttribOffset++;
-}
-
-void GrGLVertexBuilder::setupBuiltinVertexAttribute(const char* inName, GrGLSLExpr4* out) {
- GrGLVertToFrag v(kVec4f_GrSLType);
- fProgramBuilder->addVarying(inName, &v);
- SkString name(inName);
- name.prepend("in");
- this->addAttribute(GrShaderVar(name.c_str(),
- kVec4f_GrSLType,
- GrShaderVar::kAttribute_TypeModifier));
- this->codeAppendf("%s = %s;", v.vsOut(), name.c_str());
- *out = v.fsIn();
- fEffectAttribOffset++;
-}
-
void GrGLVertexBuilder::emitAttributes(const GrGeometryProcessor& gp) {
- const GrGeometryProcessor::VertexAttribArray& vars = gp.getVertexAttribs();
- int numAttributes = vars.count();
- for (int a = 0; a < numAttributes; ++a) {
- this->addAttribute(vars[a]);
+ const GrGeometryProcessor::VertexAttribArray& v = gp.getAttribs();
+ int vaCount = v.count();
+ for (int i = 0; i < vaCount; i++) {
+ this->addAttribute(&v[i]);
}
+ return;
}
void GrGLVertexBuilder::transformToNormalizedDeviceSpace() {
@@ -124,49 +73,14 @@ void GrGLVertexBuilder::transformToNormalizedDeviceSpace() {
}
void GrGLVertexBuilder::bindVertexAttributes(GrGLuint programID) {
- // Bind the attrib locations to same values for all shaders
- const GrProgramDesc::KeyHeader& header = fProgramBuilder->header();
- SkASSERT(-1 != header.fPositionAttributeIndex);
- GL_CALL(BindAttribLocation(programID,
- header.fPositionAttributeIndex,
- fPositionVar->c_str()));
- if (-1 != header.fLocalCoordAttributeIndex) {
- GL_CALL(BindAttribLocation(programID,
- header.fLocalCoordAttributeIndex,
- fLocalCoordsVar->c_str()));
- }
- if (-1 != header.fColorAttributeIndex) {
- GL_CALL(BindAttribLocation(programID,
- header.fColorAttributeIndex,
- color_attribute_name()));
- }
- if (-1 != header.fCoverageAttributeIndex) {
- GL_CALL(BindAttribLocation(programID,
- header.fCoverageAttributeIndex,
- coverage_attribute_name()));
- }
-
- const GrOptDrawState& optState = fProgramBuilder->optState();
- const GrVertexAttrib* vaPtr = optState.getVertexAttribs();
- const int vaCount = optState.getVertexAttribCount();
+ const GrGeometryProcessor* gp = fProgramBuilder->fOptState.getGeometryProcessor();
- // We start binding attributes after builtins
- int i = fEffectAttribOffset;
- for (int index = 0; index < vaCount; index++) {
- if (kGeometryProcessor_GrVertexAttribBinding != vaPtr[index].fBinding) {
- continue;
- }
- SkASSERT(index != header.fPositionAttributeIndex &&
- index != header.fLocalCoordAttributeIndex &&
- index != header.fColorAttributeIndex &&
- index != header.fCoverageAttributeIndex);
- // We should never find another effect attribute if we have bound everything
- SkASSERT(i < fInputs.count());
- GL_CALL(BindAttribLocation(programID, index, fInputs[i].c_str()));
- i++;
+ const GrGeometryProcessor::VertexAttribArray& v = gp->getAttribs();
+ int vaCount = v.count();
+ for (int i = 0; i < vaCount; i++) {
+ GL_CALL(BindAttribLocation(programID, i, v[i].fName));
}
- // Make sure we bound everything
- SkASSERT(fInputs.count() == i);
+ return;
}
bool GrGLVertexBuilder::compileAndAttachShaders(GrGLuint programId,
diff --git a/src/gpu/gl/builders/GrGLVertexShaderBuilder.h b/src/gpu/gl/builders/GrGLVertexShaderBuilder.h
index 7d6d95e508..dbff24fe83 100644
--- a/src/gpu/gl/builders/GrGLVertexShaderBuilder.h
+++ b/src/gpu/gl/builders/GrGLVertexShaderBuilder.h
@@ -16,29 +16,20 @@ class GrGLVertexBuilder : public GrGLShaderBuilder {
public:
GrGLVertexBuilder(GrGLProgramBuilder* program);
- /**
- * Are explicit local coordinates provided as input to the vertex shader.
- */
- bool hasLocalCoords() const { return (fLocalCoordsVar != 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; }
-
- /** 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 the expected position output */
const char* glPosition() const { return "pos3"; }
+ const char* positionCoords() const { return "position"; }
+ const char* localCoords() const { return "localCoords"; }
/** returns the expected uviewM matrix */
// TODO all of this fixed function stuff can live on the GP/PP
const char* uViewM() const { return "uViewM"; }
- const char* inPosition() const { return "inPosition"; }
+ void addAttribute(const GrGeometryProcessor::GrAttribute* attr) {
+ this->addAttribute(GrShaderVar(attr->fName,
+ GrVertexAttribTypeToSLType(attr->fType),
+ GrShaderVar::kAttribute_TypeModifier));
+ }
private:
/*
@@ -52,27 +43,14 @@ private:
void transformToNormalizedDeviceSpace();
//TODO GP itself should setup the uniform view matrix
void setupUniformViewMatrix();
- void setupPositionAndLocalCoords();
- void setupBuiltinVertexAttribute(const char* inName, GrGLSLExpr1* out);
- void setupBuiltinVertexAttribute(const char* inName, GrGLSLExpr4* out);
void emitAttributes(const GrGeometryProcessor& gp);
void bindVertexAttributes(GrGLuint programID);
bool compileAndAttachShaders(GrGLuint programId, SkTDArray<GrGLuint>* shaderIds) const;
// an internal call which checks for uniquness of a var before adding it to the list of inputs
bool addAttribute(const GrShaderVar& var);
- struct AttributePair {
- void set(int index, const SkString& name) {
- fIndex = index; fName = name;
- }
- int fIndex;
- SkString fName;
- };
- GrGLShaderVar* fPositionVar;
- GrGLShaderVar* fLocalCoordsVar;
- const char* fRtAdjustName;
- int fEffectAttribOffset;
+ const char* fRtAdjustName;
friend class GrGLProgramBuilder;
diff --git a/tests/GLProgramsTest.cpp b/tests/GLProgramsTest.cpp
index f03f3014aa..aa8359d5e5 100644
--- a/tests/GLProgramsTest.cpp
+++ b/tests/GLProgramsTest.cpp
@@ -118,50 +118,6 @@ static GrRenderTarget* random_render_target(GrContext* context,
return SkRef(texture->asRenderTarget());
}
-// TODO clean this up, we have to do this to test geometry processors but there has got to be
-// a better way. In the mean time, we actually fill out these generic vertex attribs below with
-// the correct vertex attribs from the GP. We have to ensure, however, we don't try to add more
-// than two attributes. In addition, we 'pad' the below array with GPs up to 6 entries, 4 fixed
-// function vertex attributes and 2 GP custom attributes.
-GrVertexAttrib kGenericVertexAttribs[] = {
- { kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding },
- { kVec2f_GrVertexAttribType, 0, kGeometryProcessor_GrVertexAttribBinding },
- { kVec2f_GrVertexAttribType, 0, kGeometryProcessor_GrVertexAttribBinding },
- { kVec2f_GrVertexAttribType, 0, kGeometryProcessor_GrVertexAttribBinding },
- { kVec2f_GrVertexAttribType, 0, kGeometryProcessor_GrVertexAttribBinding },
- { kVec2f_GrVertexAttribType, 0, kGeometryProcessor_GrVertexAttribBinding }
-};
-
-/*
- * convert sl type to vertexattrib type, not a complete implementation, only use for debugging
- */
-static GrVertexAttribType convert_sltype_to_attribtype(GrSLType type) {
- switch (type) {
- case kFloat_GrSLType:
- return kFloat_GrVertexAttribType;
- case kVec2f_GrSLType:
- return kVec2f_GrVertexAttribType;
- case kVec3f_GrSLType:
- return kVec3f_GrVertexAttribType;
- case kVec4f_GrSLType:
- return kVec4f_GrVertexAttribType;
- default:
- SkFAIL("Type isn't convertible");
- return kFloat_GrVertexAttribType;
- }
-}
-// end test hack
-
-static void setup_random_ff_attribute(GrVertexAttribBinding binding, GrVertexAttribType type,
- SkRandom* random, int* attribIndex, int* runningStride) {
- if (random->nextBool()) {
- kGenericVertexAttribs[*attribIndex].fType = type;
- kGenericVertexAttribs[*attribIndex].fOffset = *runningStride;
- kGenericVertexAttribs[*attribIndex].fBinding = binding;
- *runningStride += GrVertexAttribTypeSize(kGenericVertexAttribs[(*attribIndex)++].fType);
- }
-}
-
static void set_random_gp(GrContext* context,
const GrDrawTargetCaps& caps,
GrDrawState* ds,
@@ -174,41 +130,6 @@ static void set_random_gp(GrContext* context,
dummyTextures));
SkASSERT(gp);
- // we have to set dummy vertex attributes, first we setup the fixed function attributes
- // always leave the position attribute untouched in the array
- int attribIndex = 1;
- int runningStride = GrVertexAttribTypeSize(kGenericVertexAttribs[0].fType);
-
- // local coords
- setup_random_ff_attribute(kLocalCoord_GrVertexAttribBinding, kVec2f_GrVertexAttribType,
- random, &attribIndex, &runningStride);
-
- // color
- setup_random_ff_attribute(kColor_GrVertexAttribBinding, kVec4f_GrVertexAttribType,
- random, &attribIndex, &runningStride);
-
- // coverage
- setup_random_ff_attribute(kCoverage_GrVertexAttribBinding, kUByte_GrVertexAttribType,
- random, &attribIndex, &runningStride);
-
- // Update the geometry processor attributes
- const GrGeometryProcessor::VertexAttribArray& v = gp->getVertexAttribs();
- int numGPAttribs = v.count();
- SkASSERT(numGPAttribs <= GrGeometryProcessor::kMaxVertexAttribs &&
- GrGeometryProcessor::kMaxVertexAttribs == 2);
-
- // we actually can't overflow if kMaxVertexAttribs == 2, but GCC 4.8 wants more proof
- int maxIndex = SK_ARRAY_COUNT(kGenericVertexAttribs);
- for (int i = 0; i < numGPAttribs && i + attribIndex < maxIndex; i++) {
- kGenericVertexAttribs[i + attribIndex].fType =
- convert_sltype_to_attribtype(v[i].getType());
- kGenericVertexAttribs[i + attribIndex].fOffset = runningStride;
- kGenericVertexAttribs[i + attribIndex].fBinding = kGeometryProcessor_GrVertexAttribBinding;
- runningStride += GrVertexAttribTypeSize(kGenericVertexAttribs[i + attribIndex].fType);
- }
-
- // update the vertex attributes with the ds
- ds->setVertexAttribs<kGenericVertexAttribs>(attribIndex + numGPAttribs, runningStride);
ds->setGeometryProcessor(gp);
}