diff options
author | 2014-11-07 11:47:10 -0800 | |
---|---|---|
committer | 2014-11-07 11:47:10 -0800 | |
commit | ff343074b2a3fdaa5f120600e28717e366bceadd (patch) | |
tree | 6c1048d98ccad875adf9976e35d1e6ea84b2b3a2 /src/gpu/GrAARectRenderer.cpp | |
parent | 7a72c6702da9e1f6fb536efe844db23f77535a19 (diff) |
Default geometry processor
BUG=skia:
Review URL: https://codereview.chromium.org/678953002
Diffstat (limited to 'src/gpu/GrAARectRenderer.cpp')
-rw-r--r-- | src/gpu/GrAARectRenderer.cpp | 394 |
1 files changed, 0 insertions, 394 deletions
diff --git a/src/gpu/GrAARectRenderer.cpp b/src/gpu/GrAARectRenderer.cpp index ead4ea16a3..46196e2e4e 100644 --- a/src/gpu/GrAARectRenderer.cpp +++ b/src/gpu/GrAARectRenderer.cpp @@ -15,251 +15,6 @@ #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[] = { @@ -548,155 +303,6 @@ 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, |