/*
 * Copyright 2016 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "InstanceProcessor.h"

#include "GrContext.h"
#include "GrRenderTargetPriv.h"
#include "GrResourceCache.h"
#include "GrResourceProvider.h"
#include "glsl/GrGLSLGeometryProcessor.h"
#include "glsl/GrGLSLFragmentShaderBuilder.h"
#include "glsl/GrGLSLProgramBuilder.h"
#include "glsl/GrGLSLVarying.h"

namespace gr_instanced {

GrCaps::InstancedSupport InstanceProcessor::CheckSupport(const GrGLSLCaps& glslCaps,
                                                         const GrCaps& caps) {
    if (!glslCaps.canUseAnyFunctionInShader() ||
        !glslCaps.flatInterpolationSupport() ||
        !glslCaps.integerSupport() ||
        0 == glslCaps.maxVertexSamplers() ||
        !caps.shaderCaps()->texelBufferSupport() ||
        caps.maxVertexAttributes() < kNumAttribs) {
        return GrCaps::InstancedSupport::kNone;
    }
    if (!caps.sampleLocationsSupport() ||
        !glslCaps.sampleVariablesSupport() ||
        !glslCaps.shaderDerivativeSupport()) {
        return GrCaps::InstancedSupport::kBasic;
    }
    if (0 == caps.maxRasterSamples() ||
        !glslCaps.sampleMaskOverrideCoverageSupport()) {
        return GrCaps::InstancedSupport::kMultisampled;
    }
    return GrCaps::InstancedSupport::kMixedSampled;
}

InstanceProcessor::InstanceProcessor(BatchInfo batchInfo, GrBuffer* paramsBuffer)
    : fBatchInfo(batchInfo) {
    this->initClassID<InstanceProcessor>();

    this->addVertexAttrib("shapeCoords", kVec2f_GrVertexAttribType, kHigh_GrSLPrecision);
    this->addVertexAttrib("vertexAttrs", kInt_GrVertexAttribType);
    this->addVertexAttrib("instanceInfo", kUint_GrVertexAttribType);
    this->addVertexAttrib("shapeMatrixX", kVec3f_GrVertexAttribType, kHigh_GrSLPrecision);
    this->addVertexAttrib("shapeMatrixY", kVec3f_GrVertexAttribType, kHigh_GrSLPrecision);
    this->addVertexAttrib("color", kVec4f_GrVertexAttribType, kLow_GrSLPrecision);
    this->addVertexAttrib("localRect", kVec4f_GrVertexAttribType, kHigh_GrSLPrecision);

    GR_STATIC_ASSERT(0 == (int)Attrib::kShapeCoords);
    GR_STATIC_ASSERT(1 == (int)Attrib::kVertexAttrs);
    GR_STATIC_ASSERT(2 == (int)Attrib::kInstanceInfo);
    GR_STATIC_ASSERT(3 == (int)Attrib::kShapeMatrixX);
    GR_STATIC_ASSERT(4 == (int)Attrib::kShapeMatrixY);
    GR_STATIC_ASSERT(5 == (int)Attrib::kColor);
    GR_STATIC_ASSERT(6 == (int)Attrib::kLocalRect);
    GR_STATIC_ASSERT(7 == kNumAttribs);

    if (fBatchInfo.fHasParams) {
        SkASSERT(paramsBuffer);
        fParamsAccess.reset(kRGBA_float_GrPixelConfig, paramsBuffer, kVertex_GrShaderFlag);
        this->addBufferAccess(&fParamsAccess);
    }

    if (fBatchInfo.fAntialiasMode >= AntialiasMode::kMSAA) {
        if (!fBatchInfo.isSimpleRects() ||
            AntialiasMode::kMixedSamples == fBatchInfo.fAntialiasMode) {
            this->setWillUseSampleLocations();
        }
    }
}

class GLSLInstanceProcessor : public GrGLSLGeometryProcessor {
public:
    void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override;

private:
    void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor&,
                 FPCoordTransformIter&& transformIter) override {
        this->setTransformDataHelper(SkMatrix::I(), pdman, &transformIter);
    }

    class VertexInputs;
    class Backend;
    class BackendNonAA;
    class BackendCoverage;
    class BackendMultisample;

    typedef GrGLSLGeometryProcessor INHERITED;
};

GrGLSLPrimitiveProcessor* InstanceProcessor::createGLSLInstance(const GrGLSLCaps&) const {
    return new GLSLInstanceProcessor();
}

class GLSLInstanceProcessor::VertexInputs {
public:
    VertexInputs(const InstanceProcessor& instProc, GrGLSLVertexBuilder* vertexBuilder)
        : fInstProc(instProc),
          fVertexBuilder(vertexBuilder) {
    }

    void initParams(const SamplerHandle paramsBuffer) {
        fParamsBuffer = paramsBuffer;
        fVertexBuilder->appendPrecisionModifier(kHigh_GrSLPrecision);
        fVertexBuilder->codeAppendf("int paramsIdx = int(%s & 0x%x);",
                                    this->attr(Attrib::kInstanceInfo),
                                    kParamsIdx_InfoMask);
    }

    const char* attr(Attrib attr) const { return fInstProc.getAttrib((int)attr).fName; }

    void fetchNextParam(GrSLType type = kVec4f_GrSLType) const {
        SkASSERT(fParamsBuffer.isValid());
        if (type != kVec4f_GrSLType) {
            fVertexBuilder->codeAppendf("%s(", GrGLSLTypeString(type));
        }
        fVertexBuilder->appendTexelFetch(fParamsBuffer, "paramsIdx++");
        if (type != kVec4f_GrSLType) {
            fVertexBuilder->codeAppend(")");
        }
    }

    void skipParams(unsigned n) const {
        SkASSERT(fParamsBuffer.isValid());
        fVertexBuilder->codeAppendf("paramsIdx += %u;", n);
    }

private:
    const InstanceProcessor&     fInstProc;
    GrGLSLVertexBuilder*         fVertexBuilder;
    SamplerHandle                fParamsBuffer;
};

class GLSLInstanceProcessor::Backend {
public:
    static Backend* SK_WARN_UNUSED_RESULT Create(const GrPipeline&, BatchInfo, const VertexInputs&);
    virtual ~Backend() {}

    void init(GrGLSLVaryingHandler*, GrGLSLVertexBuilder*);
    virtual void setupRect(GrGLSLVertexBuilder*) = 0;
    virtual void setupOval(GrGLSLVertexBuilder*) = 0;
    void setupRRect(GrGLSLVertexBuilder*, int* usedShapeDefinitions);

    void initInnerShape(GrGLSLVaryingHandler*, GrGLSLVertexBuilder*);
    virtual void setupInnerRect(GrGLSLVertexBuilder*) = 0;
    virtual void setupInnerOval(GrGLSLVertexBuilder*) = 0;
    void setupInnerSimpleRRect(GrGLSLVertexBuilder*);

    const char* outShapeCoords() {
        return fModifiedShapeCoords ? fModifiedShapeCoords : fInputs.attr(Attrib::kShapeCoords);
    }

    void emitCode(GrGLSLVertexBuilder*, GrGLSLPPFragmentBuilder*, const char* outCoverage,
                  const char* outColor);

protected:
    Backend(BatchInfo batchInfo, const VertexInputs& inputs)
        : fBatchInfo(batchInfo),
          fInputs(inputs),
          fModifiesCoverage(false),
          fModifiesColor(false),
          fNeedsNeighborRadii(false),
          fColor(kVec4f_GrSLType),
          fTriangleIsArc(kInt_GrSLType),
          fArcCoords(kVec2f_GrSLType),
          fInnerShapeCoords(kVec2f_GrSLType),
          fInnerRRect(kVec4f_GrSLType),
          fModifiedShapeCoords(nullptr) {
        if (fBatchInfo.fShapeTypes & kRRect_ShapesMask) {
            fModifiedShapeCoords = "adjustedShapeCoords";
        }
    }

    virtual void onInit(GrGLSLVaryingHandler*, GrGLSLVertexBuilder*) = 0;
    virtual void adjustRRectVertices(GrGLSLVertexBuilder*);
    virtual void onSetupRRect(GrGLSLVertexBuilder*) {}

    virtual void onInitInnerShape(GrGLSLVaryingHandler*, GrGLSLVertexBuilder*) = 0;
    virtual void onSetupInnerSimpleRRect(GrGLSLVertexBuilder*) = 0;

    virtual void onEmitCode(GrGLSLVertexBuilder*, GrGLSLPPFragmentBuilder*,
                            const char* outCoverage, const char* outColor) = 0;

    void setupSimpleRadii(GrGLSLVertexBuilder*);
    void setupNinePatchRadii(GrGLSLVertexBuilder*);
    void setupComplexRadii(GrGLSLVertexBuilder*);

    const BatchInfo       fBatchInfo;
    const VertexInputs&   fInputs;
    bool                  fModifiesCoverage;
    bool                  fModifiesColor;
    bool                  fNeedsNeighborRadii;
    GrGLSLVertToFrag      fColor;
    GrGLSLVertToFrag      fTriangleIsArc;
    GrGLSLVertToFrag      fArcCoords;
    GrGLSLVertToFrag      fInnerShapeCoords;
    GrGLSLVertToFrag      fInnerRRect;
    const char*           fModifiedShapeCoords;
};

void GLSLInstanceProcessor::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
    const GrPipeline& pipeline = args.fVertBuilder->getProgramBuilder()->pipeline();
    const InstanceProcessor& ip = args.fGP.cast<InstanceProcessor>();
    GrGLSLUniformHandler* uniHandler = args.fUniformHandler;
    GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
    GrGLSLVertexBuilder* v = args.fVertBuilder;
    GrGLSLPPFragmentBuilder* f = args.fFragBuilder;

    varyingHandler->emitAttributes(ip);

    VertexInputs inputs(ip, v);
    if (ip.batchInfo().fHasParams) {
        SkASSERT(1 == ip.numBuffers());
        inputs.initParams(args.fBufferSamplers[0]);
    }

    if (!ip.batchInfo().fHasPerspective) {
        v->codeAppendf("mat2x3 shapeMatrix = mat2x3(%s, %s);",
                       inputs.attr(Attrib::kShapeMatrixX), inputs.attr(Attrib::kShapeMatrixY));
    } else {
        v->defineConstantf("int", "PERSPECTIVE_FLAG", "0x%x", kPerspective_InfoFlag);
        v->codeAppendf("mat3 shapeMatrix = mat3(%s, %s, vec3(0, 0, 1));",
                       inputs.attr(Attrib::kShapeMatrixX), inputs.attr(Attrib::kShapeMatrixY));
        v->codeAppendf("if (0 != (%s & PERSPECTIVE_FLAG)) {",
                       inputs.attr(Attrib::kInstanceInfo));
        v->codeAppend (    "shapeMatrix[2] = ");
        inputs.fetchNextParam(kVec3f_GrSLType);
        v->codeAppend (    ";");
        v->codeAppend ("}");
    }

    bool hasSingleShapeType = SkIsPow2(ip.batchInfo().fShapeTypes);
    if (!hasSingleShapeType) {
        v->defineConstant("SHAPE_TYPE_BIT", kShapeType_InfoBit);
        v->codeAppendf("uint shapeType = %s >> SHAPE_TYPE_BIT;",
                       inputs.attr(Attrib::kInstanceInfo));
    }

    std::unique_ptr<Backend> backend(Backend::Create(pipeline, ip.batchInfo(), inputs));
    backend->init(varyingHandler, v);

    int usedShapeDefinitions = 0;

    if (hasSingleShapeType || !(ip.batchInfo().fShapeTypes & ~kRRect_ShapesMask)) {
        if (kRect_ShapeFlag == ip.batchInfo().fShapeTypes) {
            backend->setupRect(v);
        } else if (kOval_ShapeFlag == ip.batchInfo().fShapeTypes) {
            backend->setupOval(v);
        } else {
            backend->setupRRect(v, &usedShapeDefinitions);
        }
    } else {
        if (ip.batchInfo().fShapeTypes & kRRect_ShapesMask) {
            v->codeAppend ("if (shapeType >= SIMPLE_R_RECT_SHAPE_TYPE) {");
            backend->setupRRect(v, &usedShapeDefinitions);
            v->codeAppend ("}");
            usedShapeDefinitions |= kSimpleRRect_ShapeFlag;
        }
        if (ip.batchInfo().fShapeTypes & kOval_ShapeFlag) {
            if (ip.batchInfo().fShapeTypes & kRect_ShapeFlag) {
                if (ip.batchInfo().fShapeTypes & kRRect_ShapesMask) {
                    v->codeAppend ("else ");
                }
                v->codeAppend ("if (OVAL_SHAPE_TYPE == shapeType) {");
                usedShapeDefinitions |= kOval_ShapeFlag;
            } else {
                v->codeAppend ("else {");
            }
            backend->setupOval(v);
            v->codeAppend ("}");
        }
        if (ip.batchInfo().fShapeTypes & kRect_ShapeFlag) {
            v->codeAppend ("else {");
            backend->setupRect(v);
            v->codeAppend ("}");
        }
    }

    if (ip.batchInfo().fInnerShapeTypes) {
        bool hasSingleInnerShapeType = SkIsPow2(ip.batchInfo().fInnerShapeTypes);
        if (!hasSingleInnerShapeType) {
            v->defineConstantf("int", "INNER_SHAPE_TYPE_MASK", "0x%x", kInnerShapeType_InfoMask);
            v->defineConstant("INNER_SHAPE_TYPE_BIT", kInnerShapeType_InfoBit);
            v->codeAppendf("uint innerShapeType = ((%s & INNER_SHAPE_TYPE_MASK) >> "
                                                  "INNER_SHAPE_TYPE_BIT);",
                           inputs.attr(Attrib::kInstanceInfo));
        }
        // Here we take advantage of the fact that outerRect == localRect in recordDRRect.
        v->codeAppendf("vec4 outer = %s;", inputs.attr(Attrib::kLocalRect));
        v->codeAppend ("vec4 inner = ");
        inputs.fetchNextParam();
        v->codeAppend (";");
        // outer2Inner is a transform from shape coords to inner shape coords:
        // e.g. innerShapeCoords = shapeCoords * outer2Inner.xy + outer2Inner.zw
        v->codeAppend ("vec4 outer2Inner = vec4(outer.zw - outer.xy, "
                                               "outer.xy + outer.zw - inner.xy - inner.zw) / "
                                               "(inner.zw - inner.xy).xyxy;");
        v->codeAppendf("vec2 innerShapeCoords = %s * outer2Inner.xy + outer2Inner.zw;",
                       backend->outShapeCoords());

        backend->initInnerShape(varyingHandler, v);

        SkASSERT(0 == (ip.batchInfo().fInnerShapeTypes & kRRect_ShapesMask) ||
                 kSimpleRRect_ShapeFlag == (ip.batchInfo().fInnerShapeTypes & kRRect_ShapesMask));

        if (hasSingleInnerShapeType) {
            if (kRect_ShapeFlag == ip.batchInfo().fInnerShapeTypes) {
                backend->setupInnerRect(v);
            } else if (kOval_ShapeFlag == ip.batchInfo().fInnerShapeTypes) {
                backend->setupInnerOval(v);
            } else {
                backend->setupInnerSimpleRRect(v);
            }
        } else {
            if (ip.batchInfo().fInnerShapeTypes & kSimpleRRect_ShapeFlag) {
                v->codeAppend ("if (SIMPLE_R_RECT_SHAPE_TYPE == innerShapeType) {");
                backend->setupInnerSimpleRRect(v);
                v->codeAppend("}");
                usedShapeDefinitions |= kSimpleRRect_ShapeFlag;
            }
            if (ip.batchInfo().fInnerShapeTypes & kOval_ShapeFlag) {
                if (ip.batchInfo().fInnerShapeTypes & kRect_ShapeFlag) {
                    if (ip.batchInfo().fInnerShapeTypes & kSimpleRRect_ShapeFlag) {
                        v->codeAppend ("else ");
                    }
                    v->codeAppend ("if (OVAL_SHAPE_TYPE == innerShapeType) {");
                    usedShapeDefinitions |= kOval_ShapeFlag;
                } else {
                    v->codeAppend ("else {");
                }
                backend->setupInnerOval(v);
                v->codeAppend("}");
            }
            if (ip.batchInfo().fInnerShapeTypes & kRect_ShapeFlag) {
                v->codeAppend("else {");
                backend->setupInnerRect(v);
                v->codeAppend("}");
            }
        }
    }

    if (usedShapeDefinitions & kOval_ShapeFlag) {
        v->defineConstant("OVAL_SHAPE_TYPE", (int)ShapeType::kOval);
    }
    if (usedShapeDefinitions & kSimpleRRect_ShapeFlag) {
        v->defineConstant("SIMPLE_R_RECT_SHAPE_TYPE", (int)ShapeType::kSimpleRRect);
    }
    if (usedShapeDefinitions & kNinePatch_ShapeFlag) {
        v->defineConstant("NINE_PATCH_SHAPE_TYPE", (int)ShapeType::kNinePatch);
    }
    SkASSERT(!(usedShapeDefinitions & (kRect_ShapeFlag | kComplexRRect_ShapeFlag)));

    backend->emitCode(v, f, pipeline.ignoresCoverage() ? nullptr : args.fOutputCoverage,
                      args.fOutputColor);

    const char* localCoords = nullptr;
    if (ip.batchInfo().fUsesLocalCoords) {
        localCoords = "localCoords";
        v->codeAppendf("vec2 t = 0.5 * (%s + vec2(1));", backend->outShapeCoords());
        v->codeAppendf("vec2 localCoords = (1.0 - t) * %s.xy + t * %s.zw;",
                       inputs.attr(Attrib::kLocalRect), inputs.attr(Attrib::kLocalRect));
    }
    if (ip.batchInfo().fHasLocalMatrix && ip.batchInfo().fHasParams) {
        v->defineConstantf("int", "LOCAL_MATRIX_FLAG", "0x%x", kLocalMatrix_InfoFlag);
        v->codeAppendf("if (0 != (%s & LOCAL_MATRIX_FLAG)) {",
                       inputs.attr(Attrib::kInstanceInfo));
        if (!ip.batchInfo().fUsesLocalCoords) {
            inputs.skipParams(2);
        } else {
            v->codeAppendf(    "mat2x3 localMatrix;");
            v->codeAppend (    "localMatrix[0] = ");
            inputs.fetchNextParam(kVec3f_GrSLType);
            v->codeAppend (    ";");
            v->codeAppend (    "localMatrix[1] = ");
            inputs.fetchNextParam(kVec3f_GrSLType);
            v->codeAppend (    ";");
            v->codeAppend (    "localCoords = (vec3(localCoords, 1) * localMatrix).xy;");
        }
        v->codeAppend("}");
    }

    GrSLType positionType = ip.batchInfo().fHasPerspective ? kVec3f_GrSLType : kVec2f_GrSLType;
    v->codeAppendf("%s deviceCoords = vec3(%s, 1) * shapeMatrix;",
                   GrGLSLTypeString(positionType), backend->outShapeCoords());
    gpArgs->fPositionVar.set(positionType, "deviceCoords");

    this->emitTransforms(v, varyingHandler, uniHandler, gpArgs->fPositionVar, localCoords,
                         args.fFPCoordTransformHandler);
}

////////////////////////////////////////////////////////////////////////////////////////////////////

void GLSLInstanceProcessor::Backend::init(GrGLSLVaryingHandler* varyingHandler,
                                          GrGLSLVertexBuilder* v) {
    if (fModifiedShapeCoords) {
        v->codeAppendf("vec2 %s = %s;", fModifiedShapeCoords, fInputs.attr(Attrib::kShapeCoords));
    }

    this->onInit(varyingHandler, v);

    if (!fColor.vsOut()) {
        varyingHandler->addFlatVarying("color", &fColor, kLow_GrSLPrecision);
        v->codeAppendf("%s = %s;", fColor.vsOut(), fInputs.attr(Attrib::kColor));
    }
}

void GLSLInstanceProcessor::Backend::setupRRect(GrGLSLVertexBuilder* v, int* usedShapeDefinitions) {
    v->codeAppendf("uvec2 corner = uvec2(%s & 1, (%s >> 1) & 1);",
                   fInputs.attr(Attrib::kVertexAttrs), fInputs.attr(Attrib::kVertexAttrs));
    v->codeAppend ("vec2 cornerSign = vec2(corner) * 2.0 - 1.0;");
    v->codeAppendf("vec2 radii%s;", fNeedsNeighborRadii ? ", neighborRadii" : "");
    v->codeAppend ("mat2 p = ");
    fInputs.fetchNextParam(kMat22f_GrSLType);
    v->codeAppend (";");
    uint8_t types = fBatchInfo.fShapeTypes & kRRect_ShapesMask;
    if (0 == (types & (types - 1))) {
        if (kSimpleRRect_ShapeFlag == types) {
            this->setupSimpleRadii(v);
        } else if (kNinePatch_ShapeFlag == types) {
            this->setupNinePatchRadii(v);
        } else if (kComplexRRect_ShapeFlag == types) {
            this->setupComplexRadii(v);
        }
    } else {
        if (types & kSimpleRRect_ShapeFlag) {
            v->codeAppend ("if (SIMPLE_R_RECT_SHAPE_TYPE == shapeType) {");
            this->setupSimpleRadii(v);
            v->codeAppend ("}");
            *usedShapeDefinitions |= kSimpleRRect_ShapeFlag;
        }
        if (types & kNinePatch_ShapeFlag) {
            if (types & kComplexRRect_ShapeFlag) {
                if (types & kSimpleRRect_ShapeFlag) {
                    v->codeAppend ("else ");
                }
                v->codeAppend ("if (NINE_PATCH_SHAPE_TYPE == shapeType) {");
                *usedShapeDefinitions |= kNinePatch_ShapeFlag;
            } else {
                v->codeAppend ("else {");
            }
            this->setupNinePatchRadii(v);
            v->codeAppend ("}");
        }
        if (types & kComplexRRect_ShapeFlag) {
            v->codeAppend ("else {");
            this->setupComplexRadii(v);
            v->codeAppend ("}");
        }
    }

    this->adjustRRectVertices(v);

    if (fArcCoords.vsOut()) {
        v->codeAppendf("%s = (cornerSign * %s + radii - vec2(1)) / radii;",
                       fArcCoords.vsOut(), fModifiedShapeCoords);
    }
    if (fTriangleIsArc.vsOut()) {
        v->codeAppendf("%s = int(all(equal(vec2(1), abs(%s))));",
                       fTriangleIsArc.vsOut(), fInputs.attr(Attrib::kShapeCoords));
    }

    this->onSetupRRect(v);
}

void GLSLInstanceProcessor::Backend::setupSimpleRadii(GrGLSLVertexBuilder* v) {
    if (fNeedsNeighborRadii) {
        v->codeAppend ("neighborRadii = ");
    }
    v->codeAppend("radii = p[0] * 2.0 / p[1];");
}

void GLSLInstanceProcessor::Backend::setupNinePatchRadii(GrGLSLVertexBuilder* v) {
    v->codeAppend("radii = vec2(p[0][corner.x], p[1][corner.y]);");
    if (fNeedsNeighborRadii) {
        v->codeAppend("neighborRadii = vec2(p[0][1u - corner.x], p[1][1u - corner.y]);");
    }
}

void GLSLInstanceProcessor::Backend::setupComplexRadii(GrGLSLVertexBuilder* v) {
    /**
     * The x and y radii of each arc are stored in separate vectors,
     * in the following order:
     *
     *        __x1 _ _ _ x3__
     *
     *    y1 |               | y2
     *
     *       |               |
     *
     *    y3 |__   _ _ _   __| y4
     *          x2       x4
     *
     */
    v->codeAppend("mat2 p2 = ");
    fInputs.fetchNextParam(kMat22f_GrSLType);
    v->codeAppend(";");
    v->codeAppend("radii = vec2(p[corner.x][corner.y], p2[corner.y][corner.x]);");
    if (fNeedsNeighborRadii) {
        v->codeAppend("neighborRadii = vec2(p[1u - corner.x][corner.y], "
                                           "p2[1u - corner.y][corner.x]);");
    }
}

