/*
 * 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->definef("PARAMS_IDX_MASK", "0x%xu", kParamsIdx_InfoMask);
        fVertexBuilder->appendPrecisionModifier(kHigh_GrSLPrecision);
        fVertexBuilder->codeAppendf("int paramsIdx = int(%s & PARAMS_IDX_MASK);",
                                    this->attr(Attrib::kInstanceInfo));
    }

    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->definef("PERSPECTIVE_FLAG", "0x%xu", kPerspective_InfoFlag);
        v->codeAppendf("mat3 shapeMatrix = mat3(%s, %s, vec3(0, 0, 1));",
                       inputs.attr(Attrib::kShapeMatrixX), inputs.attr(Attrib::kShapeMatrixY));
        v->codeAppendf("if (0u != (%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->define("SHAPE_TYPE_BIT", kShapeType_InfoBit);
        v->codeAppendf("uint shapeType = %s >> SHAPE_TYPE_BIT;",
                       inputs.attr(Attrib::kInstanceInfo));
    }

    SkAutoTDelete<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->definef("INNER_SHAPE_TYPE_MASK", "0x%xu", kInnerShapeType_InfoMask);
            v->define("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->definef("OVAL_SHAPE_TYPE", "%du", (int)ShapeType::kOval);
    }
    if (usedShapeDefinitions & kSimpleRRect_ShapeFlag) {
        v->definef("SIMPLE_R_RECT_SHAPE_TYPE", "%du", (int)ShapeType::kSimpleRRect);
    }
    if (usedShapeDefinitions & kNinePatch_ShapeFlag) {
        v->definef("NINE_PATCH_SHAPE_TYPE", "%du", (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->definef("LOCAL_MATRIX_FLAG", "0x%xu", kLocalMatrix_InfoFlag);
        v->codeAppendf("if (0u != (%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->definef("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->define("SAMPLE_COUNT", fEffectiveSampleCnt);
    if (this->isMixedSampled()) {
        f->definef("SAMPLE_MASK_ALL", "0x%x", (1 << fEffectiveSampleCnt) - 1);
        f->definef("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->enableFeature(GrGLSLPPFragmentBuilder::kStandardDerivatives_GLSLFeature);
            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.getStencil());
            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";
    }
}

}
