diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gpu/GrAAConvexPathRenderer.cpp | 4 | ||||
-rw-r--r-- | src/gpu/GrAARectRenderer.cpp | 394 | ||||
-rw-r--r-- | src/gpu/GrAARectRenderer.h | 18 | ||||
-rw-r--r-- | src/gpu/GrDefaultGeoProcFactory.cpp | 182 | ||||
-rw-r--r-- | src/gpu/GrDefaultGeoProcFactory.h | 83 | ||||
-rw-r--r-- | src/gpu/GrOptDrawState.cpp | 7 | ||||
-rw-r--r-- | src/gpu/GrOvalRenderer.cpp | 12 | ||||
-rw-r--r-- | src/gpu/GrProcessor.cpp | 2 | ||||
-rw-r--r-- | src/gpu/effects/GrBezierEffect.cpp | 12 | ||||
-rw-r--r-- | src/gpu/effects/GrCustomCoordsTextureEffect.cpp | 4 | ||||
-rw-r--r-- | src/gpu/effects/GrDashingEffect.cpp | 8 | ||||
-rwxr-xr-x | src/gpu/effects/GrDistanceFieldTextureEffect.cpp | 12 | ||||
-rw-r--r-- | src/gpu/gl/GrGLSL.h | 8 | ||||
-rw-r--r-- | src/gpu/gl/builders/GrGLProgramBuilder.cpp | 92 | ||||
-rw-r--r-- | src/gpu/gl/builders/GrGLProgramBuilder.h | 24 | ||||
-rw-r--r-- | src/gpu/gl/builders/GrGLVertexShaderBuilder.cpp | 59 | ||||
-rw-r--r-- | src/gpu/gl/builders/GrGLVertexShaderBuilder.h | 17 |
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(¢er, 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; |