void GLSLInstanceProcessor::Backend::adjustRRectVertices(GrGLSLVertexBuilder* v) {
    // Resize the 4 triangles that arcs are drawn into so they match their corresponding radii.
    // 0.5 is a special value that indicates the edge of an arc triangle.
    v->codeAppendf("if (abs(%s.x) == 0.5)"
                       "%s.x = cornerSign.x * (1.0 - radii.x);",
                       fInputs.attr(Attrib::kShapeCoords), fModifiedShapeCoords);
    v->codeAppendf("if (abs(%s.y) == 0.5) "
                       "%s.y = cornerSign.y * (1.0 - radii.y);",
                       fInputs.attr(Attrib::kShapeCoords), fModifiedShapeCoords);
}

void GLSLInstanceProcessor::Backend::initInnerShape(GrGLSLVaryingHandler* varyingHandler,
                                                    GrGLSLVertexBuilder* v) {
    SkASSERT(!(fBatchInfo.fInnerShapeTypes & (kNinePatch_ShapeFlag | kComplexRRect_ShapeFlag)));

    this->onInitInnerShape(varyingHandler, v);

    if (fInnerShapeCoords.vsOut()) {
        v->codeAppendf("%s = innerShapeCoords;", fInnerShapeCoords.vsOut());
    }
}

void GLSLInstanceProcessor::Backend::setupInnerSimpleRRect(GrGLSLVertexBuilder* v) {
    v->codeAppend("mat2 innerP = ");
    fInputs.fetchNextParam(kMat22f_GrSLType);
    v->codeAppend(";");
    v->codeAppend("vec2 innerRadii = innerP[0] * 2.0 / innerP[1];");
    this->onSetupInnerSimpleRRect(v);
}

void GLSLInstanceProcessor::Backend::emitCode(GrGLSLVertexBuilder* v, GrGLSLPPFragmentBuilder* f,
                                              const char* outCoverage, const char* outColor) {
    SkASSERT(!fModifiesCoverage || outCoverage);
    this->onEmitCode(v, f, fModifiesCoverage ? outCoverage : nullptr,
                     fModifiesColor ? outColor : nullptr);
    if (outCoverage && !fModifiesCoverage) {
        // Even though the subclass doesn't use coverage, we are expected to assign some value.
        f->codeAppendf("%s = vec4(1);", outCoverage);
    }
    if (!fModifiesColor) {
        // The subclass didn't assign a value to the output color.
        f->codeAppendf("%s = %s;", outColor, fColor.fsIn());
    }
}

////////////////////////////////////////////////////////////////////////////////////////////////////

class GLSLInstanceProcessor::BackendNonAA : public Backend {
public:
    BackendNonAA(BatchInfo batchInfo, const VertexInputs& inputs)
        : INHERITED(batchInfo, inputs) {
        if (fBatchInfo.fCannotDiscard && !fBatchInfo.isSimpleRects()) {
            fModifiesColor = !fBatchInfo.fCannotTweakAlphaForCoverage;
            fModifiesCoverage = !fModifiesColor;
        }
    }

private:
    void onInit(GrGLSLVaryingHandler*, GrGLSLVertexBuilder*) override;
    void setupRect(GrGLSLVertexBuilder*) override;
    void setupOval(GrGLSLVertexBuilder*) override;

