aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/gpu/GrAAConvexPathRenderer.cpp4
-rw-r--r--src/gpu/GrAARectRenderer.cpp394
-rw-r--r--src/gpu/GrAARectRenderer.h18
-rw-r--r--src/gpu/GrDefaultGeoProcFactory.cpp182
-rw-r--r--src/gpu/GrDefaultGeoProcFactory.h83
-rw-r--r--src/gpu/GrOptDrawState.cpp7
-rw-r--r--src/gpu/GrOvalRenderer.cpp12
-rw-r--r--src/gpu/GrProcessor.cpp2
-rw-r--r--src/gpu/effects/GrBezierEffect.cpp12
-rw-r--r--src/gpu/effects/GrCustomCoordsTextureEffect.cpp4
-rw-r--r--src/gpu/effects/GrDashingEffect.cpp8
-rwxr-xr-xsrc/gpu/effects/GrDistanceFieldTextureEffect.cpp12
-rw-r--r--src/gpu/gl/GrGLSL.h8
-rw-r--r--src/gpu/gl/builders/GrGLProgramBuilder.cpp92
-rw-r--r--src/gpu/gl/builders/GrGLProgramBuilder.h24
-rw-r--r--src/gpu/gl/builders/GrGLVertexShaderBuilder.cpp59
-rw-r--r--src/gpu/gl/builders/GrGLVertexShaderBuilder.h17
17 files changed, 479 insertions, 459 deletions
diff --git a/src/gpu/GrAAConvexPathRenderer.cpp b/src/gpu/GrAAConvexPathRenderer.cpp
index 3325b1cf68..eecc72270c 100644
--- a/src/gpu/GrAAConvexPathRenderer.cpp
+++ b/src/gpu/GrAAConvexPathRenderer.cpp
@@ -561,10 +561,6 @@ public:
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());
}
static inline void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder*) {}
diff --git a/src/gpu/GrAARectRenderer.cpp b/src/gpu/GrAARectRenderer.cpp
index 46196e2e4e..ead4ea16a3 100644
--- a/src/gpu/GrAARectRenderer.cpp
+++ b/src/gpu/GrAARectRenderer.cpp
@@ -15,6 +15,251 @@
#include "GrGeometryProcessor.h"
///////////////////////////////////////////////////////////////////////////////
+class GrGLAlignedRectEffect;
+
+// Axis Aligned special case
+class GrAlignedRectEffect : public GrGeometryProcessor {
+public:
+ static GrGeometryProcessor* Create() {
+ GR_CREATE_STATIC_PROCESSOR(gAlignedRectEffect, GrAlignedRectEffect, ());
+ gAlignedRectEffect->ref();
+ return gAlignedRectEffect;
+ }
+
+ virtual ~GrAlignedRectEffect() {}
+
+ static const char* Name() { return "AlignedRectEdge"; }
+
+ const GrShaderVar& inRect() const { return fInRect; }
+
+ virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERRIDE {
+ return GrTBackendGeometryProcessorFactory<GrAlignedRectEffect>::getInstance();
+ }
+
+ class GLProcessor : public GrGLGeometryProcessor {
+ public:
+ GLProcessor(const GrBackendProcessorFactory& factory, const GrProcessor&)
+ : INHERITED (factory) {}
+
+ virtual void emitCode(const EmitArgs& args) SK_OVERRIDE {
+ // setup the varying for the Axis aligned rect effect
+ // xy -> interpolated offset
+ // zw -> w/2+0.5, h/2+0.5
+ GrGLVertToFrag v(kVec4f_GrSLType);
+ args.fPB->addVarying("Rect", &v);
+
+ const GrShaderVar& inRect = args.fGP.cast<GrAlignedRectEffect>().inRect();
+ GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
+ vsBuilder->codeAppendf("\t%s = %s;\n", v.fsIn(), inRect.c_str());
+
+ GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
+ // TODO: compute all these offsets, spans, and scales in the VS
+ fsBuilder->codeAppendf("\tfloat insetW = min(1.0, %s.z) - 0.5;\n", v.fsIn());
+ fsBuilder->codeAppendf("\tfloat insetH = min(1.0, %s.w) - 0.5;\n", v.fsIn());
+ fsBuilder->codeAppend("\tfloat outset = 0.5;\n");
+ // For rects > 1 pixel wide and tall the span's are noops (i.e., 1.0). For rects
+ // < 1 pixel wide or tall they serve to normalize the < 1 ramp to a 0 .. 1 range.
+ fsBuilder->codeAppend("\tfloat spanW = insetW + outset;\n");
+ fsBuilder->codeAppend("\tfloat spanH = insetH + outset;\n");
+ // For rects < 1 pixel wide or tall, these scale factors are used to cap the maximum
+ // value of coverage that is used. In other words it is the coverage that is
+ // used in the interior of the rect after the ramp.
+ fsBuilder->codeAppend("\tfloat scaleW = min(1.0, 2.0*insetW/spanW);\n");
+ fsBuilder->codeAppend("\tfloat scaleH = min(1.0, 2.0*insetH/spanH);\n");
+
+ // Compute the coverage for the rect's width
+ fsBuilder->codeAppendf(
+ "\tfloat coverage = scaleW*clamp((%s.z-abs(%s.x))/spanW, 0.0, 1.0);\n", v.fsIn(),
+ v.fsIn());
+ // Compute the coverage for the rect's height and merge with the width
+ fsBuilder->codeAppendf(
+ "\tcoverage = coverage*scaleH*clamp((%s.w-abs(%s.y))/spanH, 0.0, 1.0);\n",
+ v.fsIn(), v.fsIn());
+
+
+ fsBuilder->codeAppendf("\t%s = %s;\n", args.fOutput,
+ (GrGLSLExpr4(args.fInput) * GrGLSLExpr1("coverage")).c_str());
+ }
+
+ static void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder*) {}
+
+ virtual void setData(const GrGLProgramDataManager& pdman, const GrProcessor&) SK_OVERRIDE {}
+
+ private:
+ typedef GrGLGeometryProcessor INHERITED;
+ };
+
+
+private:
+ GrAlignedRectEffect()
+ : fInRect(this->addVertexAttrib(GrShaderVar("inRect",
+ kVec4f_GrSLType,
+ GrShaderVar::kAttribute_TypeModifier))) {
+ }
+
+ const GrShaderVar& fInRect;
+
+ virtual bool onIsEqual(const GrGeometryProcessor&) const SK_OVERRIDE { return true; }
+
+ virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE {
+ inout->mulByUnknownAlpha();
+ }
+
+ GR_DECLARE_GEOMETRY_PROCESSOR_TEST;
+
+ typedef GrGeometryProcessor INHERITED;
+};
+
+
+GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrAlignedRectEffect);
+
+GrGeometryProcessor* GrAlignedRectEffect::TestCreate(SkRandom* random,
+ GrContext* context,
+ const GrDrawTargetCaps&,
+ GrTexture* textures[]) {
+ return GrAlignedRectEffect::Create();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+class GrGLRectEffect;
+
+/**
+ * The output of this effect is a modulation of the input color and coverage
+ * for an arbitrarily oriented rect. The rect is specified as:
+ * Center of the rect
+ * Unit vector point down the height of the rect
+ * Half width + 0.5
+ * Half height + 0.5
+ * The center and vector are stored in a vec4 varying ("RectEdge") with the
+ * center in the xy components and the vector in the zw components.
+ * The munged width and height are stored in a vec2 varying ("WidthHeight")
+ * with the width in x and the height in y.
+ */
+
+class GrRectEffect : public GrGeometryProcessor {
+public:
+ static GrGeometryProcessor* Create() {
+ GR_CREATE_STATIC_PROCESSOR(gRectEffect, GrRectEffect, ());
+ gRectEffect->ref();
+ return gRectEffect;
+ }
+
+ virtual ~GrRectEffect() {}
+
+ static const char* Name() { return "RectEdge"; }
+
+ const GrShaderVar& inRectEdge() const { return fInRectEdge; }
+ const GrShaderVar& inWidthHeight() const { return fInWidthHeight; }
+
+ virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERRIDE {
+ return GrTBackendGeometryProcessorFactory<GrRectEffect>::getInstance();
+ }
+
+ class GLProcessor : public GrGLGeometryProcessor {
+ public:
+ GLProcessor(const GrBackendProcessorFactory& factory, const GrProcessor&)
+ : INHERITED (factory) {}
+
+ virtual void emitCode(const EmitArgs& args) SK_OVERRIDE {
+ // setup the varying for the center point and the unit vector
+ // that points down the height of the rect
+ GrGLVertToFrag rectEdge(kVec4f_GrSLType);
+ args.fPB->addVarying("RectEdge", &rectEdge);
+
+ const GrRectEffect& rectEffect = args.fGP.cast<GrRectEffect>();
+ GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
+ vsBuilder->codeAppendf("%s = %s;", rectEdge.vsOut(), rectEffect.inRectEdge().c_str());
+
+ // setup the varying for width/2+.5 and height/2+.5
+ GrGLVertToFrag widthHeight(kVec2f_GrSLType);
+ args.fPB->addVarying("WidthHeight", &widthHeight);
+ vsBuilder->codeAppendf("%s = %s;",
+ widthHeight.vsOut(),
+ rectEffect.inWidthHeight().c_str());
+
+ GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
+ // TODO: compute all these offsets, spans, and scales in the VS
+ fsBuilder->codeAppendf("\tfloat insetW = min(1.0, %s.x) - 0.5;\n", widthHeight.fsIn());
+ fsBuilder->codeAppendf("\tfloat insetH = min(1.0, %s.y) - 0.5;\n", widthHeight.fsIn());
+ fsBuilder->codeAppend("\tfloat outset = 0.5;\n");
+ // For rects > 1 pixel wide and tall the span's are noops (i.e., 1.0). For rects
+ // < 1 pixel wide or tall they serve to normalize the < 1 ramp to a 0 .. 1 range.
+ fsBuilder->codeAppend("\tfloat spanW = insetW + outset;\n");
+ fsBuilder->codeAppend("\tfloat spanH = insetH + outset;\n");
+ // For rects < 1 pixel wide or tall, these scale factors are used to cap the maximum
+ // value of coverage that is used. In other words it is the coverage that is
+ // used in the interior of the rect after the ramp.
+ fsBuilder->codeAppend("\tfloat scaleW = min(1.0, 2.0*insetW/spanW);\n");
+ fsBuilder->codeAppend("\tfloat scaleH = min(1.0, 2.0*insetH/spanH);\n");
+
+ // Compute the coverage for the rect's width
+ fsBuilder->codeAppendf("\tvec2 offset = %s.xy - %s.xy;\n",
+ fsBuilder->fragmentPosition(), rectEdge.fsIn());
+ fsBuilder->codeAppendf("\tfloat perpDot = abs(offset.x * %s.w - offset.y * %s.z);\n",
+ rectEdge.fsIn(), rectEdge.fsIn());
+ fsBuilder->codeAppendf(
+ "\tfloat coverage = scaleW*clamp((%s.x-perpDot)/spanW, 0.0, 1.0);\n",
+ widthHeight.fsIn());
+
+ // Compute the coverage for the rect's height and merge with the width
+ fsBuilder->codeAppendf("\tperpDot = abs(dot(offset, %s.zw));\n",
+ rectEdge.fsIn());
+ fsBuilder->codeAppendf(
+ "\tcoverage = coverage*scaleH*clamp((%s.y-perpDot)/spanH, 0.0, 1.0);\n",
+ widthHeight.fsIn());
+
+
+ fsBuilder->codeAppendf("\t%s = %s;\n", args.fOutput,
+ (GrGLSLExpr4(args.fInput) * GrGLSLExpr1("coverage")).c_str());
+ }
+
+ static void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder*) {}
+
+ virtual void setData(const GrGLProgramDataManager& pdman, const GrProcessor&) SK_OVERRIDE {}
+
+ private:
+ typedef GrGLGeometryProcessor INHERITED;
+ };
+
+
+
+private:
+ GrRectEffect()
+ : fInRectEdge(this->addVertexAttrib(GrShaderVar("inRectEdge",
+ kVec4f_GrSLType,
+ GrShaderVar::kAttribute_TypeModifier)))
+ , fInWidthHeight(this->addVertexAttrib(
+ GrShaderVar("inWidthHeight",
+ kVec2f_GrSLType,
+ GrShaderVar::kAttribute_TypeModifier))) {
+ this->setWillReadFragmentPosition();
+ }
+
+ virtual bool onIsEqual(const GrGeometryProcessor&) const SK_OVERRIDE { return true; }
+
+ virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE {
+ inout->mulByUnknownAlpha();
+ }
+
+ const GrShaderVar& fInRectEdge;
+ const GrShaderVar& fInWidthHeight;
+
+ GR_DECLARE_GEOMETRY_PROCESSOR_TEST;
+
+ typedef GrGeometryProcessor INHERITED;
+};
+
+
+GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrRectEffect);
+
+GrGeometryProcessor* GrRectEffect::TestCreate(SkRandom* random,
+ GrContext* context,
+ const GrDrawTargetCaps&,
+ GrTexture* textures[]) {
+ return GrRectEffect::Create();
+}
+
+///////////////////////////////////////////////////////////////////////////////
namespace {
extern const GrVertexAttrib gAARectAttribs[] = {
@@ -303,6 +548,155 @@ void GrAARectRenderer::geometryFillAARect(GrDrawTarget* target,
target->resetIndexSource();
}
+namespace {
+
+// Rotated
+struct RectVertex {
+ SkPoint fPos;
+ SkPoint fCenter;
+ SkPoint fDir;
+ SkPoint fWidthHeight;
+};
+
+// Rotated
+extern const GrVertexAttrib gAARectVertexAttribs[] = {
+ { kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding },
+ { kVec4f_GrVertexAttribType, sizeof(SkPoint), kGeometryProcessor_GrVertexAttribBinding },
+ { kVec2f_GrVertexAttribType, 3*sizeof(SkPoint), kGeometryProcessor_GrVertexAttribBinding }
+};
+
+// Axis Aligned
+struct AARectVertex {
+ SkPoint fPos;
+ SkPoint fOffset;
+ SkPoint fWidthHeight;
+};
+
+// Axis Aligned
+extern const GrVertexAttrib gAAAARectVertexAttribs[] = {
+ { kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding },
+ { kVec4f_GrVertexAttribType, sizeof(SkPoint), kGeometryProcessor_GrVertexAttribBinding },
+};
+
+};
+
+void GrAARectRenderer::shaderFillAARect(GrDrawTarget* target,
+ const SkRect& rect,
+ const SkMatrix& combinedMatrix) {
+ GrDrawState* drawState = target->drawState();
+
+ SkPoint center = SkPoint::Make(rect.centerX(), rect.centerY());
+ combinedMatrix.mapPoints(&center, 1);
+
+ // compute transformed (0, 1) vector
+ SkVector dir = { combinedMatrix[SkMatrix::kMSkewX], combinedMatrix[SkMatrix::kMScaleY] };
+ dir.normalize();
+
+ // compute transformed (width, 0) and (0, height) vectors
+ SkVector vec[2] = {
+ { combinedMatrix[SkMatrix::kMScaleX], combinedMatrix[SkMatrix::kMSkewY] },
+ { combinedMatrix[SkMatrix::kMSkewX], combinedMatrix[SkMatrix::kMScaleY] }
+ };
+
+ SkScalar newWidth = SkScalarHalf(rect.width() * vec[0].length()) + SK_ScalarHalf;
+ SkScalar newHeight = SkScalarHalf(rect.height() * vec[1].length()) + SK_ScalarHalf;
+ drawState->setVertexAttribs<gAARectVertexAttribs>(SK_ARRAY_COUNT(gAARectVertexAttribs),
+ sizeof(RectVertex));
+
+ GrDrawTarget::AutoReleaseGeometry geo(target, 4, 0);
+ if (!geo.succeeded()) {
+ SkDebugf("Failed to get space for vertices!\n");
+ return;
+ }
+
+ RectVertex* verts = reinterpret_cast<RectVertex*>(geo.vertices());
+
+ GrGeometryProcessor* gp = GrRectEffect::Create();
+ drawState->setGeometryProcessor(gp)->unref();
+
+ for (int i = 0; i < 4; ++i) {
+ verts[i].fCenter = center;
+ verts[i].fDir = dir;
+ verts[i].fWidthHeight.fX = newWidth;
+ verts[i].fWidthHeight.fY = newHeight;
+ }
+
+ SkRect devRect;
+ combinedMatrix.mapRect(&devRect, rect);
+
+ SkRect devBounds = {
+ devRect.fLeft - SK_ScalarHalf,
+ devRect.fTop - SK_ScalarHalf,
+ devRect.fRight + SK_ScalarHalf,
+ devRect.fBottom + SK_ScalarHalf
+ };
+
+ verts[0].fPos = SkPoint::Make(devBounds.fLeft, devBounds.fTop);
+ verts[1].fPos = SkPoint::Make(devBounds.fLeft, devBounds.fBottom);
+ verts[2].fPos = SkPoint::Make(devBounds.fRight, devBounds.fBottom);
+ verts[3].fPos = SkPoint::Make(devBounds.fRight, devBounds.fTop);
+
+ target->setIndexSourceToBuffer(fGpu->getContext()->getQuadIndexBuffer());
+ target->drawIndexedInstances(kTriangles_GrPrimitiveType, 1, 4, 6);
+ target->resetIndexSource();
+}
+
+void GrAARectRenderer::shaderFillAlignedAARect(GrDrawTarget* target,
+ const SkRect& rect,
+ const SkMatrix& combinedMatrix) {
+ GrDrawState* drawState = target->drawState();
+ SkASSERT(combinedMatrix.rectStaysRect());
+
+ drawState->setVertexAttribs<gAAAARectVertexAttribs>(SK_ARRAY_COUNT(gAAAARectVertexAttribs),
+ sizeof(AARectVertex));
+
+ GrDrawTarget::AutoReleaseGeometry geo(target, 4, 0);
+ if (!geo.succeeded()) {
+ SkDebugf("Failed to get space for vertices!\n");
+ return;
+ }
+
+ AARectVertex* verts = reinterpret_cast<AARectVertex*>(geo.vertices());
+
+ GrGeometryProcessor* gp = GrAlignedRectEffect::Create();
+ drawState->setGeometryProcessor(gp)->unref();
+
+ SkRect devRect;
+ combinedMatrix.mapRect(&devRect, rect);
+
+ SkRect devBounds = {
+ devRect.fLeft - SK_ScalarHalf,
+ devRect.fTop - SK_ScalarHalf,
+ devRect.fRight + SK_ScalarHalf,
+ devRect.fBottom + SK_ScalarHalf
+ };
+
+ SkPoint widthHeight = {
+ SkScalarHalf(devRect.width()) + SK_ScalarHalf,
+ SkScalarHalf(devRect.height()) + SK_ScalarHalf
+ };
+
+ verts[0].fPos = SkPoint::Make(devBounds.fLeft, devBounds.fTop);
+ verts[0].fOffset = SkPoint::Make(-widthHeight.fX, -widthHeight.fY);
+ verts[0].fWidthHeight = widthHeight;
+
+ verts[1].fPos = SkPoint::Make(devBounds.fLeft, devBounds.fBottom);
+ verts[1].fOffset = SkPoint::Make(-widthHeight.fX, widthHeight.fY);
+ verts[1].fWidthHeight = widthHeight;
+
+ verts[2].fPos = SkPoint::Make(devBounds.fRight, devBounds.fBottom);
+ verts[2].fOffset = widthHeight;
+ verts[2].fWidthHeight = widthHeight;
+
+ verts[3].fPos = SkPoint::Make(devBounds.fRight, devBounds.fTop);
+ verts[3].fOffset = SkPoint::Make(widthHeight.fX, -widthHeight.fY);
+ verts[3].fWidthHeight = widthHeight;
+
+ target->setIndexSourceToBuffer(fGpu->getContext()->getQuadIndexBuffer());
+ target->drawIndexedInstances(kTriangles_GrPrimitiveType, 1, 4, 6);
+ target->resetIndexSource();
+}
+
void GrAARectRenderer::strokeAARect(GrDrawTarget* target,
const SkRect& rect,
const SkMatrix& combinedMatrix,
diff --git a/src/gpu/GrAARectRenderer.h b/src/gpu/GrAARectRenderer.h
index e39b87a5fd..c6e3976b7f 100644
--- a/src/gpu/GrAARectRenderer.h
+++ b/src/gpu/GrAARectRenderer.h
@@ -44,7 +44,17 @@ public:
const SkRect& rect,
const SkMatrix& combinedMatrix,
const SkRect& devRect) {
+#ifdef SHADER_AA_FILL_RECT
+ if (combinedMatrix.rectStaysRect()) {
+ this->shaderFillAlignedAARect(gpu, target,
+ rect, combinedMatrix);
+ } else {
+ this->shaderFillAARect(gpu, target,
+ rect, combinedMatrix);
+ }
+#else
this->geometryFillAARect(target, rect, combinedMatrix, devRect);
+#endif
}
void strokeAARect(GrDrawTarget* target,
@@ -66,6 +76,14 @@ private:
const SkMatrix& combinedMatrix,
const SkRect& devRect);
+ void shaderFillAARect(GrDrawTarget* target,
+ const SkRect& rect,
+ const SkMatrix& combinedMatrix);
+
+ void shaderFillAlignedAARect(GrDrawTarget* target,
+ const SkRect& rect,
+ const SkMatrix& combinedMatrix);
+
void geometryStrokeAARect(GrDrawTarget* target,
const SkRect& devOutside,
const SkRect& devOutsideAssist,
diff --git a/src/gpu/GrDefaultGeoProcFactory.cpp b/src/gpu/GrDefaultGeoProcFactory.cpp
deleted file mode 100644
index 8e93f379b6..0000000000
--- a/src/gpu/GrDefaultGeoProcFactory.cpp
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Copyright 2014 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "GrDefaultGeoProcFactory.h"
-
-#include "gl/builders/GrGLProgramBuilder.h"
-#include "gl/GrGLGeometryProcessor.h"
-#include "GrDrawState.h"
-#include "GrTBackendProcessorFactory.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.
- */
-class DefaultGeoProc : public GrGeometryProcessor {
-public:
- static GrGeometryProcessor* Create() {
- GR_CREATE_STATIC_PROCESSOR(gDefaultGeoProc, DefaultGeoProc, ());
- return SkRef(gDefaultGeoProc);
- }
-
- static const char* Name() { return "DefaultGeometryProcessor"; }
-
- virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERRIDE {
- return GrTBackendGeometryProcessorFactory<DefaultGeoProc>::getInstance();
- }
-
- class GLProcessor : public GrGLGeometryProcessor {
- public:
- GLProcessor(const GrBackendProcessorFactory& factory, const GrProcessor&)
- : INHERITED (factory) {}
-
- virtual void emitCode(const EmitArgs& args) SK_OVERRIDE {
- GrGLVertexBuilder* vs = args.fPB->getVertexShaderBuilder();
-
- // setup position varying
- vs->codeAppendf("%s = %s * vec3(%s, 1);", vs->glPosition(), vs->uViewM(),
- vs->inPosition());
-
- // output coverage in FS(pass through)
- GrGLGPFragmentBuilder* fs = args.fPB->getFragmentShaderBuilder();
- fs->codeAppendf("%s = %s;", args.fOutput, GrGLSLExpr4(args.fInput).c_str());
- }
-
- static inline void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder*) {}
-
- virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE {}
-
- private:
- typedef GrGLGeometryProcessor INHERITED;
- };
-
-private:
- DefaultGeoProc() {}
-
- virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE {
- return true;
- }
-
- virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE {
- inout->mulByUnknownAlpha();
- }
-
- GR_DECLARE_GEOMETRY_PROCESSOR_TEST;
-
- typedef GrFragmentProcessor INHERITED;
-};
-
-GR_DEFINE_GEOMETRY_PROCESSOR_TEST(DefaultGeoProc);
-
-GrGeometryProcessor* DefaultGeoProc::TestCreate(SkRandom* random,
- GrContext*,
- const GrDrawTargetCaps& caps,
- GrTexture*[]) {
- return DefaultGeoProc::Create();
-}
-
-// 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 },
- { kVec4ub_GrVertexAttribType, sizeof(SkPoint), kCoverage_GrVertexAttribBinding },
-};
-
-GrVertexAttrib kDefaultPosColorGeoProc[] = {
- { kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding },
- { kVec4ub_GrVertexAttribType, sizeof(SkPoint), kColor_GrVertexAttribBinding },
- { kVec4ub_GrVertexAttribType, sizeof(SkPoint) + sizeof(GrColor), kCoverage_GrVertexAttribBinding },
-};
-
-GrVertexAttrib kDefaultPosUVGeoProc[] = {
- { kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding },
- { kVec2f_GrVertexAttribType, sizeof(SkPoint), kLocalCoord_GrVertexAttribBinding },
- { kVec4ub_GrVertexAttribType, 2 * sizeof(SkPoint), kCoverage_GrVertexAttribBinding },
-};
-
-GrVertexAttrib kDefaultPosColUVGeoProc[] = {
- { kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding },
- { kVec4ub_GrVertexAttribType, sizeof(SkPoint), kColor_GrVertexAttribBinding },
- { kVec2f_GrVertexAttribType, sizeof(SkPoint) + sizeof(GrColor), kLocalCoord_GrVertexAttribBinding },
- { kVec4ub_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(kVec4ub_GrVertexAttribType);
- default:
- SkFAIL("Should never get here");
- return 0;
- }
-}
-
-const GrGeometryProcessor*
-GrDefaultGeoProcFactory::CreateAndSetAttribs(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<kDefaultPosColUVGeoProc>(count, size);
- } else {
- ds->setVertexAttribs<kDefaultPosColUVGeoProc>(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<kDefaultPosUVGeoProc>(count, size);
- } else {
- ds->setVertexAttribs<kDefaultPosUVGeoProc>(count, size);
- }
- } else if (hasCoverage) {
- size += get_size(kCoverage_GPType);
- count++;
- ds->setVertexAttribs<kDefaultPositionGeoProc>(count, size);
- } else {
- // Just position
- ds->setVertexAttribs<kDefaultPositionGeoProc>(count, size);
- }
- return DefaultGeoProc::Create();
-}
-
-const GrGeometryProcessor* GrDefaultGeoProcFactory::Create() {
- return DefaultGeoProc::Create();
-}
diff --git a/src/gpu/GrDefaultGeoProcFactory.h b/src/gpu/GrDefaultGeoProcFactory.h
deleted file mode 100644
index 26ce66249a..0000000000
--- a/src/gpu/GrDefaultGeoProcFactory.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright 2014 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef GrDefaultGeoProcFactory_DEFINED
-#define GrDefaultGeoProcFactory_DEFINED
-
-#include "GrGeometryProcessor.h"
-
-class GrDrawState;
-
-/*
- * A factory for creating default Geometry Processors which simply multiply position by the uniform
- * 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:
- // Structs for adding vertex attributes
- struct PositionAttr {
- SkPoint fPosition;
- };
-
- struct PositionCoverageAttr {
- SkPoint fPosition;
- GrColor fCoverage;
- };
-
- struct PositionColorAttr {
- SkPoint fPosition;
- SkColor fColor;
- };
-
- struct PositionColorCoverageAttr {
- SkPoint fPosition;
- SkColor fColor;
- GrColor fCoverage;
- };
-
- struct PositionLocalCoordAttr {
- SkPoint fPosition;
- SkPoint fLocalCoord;
- };
-
- struct PositionLocalCoordCoverageAttr {
- SkPoint fPosition;
- SkPoint fLocalCoord;
- GrColor fCoverage;
- };
-
- struct PositionColorLocalCoordAttr {
- SkPoint fPosition;
- GrColor fColor;
- SkPoint fLocalCoord;
- };
-
- struct PositionColorLocalCoordCoverage {
- SkPoint fPosition;
- GrColor fColor;
- SkPoint fLocalCoord;
- GrColor fCoverage;
- };
-
- enum GPType {
- kPosition_GPType = 0x0, // we ALWAYS have position
- kColor_GPType = 0x01,
- kLocalCoord_GPType = 0x02,
- kCoverage_GPType= 0x04,
- kLastGPType = kCoverage_GPType
- };
-
- // YOU MUST UNREF
- static const GrGeometryProcessor* CreateAndSetAttribs(GrDrawState*, uint32_t GPTypeFlags);
- static const GrGeometryProcessor* Create();
-};
-
-#endif
diff --git a/src/gpu/GrOptDrawState.cpp b/src/gpu/GrOptDrawState.cpp
index a9d8ec4888..529e9ed75e 100644
--- a/src/gpu/GrOptDrawState.cpp
+++ b/src/gpu/GrOptDrawState.cpp
@@ -7,10 +7,9 @@
#include "GrOptDrawState.h"
-#include "GrDefaultGeoProcFactory.h"
#include "GrDrawState.h"
#include "GrDrawTargetCaps.h"
-#include "GrGpu.h"
+#include "gl/GrGpuGL.h"
GrOptDrawState::GrOptDrawState(const GrDrawState& drawState,
BlendOptFlags blendOptFlags,
@@ -64,10 +63,6 @@ GrOptDrawState::GrOptDrawState(const GrDrawState& drawState,
// Copy GeometryProcesssor from DS or ODS
if (drawState.hasGeometryProcessor()) {
fGeometryProcessor.initAndRef(drawState.fGeometryProcessor);
- } else if (!GrGpu::IsPathRenderingDrawType(drawType)) {
- // Install default GP, this will be ignored if we are rendering with fragment shader only
- // TODO(joshualitt) rendering code should do this
- fGeometryProcessor.reset(GrDefaultGeoProcFactory::Create());
} else {
fGeometryProcessor.reset(NULL);
}
diff --git a/src/gpu/GrOvalRenderer.cpp b/src/gpu/GrOvalRenderer.cpp
index c06909d5e1..4575287d05 100644
--- a/src/gpu/GrOvalRenderer.cpp
+++ b/src/gpu/GrOvalRenderer.cpp
@@ -100,10 +100,6 @@ public:
GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();;
vsBuilder->codeAppendf("%s = %s;", v.vsOut(), circleEffect.inCircleEdge().c_str());
- // setup position varying
- vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(),
- vsBuilder->uViewM(), vsBuilder->inPosition());
-
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());
@@ -223,10 +219,6 @@ public:
vsBuilder->codeAppendf("%s = %s;", ellipseRadii.vsOut(),
ellipseEffect.inEllipseRadii().c_str());
- // setup position varying
- vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(),
- vsBuilder->uViewM(), vsBuilder->inPosition());
-
// for outer curve
GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
fsBuilder->codeAppendf("vec2 scaledOffset = %s*%s.xy;", ellipseOffsets.fsIn(),
@@ -373,10 +365,6 @@ public:
vsBuilder->codeAppendf("%s = %s;", offsets1.vsOut(),
ellipseEffect.inEllipseOffsets1().c_str());
- // setup position varying
- vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(),
- vsBuilder->uViewM(), vsBuilder->inPosition());
-
GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
SkAssertResult(fsBuilder->enableFeature(
GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
diff --git a/src/gpu/GrProcessor.cpp b/src/gpu/GrProcessor.cpp
index 3de1dcf891..79798b6b82 100644
--- a/src/gpu/GrProcessor.cpp
+++ b/src/gpu/GrProcessor.cpp
@@ -38,7 +38,7 @@ GrProcessorTestFactory<GrGeometryProcessor>::GetFactories() {
* manually adjusted.
*/
static const int kFPFactoryCount = 37;
-static const int kGPFactoryCount = 14;
+static const int kGPFactoryCount = 15;
template<>
void GrProcessorTestFactory<GrFragmentProcessor>::VerifyFactoryCount() {
diff --git a/src/gpu/effects/GrBezierEffect.cpp b/src/gpu/effects/GrBezierEffect.cpp
index 26049b398b..196168c06a 100644
--- a/src/gpu/effects/GrBezierEffect.cpp
+++ b/src/gpu/effects/GrBezierEffect.cpp
@@ -44,10 +44,6 @@ void GrGLConicEffect::emitCode(const EmitArgs& args) {
GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
vsBuilder->codeAppendf("%s = %s;", v.vsOut(), inConicCoeffs.c_str());
- // setup position varying
- vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), vsBuilder->uViewM(),
- vsBuilder->inPosition());
-
GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
fsBuilder->codeAppend("float edgeAlpha;");
@@ -188,10 +184,6 @@ void GrGLQuadEffect::emitCode(const EmitArgs& args) {
const GrShaderVar& inHairQuadEdge = args.fGP.cast<GrQuadEffect>().inHairQuadEdge();
vsBuilder->codeAppendf("%s = %s;", v.vsOut(), inHairQuadEdge.c_str());
- // setup position varying
- vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), vsBuilder->uViewM(),
- vsBuilder->inPosition());
-
GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
fsBuilder->codeAppendf("float edgeAlpha;");
@@ -318,10 +310,6 @@ void GrGLCubicEffect::emitCode(const EmitArgs& args) {
const GrShaderVar& inCubicCoeffs = args.fGP.cast<GrCubicEffect>().inCubicCoeffs();
vsBuilder->codeAppendf("%s = %s;", v.vsOut(), inCubicCoeffs.c_str());
- // setup position varying
- vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), vsBuilder->uViewM(),
- vsBuilder->inPosition());
-
GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
GrGLShaderVar edgeAlpha("edgeAlpha", kFloat_GrSLType, 0, GrGLShaderVar::kHigh_Precision);
diff --git a/src/gpu/effects/GrCustomCoordsTextureEffect.cpp b/src/gpu/effects/GrCustomCoordsTextureEffect.cpp
index 77e799414a..afa0754603 100644
--- a/src/gpu/effects/GrCustomCoordsTextureEffect.cpp
+++ b/src/gpu/effects/GrCustomCoordsTextureEffect.cpp
@@ -31,10 +31,6 @@ public:
const GrShaderVar& inTextureCoords = customCoordsTextureEffect.inTextureCoords();
vsBuilder->codeAppendf("%s = %s;", v.vsOut(), inTextureCoords.c_str());
- // setup position varying
- vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(),
- vsBuilder->uViewM(), vsBuilder->inPosition());
-
GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
fsBuilder->codeAppendf("%s = ", args.fOutput);
fsBuilder->appendTextureLookupAndModulate(args.fInput,
diff --git a/src/gpu/effects/GrDashingEffect.cpp b/src/gpu/effects/GrDashingEffect.cpp
index 65ba84858d..f2e4438158 100644
--- a/src/gpu/effects/GrDashingEffect.cpp
+++ b/src/gpu/effects/GrDashingEffect.cpp
@@ -520,10 +520,6 @@ void GLDashingCircleEffect::emitCode(const EmitArgs& args) {
GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
vsBuilder->codeAppendf("\t%s = %s;\n", v.vsOut(), dce.inCoord().c_str());
- // setup position varying
- vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), vsBuilder->uViewM(),
- vsBuilder->inPosition());
-
// transforms all points so that we can compare them to our test circle
GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
fsBuilder->codeAppendf("\t\tfloat xShifted = %s.x - floor(%s.x / %s.z) * %s.z;\n",
@@ -727,10 +723,6 @@ void GLDashingLineEffect::emitCode(const EmitArgs& args) {
GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
vsBuilder->codeAppendf("\t%s = %s;\n", v.vsOut(), de.inCoord().c_str());
- // setup position varying
- vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), vsBuilder->uViewM(),
- vsBuilder->inPosition());
-
// transforms all points so that we can compare them to our test rect
GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
fsBuilder->codeAppendf("\t\tfloat xShifted = %s.x - floor(%s.x / %s) * %s;\n",
diff --git a/src/gpu/effects/GrDistanceFieldTextureEffect.cpp b/src/gpu/effects/GrDistanceFieldTextureEffect.cpp
index 0c7a9a3d8c..b9776986b5 100755
--- a/src/gpu/effects/GrDistanceFieldTextureEffect.cpp
+++ b/src/gpu/effects/GrDistanceFieldTextureEffect.cpp
@@ -45,10 +45,6 @@ public:
GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
vsBuilder->codeAppendf("\t%s = %s;\n", v.vsOut(), dfTexEffect.inTextureCoords().c_str());
- // setup position varying
- vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(),
- vsBuilder->uViewM(), vsBuilder->inPosition());
-
const char* textureSizeUniName = NULL;
fTextureSizeUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kVec2f_GrSLType, "TextureSize",
@@ -260,10 +256,6 @@ public:
GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
vsBuilder->codeAppendf("%s = %s;", v.vsOut(), dfTexEffect.inTextureCoords().c_str());
- // setup position varying
- vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(),
- vsBuilder->uViewM(), vsBuilder->inPosition());
-
const char* textureSizeUniName = NULL;
fTextureSizeUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kVec2f_GrSLType, "TextureSize",
@@ -418,10 +410,6 @@ public:
GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
vsBuilder->codeAppendf("\t%s = %s;\n", v.vsOut(), dfTexEffect.inTextureCoords().c_str());
- // setup position varying
- vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(),
- vsBuilder->uViewM(), vsBuilder->inPosition());
-
const char* textureSizeUniName = NULL;
// width, height, 1/(3*width)
fTextureSizeUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility,
diff --git a/src/gpu/gl/GrGLSL.h b/src/gpu/gl/GrGLSL.h
index 99671c130e..b031a40a61 100644
--- a/src/gpu/gl/GrGLSL.h
+++ b/src/gpu/gl/GrGLSL.h
@@ -106,10 +106,6 @@ public:
return fExpr.c_str();
}
- bool isValid() const {
- return kFullExpr_ExprType != fType || !fExpr.isEmpty();
- }
-
protected:
/** Constructs an invalid expression.
* Useful only as a return value from functions that never actually return
@@ -170,6 +166,10 @@ protected:
fExpr.appendf(format, in0, in1);
}
+ bool isValid() const {
+ return kFullExpr_ExprType != fType || !fExpr.isEmpty();
+ }
+
/** Returns expression casted to another type.
* Generic implementation that is called for non-trivial cases of casts. */
template <typename T>
diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.cpp b/src/gpu/gl/builders/GrGLProgramBuilder.cpp
index de4a1d5e6e..8fc6020121 100644
--- a/src/gpu/gl/builders/GrGLProgramBuilder.cpp
+++ b/src/gpu/gl/builders/GrGLProgramBuilder.cpp
@@ -57,11 +57,9 @@ GrGLProgram* GrGLProgramBuilder::CreateProgram(const GrOptDrawState& optState,
bool hasVertexShader = !(header.fUseNvpr &&
gpu->glPathRendering()->texturingMode() ==
GrGLPathRendering::FixedFunction_TexturingMode);
-
if (hasVertexShader) {
- pb->fVS.setupUniformViewMatrix();
- pb->fVS.setupPositionAndLocalCoords();
-
+ pb->fVS.setupLocalCoords();
+ pb->fVS.transformGLToSkiaCoords();
if (header.fEmitsPointSize) {
pb->fVS.codeAppend("gl_PointSize = 1.0;");
}
@@ -77,10 +75,10 @@ GrGLProgram* GrGLProgramBuilder::CreateProgram(const GrOptDrawState& optState,
// remove this cast to a vec4.
GrGLSLExpr4 inputCoverageVec4 = GrGLSLExpr4::VectorCast(inputCoverage);
- pb->emitAndInstallProcs(&inputColor, &inputCoverageVec4);
+ pb->emitAndInstallProcs(optState, &inputColor, &inputCoverageVec4);
if (hasVertexShader) {
- pb->fVS.transformToNormalizedDeviceSpace();
+ pb->fVS.transformSkiaToGLCoords();
}
// write the secondary color output if necessary
@@ -173,17 +171,7 @@ GrGLProgramDataManager::UniformHandle GrGLProgramBuilder::addUniformArray(uint32
UniformInfo& uni = fUniforms.push_back();
uni.fVariable.setType(type);
uni.fVariable.setTypeModifier(GrGLShaderVar::kUniform_TypeModifier);
- // TODO this is a bit hacky, lets think of a better way. Basically we need to be able to use
- // the uniform view matrix name in the GP, and the GP is immutable so it has to tell the PB
- // exactly what name it wants to use for the uniform view matrix. If we prefix anythings, then
- // the names will mismatch. I think the correct solution is to have all GPs which need the
- // uniform view matrix, they should upload the view matrix in their setData along with regular
- // uniforms.
- char prefix = 'u';
- if ('u' == name[0]) {
- prefix = '\0';
- }
- this->nameVariable(uni.fVariable.accessName(), prefix, name);
+ this->nameVariable(uni.fVariable.accessName(), 'u', name);
uni.fVariable.setArrayCount(count);
uni.fVisibility = visibility;
@@ -242,40 +230,23 @@ void GrGLProgramBuilder::setupUniformColorAndCoverageIfNeeded(GrGLSLExpr4* input
}
}
-void GrGLProgramBuilder::emitAndInstallProcs(GrGLSLExpr4* inputColor,
+void GrGLProgramBuilder::emitAndInstallProcs(const GrOptDrawState& optState,
+ GrGLSLExpr4* inputColor,
GrGLSLExpr4* inputCoverage) {
- // We need to collect all of the transforms to thread them through the GP in the case of GPs
- // which use additional shader stages between the VS and the FS. To do this we emit a dummy
- // input coverage
- GrGLSLExpr4 coverageInput = *inputCoverage;
- if (fOptState.hasGeometryProcessor()) {
- AutoStageAdvance adv(this);
- SkString outColorName;
- this->nameVariable(&outColorName, '\0', "gpOutput");
- coverageInput = outColorName;
- }
- GrGLSLExpr4 gpOutput = coverageInput;
-
- // Emit fragment processors
fFragmentProcessors.reset(SkNEW(GrGLInstalledFragProcs));
- int numProcs = fOptState.numFragmentStages();
- this->emitAndInstallFragProcs(0, fOptState.numColorStages(), inputColor);
- this->emitAndInstallFragProcs(fOptState.numColorStages(), numProcs, &coverageInput);
-
- // We have to save the existing code stack, and then append it to the fragment shader code
- // after emiting the GP
- if (fOptState.hasGeometryProcessor()) {
- SkString existingCode(fFS.fCode);
- fFS.fCode.reset();
- const GrGeometryProcessor& gp = *fOptState.getGeometryProcessor();
+ int numProcs = optState.numFragmentStages();
+ this->emitAndInstallFragProcs(0, optState.numColorStages(), inputColor);
+ if (optState.hasGeometryProcessor()) {
+ const GrGeometryProcessor& gp = *optState.getGeometryProcessor();
fVS.emitAttributes(gp);
ProcKeyProvider keyProvider(&fDesc,
ProcKeyProvider::kGeometry_ProcessorType,
GrGLProgramDescBuilder::kProcessorKeyOffsetsAndLengthOffset);
- this->emitAndInstallProc<GrGeometryProcessor>(gp, 0, keyProvider, *inputCoverage, &gpOutput);
- fFS.fCode.append(existingCode);
+ GrGLSLExpr4 output;
+ this->emitAndInstallProc<GrGeometryProcessor>(gp, 0, keyProvider, *inputCoverage, &output);
+ *inputCoverage = output;
}
- *inputCoverage = coverageInput;
+ this->emitAndInstallFragProcs(optState.numColorStages(), numProcs, inputCoverage);
}
void GrGLProgramBuilder::emitAndInstallFragProcs(int procOffset, int numProcs, GrGLSLExpr4* inOut) {
@@ -301,14 +272,9 @@ void GrGLProgramBuilder::emitAndInstallProc(const Proc& proc,
// 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.
+ // create var to hold stage result
SkString outColorName;
- if (output->isValid()) {
- outColorName = output->c_str();
- } else {
- this->nameVariable(&outColorName, '\0', "output");
- }
+ this->nameVariable(&outColorName, '\0', "output");
fFS.codeAppendf("vec4 %s;", outColorName.c_str());
*output = outColorName;
@@ -349,8 +315,8 @@ void GrGLProgramBuilder::emitAndInstallProc(const GrFragmentStage& fs,
void GrGLProgramBuilder::emitAndInstallProc(const GrGeometryProcessor& gp,
const GrProcessorKey& key,
- const char* outCoverage,
- const char* inCoverage) {
+ const char* outColor,
+ const char* inColor) {
SkASSERT(!fGeometryProcessor);
fGeometryProcessor = SkNEW(GrGLInstalledGeoProc);
@@ -359,7 +325,7 @@ void GrGLProgramBuilder::emitAndInstallProc(const GrGeometryProcessor& gp,
SkSTArray<4, GrGLProcessor::TextureSampler> samplers(gp.numTextures());
this->emitSamplers(gp, &samplers, fGeometryProcessor);
- GrGLGeometryProcessor::EmitArgs args(this, gp, key, outCoverage, inCoverage, samplers);
+ GrGLGeometryProcessor::EmitArgs args(this, gp, key, outColor, inColor, samplers);
fGeometryProcessor->fGLProc->emitCode(args);
// We have to check that effects and the code they emit are consistent, ie if an effect
@@ -408,13 +374,23 @@ void GrGLProgramBuilder::emitTransforms(const GrFragmentStage& effectStage,
suffixedVaryingName.appendf("_%i", t);
varyingName = suffixedVaryingName.c_str();
}
- const char* coords = kPosition_GrCoordSet == effect->coordTransform(t).sourceCoords() ?
- fVS.positionAttribute().c_str() :
- fVS.localCoordsAttribute().c_str();
GrGLVertToFrag v(varyingType);
- this->addCoordVarying(varyingName, &v, uniName, coords);
+ this->addVarying(varyingName, &v);
+ const GrGLShaderVar& coords =
+ kPosition_GrCoordSet == effect->coordTransform(t).sourceCoords() ?
+ fVS.positionAttribute() :
+ fVS.localCoordsAttribute();
+
+ // varying = matrix * coords (logically)
SkASSERT(kVec2f_GrSLType == varyingType || kVec3f_GrSLType == varyingType);
+ if (kVec2f_GrSLType == varyingType) {
+ fVS.codeAppendf("%s = (%s * vec3(%s, 1)).xy;",
+ v.vsOut(), uniName, coords.c_str());
+ } else {
+ fVS.codeAppendf("%s = %s * vec3(%s, 1);",
+ v.vsOut(), uniName, coords.c_str());
+ }
SkNEW_APPEND_TO_TARRAY(outCoords, GrGLProcessor::TransformedCoords,
(SkString(v.fsIn()), varyingType));
}
diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.h b/src/gpu/gl/builders/GrGLProgramBuilder.h
index a44fa91090..4bcf50be6a 100644
--- a/src/gpu/gl/builders/GrGLProgramBuilder.h
+++ b/src/gpu/gl/builders/GrGLProgramBuilder.h
@@ -241,7 +241,8 @@ protected:
// generating stage code.
void nameVariable(SkString* out, char prefix, const char* name);
void setupUniformColorAndCoverageIfNeeded(GrGLSLExpr4* inputColor, GrGLSLExpr1* inputCoverage);
- void emitAndInstallProcs(GrGLSLExpr4* inputColor,
+ void emitAndInstallProcs(const GrOptDrawState& optState,
+ GrGLSLExpr4* inputColor,
GrGLSLExpr4* inputCoverage);
void emitAndInstallFragProcs(int procOffset, int numProcs, GrGLSLExpr4* inOut);
template <class Proc>
@@ -258,8 +259,8 @@ protected:
const char* inColor);
void emitAndInstallProc(const GrGeometryProcessor&,
const GrProcessorKey&,
- const char* outCoverage,
- const char* inCoverage);
+ const char* outColor,
+ const char* inColor);
void verify(const GrGeometryProcessor&);
void verify(const GrFragmentProcessor&);
void emitSamplers(const GrProcessor&,
@@ -313,22 +314,6 @@ protected:
void enterStage() { fOutOfStage = false; }
int stageIndex() const { return fStageIndex; }
- struct TransformVarying {
- TransformVarying(const GrGLVarying& v, const char* uniName, const char* sourceCoords)
- : fV(v), fUniName(uniName), fSourceCoords(sourceCoords) {}
- GrGLVarying fV;
- SkString fUniName;
- SkString fSourceCoords;
- };
-
- void addCoordVarying(const char* name, GrGLVarying* v, const char* uniName,
- const char* sourceCoords) {
- this->addVarying(name, v);
- fCoordVaryings.push_back(TransformVarying(*v, uniName, sourceCoords));
- }
-
- const char* rtAdjustment() const { return "rtAdjustment"; }
-
// number of each input/output type in a single allocation block, used by many builders
static const int kVarsPerBlock;
@@ -346,7 +331,6 @@ protected:
const GrProgramDesc& fDesc;
GrGpuGL* fGpu;
UniformInfoArray fUniforms;
- SkSTArray<16, TransformVarying, true> fCoordVaryings;
friend class GrGLShaderBuilder;
friend class GrGLVertexBuilder;
diff --git a/src/gpu/gl/builders/GrGLVertexShaderBuilder.cpp b/src/gpu/gl/builders/GrGLVertexShaderBuilder.cpp
index 7af5ce9843..2bef113410 100644
--- a/src/gpu/gl/builders/GrGLVertexShaderBuilder.cpp
+++ b/src/gpu/gl/builders/GrGLVertexShaderBuilder.cpp
@@ -20,7 +20,6 @@ GrGLVertexBuilder::GrGLVertexBuilder(GrGLProgramBuilder* program)
: INHERITED(program)
, fPositionVar(NULL)
, fLocalCoordsVar(NULL)
- , fRtAdjustName(NULL)
, fEffectAttribOffset(0) {
}
@@ -32,22 +31,9 @@ void GrGLVertexBuilder::addVarying(const char* name, GrGLVarying* v) {
v->fVsOut = fOutputs.back().getName().c_str();
}
-void GrGLVertexBuilder::setupUniformViewMatrix() {
- fProgramBuilder->fUniformHandles.fViewMatrixUni =
- fProgramBuilder->addUniform(GrGLProgramBuilder::kVertex_Visibility,
- kMat33f_GrSLType,
- this->uViewM());
-}
-
-void GrGLVertexBuilder::setupPositionAndLocalCoords() {
- // Setup position
- this->codeAppendf("vec3 %s;", this->glPosition());
-
- // setup position and local coords attribute
+void GrGLVertexBuilder::setupLocalCoords() {
fPositionVar = &fInputs.push_back();
- fPositionVar->set(kVec2f_GrSLType,
- GrGLShaderVar::kAttribute_TypeModifier,
- this->inPosition());
+ fPositionVar->set(kVec2f_GrSLType, GrGLShaderVar::kAttribute_TypeModifier, "inPosition");
if (-1 != fProgramBuilder->header().fLocalCoordAttributeIndex) {
fLocalCoordsVar = &fInputs.push_back();
fLocalCoordsVar->set(kVec2f_GrSLType,
@@ -59,6 +45,18 @@ void GrGLVertexBuilder::setupPositionAndLocalCoords() {
fEffectAttribOffset = fInputs.count();
}
+void GrGLVertexBuilder::transformGLToSkiaCoords() {
+ const char* viewMName;
+ fProgramBuilder->fUniformHandles.fViewMatrixUni =
+ fProgramBuilder->addUniform(GrGLProgramBuilder::kVertex_Visibility,
+ kMat33f_GrSLType,
+ "ViewM",
+ &viewMName);
+
+ // Transform the position into Skia's device coords.
+ this->codeAppendf("vec3 pos3 = %s * vec3(%s, 1);", viewMName, fPositionVar->c_str());
+}
+
void GrGLVertexBuilder::setupBuiltinVertexAttribute(const char* inName, GrGLSLExpr1* out) {
GrGLVertToFrag v(kFloat_GrSLType);
fProgramBuilder->addVarying(inName, &v);
@@ -93,34 +91,17 @@ void GrGLVertexBuilder::emitAttributes(const GrGeometryProcessor& gp) {
}
}
-void GrGLVertexBuilder::transformToNormalizedDeviceSpace() {
- // setup RT Uniform
+void GrGLVertexBuilder::transformSkiaToGLCoords() {
+ const char* rtAdjustName;
fProgramBuilder->fUniformHandles.fRTAdjustmentUni =
fProgramBuilder->addUniform(GrGLProgramBuilder::kVertex_Visibility,
kVec4f_GrSLType,
- fProgramBuilder->rtAdjustment(),
- &fRtAdjustName);
- // Wire transforms
- SkTArray<GrGLProgramBuilder::TransformVarying, true>& transVs = fProgramBuilder->fCoordVaryings;
- int transformCount = transVs.count();
- for (int i = 0; i < transformCount; i++) {
- const char* coords = transVs[i].fSourceCoords.c_str();
-
- // varying = matrix * coords (logically)
- const GrGLVarying& v = transVs[i].fV;
- if (kVec2f_GrSLType == v.fType) {
- this->codeAppendf("%s = (%s * vec3(%s, 1)).xy;", v.fVsOut, transVs[i].fUniName.c_str(),
- coords);
- } else {
- this->codeAppendf("%s = %s * vec3(%s, 1);", v.fVsOut, transVs[i].fUniName.c_str(),
- coords);
- }
- }
+ "rtAdjustment",
+ &rtAdjustName);
// Transform from Skia's device coords to GL's normalized device coords.
- this->codeAppendf("gl_Position = vec4(dot(%s.xz, %s.xy), dot(%s.yz, %s.zw), 0, %s.z);",
- this->glPosition(), fRtAdjustName, this->glPosition(), fRtAdjustName,
- this->glPosition());
+ this->codeAppendf("gl_Position = vec4(dot(pos3.xz, %s.xy), dot(pos3.yz, %s.zw), 0, pos3.z);",
+ rtAdjustName, rtAdjustName);
}
void GrGLVertexBuilder::bindVertexAttributes(GrGLuint programID) {
diff --git a/src/gpu/gl/builders/GrGLVertexShaderBuilder.h b/src/gpu/gl/builders/GrGLVertexShaderBuilder.h
index 7d6d95e508..2f14bd7702 100644
--- a/src/gpu/gl/builders/GrGLVertexShaderBuilder.h
+++ b/src/gpu/gl/builders/GrGLVertexShaderBuilder.h
@@ -31,15 +31,6 @@ public:
*/
const GrGLShaderVar& positionAttribute() const { return *fPositionVar; }
- /** returns the expected position output */
- const char* glPosition() const { return "pos3"; }
-
- /** 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"; }
-
-
private:
/*
* Internal call for GrGLProgramBuilder.addVarying
@@ -49,13 +40,12 @@ private:
/*
* private helpers for compilation by GrGLProgramBuilder
*/
- void transformToNormalizedDeviceSpace();
- //TODO GP itself should setup the uniform view matrix
- void setupUniformViewMatrix();
- void setupPositionAndLocalCoords();
+ void setupLocalCoords();
+ void transformGLToSkiaCoords();
void setupBuiltinVertexAttribute(const char* inName, GrGLSLExpr1* out);
void setupBuiltinVertexAttribute(const char* inName, GrGLSLExpr4* out);
void emitAttributes(const GrGeometryProcessor& gp);
+ void transformSkiaToGLCoords();
void bindVertexAttributes(GrGLuint programID);
bool compileAndAttachShaders(GrGLuint programId, SkTDArray<GrGLuint>* shaderIds) const;
@@ -71,7 +61,6 @@ private:
GrGLShaderVar* fPositionVar;
GrGLShaderVar* fLocalCoordsVar;
- const char* fRtAdjustName;
int fEffectAttribOffset;
friend class GrGLProgramBuilder;