| Index: src/gpu/GrAARectRenderer.cpp
|
| diff --git a/src/gpu/GrAARectRenderer.cpp b/src/gpu/GrAARectRenderer.cpp
|
| index ead4ea16a37aac51d45ca9e729dca52335f56774..46196e2e4ef542d8e3d8a70d8e7fcc377b59b1f7 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,
|
|
|