    void onInitInnerShape(GrGLSLVaryingHandler*, GrGLSLVertexBuilder*) override;
    void setupInnerRect(GrGLSLVertexBuilder*) override;
    void setupInnerOval(GrGLSLVertexBuilder*) override;
    void onSetupInnerSimpleRRect(GrGLSLVertexBuilder*) override;

    void onEmitCode(GrGLSLVertexBuilder*, GrGLSLPPFragmentBuilder*, const char*,
                    const char*) override;

    typedef Backend INHERITED;
};

void GLSLInstanceProcessor::BackendNonAA::onInit(GrGLSLVaryingHandler* varyingHandler,
                                                 GrGLSLVertexBuilder*) {
    if (kRect_ShapeFlag != fBatchInfo.fShapeTypes) {
        varyingHandler->addFlatVarying("triangleIsArc", &fTriangleIsArc, kLow_GrSLPrecision);
        varyingHandler->addVarying("arcCoords", &fArcCoords, kMedium_GrSLPrecision);
    }
}

void GLSLInstanceProcessor::BackendNonAA::setupRect(GrGLSLVertexBuilder* v) {
    if (fTriangleIsArc.vsOut()) {
        v->codeAppendf("%s = 0;", fTriangleIsArc.vsOut());
    }
}

void GLSLInstanceProcessor::BackendNonAA::setupOval(GrGLSLVertexBuilder* v) {
    SkASSERT(fArcCoords.vsOut());
    SkASSERT(fTriangleIsArc.vsOut());
    v->codeAppendf("%s = %s;", fArcCoords.vsOut(), this->outShapeCoords());
    v->codeAppendf("%s = %s & 1;", fTriangleIsArc.vsOut(), fInputs.attr(Attrib::kVertexAttrs));
}

void GLSLInstanceProcessor::BackendNonAA::onInitInnerShape(GrGLSLVaryingHandler* varyingHandler,
                                                           GrGLSLVertexBuilder*) {
    varyingHandler->addVarying("innerShapeCoords", &fInnerShapeCoords, kMedium_GrSLPrecision);
    if (kRect_ShapeFlag != fBatchInfo.fInnerShapeTypes &&
        kOval_ShapeFlag != fBatchInfo.fInnerShapeTypes) {
        varyingHandler->addFlatVarying("innerRRect", &fInnerRRect, kMedium_GrSLPrecision);
    }
}

void GLSLInstanceProcessor::BackendNonAA::setupInnerRect(GrGLSLVertexBuilder* v) {
    if (fInnerRRect.vsOut()) {
        v->codeAppendf("%s = vec4(1);", fInnerRRect.vsOut());
    }
}

void GLSLInstanceProcessor::BackendNonAA::setupInnerOval(GrGLSLVertexBuilder* v) {
    if (fInnerRRect.vsOut()) {
        v->codeAppendf("%s = vec4(0, 0, 1, 1);", fInnerRRect.vsOut());
    }
}

void GLSLInstanceProcessor::BackendNonAA::onSetupInnerSimpleRRect(GrGLSLVertexBuilder* v) {
    v->codeAppendf("%s = vec4(1.0 - innerRadii, 1.0 / innerRadii);", fInnerRRect.vsOut());
}

void GLSLInstanceProcessor::BackendNonAA::onEmitCode(GrGLSLVertexBuilder*,
                                                     GrGLSLPPFragmentBuilder* f,
                                                     const char* outCoverage,
                                                     const char* outColor) {
    const char* dropFragment = nullptr;
    if (!fBatchInfo.fCannotDiscard) {
        dropFragment = "discard";
    } else if (fModifiesCoverage) {
        f->appendPrecisionModifier(kLow_GrSLPrecision);
        f->codeAppend ("float covered = 1.0;");
        dropFragment = "covered = 0.0";
    } else if (fModifiesColor) {
        f->appendPrecisionModifier(kLow_GrSLPrecision);
        f->codeAppendf("vec4 color = %s;", fColor.fsIn());
        dropFragment = "color = vec4(0)";
    }
    if (fTriangleIsArc.fsIn()) {
        SkASSERT(dropFragment);
        f->codeAppendf("if (%s != 0 && dot(%s, %s) > 1.0) %s;",
                       fTriangleIsArc.fsIn(), fArcCoords.fsIn(), fArcCoords.fsIn(), dropFragment);
    }
    if (fBatchInfo.fInnerShapeTypes) {
        SkASSERT(dropFragment);
        f->codeAppendf("// Inner shape.\n");
        if (kRect_ShapeFlag == fBatchInfo.fInnerShapeTypes) {
            f->codeAppendf("if (all(lessThanEqual(abs(%s), vec2(1)))) %s;",
                           fInnerShapeCoords.fsIn(), dropFragment);
        } else if (kOval_ShapeFlag == fBatchInfo.fInnerShapeTypes) {
            f->codeAppendf("if ((dot(%s, %s) <= 1.0)) %s;",
                           fInnerShapeCoords.fsIn(), fInnerShapeCoords.fsIn(), dropFragment);
        } else {
            f->codeAppendf("if (all(lessThan(abs(%s), vec2(1)))) {", fInnerShapeCoords.fsIn());
            f->codeAppendf(    "vec2 distanceToArcEdge = abs(%s) - %s.xy;",
                               fInnerShapeCoords.fsIn(), fInnerRRect.fsIn());
            f->codeAppend (    "if (any(lessThan(distanceToArcEdge, vec2(0)))) {");
            f->codeAppendf(        "%s;", dropFragment);
            f->codeAppend (    "} else {");
            f->codeAppendf(        "vec2 rrectCoords = distanceToArcEdge * %s.zw;",
                                   fInnerRRect.fsIn());
            f->codeAppend (        "if (dot(rrectCoords, rrectCoords) <= 1.0) {");
            f->codeAppendf(            "%s;", dropFragment);
            f->codeAppend (        "}");
            f->codeAppend (    "}");
            f->codeAppend ("}");
        }
    }
    if (fModifiesCoverage) {
        f->codeAppendf("%s = vec4(covered);", outCoverage);
    } else if (fModifiesColor) {
        f->codeAppendf("%s = color;", outColor);
    }
}

////////////////////////////////////////////////////////////////////////////////////////////////////

class GLSLInstanceProcessor::BackendCoverage : public Backend {
public:
    BackendCoverage(BatchInfo batchInfo, const VertexInputs& inputs)
        : INHERITED(batchInfo, inputs),
          fColorTimesRectCoverage(kVec4f_GrSLType),
          fRectCoverage(kFloat_GrSLType),
          fEllipseCoords(kVec2f_GrSLType),
          fEllipseName(kVec2f_GrSLType),
          fBloatedRadius(kFloat_GrSLType),
          fDistanceToInnerEdge(kVec2f_GrSLType),
          fInnerShapeBloatedHalfSize(kVec2f_GrSLType),
          fInnerEllipseCoords(kVec2f_GrSLType),
          fInnerEllipseName(kVec2f_GrSLType) {
        fShapeIsCircle = !fBatchInfo.fNonSquare && !(fBatchInfo.fShapeTypes & kRRect_ShapesMask);
        fTweakAlphaForCoverage = !fBatchInfo.fCannotTweakAlphaForCoverage &&
                                 !fBatchInfo.fInnerShapeTypes;
        fModifiesCoverage = !fTweakAlphaForCoverage;
        fModifiesColor = fTweakAlphaForCoverage;
        fModifiedShapeCoords = "bloatedShapeCoords";
    }

private:
    void onInit(GrGLSLVaryingHandler*, GrGLSLVertexBuilder*) override;
    void setupRect(GrGLSLVertexBuilder*) override;
    void setupOval(GrGLSLVertexBuilder*) override;
    void adjustRRectVertices(GrGLSLVertexBuilder*) override;
    void onSetupRRect(GrGLSLVertexBuilder*) override;

    void onInitInnerShape(GrGLSLVaryingHandler*, GrGLSLVertexBuilder*) override;
    void setupInnerRect(GrGLSLVertexBuilder*) override;
    void setupInnerOval(GrGLSLVertexBuilder*) override;
    void onSetupInnerSimpleRRect(GrGLSLVertexBuilder*) override;

    void onEmitCode(GrGLSLVertexBuilder*, GrGLSLPPFragmentBuilder*, const char* outCoverage,
                    const char* outColor) override;

    void emitRect(GrGLSLPPFragmentBuilder*, const char* outCoverage, const char* outColor);
    void emitCircle(GrGLSLPPFragmentBuilder*, const char* outCoverage);
    void emitArc(GrGLSLPPFragmentBuilder* f, const char* ellipseCoords, const char* ellipseName,
                 bool ellipseCoordsNeedClamp, bool ellipseCoordsMayBeNegative,
                 const char* outCoverage);
    void emitInnerRect(GrGLSLPPFragmentBuilder*, const char* outCoverage);

    GrGLSLVertToFrag   fColorTimesRectCoverage;
    GrGLSLVertToFrag   fRectCoverage;
    GrGLSLVertToFrag   fEllipseCoords;
    GrGLSLVertToFrag   fEllipseName;
    GrGLSLVertToFrag   fBloatedRadius;
    GrGLSLVertToFrag   fDistanceToInnerEdge;
    GrGLSLVertToFrag   fInnerShapeBloatedHalfSize;
    GrGLSLVertToFrag   fInnerEllipseCoords;
    GrGLSLVertToFrag   fInnerEllipseName;
    bool               fShapeIsCircle;
    bool               fTweakAlphaForCoverage;

    typedef Backend INHERITED;
};

void GLSLInstanceProcessor::BackendCoverage::onInit(GrGLSLVaryingHandler* varyingHandler,
                                                    GrGLSLVertexBuilder* v) {
    v->codeAppend ("mat2 shapeTransposeMatrix = transpose(mat2(shapeMatrix));");
    v->codeAppend ("vec2 shapeHalfSize = vec2(length(shapeTransposeMatrix[0]), "
                                             "length(shapeTransposeMatrix[1]));");
    v->codeAppend ("vec2 bloat = 0.5 / shapeHalfSize;");
    v->codeAppendf("bloatedShapeCoords = %s * (1.0 + bloat);", fInputs.attr(Attrib::kShapeCoords));

    if (kOval_ShapeFlag != fBatchInfo.fShapeTypes) {
        if (fTweakAlphaForCoverage) {
            varyingHandler->addVarying("colorTimesRectCoverage", &fColorTimesRectCoverage,
                                       kLow_GrSLPrecision);
            if (kRect_ShapeFlag == fBatchInfo.fShapeTypes) {
                fColor = fColorTimesRectCoverage;
            }
        } else {
            varyingHandler->addVarying("rectCoverage", &fRectCoverage, kLow_GrSLPrecision);
        }
        v->codeAppend("float rectCoverage = 0.0;");
    }
    if (kRect_ShapeFlag != fBatchInfo.fShapeTypes) {
        varyingHandler->addFlatVarying("triangleIsArc", &fTriangleIsArc, kLow_GrSLPrecision);
        if (!fShapeIsCircle) {
            varyingHandler->addVarying("ellipseCoords", &fEllipseCoords, kMedium_GrSLPrecision);
            varyingHandler->addFlatVarying("ellipseName", &fEllipseName, kHigh_GrSLPrecision);
        } else {
            varyingHandler->addVarying("circleCoords", &fEllipseCoords, kHigh_GrSLPrecision);
            varyingHandler->addFlatVarying("bloatedRadius", &fBloatedRadius, kHigh_GrSLPrecision);
        }
    }
}

void GLSLInstanceProcessor::BackendCoverage::setupRect(GrGLSLVertexBuilder* v) {
    // Make the border one pixel wide. Inner vs outer is indicated by coordAttrs.
    v->codeAppendf("vec2 rectBloat = (%s != 0) ? bloat : -bloat;",
                   fInputs.attr(Attrib::kVertexAttrs));
    // Here we use the absolute value, because when the rect is thinner than a pixel, this makes it
    // mark the spot where pixel center is within half a pixel of the *opposite* edge. This,
    // combined with the "maxCoverage" logic below gives us mathematically correct coverage even for
    // subpixel rectangles.
    v->codeAppendf("bloatedShapeCoords = %s * abs(vec2(1.0 + rectBloat));",
                   fInputs.attr(Attrib::kShapeCoords));

    // Determine coverage at the vertex. Coverage naturally ramps from 0 to 1 unless the rect is
    // narrower than a pixel.
    v->codeAppend ("float maxCoverage = 4.0 * min(0.5, shapeHalfSize.x) *"
                                             "min(0.5, shapeHalfSize.y);");
    v->codeAppendf("rectCoverage = (%s != 0) ? 0.0 : maxCoverage;",
                   fInputs.attr(Attrib::kVertexAttrs));

    if (fTriangleIsArc.vsOut()) {
        v->codeAppendf("%s = 0;", fTriangleIsArc.vsOut());
    }
}

void GLSLInstanceProcessor::BackendCoverage::setupOval(GrGLSLVertexBuilder* v) {
    // Offset the inner and outer octagons by one pixel. Inner vs outer is indicated by coordAttrs.
    v->codeAppendf("vec2 ovalBloat = (%s != 0) ? bloat : -bloat;",
                   fInputs.attr(Attrib::kVertexAttrs));
    v->codeAppendf("bloatedShapeCoords = %s * max(vec2(1.0 + ovalBloat), vec2(0));",
                   fInputs.attr(Attrib::kShapeCoords));
    v->codeAppendf("%s = bloatedShapeCoords * shapeHalfSize;", fEllipseCoords.vsOut());
    if (fEllipseName.vsOut()) {
        v->codeAppendf("%s = 1.0 / (shapeHalfSize * shapeHalfSize);", fEllipseName.vsOut());
    }
    if (fBloatedRadius.vsOut()) {
        SkASSERT(fShapeIsCircle);
        v->codeAppendf("%s = shapeHalfSize.x + 0.5;", fBloatedRadius.vsOut());
    }
    if (fTriangleIsArc.vsOut()) {
        v->codeAppendf("%s = int(%s != 0);",
                       fTriangleIsArc.vsOut(), fInputs.attr(Attrib::kVertexAttrs));
    }
    if (fColorTimesRectCoverage.vsOut() || fRectCoverage.vsOut()) {
        v->codeAppendf("rectCoverage = 1.0;");
    }
}

void GLSLInstanceProcessor::BackendCoverage::adjustRRectVertices(GrGLSLVertexBuilder* v) {
    // We try to let the AA borders line up with the arc edges on their particular side, but we
    // can't allow them to get closer than one half pixel to the edge or they might overlap with
    // their neighboring border.
    v->codeAppend("vec2 innerEdge = max(1.0 - bloat, vec2(0));");
    v->codeAppend ("vec2 borderEdge = cornerSign * clamp(1.0 - radii, -innerEdge, innerEdge);");
    // 0.5 is a special value that indicates this vertex is an arc edge.
    v->codeAppendf("if (abs(%s.x) == 0.5)"
                       "bloatedShapeCoords.x = borderEdge.x;", fInputs.attr(Attrib::kShapeCoords));
    v->codeAppendf("if (abs(%s.y) == 0.5)"
                       "bloatedShapeCoords.y = borderEdge.y;", fInputs.attr(Attrib::kShapeCoords));

    // Adjust the interior border vertices to make the border one pixel wide. 0.75 is a special
    // value to indicate these points.
    v->codeAppendf("if (abs(%s.x) == 0.75) "
                       "bloatedShapeCoords.x = cornerSign.x * innerEdge.x;",
                       fInputs.attr(Attrib::kShapeCoords));
    v->codeAppendf("if (abs(%s.y) == 0.75) "
                       "bloatedShapeCoords.y = cornerSign.y * innerEdge.y;",
                       fInputs.attr(Attrib::kShapeCoords));
}

void GLSLInstanceProcessor::BackendCoverage::onSetupRRect(GrGLSLVertexBuilder* v) {
    // The geometry is laid out in such a way that rectCoverage will be 0 and 1 on the vertices, but
    // we still need to recompute this value because when the rrect gets thinner than one pixel, the
    // interior edge of the border will necessarily clamp, and we need to match the AA behavior of
    // the arc segments (i.e. distance from bloated edge only; ignoring the fact that the pixel
    // actully has less coverage because it's not completely inside the opposite edge.)
    v->codeAppend("vec2 d = shapeHalfSize + 0.5 - abs(bloatedShapeCoords) * shapeHalfSize;");
    v->codeAppend("rectCoverage = min(d.x, d.y);");

    SkASSERT(!fShapeIsCircle);
    // The AA border does not get closer than one half pixel to the edge of the rect, so to get a
    // smooth transition from flat edge to arc, we don't allow the radii to be smaller than one half
    // pixel. (We don't worry about the transition on the opposite side when a radius is so large
    // that the border clamped on that side.)
    v->codeAppendf("vec2 clampedRadii = max(radii, bloat);");
    v->codeAppendf("%s = (cornerSign * bloatedShapeCoords + clampedRadii - vec2(1)) * "
                        "shapeHalfSize;", fEllipseCoords.vsOut());
    v->codeAppendf("%s = 1.0 / (clampedRadii * clampedRadii * shapeHalfSize * shapeHalfSize);",
                   fEllipseName.vsOut());
}

void GLSLInstanceProcessor::BackendCoverage::onInitInnerShape(GrGLSLVaryingHandler* varyingHandler,
                                                              GrGLSLVertexBuilder* v) {
    v->codeAppend("vec2 innerShapeHalfSize = shapeHalfSize / outer2Inner.xy;");

    if (kOval_ShapeFlag == fBatchInfo.fInnerShapeTypes) {
        varyingHandler->addVarying("innerEllipseCoords", &fInnerEllipseCoords,
                                   kMedium_GrSLPrecision);
        varyingHandler->addFlatVarying("innerEllipseName", &fInnerEllipseName, kHigh_GrSLPrecision);
    } else {
        varyingHandler->addVarying("distanceToInnerEdge", &fDistanceToInnerEdge,
                                   kMedium_GrSLPrecision);
        varyingHandler->addFlatVarying("innerShapeBloatedHalfSize", &fInnerShapeBloatedHalfSize,
                                       kMedium_GrSLPrecision);
        if (kRect_ShapeFlag != fBatchInfo.fInnerShapeTypes) {
            varyingHandler->addVarying("innerShapeCoords", &fInnerShapeCoords,
                                       kMedium_GrSLPrecision);
            varyingHandler->addFlatVarying("innerEllipseName", &fInnerEllipseName,
                                           kHigh_GrSLPrecision);
            varyingHandler->addFlatVarying("innerRRect", &fInnerRRect, kMedium_GrSLPrecision);
        }
    }
}

void GLSLInstanceProcessor::BackendCoverage::setupInnerRect(GrGLSLVertexBuilder* v) {
    if (fInnerRRect.vsOut()) {
        // The fragment shader will generalize every inner shape as a round rect. Since this one
        // is a rect, we simply emit bogus parameters for the round rect (effectively negative
        // radii) that ensure the fragment shader always takes the "emitRect" codepath.
        v->codeAppendf("%s.xy = abs(outer2Inner.xy) * (1.0 + bloat) + abs(outer2Inner.zw);",
                       fInnerRRect.vsOut());
    }
}

void GLSLInstanceProcessor::BackendCoverage::setupInnerOval(GrGLSLVertexBuilder* v) {
    v->codeAppendf("%s = 1.0 / (innerShapeHalfSize * innerShapeHalfSize);",
                   fInnerEllipseName.vsOut());
    if (fInnerEllipseCoords.vsOut()) {
        v->codeAppendf("%s = innerShapeCoords * innerShapeHalfSize;", fInnerEllipseCoords.vsOut());
    }
    if (fInnerRRect.vsOut()) {
        v->codeAppendf("%s = vec4(0, 0, innerShapeHalfSize);", fInnerRRect.vsOut());
    }
}

void GLSLInstanceProcessor::BackendCoverage::onSetupInnerSimpleRRect(GrGLSLVertexBuilder* v) {
    // The distance to ellipse formula doesn't work well when the radii are less than half a pixel.
    v->codeAppend ("innerRadii = max(innerRadii, bloat);");
    v->codeAppendf("%s = 1.0 / (innerRadii * innerRadii * innerShapeHalfSize * "
                               "innerShapeHalfSize);",
                   fInnerEllipseName.vsOut());
    v->codeAppendf("%s = vec4(1.0 - innerRadii, innerShapeHalfSize);", fInnerRRect.vsOut());
}

void GLSLInstanceProcessor::BackendCoverage::onEmitCode(GrGLSLVertexBuilder* v,
                                                        GrGLSLPPFragmentBuilder* f,
                                                        const char* outCoverage,
                                                        const char* outColor) {
    if (fColorTimesRectCoverage.vsOut()) {
        SkASSERT(!fRectCoverage.vsOut());
        v->codeAppendf("%s = %s * rectCoverage;",
                       fColorTimesRectCoverage.vsOut(), fInputs.attr(Attrib::kColor));
    }
    if (fRectCoverage.vsOut()) {
        SkASSERT(!fColorTimesRectCoverage.vsOut());
        v->codeAppendf("%s = rectCoverage;", fRectCoverage.vsOut());
    }

    SkString coverage("float coverage");
    if (f->getProgramBuilder()->glslCaps()->usesPrecisionModifiers()) {
        coverage.prependf("lowp ");
    }
    if (fBatchInfo.fInnerShapeTypes || (!fTweakAlphaForCoverage && fTriangleIsArc.fsIn())) {
        f->codeAppendf("%s;", coverage.c_str());
        coverage = "coverage";
    }
    if (fTriangleIsArc.fsIn()) {
        f->codeAppendf("if (%s == 0) {", fTriangleIsArc.fsIn());
        this->emitRect(f, coverage.c_str(), outColor);
        f->codeAppend ("} else {");
        if (fShapeIsCircle) {
            this->emitCircle(f, coverage.c_str());
        } else {
            bool ellipseCoordsMayBeNegative = SkToBool(fBatchInfo.fShapeTypes & kOval_ShapeFlag);
            this->emitArc(f, fEllipseCoords.fsIn(), fEllipseName.fsIn(),
                          true /*ellipseCoordsNeedClamp*/, ellipseCoordsMayBeNegative,
                          coverage.c_str());
        }
        if (fTweakAlphaForCoverage) {
            f->codeAppendf("%s = %s * coverage;", outColor, fColor.fsIn());
        }
        f->codeAppend ("}");
    } else {
        this->emitRect(f, coverage.c_str(), outColor);
    }

    if (fBatchInfo.fInnerShapeTypes) {
        f->codeAppendf("// Inner shape.\n");
        SkString innerCoverageDecl("float innerCoverage");
        if (f->getProgramBuilder()->glslCaps()->usesPrecisionModifiers()) {
            innerCoverageDecl.prependf("lowp ");
        }
        if (kOval_ShapeFlag == fBatchInfo.fInnerShapeTypes) {
            this->emitArc(f, fInnerEllipseCoords.fsIn(), fInnerEllipseName.fsIn(),
                          true /*ellipseCoordsNeedClamp*/, true /*ellipseCoordsMayBeNegative*/,
                          innerCoverageDecl.c_str());
        } else {
            v->codeAppendf("%s = innerShapeCoords * innerShapeHalfSize;",
                           fDistanceToInnerEdge.vsOut());
            v->codeAppendf("%s = innerShapeHalfSize + 0.5;", fInnerShapeBloatedHalfSize.vsOut());

            if (kRect_ShapeFlag == fBatchInfo.fInnerShapeTypes) {
                this->emitInnerRect(f, innerCoverageDecl.c_str());
            } else {
                f->codeAppendf("%s = 0.0;", innerCoverageDecl.c_str());
                f->appendPrecisionModifier(kMedium_GrSLPrecision);
                f->codeAppendf("vec2 distanceToArcEdge = abs(%s) - %s.xy;",
                               fInnerShapeCoords.fsIn(), fInnerRRect.fsIn());
                f->codeAppend ("if (any(lessThan(distanceToArcEdge, vec2(1e-5)))) {");
                this->emitInnerRect(f, "innerCoverage");
                f->codeAppend ("} else {");
                f->appendPrecisionModifier(kMedium_GrSLPrecision);
                f->codeAppendf(    "vec2 ellipseCoords = distanceToArcEdge * %s.zw;",
                                   fInnerRRect.fsIn());
                this->emitArc(f, "ellipseCoords", fInnerEllipseName.fsIn(),
                              false /*ellipseCoordsNeedClamp*/,
                              false /*ellipseCoordsMayBeNegative*/, "innerCoverage");
                f->codeAppend ("}");
            }
        }
        f->codeAppendf("%s = vec4(max(coverage - innerCoverage, 0.0));", outCoverage);
    } else if (!fTweakAlphaForCoverage) {
        f->codeAppendf("%s = vec4(coverage);", outCoverage);
    }
}

void GLSLInstanceProcessor::BackendCoverage::emitRect(GrGLSLPPFragmentBuilder* f,
                                                      const char* outCoverage,
                                                      const char* outColor) {
    if (fColorTimesRectCoverage.fsIn()) {
        f->codeAppendf("%s = %s;", outColor, fColorTimesRectCoverage.fsIn());
    } else if (fTweakAlphaForCoverage) {
        // We are drawing just ovals. The interior rect always has 100% coverage.
        f->codeAppendf("%s = %s;", outColor, fColor.fsIn());
    } else if (fRectCoverage.fsIn()) {
        f->codeAppendf("%s = %s;", outCoverage, fRectCoverage.fsIn());
    } else {
        f->codeAppendf("%s = 1.0;", outCoverage);
    }
}

void GLSLInstanceProcessor::BackendCoverage::emitCircle(GrGLSLPPFragmentBuilder* f,
                                                        const char* outCoverage) {
    // TODO: circleCoords = max(circleCoords, 0) if we decide to do this optimization on rrects.
    SkASSERT(!(kRRect_ShapesMask & fBatchInfo.fShapeTypes));
    f->appendPrecisionModifier(kMedium_GrSLPrecision);
    f->codeAppendf("float distanceToEdge = %s - length(%s);",
                   fBloatedRadius.fsIn(), fEllipseCoords.fsIn());
    f->codeAppendf("%s = clamp(distanceToEdge, 0.0, 1.0);", outCoverage);
}

void GLSLInstanceProcessor::BackendCoverage::emitArc(GrGLSLPPFragmentBuilder* f,
                                                     const char* ellipseCoords,
                                                     const char* ellipseName,
                                                     bool ellipseCoordsNeedClamp,
                                                     bool ellipseCoordsMayBeNegative,
                                                     const char* outCoverage) {
    SkASSERT(!ellipseCoordsMayBeNegative || ellipseCoordsNeedClamp);
    if (ellipseCoordsNeedClamp) {
        // This serves two purposes:
        //  - To restrict the arcs of rounded rects to their positive quadrants.
        //  - To avoid inversesqrt(0) in the ellipse formula.
        f->appendPrecisionModifier(kMedium_GrSLPrecision);
        if (ellipseCoordsMayBeNegative) {
            f->codeAppendf("vec2 ellipseClampedCoords = max(abs(%s), vec2(1e-4));", ellipseCoords);
        } else {
            f->codeAppendf("vec2 ellipseClampedCoords = max(%s, vec2(1e-4));", ellipseCoords);
        }
        ellipseCoords = "ellipseClampedCoords";
    }
    // ellipseCoords are in pixel space and ellipseName is 1 / rx^2, 1 / ry^2.
    f->appendPrecisionModifier(kHigh_GrSLPrecision);
    f->codeAppendf("vec2 Z = %s * %s;", ellipseCoords, ellipseName);
    // implicit is the evaluation of (x/rx)^2 + (y/ry)^2 - 1.
    f->appendPrecisionModifier(kHigh_GrSLPrecision);
    f->codeAppendf("float implicit = dot(Z, %s) - 1.0;", ellipseCoords);
    // gradDot is the squared length of the gradient of the implicit.
    f->appendPrecisionModifier(kHigh_GrSLPrecision);
    f->codeAppendf("float gradDot = 4.0 * dot(Z, Z);");
    f->appendPrecisionModifier(kMedium_GrSLPrecision);
    f->codeAppend ("float approxDist = implicit * inversesqrt(gradDot);");
    f->codeAppendf("%s = clamp(0.5 - approxDist, 0.0, 1.0);", outCoverage);
}

void GLSLInstanceProcessor::BackendCoverage::emitInnerRect(GrGLSLPPFragmentBuilder* f,
                                                           const char* outCoverage) {
    f->appendPrecisionModifier(kLow_GrSLPrecision);
    f->codeAppendf("vec2 c = %s - abs(%s);",
                   fInnerShapeBloatedHalfSize.fsIn(), fDistanceToInnerEdge.fsIn());
    f->codeAppendf("%s = clamp(min(c.x, c.y), 0.0, 1.0);", outCoverage);
}

////////////////////////////////////////////////////////////////////////////////////////////////////

class GLSLInstanceProcessor::BackendMultisample : public Backend {
public:
    BackendMultisample(BatchInfo batchInfo, const VertexInputs& inputs, int effectiveSampleCnt)
        : INHERITED(batchInfo, inputs),
          fEffectiveSampleCnt(effectiveSampleCnt),
          fShapeCoords(kVec2f_GrSLType),
          fShapeInverseMatrix(kMat22f_GrSLType),
          fFragShapeHalfSpan(kVec2f_GrSLType),
          fArcTest(kVec2f_GrSLType),
          fArcInverseMatrix(kMat22f_GrSLType),
          fFragArcHalfSpan(kVec2f_GrSLType),
          fEarlyAccept(kInt_GrSLType),
          fInnerShapeInverseMatrix(kMat22f_GrSLType),
          fFragInnerShapeHalfSpan(kVec2f_GrSLType) {
        fRectTrianglesMaySplit = fBatchInfo.fHasPerspective;
        fNeedsNeighborRadii = this->isMixedSampled() && !fBatchInfo.fHasPerspective;
    }

private:
    bool isMixedSampled() const { return AntialiasMode::kMixedSamples == fBatchInfo.fAntialiasMode; }

    void onInit(GrGLSLVaryingHandler*, GrGLSLVertexBuilder*) override;
    void setupRect(GrGLSLVertexBuilder*) override;
    void setupOval(GrGLSLVertexBuilder*) override;
    void adjustRRectVertices(GrGLSLVertexBuilder*) override;
    void onSetupRRect(GrGLSLVertexBuilder*) override;

    void onInitInnerShape(GrGLSLVaryingHandler*, GrGLSLVertexBuilder*) override;
    void setupInnerRect(GrGLSLVertexBuilder*) override;
    void setupInnerOval(GrGLSLVertexBuilder*) override;
    void onSetupInnerSimpleRRect(GrGLSLVertexBuilder*) override;

    void onEmitCode(GrGLSLVertexBuilder*, GrGLSLPPFragmentBuilder*, const char*,
                    const char*) override;

    struct EmitShapeCoords {
        const GrGLSLVarying*   fVarying;
        const char*            fInverseMatrix;
        const char*            fFragHalfSpan;
    };

    struct EmitShapeOpts {
        bool fIsTightGeometry;
        bool fResolveMixedSamples;
        bool fInvertCoverage;
    };

    void emitRect(GrGLSLPPFragmentBuilder*, const EmitShapeCoords&, const EmitShapeOpts&);
    void emitArc(GrGLSLPPFragmentBuilder*, const EmitShapeCoords&, bool coordsMayBeNegative,
                 bool clampCoords, const EmitShapeOpts&);
    void emitSimpleRRect(GrGLSLPPFragmentBuilder*, const EmitShapeCoords&, const char* rrect,
                         const EmitShapeOpts&);
    void interpolateAtSample(GrGLSLPPFragmentBuilder*, const GrGLSLVarying&, const char* sampleIdx,
                             const char* interpolationMatrix);
    void acceptOrRejectWholeFragment(GrGLSLPPFragmentBuilder*, bool inside, const EmitShapeOpts&);
    void acceptCoverageMask(GrGLSLPPFragmentBuilder*, const char* shapeMask, const EmitShapeOpts&,
                            bool maybeSharedEdge = true);

    int                fEffectiveSampleCnt;
    bool               fRectTrianglesMaySplit;
    GrGLSLVertToFrag   fShapeCoords;
    GrGLSLVertToFrag   fShapeInverseMatrix;
    GrGLSLVertToFrag   fFragShapeHalfSpan;
    GrGLSLVertToFrag   fArcTest;
    GrGLSLVertToFrag   fArcInverseMatrix;
    GrGLSLVertToFrag   fFragArcHalfSpan;
    GrGLSLVertToFrag   fEarlyAccept;
    GrGLSLVertToFrag   fInnerShapeInverseMatrix;
    GrGLSLVertToFrag   fFragInnerShapeHalfSpan;
    SkString           fSquareFun;

    typedef Backend INHERITED;
};

void GLSLInstanceProcessor::BackendMultisample::onInit(GrGLSLVaryingHandler* varyingHandler,
                                                       GrGLSLVertexBuilder* v) {
    if (!this->isMixedSampled()) {
        if (kRect_ShapeFlag != fBatchInfo.fShapeTypes) {
            varyingHandler->addFlatVarying("triangleIsArc", &fTriangleIsArc, kLow_GrSLPrecision);
            varyingHandler->addVarying("arcCoords", &fArcCoords, kHigh_GrSLPrecision);
            if (!fBatchInfo.fHasPerspective) {
                varyingHandler->addFlatVarying("arcInverseMatrix", &fArcInverseMatrix,
                                               kHigh_GrSLPrecision);
                varyingHandler->addFlatVarying("fragArcHalfSpan", &fFragArcHalfSpan,
                                               kHigh_GrSLPrecision);
            }
        } else if (!fBatchInfo.fInnerShapeTypes) {
            return;
        }
    } else {
        varyingHandler->addVarying("shapeCoords", &fShapeCoords, kHigh_GrSLPrecision);
        if (!fBatchInfo.fHasPerspective) {
            varyingHandler->addFlatVarying("shapeInverseMatrix", &fShapeInverseMatrix,
                                           kHigh_GrSLPrecision);
            varyingHandler->addFlatVarying("fragShapeHalfSpan", &fFragShapeHalfSpan,
                                           kHigh_GrSLPrecision);
        }
        if (fBatchInfo.fShapeTypes & kRRect_ShapesMask) {
            varyingHandler->addVarying("arcCoords", &fArcCoords, kHigh_GrSLPrecision);
            varyingHandler->addVarying("arcTest", &fArcTest, kHigh_GrSLPrecision);
            if (!fBatchInfo.fHasPerspective) {
                varyingHandler->addFlatVarying("arcInverseMatrix", &fArcInverseMatrix,
                                               kHigh_GrSLPrecision);
                varyingHandler->addFlatVarying("fragArcHalfSpan", &fFragArcHalfSpan,
                                               kHigh_GrSLPrecision);
            }
        } else if (fBatchInfo.fShapeTypes & kOval_ShapeFlag) {
            fArcCoords = fShapeCoords;
            fArcInverseMatrix = fShapeInverseMatrix;
            fFragArcHalfSpan = fFragShapeHalfSpan;
            if (fBatchInfo.fShapeTypes & kRect_ShapeFlag) {
                varyingHandler->addFlatVarying("triangleIsArc", &fTriangleIsArc,
                                               kLow_GrSLPrecision);
            }
        }
        if (kRect_ShapeFlag != fBatchInfo.fShapeTypes) {
           v->defineConstantf("int", "SAMPLE_MASK_ALL", "0x%x", (1 << fEffectiveSampleCnt) - 1);
           varyingHandler->addFlatVarying("earlyAccept", &fEarlyAccept, kHigh_GrSLPrecision);
        }
    }
    if (!fBatchInfo.fHasPerspective) {
        v->codeAppend("mat2 shapeInverseMatrix = inverse(mat2(shapeMatrix));");
        v->codeAppend("vec2 fragShapeSpan = abs(vec4(shapeInverseMatrix).xz) + "
                                           "abs(vec4(shapeInverseMatrix).yw);");
    }
}

void GLSLInstanceProcessor::BackendMultisample::setupRect(GrGLSLVertexBuilder* v) {
    if (fShapeCoords.vsOut()) {
        v->codeAppendf("%s = %s;", fShapeCoords.vsOut(), this->outShapeCoords());
    }
    if (fShapeInverseMatrix.vsOut()) {
        v->codeAppendf("%s = shapeInverseMatrix;", fShapeInverseMatrix.vsOut());
    }
    if (fFragShapeHalfSpan.vsOut()) {
        v->codeAppendf("%s = 0.5 * fragShapeSpan;", fFragShapeHalfSpan.vsOut());
    }
    if (fArcTest.vsOut()) {
        // Pick a value that is not > 0.
        v->codeAppendf("%s = vec2(0);", fArcTest.vsOut());
    }
    if (fTriangleIsArc.vsOut()) {
        v->codeAppendf("%s = 0;", fTriangleIsArc.vsOut());
    }
    if (fEarlyAccept.vsOut()) {
        v->codeAppendf("%s = SAMPLE_MASK_ALL;", fEarlyAccept.vsOut());
    }
}

void GLSLInstanceProcessor::BackendMultisample::setupOval(GrGLSLVertexBuilder* v) {
    v->codeAppendf("%s = abs(%s);", fArcCoords.vsOut(), this->outShapeCoords());
    if (fArcInverseMatrix.vsOut()) {
        v->codeAppendf("vec2 s = sign(%s);", this->outShapeCoords());
        v->codeAppendf("%s = shapeInverseMatrix * mat2(s.x, 0, 0 , s.y);",
                       fArcInverseMatrix.vsOut());
    }
    if (fFragArcHalfSpan.vsOut()) {
        v->codeAppendf("%s = 0.5 * fragShapeSpan;", fFragArcHalfSpan.vsOut());
    }
    if (fArcTest.vsOut()) {
        // Pick a value that is > 0.
        v->codeAppendf("%s = vec2(1);", fArcTest.vsOut());
    }
    if (fTriangleIsArc.vsOut()) {
        if (!this->isMixedSampled()) {
            v->codeAppendf("%s = %s & 1;",
                           fTriangleIsArc.vsOut(), fInputs.attr(Attrib::kVertexAttrs));
        } else {
            v->codeAppendf("%s = 1;", fTriangleIsArc.vsOut());
        }
    }
    if (fEarlyAccept.vsOut()) {
        v->codeAppendf("%s = ~%s & SAMPLE_MASK_ALL;",
                       fEarlyAccept.vsOut(), fInputs.attr(Attrib::kVertexAttrs));
    }
}

void GLSLInstanceProcessor::BackendMultisample::adjustRRectVertices(GrGLSLVertexBuilder* v) {
    if (!this->isMixedSampled()) {
        INHERITED::adjustRRectVertices(v);
        return;
    }

    if (!fBatchInfo.fHasPerspective) {
        // For the mixed samples algorithm it's best to bloat the corner triangles a bit so that
        // more of the pixels that cross into the arc region are completely inside the shared edges.
        // We also snap to a regular rect if the radii shrink smaller than a pixel.
        v->codeAppend ("vec2 midpt = 0.5 * (neighborRadii - radii);");
        v->codeAppend ("vec2 cornerSize = any(lessThan(radii, fragShapeSpan)) ? "
                           "vec2(0) : min(radii + 0.5 * fragShapeSpan, 1.0 - midpt);");
    } else {
        // TODO: We could still bloat the corner triangle in the perspective case; we would just
        // need to find the screen-space derivative of shape coords at this particular point.
        v->codeAppend ("vec2 cornerSize = any(lessThan(radii, vec2(1e-3))) ? vec2(0) : radii;");
    }

    v->codeAppendf("if (abs(%s.x) == 0.5)"
                       "%s.x = cornerSign.x * (1.0 - cornerSize.x);",
                       fInputs.attr(Attrib::kShapeCoords), fModifiedShapeCoords);
    v->codeAppendf("if (abs(%s.y) == 0.5)"
                       "%s.y = cornerSign.y * (1.0 - cornerSize.y);",
                       fInputs.attr(Attrib::kShapeCoords), fModifiedShapeCoords);
}

void GLSLInstanceProcessor::BackendMultisample::onSetupRRect(GrGLSLVertexBuilder* v) {
    if (fShapeCoords.vsOut()) {
        v->codeAppendf("%s = %s;", fShapeCoords.vsOut(), this->outShapeCoords());
    }
    if (fShapeInverseMatrix.vsOut()) {
        v->codeAppendf("%s = shapeInverseMatrix;", fShapeInverseMatrix.vsOut());
    }
    if (fFragShapeHalfSpan.vsOut()) {
        v->codeAppendf("%s = 0.5 * fragShapeSpan;", fFragShapeHalfSpan.vsOut());
    }
    if (fArcInverseMatrix.vsOut()) {
        v->codeAppend ("vec2 s = cornerSign / radii;");
        v->codeAppendf("%s = shapeInverseMatrix * mat2(s.x, 0, 0, s.y);",
                       fArcInverseMatrix.vsOut());
    }
    if (fFragArcHalfSpan.vsOut()) {
        v->codeAppendf("%s = 0.5 * (abs(vec4(%s).xz) + abs(vec4(%s).yw));",
                       fFragArcHalfSpan.vsOut(), fArcInverseMatrix.vsOut(),
                       fArcInverseMatrix.vsOut());
    }
    if (fArcTest.vsOut()) {
        // The interior triangles are laid out as a fan. fArcTest is both distances from shared
        // edges of a fan triangle to a point within that triangle. fArcTest is used to check if a
        // fragment is too close to either shared edge, in which case we point sample the shape as a
        // rect at that point in order to guarantee the mixed samples discard logic works correctly.
        v->codeAppendf("%s = (cornerSize == vec2(0)) ? vec2(0) : "
                       "cornerSign * %s * mat2(1, cornerSize.x - 1.0, cornerSize.y - 1.0, 1);",
                       fArcTest.vsOut(), fModifiedShapeCoords);
        if (!fBatchInfo.fHasPerspective) {
            // Shift the point at which distances to edges are measured from the center of the pixel
            // to the corner. This way the sign of fArcTest will quickly tell us whether a pixel
            // is completely inside the shared edge. Perspective mode will accomplish this same task
            // by finding the derivatives in the fragment shader.
            v->codeAppendf("%s -= 0.5 * (fragShapeSpan.yx * abs(radii - 1.0) + fragShapeSpan);",
                           fArcTest.vsOut());
        }
    }
    if (fEarlyAccept.vsOut()) {
        SkASSERT(this->isMixedSampled());
        v->codeAppendf("%s = all(equal(vec2(1), abs(%s))) ? 0 : SAMPLE_MASK_ALL;",
                       fEarlyAccept.vsOut(), fInputs.attr(Attrib::kShapeCoords));
    }
}

void
GLSLInstanceProcessor::BackendMultisample::onInitInnerShape(GrGLSLVaryingHandler* varyingHandler,
                                                            GrGLSLVertexBuilder* v) {
    varyingHandler->addVarying("innerShapeCoords", &fInnerShapeCoords, kHigh_GrSLPrecision);
    if (kOval_ShapeFlag != fBatchInfo.fInnerShapeTypes &&
        kRect_ShapeFlag != fBatchInfo.fInnerShapeTypes) {
        varyingHandler->addFlatVarying("innerRRect", &fInnerRRect, kHigh_GrSLPrecision);
    }
    if (!fBatchInfo.fHasPerspective) {
        varyingHandler->addFlatVarying("innerShapeInverseMatrix", &fInnerShapeInverseMatrix,
                                       kHigh_GrSLPrecision);
        v->codeAppendf("%s = shapeInverseMatrix * mat2(outer2Inner.x, 0, 0, outer2Inner.y);",
                       fInnerShapeInverseMatrix.vsOut());
        varyingHandler->addFlatVarying("fragInnerShapeHalfSpan", &fFragInnerShapeHalfSpan,
                                       kHigh_GrSLPrecision);
        v->codeAppendf("%s = 0.5 * fragShapeSpan * outer2Inner.xy;",
                       fFragInnerShapeHalfSpan.vsOut());
    }
}

void GLSLInstanceProcessor::BackendMultisample::setupInnerRect(GrGLSLVertexBuilder* v) {
    if (fInnerRRect.vsOut()) {
        // The fragment shader will generalize every inner shape as a round rect. Since this one
        // is a rect, we simply emit bogus parameters for the round rect (negative radii) that
        // ensure the fragment shader always takes the "sample as rect" codepath.
        v->codeAppendf("%s = vec4(2.0 * (inner.zw - inner.xy) / (outer.zw - outer.xy), vec2(0));",
                       fInnerRRect.vsOut());
    }
}

void GLSLInstanceProcessor::BackendMultisample::setupInnerOval(GrGLSLVertexBuilder* v) {
    if (fInnerRRect.vsOut()) {
        v->codeAppendf("%s = vec4(0, 0, 1, 1);", fInnerRRect.vsOut());
    }
}

void GLSLInstanceProcessor::BackendMultisample::onSetupInnerSimpleRRect(GrGLSLVertexBuilder* v) {
    // Avoid numeric instability by not allowing the inner radii to get smaller than 1/10th pixel.
    if (fFragInnerShapeHalfSpan.vsOut()) {
        v->codeAppendf("innerRadii = max(innerRadii, 2e-1 * %s);", fFragInnerShapeHalfSpan.vsOut());
    } else {
        v->codeAppend ("innerRadii = max(innerRadii, vec2(1e-4));");
    }
    v->codeAppendf("%s = vec4(1.0 - innerRadii, 1.0 / innerRadii);", fInnerRRect.vsOut());
}

void GLSLInstanceProcessor::BackendMultisample::onEmitCode(GrGLSLVertexBuilder*,
                                                           GrGLSLPPFragmentBuilder* f,
                                                           const char*, const char*) {
    f->defineConstant("SAMPLE_COUNT", fEffectiveSampleCnt);
    if (this->isMixedSampled()) {
        f->defineConstantf("int", "SAMPLE_MASK_ALL", "0x%x", (1 << fEffectiveSampleCnt) - 1);
        f->defineConstantf("int", "SAMPLE_MASK_MSB", "0x%x", 1 << (fEffectiveSampleCnt - 1));
    }

    if (kRect_ShapeFlag != (fBatchInfo.fShapeTypes | fBatchInfo.fInnerShapeTypes)) {
        GrGLSLShaderVar x("x", kVec2f_GrSLType, GrGLSLShaderVar::kNonArray, kHigh_GrSLPrecision);
        f->emitFunction(kFloat_GrSLType, "square", 1, &x, "return dot(x, x);", &fSquareFun);
    }

    EmitShapeCoords shapeCoords;
    shapeCoords.fVarying = &fShapeCoords;
    shapeCoords.fInverseMatrix = fShapeInverseMatrix.fsIn();
    shapeCoords.fFragHalfSpan = fFragShapeHalfSpan.fsIn();

    EmitShapeCoords arcCoords;
    arcCoords.fVarying = &fArcCoords;
    arcCoords.fInverseMatrix = fArcInverseMatrix.fsIn();
    arcCoords.fFragHalfSpan = fFragArcHalfSpan.fsIn();
    bool clampArcCoords = this->isMixedSampled() && (fBatchInfo.fShapeTypes & kRRect_ShapesMask);

    EmitShapeOpts opts;
    opts.fIsTightGeometry = true;
    opts.fResolveMixedSamples = this->isMixedSampled();
    opts.fInvertCoverage = false;

    if (fBatchInfo.fHasPerspective && fBatchInfo.fInnerShapeTypes) {
        // This determines if the fragment should consider the inner shape in its sample mask.
        // We take the derivative early in case discards may occur before we get to the inner shape.
        f->appendPrecisionModifier(kHigh_GrSLPrecision);
        f->codeAppendf("vec2 fragInnerShapeApproxHalfSpan = 0.5 * fwidth(%s);",
                       fInnerShapeCoords.fsIn());
    }

    if (!this->isMixedSampled()) {
        SkASSERT(!fArcTest.fsIn());
        if (fTriangleIsArc.fsIn()) {
            f->codeAppendf("if (%s != 0) {", fTriangleIsArc.fsIn());
            this->emitArc(f, arcCoords, false, clampArcCoords, opts);

            f->codeAppend ("}");
        }
    } else {
        const char* arcTest = fArcTest.fsIn();
        if (arcTest && fBatchInfo.fHasPerspective) {
            // The non-perspective version accounts for fwidth() in the vertex shader.
            // We make sure to take the derivative here, before a neighbor pixel may early accept.
            f->appendPrecisionModifier(kHigh_GrSLPrecision);
            f->codeAppendf("vec2 arcTest = %s - 0.5 * fwidth(%s);",
                           fArcTest.fsIn(), fArcTest.fsIn());
            arcTest = "arcTest";
        }
        const char* earlyAccept = fEarlyAccept.fsIn() ? fEarlyAccept.fsIn() : "SAMPLE_MASK_ALL";
        f->codeAppendf("if (gl_SampleMaskIn[0] == %s) {", earlyAccept);
        f->overrideSampleCoverage(earlyAccept);
        f->codeAppend ("} else {");
        if (arcTest) {
            // At this point, if the sample mask is all set it means we are inside an arc triangle.
            f->codeAppendf("if (gl_SampleMaskIn[0] == SAMPLE_MASK_ALL || "
                               "all(greaterThan(%s, vec2(0)))) {", arcTest);
            this->emitArc(f, arcCoords, false, clampArcCoords, opts);
            f->codeAppend ("} else {");
            this->emitRect(f, shapeCoords, opts);
            f->codeAppend ("}");
        } else if (fTriangleIsArc.fsIn()) {
            f->codeAppendf("if (%s == 0) {", fTriangleIsArc.fsIn());
            this->emitRect(f, shapeCoords, opts);
            f->codeAppend ("} else {");
            this->emitArc(f, arcCoords, false, clampArcCoords, opts);
            f->codeAppend ("}");
        } else if (fBatchInfo.fShapeTypes == kOval_ShapeFlag) {
            this->emitArc(f, arcCoords, false, clampArcCoords, opts);
        } else {
            SkASSERT(fBatchInfo.fShapeTypes == kRect_ShapeFlag);
            this->emitRect(f, shapeCoords, opts);
        }
        f->codeAppend ("}");
    }

    if (fBatchInfo.fInnerShapeTypes) {
        f->codeAppendf("// Inner shape.\n");

        EmitShapeCoords innerShapeCoords;
        innerShapeCoords.fVarying = &fInnerShapeCoords;
        if (!fBatchInfo.fHasPerspective) {
            innerShapeCoords.fInverseMatrix = fInnerShapeInverseMatrix.fsIn();
            innerShapeCoords.fFragHalfSpan = fFragInnerShapeHalfSpan.fsIn();
        }

        EmitShapeOpts innerOpts;
        innerOpts.fIsTightGeometry = false;
        innerOpts.fResolveMixedSamples = false; // Mixed samples are resolved in the outer shape.
        innerOpts.fInvertCoverage = true;

        if (kOval_ShapeFlag == fBatchInfo.fInnerShapeTypes) {
            this->emitArc(f, innerShapeCoords, true, false, innerOpts);
        } else {
            f->codeAppendf("if (all(lessThan(abs(%s), 1.0 + %s))) {", fInnerShapeCoords.fsIn(),
                           !fBatchInfo.fHasPerspective ? innerShapeCoords.fFragHalfSpan
                                                       : "fragInnerShapeApproxHalfSpan"); // Above.
            if (kRect_ShapeFlag == fBatchInfo.fInnerShapeTypes) {
                this->emitRect(f, innerShapeCoords, innerOpts);
            } else {
                this->emitSimpleRRect(f, innerShapeCoords, fInnerRRect.fsIn(), innerOpts);
            }
            f->codeAppend ("}");
        }
    }
}

void GLSLInstanceProcessor::BackendMultisample::emitRect(GrGLSLPPFragmentBuilder* f,
                                                         const EmitShapeCoords& coords,
                                                         const EmitShapeOpts& opts) {
    // Full MSAA doesn't need to do anything to draw a rect.
    SkASSERT(!opts.fIsTightGeometry || opts.fResolveMixedSamples);
    if (coords.fFragHalfSpan) {
        f->codeAppendf("if (all(lessThanEqual(abs(%s), 1.0 - %s))) {",
                       coords.fVarying->fsIn(), coords.fFragHalfSpan);
        // The entire pixel is inside the rect.
        this->acceptOrRejectWholeFragment(f, true, opts);
        f->codeAppend ("} else ");
        if (opts.fIsTightGeometry && !fRectTrianglesMaySplit) {
            f->codeAppendf("if (any(lessThan(abs(%s), 1.0 - %s))) {",
                           coords.fVarying->fsIn(), coords.fFragHalfSpan);
            // The pixel falls on an edge of the rectangle and is known to not be on a shared edge.
            this->acceptCoverageMask(f, "gl_SampleMaskIn[0]", opts, false);
            f->codeAppend ("} else");
        }
        f->codeAppend ("{");
    }
    f->codeAppend ("int rectMask = 0;");
    f->codeAppend ("for (int i = 0; i < SAMPLE_COUNT; i++) {");
    f->appendPrecisionModifier(kHigh_GrSLPrecision);
    f->codeAppend (    "vec2 pt = ");
    this->interpolateAtSample(f, *coords.fVarying, "i", coords.fInverseMatrix);
    f->codeAppend (    ";");
    f->codeAppend (    "if (all(lessThan(abs(pt), vec2(1)))) rectMask |= (1 << i);");
    f->codeAppend ("}");
    this->acceptCoverageMask(f, "rectMask", opts);
    if (coords.fFragHalfSpan) {
        f->codeAppend ("}");
    }
}

void GLSLInstanceProcessor::BackendMultisample::emitArc(GrGLSLPPFragmentBuilder* f,
                                                        const EmitShapeCoords& coords,
                                                        bool coordsMayBeNegative, bool clampCoords,
                                                        const EmitShapeOpts& opts) {
    if (coords.fFragHalfSpan) {
        SkString absArcCoords;
        absArcCoords.printf(coordsMayBeNegative ? "abs(%s)" : "%s", coords.fVarying->fsIn());
        if (clampCoords) {
            f->codeAppendf("if (%s(max(%s + %s, vec2(0))) < 1.0) {",
                           fSquareFun.c_str(), absArcCoords.c_str(), coords.fFragHalfSpan);
        } else {
            f->codeAppendf("if (%s(%s + %s) < 1.0) {",
                           fSquareFun.c_str(), absArcCoords.c_str(), coords.fFragHalfSpan);
        }
        // The entire pixel is inside the arc.
        this->acceptOrRejectWholeFragment(f, true, opts);
        f->codeAppendf("} else if (%s(max(%s - %s, vec2(0))) >= 1.0) {",
                       fSquareFun.c_str(), absArcCoords.c_str(), coords.fFragHalfSpan);
        // The entire pixel is outside the arc.
        this->acceptOrRejectWholeFragment(f, false, opts);
        f->codeAppend ("} else {");
    }
    f->codeAppend (    "int arcMask = 0;");
    f->codeAppend (    "for (int i = 0; i < SAMPLE_COUNT; i++) {");
    f->appendPrecisionModifier(kHigh_GrSLPrecision);
    f->codeAppend (        "vec2 pt = ");
    this->interpolateAtSample(f, *coords.fVarying, "i", coords.fInverseMatrix);
    f->codeAppend (        ";");
    if (clampCoords) {
        SkASSERT(!coordsMayBeNegative);
        f->codeAppend (    "pt = max(pt, vec2(0));");
    }
    f->codeAppendf(        "if (%s(pt) < 1.0) arcMask |= (1 << i);", fSquareFun.c_str());
    f->codeAppend (    "}");
    this->acceptCoverageMask(f, "arcMask", opts);
    if (coords.fFragHalfSpan) {
        f->codeAppend ("}");
    }
}

void GLSLInstanceProcessor::BackendMultisample::emitSimpleRRect(GrGLSLPPFragmentBuilder* f,
                                                                const EmitShapeCoords& coords,
                                                                const char* rrect,
                                                                const EmitShapeOpts& opts) {
    f->appendPrecisionModifier(kHigh_GrSLPrecision);
    f->codeAppendf("vec2 distanceToArcEdge = abs(%s) - %s.xy;", coords.fVarying->fsIn(), rrect);
    f->codeAppend ("if (any(lessThan(distanceToArcEdge, vec2(0)))) {");
    this->emitRect(f, coords, opts);
    f->codeAppend ("} else {");
    if (coords.fInverseMatrix && coords.fFragHalfSpan) {
        f->appendPrecisionModifier(kHigh_GrSLPrecision);
        f->codeAppendf("vec2 rrectCoords = distanceToArcEdge * %s.zw;", rrect);
        f->appendPrecisionModifier(kHigh_GrSLPrecision);
        f->codeAppendf("vec2 fragRRectHalfSpan = %s * %s.zw;", coords.fFragHalfSpan, rrect);
        f->codeAppendf("if (%s(rrectCoords + fragRRectHalfSpan) <= 1.0) {", fSquareFun.c_str());
        // The entire pixel is inside the round rect.
        this->acceptOrRejectWholeFragment(f, true, opts);
        f->codeAppendf("} else if (%s(max(rrectCoords - fragRRectHalfSpan, vec2(0))) >= 1.0) {",
                       fSquareFun.c_str());
        // The entire pixel is outside the round rect.
        this->acceptOrRejectWholeFragment(f, false, opts);
        f->codeAppend ("} else {");
        f->appendPrecisionModifier(kHigh_GrSLPrecision);
        f->codeAppendf(    "vec2 s = %s.zw * sign(%s);", rrect, coords.fVarying->fsIn());
        f->appendPrecisionModifier(kHigh_GrSLPrecision);
        f->codeAppendf(    "mat2 innerRRectInverseMatrix = %s * mat2(s.x, 0, 0, s.y);",
                           coords.fInverseMatrix);
        f->appendPrecisionModifier(kHigh_GrSLPrecision);
        f->codeAppend (    "int rrectMask = 0;");
        f->codeAppend (    "for (int i = 0; i < SAMPLE_COUNT; i++) {");
        f->appendPrecisionModifier(kHigh_GrSLPrecision);
        f->codeAppend (        "vec2 pt = rrectCoords + ");
        f->appendOffsetToSample("i", GrGLSLFPFragmentBuilder::kSkiaDevice_Coordinates);
        f->codeAppend (                  "* innerRRectInverseMatrix;");
        f->codeAppendf(        "if (%s(max(pt, vec2(0))) < 1.0) rrectMask |= (1 << i);",
                               fSquareFun.c_str());
        f->codeAppend (    "}");
        this->acceptCoverageMask(f, "rrectMask", opts);
        f->codeAppend ("}");
    } else {
        f->codeAppend ("int rrectMask = 0;");
        f->codeAppend ("for (int i = 0; i < SAMPLE_COUNT; i++) {");
        f->appendPrecisionModifier(kHigh_GrSLPrecision);
        f->codeAppend (    "vec2 shapePt = ");
        this->interpolateAtSample(f, *coords.fVarying, "i", nullptr);
        f->codeAppend (    ";");
        f->appendPrecisionModifier(kHigh_GrSLPrecision);
        f->codeAppendf(    "vec2 rrectPt = max(abs(shapePt) - %s.xy, vec2(0)) * %s.zw;",
                           rrect, rrect);
        f->codeAppendf(    "if (%s(rrectPt) < 1.0) rrectMask |= (1 << i);", fSquareFun.c_str());
        f->codeAppend ("}");
        this->acceptCoverageMask(f, "rrectMask", opts);
    }
    f->codeAppend ("}");
}

void GLSLInstanceProcessor::BackendMultisample::interpolateAtSample(GrGLSLPPFragmentBuilder* f,
                                                                  const GrGLSLVarying& varying,
                                                                  const char* sampleIdx,
                                                                  const char* interpolationMatrix) {
    if (interpolationMatrix) {
        f->codeAppendf("(%s + ", varying.fsIn());
        f->appendOffsetToSample(sampleIdx, GrGLSLFPFragmentBuilder::kSkiaDevice_Coordinates);
        f->codeAppendf(" * %s)", interpolationMatrix);
    } else {
        SkAssertResult(
            f->enableFeature(GrGLSLFragmentBuilder::kMultisampleInterpolation_GLSLFeature));
        f->codeAppendf("interpolateAtOffset(%s, ", varying.fsIn());
        f->appendOffsetToSample(sampleIdx, GrGLSLFPFragmentBuilder::kGLSLWindow_Coordinates);
        f->codeAppend(")");
    }
}

void
GLSLInstanceProcessor::BackendMultisample::acceptOrRejectWholeFragment(GrGLSLPPFragmentBuilder* f,
                                                                       bool inside,
                                                                       const EmitShapeOpts& opts) {
    if (inside != opts.fInvertCoverage) { // Accept the entire fragment.
        if (opts.fResolveMixedSamples) {
            // This is a mixed sampled fragment in the interior of the shape. Reassign 100% coverage
            // to one fragment, and drop all other fragments that may fall on this same pixel. Since
            // our geometry is water tight and non-overlapping, we can take advantage of the
            // properties that (1) the incoming sample masks will be disjoint across fragments that
            // fall on a common pixel, and (2) since the entire fragment is inside the shape, each
            // sample's corresponding bit will be set in the incoming sample mask of exactly one
            // fragment.
            f->codeAppend("if ((gl_SampleMaskIn[0] & SAMPLE_MASK_MSB) == 0) {");
            // Drop this fragment.
            if (!fBatchInfo.fCannotDiscard) {
                f->codeAppend("discard;");
            } else {
                f->overrideSampleCoverage("0");
            }
            f->codeAppend("} else {");
            // Override the lone surviving fragment to full coverage.
            f->overrideSampleCoverage("-1");
            f->codeAppend("}");
        }
    } else { // Reject the entire fragment.
        if (!fBatchInfo.fCannotDiscard) {
            f->codeAppend("discard;");
        } else if (opts.fResolveMixedSamples) {
            f->overrideSampleCoverage("0");
        } else {
            f->maskSampleCoverage("0");
        }
    }
}

void GLSLInstanceProcessor::BackendMultisample::acceptCoverageMask(GrGLSLPPFragmentBuilder* f,
                                                                   const char* shapeMask,
                                                                   const EmitShapeOpts& opts,
                                                                   bool maybeSharedEdge) {
    if (opts.fResolveMixedSamples) {
        if (maybeSharedEdge) {
            // This is a mixed sampled fragment, potentially on the outer edge of the shape, with
            // only partial shape coverage. Override the coverage of one fragment to "shapeMask",
            // and drop all other fragments that may fall on this same pixel. Since our geometry is
            // water tight, non-overlapping, and completely contains the shape, this means that each
            // "on" bit from shapeMask is guaranteed to be set in the incoming sample mask of one,
            // and only one, fragment that falls on this same pixel.
            SkASSERT(!opts.fInvertCoverage);
            f->codeAppendf("if ((gl_SampleMaskIn[0] & (1 << findMSB(%s))) == 0) {", shapeMask);
            // Drop this fragment.
            if (!fBatchInfo.fCannotDiscard) {
                f->codeAppend ("discard;");
            } else {
                f->overrideSampleCoverage("0");
            }
            f->codeAppend ("} else {");
            // Override the coverage of the lone surviving fragment to "shapeMask".
            f->overrideSampleCoverage(shapeMask);
            f->codeAppend ("}");
        } else {
            f->overrideSampleCoverage(shapeMask);
        }
    } else {
        f->maskSampleCoverage(shapeMask, opts.fInvertCoverage);
    }
}

////////////////////////////////////////////////////////////////////////////////////////////////////

GLSLInstanceProcessor::Backend*
GLSLInstanceProcessor::Backend::Create(const GrPipeline& pipeline, BatchInfo batchInfo,
                                       const VertexInputs& inputs) {
    switch (batchInfo.fAntialiasMode) {
        default:
            SkFAIL("Unexpected antialias mode.");
        case AntialiasMode::kNone:
            return new BackendNonAA(batchInfo, inputs);
        case AntialiasMode::kCoverage:
            return new BackendCoverage(batchInfo, inputs);
        case AntialiasMode::kMSAA:
        case AntialiasMode::kMixedSamples: {
            const GrRenderTargetPriv& rtp = pipeline.getRenderTarget()->renderTargetPriv();
            const GrGpu::MultisampleSpecs& specs = rtp.getMultisampleSpecs(pipeline);
            return new BackendMultisample(batchInfo, inputs, specs.fEffectiveSampleCnt);
        }
    }
}

////////////////////////////////////////////////////////////////////////////////////////////////////

const ShapeVertex kVertexData[] = {
    // Rectangle.
    {+1, +1, ~0},   /*0*/
    {-1, +1, ~0},   /*1*/
    {-1, -1, ~0},   /*2*/
    {+1, -1, ~0},   /*3*/
    // The next 4 are for the bordered version.
    {+1, +1,  0},   /*4*/
    {-1, +1,  0},   /*5*/
    {-1, -1,  0},   /*6*/
    {+1, -1,  0},   /*7*/

    // Octagon that inscribes the unit circle, cut by an interior unit octagon.
    {+1.000000f,  0.000000f,  0},   /* 8*/
    {+1.000000f, +0.414214f, ~0},   /* 9*/
    {+0.707106f, +0.707106f,  0},   /*10*/
    {+0.414214f, +1.000000f, ~0},   /*11*/
    { 0.000000f, +1.000000f,  0},   /*12*/
    {-0.414214f, +1.000000f, ~0},   /*13*/
    {-0.707106f, +0.707106f,  0},   /*14*/
    {-1.000000f, +0.414214f, ~0},   /*15*/
    {-1.000000f,  0.000000f,  0},   /*16*/
    {-1.000000f, -0.414214f, ~0},   /*17*/
    {-0.707106f, -0.707106f,  0},   /*18*/
    {-0.414214f, -1.000000f, ~0},   /*19*/
    { 0.000000f, -1.000000f,  0},   /*20*/
    {+0.414214f, -1.000000f, ~0},   /*21*/
    {+0.707106f, -0.707106f,  0},   /*22*/
    {+1.000000f, -0.414214f, ~0},   /*23*/
    // This vertex is for the fanned versions.
    { 0.000000f,  0.000000f, ~0},   /*24*/

    // Rectangle with disjoint corner segments.
    {+1.0, +0.5,  0x3},   /*25*/
    {+1.0, +1.0,  0x3},   /*26*/
    {+0.5, +1.0,  0x3},   /*27*/
    {-0.5, +1.0,  0x2},   /*28*/
    {-1.0, +1.0,  0x2},   /*29*/
    {-1.0, +0.5,  0x2},   /*30*/
    {-1.0, -0.5,  0x0},   /*31*/
    {-1.0, -1.0,  0x0},   /*32*/
    {-0.5, -1.0,  0x0},   /*33*/
    {+0.5, -1.0,  0x1},   /*34*/
    {+1.0, -1.0,  0x1},   /*35*/
    {+1.0, -0.5,  0x1},   /*36*/
    // The next 4 are for the fanned version.
    { 0.0,  0.0,  0x3},   /*37*/
    { 0.0,  0.0,  0x2},   /*38*/
    { 0.0,  0.0,  0x0},   /*39*/
    { 0.0,  0.0,  0x1},   /*40*/
    // The next 8 are for the bordered version.
    {+0.75, +0.50,  0x3},   /*41*/
    {+0.50, +0.75,  0x3},   /*42*/
    {-0.50, +0.75,  0x2},   /*43*/
    {-0.75, +0.50,  0x2},   /*44*/
    {-0.75, -0.50,  0x0},   /*45*/
    {-0.50, -0.75,  0x0},   /*46*/
    {+0.50, -0.75,  0x1},   /*47*/
    {+0.75, -0.50,  0x1},   /*48*/

    // 16-gon that inscribes the unit circle, cut by an interior unit 16-gon.
    {+1.000000f, +0.000000f,  0},   /*49*/
    {+1.000000f, +0.198913f, ~0},   /*50*/
    {+0.923879f, +0.382683f,  0},   /*51*/
    {+0.847760f, +0.566455f, ~0},   /*52*/
    {+0.707106f, +0.707106f,  0},   /*53*/
    {+0.566455f, +0.847760f, ~0},   /*54*/
    {+0.382683f, +0.923879f,  0},   /*55*/
    {+0.198913f, +1.000000f, ~0},   /*56*/
    {+0.000000f, +1.000000f,  0},   /*57*/
    {-0.198913f, +1.000000f, ~0},   /*58*/
    {-0.382683f, +0.923879f,  0},   /*59*/
    {-0.566455f, +0.847760f, ~0},   /*60*/
    {-0.707106f, +0.707106f,  0},   /*61*/
    {-0.847760f, +0.566455f, ~0},   /*62*/
    {-0.923879f, +0.382683f,  0},   /*63*/
    {-1.000000f, +0.198913f, ~0},   /*64*/
    {-1.000000f, +0.000000f,  0},   /*65*/
    {-1.000000f, -0.198913f, ~0},   /*66*/
    {-0.923879f, -0.382683f,  0},   /*67*/
    {-0.847760f, -0.566455f, ~0},   /*68*/
    {-0.707106f, -0.707106f,  0},   /*69*/
    {-0.566455f, -0.847760f, ~0},   /*70*/
    {-0.382683f, -0.923879f,  0},   /*71*/
    {-0.198913f, -1.000000f, ~0},   /*72*/
    {-0.000000f, -1.000000f,  0},   /*73*/
    {+0.198913f, -1.000000f, ~0},   /*74*/
    {+0.382683f, -0.923879f,  0},   /*75*/
    {+0.566455f, -0.847760f, ~0},   /*76*/
    {+0.707106f, -0.707106f,  0},   /*77*/
    {+0.847760f, -0.566455f, ~0},   /*78*/
    {+0.923879f, -0.382683f,  0},   /*79*/
    {+1.000000f, -0.198913f, ~0},   /*80*/
};

const uint8_t kIndexData[] = {
    // Rectangle.
    0, 1, 2,
    0, 2, 3,

    // Rectangle with a border.
    0, 1, 5,
    5, 4, 0,
    1, 2, 6,
    6, 5, 1,
    2, 3, 7,
    7, 6, 2,
    3, 0, 4,
    4, 7, 3,
    4, 5, 6,
    6, 7, 4,

    // Octagon that inscribes the unit circle, cut by an interior unit octagon.
    10,  8,  9,
    12, 10, 11,
    14, 12, 13,
    16, 14, 15,
    18, 16, 17,
    20, 18, 19,
    22, 20, 21,
     8, 22, 23,
     8, 10, 12,
    12, 14, 16,
    16, 18, 20,
    20, 22,  8,
     8, 12, 16,
    16, 20,  8,

    // Same octagons, but with the interior arranged as a fan. Used by mixed samples.
    10,  8,  9,
    12, 10, 11,
    14, 12, 13,
    16, 14, 15,
    18, 16, 17,
    20, 18, 19,
    22, 20, 21,
     8, 22, 23,
    24,  8, 10,
    12, 24, 10,
    24, 12, 14,
    16, 24, 14,
    24, 16, 18,
    20, 24, 18,
    24, 20, 22,
     8, 24, 22,

    // Same octagons, but with the inner and outer disjoint. Used by coverage AA.
     8, 22, 23,
     9,  8, 23,
    10,  8,  9,
    11, 10,  9,
    12, 10, 11,
    13, 12, 11,
    14, 12, 13,
    15, 14, 13,
    16, 14, 15,
    17, 16, 15,
    18, 16, 17,
    19, 18, 17,
    20, 18, 19,
    21, 20, 19,
    22, 20, 21,
    23, 22, 21,
    22,  8, 10,
    10, 12, 14,
    14, 16, 18,
    18, 20, 22,
    22, 10, 14,
    14, 18, 22,

    // Rectangle with disjoint corner segments.
    27, 25, 26,
    30, 28, 29,
    33, 31, 32,
    36, 34, 35,
    25, 27, 28,
    28, 30, 31,
    31, 33, 34,
    34, 36, 25,
    25, 28, 31,
    31, 34, 25,

    // Same rectangle with disjoint corners, but with the interior arranged as a fan. Used by
    // mixed samples.
    27, 25, 26,
    30, 28, 29,
    33, 31, 32,
    36, 34, 35,
    27, 37, 25,
    28, 37, 27,
    30, 38, 28,
    31, 38, 30,
    33, 39, 31,
    34, 39, 33,
    36, 40, 34,
    25, 40, 36,

    // Same rectangle with disjoint corners, with a border as well. Used by coverage AA.
    41, 25, 26,
    42, 41, 26,
    27, 42, 26,
    43, 28, 29,
    44, 43, 29,
    30, 44, 29,
    45, 31, 32,
    46, 45, 32,
    33, 46, 32,
    47, 34, 35,
    48, 47, 35,
    36, 48, 35,
    27, 28, 42,
    42, 28, 43,
    30, 31, 44,
    44, 31, 45,
    33, 34, 46,
    46, 34, 47,
    36, 25, 48,
    48, 25, 41,
    41, 42, 43,
    43, 44, 45,
    45, 46, 47,
    47, 48, 41,
    41, 43, 45,
    45, 47, 41,

    // Same as the disjoint octagons, but with 16-gons instead. Used by coverage AA when the oval is
    // sufficiently large.
    49, 79, 80,
    50, 49, 80,
    51, 49, 50,
    52, 51, 50,
    53, 51, 52,
    54, 53, 52,
    55, 53, 54,
    56, 55, 54,
    57, 55, 56,
    58, 57, 56,
    59, 57, 58,
    60, 59, 58,
    61, 59, 60,
    62, 61, 60,
    63, 61, 62,
    64, 63, 62,
    65, 63, 64,
    66, 65, 64,
    67, 65, 66,
    68, 67, 66,
    69, 67, 68,
    70, 69, 68,
    71, 69, 70,
    72, 71, 70,
    73, 71, 72,
    74, 73, 72,
    75, 73, 74,
    76, 75, 74,
    77, 75, 76,
    78, 77, 76,
    79, 77, 78,
    80, 79, 78,
    49, 51, 53,
    53, 55, 57,
    57, 59, 61,
    61, 63, 65,
    65, 67, 69,
    69, 71, 73,
    73, 75, 77,
    77, 79, 49,
    49, 53, 57,
    57, 61, 65,
    65, 69, 73,
    73, 77, 49,
    49, 57, 65,
    65, 73, 49,
};

enum {
    kRect_FirstIndex = 0,
    kRect_TriCount = 2,

    kFramedRect_FirstIndex = 6,
    kFramedRect_TriCount = 10,

    kOctagons_FirstIndex = 36,
    kOctagons_TriCount = 14,

    kOctagonsFanned_FirstIndex = 78,
    kOctagonsFanned_TriCount = 16,

    kDisjointOctagons_FirstIndex = 126,
    kDisjointOctagons_TriCount = 22,

    kCorneredRect_FirstIndex = 192,
    kCorneredRect_TriCount = 10,

    kCorneredRectFanned_FirstIndex = 222,
    kCorneredRectFanned_TriCount = 12,

    kCorneredFramedRect_FirstIndex = 258,
    kCorneredFramedRect_TriCount = 26,

    kDisjoint16Gons_FirstIndex = 336,
    kDisjoint16Gons_TriCount = 46,
};

GR_DECLARE_STATIC_UNIQUE_KEY(gShapeVertexBufferKey);

const GrBuffer* InstanceProcessor::FindOrCreateVertexBuffer(GrGpu* gpu) {
    GR_DEFINE_STATIC_UNIQUE_KEY(gShapeVertexBufferKey);
    GrResourceCache* cache = gpu->getContext()->getResourceCache();
    if (GrGpuResource* cached = cache->findAndRefUniqueResource(gShapeVertexBufferKey)) {
        return static_cast<GrBuffer*>(cached);
    }
    if (GrBuffer* buffer = gpu->createBuffer(sizeof(kVertexData), kVertex_GrBufferType,
                                             kStatic_GrAccessPattern, kVertexData)) {
        buffer->resourcePriv().setUniqueKey(gShapeVertexBufferKey);
        return buffer;
    }
    return nullptr;
}

GR_DECLARE_STATIC_UNIQUE_KEY(gShapeIndexBufferKey);

const GrBuffer* InstanceProcessor::FindOrCreateIndex8Buffer(GrGpu* gpu) {
    GR_DEFINE_STATIC_UNIQUE_KEY(gShapeIndexBufferKey);
    GrResourceCache* cache = gpu->getContext()->getResourceCache();
    if (GrGpuResource* cached = cache->findAndRefUniqueResource(gShapeIndexBufferKey)) {
        return static_cast<GrBuffer*>(cached);
    }
    if (GrBuffer* buffer = gpu->createBuffer(sizeof(kIndexData), kIndex_GrBufferType,
                                             kStatic_GrAccessPattern, kIndexData)) {
        buffer->resourcePriv().setUniqueKey(gShapeIndexBufferKey);
        return buffer;
    }
    return nullptr;
}

IndexRange InstanceProcessor::GetIndexRangeForRect(AntialiasMode aa) {
    static constexpr IndexRange kRectRanges[kNumAntialiasModes] = {
        {kRect_FirstIndex,        3 * kRect_TriCount},        // kNone
        {kFramedRect_FirstIndex,  3 * kFramedRect_TriCount},  // kCoverage
        {kRect_FirstIndex,        3 * kRect_TriCount},        // kMSAA
        {kRect_FirstIndex,        3 * kRect_TriCount}         // kMixedSamples
    };

    SkASSERT(aa >= AntialiasMode::kNone && aa <= AntialiasMode::kMixedSamples);
    return kRectRanges[(int)aa];

    GR_STATIC_ASSERT(0 == (int)AntialiasMode::kNone);
    GR_STATIC_ASSERT(1 == (int)AntialiasMode::kCoverage);
    GR_STATIC_ASSERT(2 == (int)AntialiasMode::kMSAA);
    GR_STATIC_ASSERT(3 == (int)AntialiasMode::kMixedSamples);
}

IndexRange InstanceProcessor::GetIndexRangeForOval(AntialiasMode aa, const SkRect& devBounds) {
    if (AntialiasMode::kCoverage == aa && devBounds.height() * devBounds.width() >= 256 * 256) {
        // This threshold was chosen quasi-scientifically on Tegra X1.
        return {kDisjoint16Gons_FirstIndex, 3 * kDisjoint16Gons_TriCount};
    }

    static constexpr IndexRange kOvalRanges[kNumAntialiasModes] = {
        {kOctagons_FirstIndex,          3 * kOctagons_TriCount},          // kNone
        {kDisjointOctagons_FirstIndex,  3 * kDisjointOctagons_TriCount},  // kCoverage
        {kOctagons_FirstIndex,          3 * kOctagons_TriCount},          // kMSAA
        {kOctagonsFanned_FirstIndex,    3 * kOctagonsFanned_TriCount}     // kMixedSamples
    };

    SkASSERT(aa >= AntialiasMode::kNone && aa <= AntialiasMode::kMixedSamples);
    return kOvalRanges[(int)aa];

    GR_STATIC_ASSERT(0 == (int)AntialiasMode::kNone);
    GR_STATIC_ASSERT(1 == (int)AntialiasMode::kCoverage);
    GR_STATIC_ASSERT(2 == (int)AntialiasMode::kMSAA);
    GR_STATIC_ASSERT(3 == (int)AntialiasMode::kMixedSamples);
}

IndexRange InstanceProcessor::GetIndexRangeForRRect(AntialiasMode aa) {
    static constexpr IndexRange kRRectRanges[kNumAntialiasModes] = {
        {kCorneredRect_FirstIndex,        3 * kCorneredRect_TriCount},        // kNone
        {kCorneredFramedRect_FirstIndex,  3 * kCorneredFramedRect_TriCount},  // kCoverage
        {kCorneredRect_FirstIndex,        3 * kCorneredRect_TriCount},        // kMSAA
        {kCorneredRectFanned_FirstIndex,  3 * kCorneredRectFanned_TriCount}   // kMixedSamples
    };

    SkASSERT(aa >= AntialiasMode::kNone && aa <= AntialiasMode::kMixedSamples);
    return kRRectRanges[(int)aa];

    GR_STATIC_ASSERT(0 == (int)AntialiasMode::kNone);
    GR_STATIC_ASSERT(1 == (int)AntialiasMode::kCoverage);
    GR_STATIC_ASSERT(2 == (int)AntialiasMode::kMSAA);
    GR_STATIC_ASSERT(3 == (int)AntialiasMode::kMixedSamples);
}

const char* InstanceProcessor::GetNameOfIndexRange(IndexRange range) {
    switch (range.fStart) {
        case kRect_FirstIndex: return "basic_rect";
        case kFramedRect_FirstIndex: return "coverage_rect";

        case kOctagons_FirstIndex: return "basic_oval";
        case kDisjointOctagons_FirstIndex: return "coverage_oval";
        case kDisjoint16Gons_FirstIndex: return "coverage_large_oval";
        case kOctagonsFanned_FirstIndex: return "mixed_samples_oval";

        case kCorneredRect_FirstIndex: return "basic_round_rect";
        case kCorneredFramedRect_FirstIndex: return "coverage_round_rect";
        case kCorneredRectFanned_FirstIndex: return "mixed_samples_round_rect";

        default: return "unknown";
    }
}

}
