InstanceProcessor.cpp revision dd57dd796845da6ec2e1f44dc1e0b7821c1e4db1
1a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton/*
2a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton * Copyright 2016 Google Inc.
3a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton *
4a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton * Use of this source code is governed by a BSD-style license that can be
5a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton * found in the LICENSE file.
6a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton */
7a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
8a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton#include "InstanceProcessor.h"
9a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
10a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton#include "GrContext.h"
11a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton#include "GrRenderTargetPriv.h"
12a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton#include "GrResourceCache.h"
13a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton#include "GrResourceProvider.h"
14a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton#include "glsl/GrGLSLGeometryProcessor.h"
15a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton#include "glsl/GrGLSLFragmentShaderBuilder.h"
16a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton#include "glsl/GrGLSLProgramBuilder.h"
17a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton#include "glsl/GrGLSLVarying.h"
18a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
19a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonnamespace gr_instanced {
20a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
21a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonbool InstanceProcessor::IsSupported(const GrGLSLCaps& glslCaps, const GrCaps& caps,
22a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                    AntialiasMode* lastSupportedAAMode) {
23a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (!glslCaps.canUseAnyFunctionInShader() ||
24a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        !glslCaps.flatInterpolationSupport() ||
25a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        !glslCaps.integerSupport() ||
26a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        0 == glslCaps.maxVertexSamplers() ||
27a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        !caps.shaderCaps()->texelBufferSupport() ||
28a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        caps.maxVertexAttributes() < kNumAttribs) {
29a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        return false;
30a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
31a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (caps.sampleLocationsSupport() &&
32a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        glslCaps.sampleVariablesSupport() &&
33a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        glslCaps.shaderDerivativeSupport()) {
34a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        if (0 != caps.maxRasterSamples() &&
35a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            glslCaps.sampleMaskOverrideCoverageSupport()) {
36a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            *lastSupportedAAMode = AntialiasMode::kMixedSamples;
37a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        } else {
38a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            *lastSupportedAAMode = AntialiasMode::kMSAA;
39a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
40a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    } else {
41a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        *lastSupportedAAMode = AntialiasMode::kCoverage;
42a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
43a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    return true;
44a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
45a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
46a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonInstanceProcessor::InstanceProcessor(BatchInfo batchInfo, GrBuffer* paramsBuffer)
47a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    : fBatchInfo(batchInfo) {
48a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    this->initClassID<InstanceProcessor>();
49a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
50a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    this->addVertexAttrib(Attribute("shapeCoords", kVec2f_GrVertexAttribType, kHigh_GrSLPrecision));
51a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    this->addVertexAttrib(Attribute("vertexAttrs", kInt_GrVertexAttribType));
52a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    this->addVertexAttrib(Attribute("instanceInfo", kUint_GrVertexAttribType));
53a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    this->addVertexAttrib(Attribute("shapeMatrixX", kVec3f_GrVertexAttribType,
54a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                    kHigh_GrSLPrecision));
55a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    this->addVertexAttrib(Attribute("shapeMatrixY", kVec3f_GrVertexAttribType,
56a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                    kHigh_GrSLPrecision));
57a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    this->addVertexAttrib(Attribute("color", kVec4f_GrVertexAttribType, kLow_GrSLPrecision));
58a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    this->addVertexAttrib(Attribute("localRect", kVec4f_GrVertexAttribType, kHigh_GrSLPrecision));
59a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
60a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GR_STATIC_ASSERT(0 == (int)Attrib::kShapeCoords);
61a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GR_STATIC_ASSERT(1 == (int)Attrib::kVertexAttrs);
62a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GR_STATIC_ASSERT(2 == (int)Attrib::kInstanceInfo);
63a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GR_STATIC_ASSERT(3 == (int)Attrib::kShapeMatrixX);
64a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GR_STATIC_ASSERT(4 == (int)Attrib::kShapeMatrixY);
65a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GR_STATIC_ASSERT(5 == (int)Attrib::kColor);
66a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GR_STATIC_ASSERT(6 == (int)Attrib::kLocalRect);
67a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GR_STATIC_ASSERT(7 == kNumAttribs);
68a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
69a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fBatchInfo.fHasParams) {
70a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        SkASSERT(paramsBuffer);
71a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        fParamsAccess.reset(kRGBA_float_GrPixelConfig, paramsBuffer, kVertex_GrShaderFlag);
72a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        this->addBufferAccess(&fParamsAccess);
73a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
74a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
75a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fBatchInfo.fAntialiasMode >= AntialiasMode::kMSAA) {
76a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        if (!fBatchInfo.isSimpleRects() ||
77a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            AntialiasMode::kMixedSamples == fBatchInfo.fAntialiasMode) {
78a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            this->setWillUseSampleLocations();
79a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
80a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
81a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
82a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
83a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonclass GLSLInstanceProcessor : public GrGLSLGeometryProcessor {
84a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonpublic:
85a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override;
86a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
87a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonprivate:
88a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void setData(const GrGLSLProgramDataManager&, const GrPrimitiveProcessor&) override {}
89a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
90a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    class VertexInputs;
91a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    class Backend;
92a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    class BackendNonAA;
93a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    class BackendCoverage;
94a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    class BackendMultisample;
95a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
96a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    typedef GrGLSLGeometryProcessor INHERITED;
97a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton};
98a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
99a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonGrGLSLPrimitiveProcessor* InstanceProcessor::createGLSLInstance(const GrGLSLCaps&) const {
100a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    return new GLSLInstanceProcessor();
101a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
102a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
103a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonclass GLSLInstanceProcessor::VertexInputs {
104a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonpublic:
105a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    VertexInputs(const InstanceProcessor& instProc, GrGLSLVertexBuilder* vertexBuilder)
106a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        : fInstProc(instProc),
107a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton          fVertexBuilder(vertexBuilder) {
108a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
109a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
110a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void initParams(const SamplerHandle paramsBuffer) {
111a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        fParamsBuffer = paramsBuffer;
112a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        fVertexBuilder->definef("PARAMS_IDX_MASK", "0x%xu", kParamsIdx_InfoMask);
113a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        fVertexBuilder->appendPrecisionModifier(kHigh_GrSLPrecision);
114a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        fVertexBuilder->codeAppendf("int paramsIdx = int(%s & PARAMS_IDX_MASK);",
115a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                    this->attr(Attrib::kInstanceInfo));
116a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
117a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
118a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    const char* attr(Attrib attr) const { return fInstProc.getAttrib((int)attr).fName; }
119a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
120a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void fetchNextParam(GrSLType type = kVec4f_GrSLType) const {
121a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        SkASSERT(fParamsBuffer.isValid());
122a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        if (type != kVec4f_GrSLType) {
123a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            fVertexBuilder->codeAppendf("%s(", GrGLSLTypeString(type));
124a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
125a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        fVertexBuilder->appendTexelFetch(fParamsBuffer, "paramsIdx++");
126a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        if (type != kVec4f_GrSLType) {
127a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            fVertexBuilder->codeAppend(")");
128a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
129a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
130a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
131a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void skipParams(unsigned n) const {
132a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        SkASSERT(fParamsBuffer.isValid());
133a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        fVertexBuilder->codeAppendf("paramsIdx += %u;", n);
134a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
135a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
136a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonprivate:
137a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    const InstanceProcessor&     fInstProc;
138a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GrGLSLVertexBuilder*         fVertexBuilder;
139a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    SamplerHandle                fParamsBuffer;
140a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton};
141a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
142a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonclass GLSLInstanceProcessor::Backend {
143a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonpublic:
144a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    static Backend* SK_WARN_UNUSED_RESULT Create(const GrPipeline&, BatchInfo, const VertexInputs&);
145a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    virtual ~Backend() {}
146a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
147a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void init(GrGLSLVaryingHandler*, GrGLSLVertexBuilder*);
148a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    virtual void setupRect(GrGLSLVertexBuilder*) = 0;
149a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    virtual void setupOval(GrGLSLVertexBuilder*) = 0;
1500caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton    void setupRRect(GrGLSLVertexBuilder*, int* usedShapeDefinitions);
151a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
152a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void initInnerShape(GrGLSLVaryingHandler*, GrGLSLVertexBuilder*);
153a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    virtual void setupInnerRect(GrGLSLVertexBuilder*) = 0;
154a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    virtual void setupInnerOval(GrGLSLVertexBuilder*) = 0;
1550caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton    void setupInnerSimpleRRect(GrGLSLVertexBuilder*);
156a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
157a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    const char* outShapeCoords() {
158a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        return fModifiedShapeCoords ? fModifiedShapeCoords : fInputs.attr(Attrib::kShapeCoords);
159a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
160a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
161a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void emitCode(GrGLSLVertexBuilder*, GrGLSLPPFragmentBuilder*, const char* outCoverage,
162a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                  const char* outColor);
163a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
164a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonprotected:
165a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    Backend(BatchInfo batchInfo, const VertexInputs& inputs)
166a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        : fBatchInfo(batchInfo),
167a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton          fInputs(inputs),
168a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton          fModifiesCoverage(false),
169a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton          fModifiesColor(false),
170a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton          fNeedsNeighborRadii(false),
171a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton          fColor(kVec4f_GrSLType),
172a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton          fTriangleIsArc(kInt_GrSLType),
173a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton          fArcCoords(kVec2f_GrSLType),
174a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton          fInnerShapeCoords(kVec2f_GrSLType),
175a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton          fInnerRRect(kVec4f_GrSLType),
176a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton          fModifiedShapeCoords(nullptr) {
177a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        if (fBatchInfo.fShapeTypes & kRRect_ShapesMask) {
178a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            fModifiedShapeCoords = "adjustedShapeCoords";
179a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
180a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
181a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
182a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    virtual void onInit(GrGLSLVaryingHandler*, GrGLSLVertexBuilder*) = 0;
183a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    virtual void adjustRRectVertices(GrGLSLVertexBuilder*);
184a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    virtual void onSetupRRect(GrGLSLVertexBuilder*) {}
185a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
186a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    virtual void onInitInnerShape(GrGLSLVaryingHandler*, GrGLSLVertexBuilder*) = 0;
1870caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton    virtual void onSetupInnerSimpleRRect(GrGLSLVertexBuilder*) = 0;
188a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
189a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    virtual void onEmitCode(GrGLSLVertexBuilder*, GrGLSLPPFragmentBuilder*,
190a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                            const char* outCoverage, const char* outColor) = 0;
191a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
192a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void setupSimpleRadii(GrGLSLVertexBuilder*);
193a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void setupNinePatchRadii(GrGLSLVertexBuilder*);
194a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void setupComplexRadii(GrGLSLVertexBuilder*);
195a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
196a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    const BatchInfo       fBatchInfo;
197a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    const VertexInputs&   fInputs;
198a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    bool                  fModifiesCoverage;
199a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    bool                  fModifiesColor;
200a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    bool                  fNeedsNeighborRadii;
201a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GrGLSLVertToFrag      fColor;
202a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GrGLSLVertToFrag      fTriangleIsArc;
203a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GrGLSLVertToFrag      fArcCoords;
204a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GrGLSLVertToFrag      fInnerShapeCoords;
205a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GrGLSLVertToFrag      fInnerRRect;
206a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    const char*           fModifiedShapeCoords;
207a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton};
208a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
209a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
210a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    const GrPipeline& pipeline = args.fVertBuilder->getProgramBuilder()->pipeline();
211a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    const InstanceProcessor& ip = args.fGP.cast<InstanceProcessor>();
212a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GrGLSLUniformHandler* uniHandler = args.fUniformHandler;
213a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
214a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GrGLSLVertexBuilder* v = args.fVertBuilder;
215a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GrGLSLPPFragmentBuilder* f = args.fFragBuilder;
216a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
217a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    varyingHandler->emitAttributes(ip);
218a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
219a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    VertexInputs inputs(ip, v);
220a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (ip.batchInfo().fHasParams) {
221a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        SkASSERT(1 == ip.numBuffers());
222a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        inputs.initParams(args.fBufferSamplers[0]);
223a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
224a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
225a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (!ip.batchInfo().fHasPerspective) {
226a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("mat2x3 shapeMatrix = mat2x3(%s, %s);",
227a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       inputs.attr(Attrib::kShapeMatrixX), inputs.attr(Attrib::kShapeMatrixY));
228a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    } else {
229a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->definef("PERSPECTIVE_FLAG", "0x%xu", kPerspective_InfoFlag);
230a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("mat3 shapeMatrix = mat3(%s, %s, vec3(0, 0, 1));",
231a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       inputs.attr(Attrib::kShapeMatrixX), inputs.attr(Attrib::kShapeMatrixY));
232a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("if (0u != (%s & PERSPECTIVE_FLAG)) {",
233a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       inputs.attr(Attrib::kInstanceInfo));
234a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppend (    "shapeMatrix[2] = ");
235a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        inputs.fetchNextParam(kVec3f_GrSLType);
236a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppend (    ";");
237a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppend ("}");
238a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
239a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
240a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    bool hasSingleShapeType = SkIsPow2(ip.batchInfo().fShapeTypes);
241a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (!hasSingleShapeType) {
242a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->define("SHAPE_TYPE_BIT", kShapeType_InfoBit);
243a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("uint shapeType = %s >> SHAPE_TYPE_BIT;",
244a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       inputs.attr(Attrib::kInstanceInfo));
245a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
246a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
247a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    SkAutoTDelete<Backend> backend(Backend::Create(pipeline, ip.batchInfo(), inputs));
248a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    backend->init(varyingHandler, v);
249a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
2500caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton    int usedShapeDefinitions = 0;
2510caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton
2520caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton    if (hasSingleShapeType || !(ip.batchInfo().fShapeTypes & ~kRRect_ShapesMask)) {
253a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        if (kRect_ShapeFlag == ip.batchInfo().fShapeTypes) {
254a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            backend->setupRect(v);
255a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        } else if (kOval_ShapeFlag == ip.batchInfo().fShapeTypes) {
256a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            backend->setupOval(v);
257a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        } else {
2580caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton            backend->setupRRect(v, &usedShapeDefinitions);
259a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
260a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    } else {
2610caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton        if (ip.batchInfo().fShapeTypes & kRRect_ShapesMask) {
2620caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton            v->codeAppend ("if (shapeType >= SIMPLE_R_RECT_SHAPE_TYPE) {");
2630caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton            backend->setupRRect(v, &usedShapeDefinitions);
2640caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton            v->codeAppend ("}");
2650caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton            usedShapeDefinitions |= kSimpleRRect_ShapeFlag;
266a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
267a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        if (ip.batchInfo().fShapeTypes & kOval_ShapeFlag) {
2680caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton            if (ip.batchInfo().fShapeTypes & kRect_ShapeFlag) {
2690caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton                if (ip.batchInfo().fShapeTypes & kRRect_ShapesMask) {
2700caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton                    v->codeAppend ("else ");
2710caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton                }
2720caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton                v->codeAppend ("if (OVAL_SHAPE_TYPE == shapeType) {");
2730caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton                usedShapeDefinitions |= kOval_ShapeFlag;
2740caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton            } else {
2750caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton                v->codeAppend ("else {");
2760caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton            }
277a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            backend->setupOval(v);
2780caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton            v->codeAppend ("}");
279a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
2800caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton        if (ip.batchInfo().fShapeTypes & kRect_ShapeFlag) {
2810caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton            v->codeAppend ("else {");
2820caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton            backend->setupRect(v);
2830caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton            v->codeAppend ("}");
284a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
285a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
286a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
287a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (ip.batchInfo().fInnerShapeTypes) {
288a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        bool hasSingleInnerShapeType = SkIsPow2(ip.batchInfo().fInnerShapeTypes);
289a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        if (!hasSingleInnerShapeType) {
290a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            v->definef("INNER_SHAPE_TYPE_MASK", "0x%xu", kInnerShapeType_InfoMask);
291a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            v->define("INNER_SHAPE_TYPE_BIT", kInnerShapeType_InfoBit);
292a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            v->codeAppendf("uint innerShapeType = ((%s & INNER_SHAPE_TYPE_MASK) >> "
293a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                  "INNER_SHAPE_TYPE_BIT);",
294a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                           inputs.attr(Attrib::kInstanceInfo));
295a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
296a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        // Here we take advantage of the fact that outerRect == localRect in recordDRRect.
297a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("vec4 outer = %s;", inputs.attr(Attrib::kLocalRect));
298a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppend ("vec4 inner = ");
299a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        inputs.fetchNextParam();
300a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppend (";");
301a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        // outer2Inner is a transform from shape coords to inner shape coords:
302a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        // e.g. innerShapeCoords = shapeCoords * outer2Inner.xy + outer2Inner.zw
303a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppend ("vec4 outer2Inner = vec4(outer.zw - outer.xy, "
304a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                               "outer.xy + outer.zw - inner.xy - inner.zw) / "
305a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                               "(inner.zw - inner.xy).xyxy;");
306a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("vec2 innerShapeCoords = %s * outer2Inner.xy + outer2Inner.zw;",
307a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       backend->outShapeCoords());
308a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
309a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        backend->initInnerShape(varyingHandler, v);
310a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
3110caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton        SkASSERT(0 == (ip.batchInfo().fInnerShapeTypes & kRRect_ShapesMask) ||
3120caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton                 kSimpleRRect_ShapeFlag == (ip.batchInfo().fInnerShapeTypes & kRRect_ShapesMask));
3130caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton
314a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        if (hasSingleInnerShapeType) {
315a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            if (kRect_ShapeFlag == ip.batchInfo().fInnerShapeTypes) {
316a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                backend->setupInnerRect(v);
317a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            } else if (kOval_ShapeFlag == ip.batchInfo().fInnerShapeTypes) {
318a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                backend->setupInnerOval(v);
319a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            } else {
3200caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton                backend->setupInnerSimpleRRect(v);
321a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            }
322a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        } else {
3230caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton            if (ip.batchInfo().fInnerShapeTypes & kSimpleRRect_ShapeFlag) {
3240caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton                v->codeAppend ("if (SIMPLE_R_RECT_SHAPE_TYPE == innerShapeType) {");
3250caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton                backend->setupInnerSimpleRRect(v);
3260caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton                v->codeAppend("}");
3270caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton                usedShapeDefinitions |= kSimpleRRect_ShapeFlag;
328a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            }
329a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            if (ip.batchInfo().fInnerShapeTypes & kOval_ShapeFlag) {
3300caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton                if (ip.batchInfo().fInnerShapeTypes & kRect_ShapeFlag) {
3310caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton                    if (ip.batchInfo().fInnerShapeTypes & kSimpleRRect_ShapeFlag) {
3320caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton                        v->codeAppend ("else ");
3330caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton                    }
3340caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton                    v->codeAppend ("if (OVAL_SHAPE_TYPE == innerShapeType) {");
3350caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton                    usedShapeDefinitions |= kOval_ShapeFlag;
3360caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton                } else {
3370caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton                    v->codeAppend ("else {");
3380caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton                }
339a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                backend->setupInnerOval(v);
3400caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton                v->codeAppend("}");
341a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            }
3420caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton            if (ip.batchInfo().fInnerShapeTypes & kRect_ShapeFlag) {
3430caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton                v->codeAppend("else {");
3440caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton                backend->setupInnerRect(v);
3450caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton                v->codeAppend("}");
346a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            }
347a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
348a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
349a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
3500caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton    if (usedShapeDefinitions & kOval_ShapeFlag) {
351a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->definef("OVAL_SHAPE_TYPE", "%du", (int)ShapeType::kOval);
352a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
3530caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton    if (usedShapeDefinitions & kSimpleRRect_ShapeFlag) {
3540caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton        v->definef("SIMPLE_R_RECT_SHAPE_TYPE", "%du", (int)ShapeType::kSimpleRRect);
3550caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton    }
3560caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton    if (usedShapeDefinitions & kNinePatch_ShapeFlag) {
3570caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton        v->definef("NINE_PATCH_SHAPE_TYPE", "%du", (int)ShapeType::kNinePatch);
3580caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton    }
3590caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton    SkASSERT(!(usedShapeDefinitions & (kRect_ShapeFlag | kComplexRRect_ShapeFlag)));
360a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
361a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    backend->emitCode(v, f, pipeline.ignoresCoverage() ? nullptr : args.fOutputCoverage,
362a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                      args.fOutputColor);
363a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
364a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    const char* localCoords = nullptr;
365a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (ip.batchInfo().fUsesLocalCoords) {
366a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        localCoords = "localCoords";
367a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("vec2 t = 0.5 * (%s + vec2(1));", backend->outShapeCoords());
368a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("vec2 localCoords = (1.0 - t) * %s.xy + t * %s.zw;",
369a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       inputs.attr(Attrib::kLocalRect), inputs.attr(Attrib::kLocalRect));
370a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
371a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (ip.batchInfo().fHasLocalMatrix && ip.batchInfo().fHasParams) {
372a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->definef("LOCAL_MATRIX_FLAG", "0x%xu", kLocalMatrix_InfoFlag);
373a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("if (0u != (%s & LOCAL_MATRIX_FLAG)) {",
374a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       inputs.attr(Attrib::kInstanceInfo));
375a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        if (!ip.batchInfo().fUsesLocalCoords) {
376a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            inputs.skipParams(2);
377a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        } else {
378a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            v->codeAppendf(    "mat2x3 localMatrix;");
379a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            v->codeAppend (    "localMatrix[0] = ");
380a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            inputs.fetchNextParam(kVec3f_GrSLType);
381a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            v->codeAppend (    ";");
382a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            v->codeAppend (    "localMatrix[1] = ");
383a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            inputs.fetchNextParam(kVec3f_GrSLType);
384a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            v->codeAppend (    ";");
385a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            v->codeAppend (    "localCoords = (vec3(localCoords, 1) * localMatrix).xy;");
386a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
387a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppend("}");
388a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
389a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
390a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GrSLType positionType = ip.batchInfo().fHasPerspective ? kVec3f_GrSLType : kVec2f_GrSLType;
391a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppendf("%s deviceCoords = vec3(%s, 1) * shapeMatrix;",
392a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                   GrGLSLTypeString(positionType), backend->outShapeCoords());
393a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    gpArgs->fPositionVar.set(positionType, "deviceCoords");
394a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
395a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    this->emitTransforms(v, varyingHandler, uniHandler, gpArgs->fPositionVar, localCoords,
396a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                         args.fTransformsIn, args.fTransformsOut);
397a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
398a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
399a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton////////////////////////////////////////////////////////////////////////////////////////////////////
400a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
401a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::Backend::init(GrGLSLVaryingHandler* varyingHandler,
402a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                          GrGLSLVertexBuilder* v) {
403a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fModifiedShapeCoords) {
404a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("vec2 %s = %s;", fModifiedShapeCoords, fInputs.attr(Attrib::kShapeCoords));
405a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
406a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
407a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    this->onInit(varyingHandler, v);
408a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
409a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (!fColor.vsOut()) {
410a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        varyingHandler->addFlatVarying("color", &fColor, kLow_GrSLPrecision);
411a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = %s;", fColor.vsOut(), fInputs.attr(Attrib::kColor));
412a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
413a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
414a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
4150caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdaltonvoid GLSLInstanceProcessor::Backend::setupRRect(GrGLSLVertexBuilder* v, int* usedShapeDefinitions) {
416a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppendf("uvec2 corner = uvec2(%s & 1, (%s >> 1) & 1);",
417a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                   fInputs.attr(Attrib::kVertexAttrs), fInputs.attr(Attrib::kVertexAttrs));
418a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppend ("vec2 cornerSign = vec2(corner) * 2.0 - 1.0;");
419a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppendf("vec2 radii%s;", fNeedsNeighborRadii ? ", neighborRadii" : "");
420a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppend ("mat2 p = ");
421a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    fInputs.fetchNextParam(kMat22f_GrSLType);
422a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppend (";");
423a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    uint8_t types = fBatchInfo.fShapeTypes & kRRect_ShapesMask;
424a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (0 == (types & (types - 1))) {
425a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        if (kSimpleRRect_ShapeFlag == types) {
426a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            this->setupSimpleRadii(v);
427a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        } else if (kNinePatch_ShapeFlag == types) {
428a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            this->setupNinePatchRadii(v);
429a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        } else if (kComplexRRect_ShapeFlag == types) {
430a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            this->setupComplexRadii(v);
431a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
432a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    } else {
433a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        if (types & kSimpleRRect_ShapeFlag) {
4340caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton            v->codeAppend ("if (SIMPLE_R_RECT_SHAPE_TYPE == shapeType) {");
435a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            this->setupSimpleRadii(v);
4360caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton            v->codeAppend ("}");
4370caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton            *usedShapeDefinitions |= kSimpleRRect_ShapeFlag;
438a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
439a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        if (types & kNinePatch_ShapeFlag) {
4400caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton            if (types & kComplexRRect_ShapeFlag) {
4410caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton                if (types & kSimpleRRect_ShapeFlag) {
4420caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton                    v->codeAppend ("else ");
4430caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton                }
4440caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton                v->codeAppend ("if (NINE_PATCH_SHAPE_TYPE == shapeType) {");
4450caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton                *usedShapeDefinitions |= kNinePatch_ShapeFlag;
4460caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton            } else {
4470caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton                v->codeAppend ("else {");
4480caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton            }
449a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            this->setupNinePatchRadii(v);
4500caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton            v->codeAppend ("}");
451a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
452a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        if (types & kComplexRRect_ShapeFlag) {
4530caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton            v->codeAppend ("else {");
454a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            this->setupComplexRadii(v);
4550caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton            v->codeAppend ("}");
456a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
457a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
458a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
459a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    this->adjustRRectVertices(v);
460a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
461a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fArcCoords.vsOut()) {
462a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = (cornerSign * %s + radii - vec2(1)) / radii;",
463a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       fArcCoords.vsOut(), fModifiedShapeCoords);
464a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
465a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fTriangleIsArc.vsOut()) {
466a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = int(all(equal(vec2(1), abs(%s))));",
467a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       fTriangleIsArc.vsOut(), fInputs.attr(Attrib::kShapeCoords));
468a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
469a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
470a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    this->onSetupRRect(v);
471a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
472a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
473a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::Backend::setupSimpleRadii(GrGLSLVertexBuilder* v) {
474a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fNeedsNeighborRadii) {
475a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppend ("neighborRadii = ");
476a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
477a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppend("radii = p[0] * 2.0 / p[1];");
478a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
479a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
480a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::Backend::setupNinePatchRadii(GrGLSLVertexBuilder* v) {
481a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppend("radii = vec2(p[0][corner.x], p[1][corner.y]);");
482a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fNeedsNeighborRadii) {
483a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppend("neighborRadii = vec2(p[0][1u - corner.x], p[1][1u - corner.y]);");
484a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
485a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
486a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
487a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::Backend::setupComplexRadii(GrGLSLVertexBuilder* v) {
488a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    /**
489a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton     * The x and y radii of each arc are stored in separate vectors,
490a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton     * in the following order:
491a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton     *
492a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton     *        __x1 _ _ _ x3__
493a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton     *
494a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton     *    y1 |               | y2
495a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton     *
496a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton     *       |               |
497a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton     *
498a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton     *    y3 |__   _ _ _   __| y4
499a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton     *          x2       x4
500a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton     *
501a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton     */
502a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppend("mat2 p2 = ");
503a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    fInputs.fetchNextParam(kMat22f_GrSLType);
504a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppend(";");
505a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppend("radii = vec2(p[corner.x][corner.y], p2[corner.y][corner.x]);");
506a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fNeedsNeighborRadii) {
507a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppend("neighborRadii = vec2(p[1u - corner.x][corner.y], "
508a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                           "p2[1u - corner.y][corner.x]);");
509a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
510a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
511a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
512a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::Backend::adjustRRectVertices(GrGLSLVertexBuilder* v) {
513a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // Resize the 4 triangles that arcs are drawn into so they match their corresponding radii.
514a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // 0.5 is a special value that indicates the edge of an arc triangle.
515a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppendf("if (abs(%s.x) == 0.5)"
516a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       "%s.x = cornerSign.x * (1.0 - radii.x);",
517a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       fInputs.attr(Attrib::kShapeCoords), fModifiedShapeCoords);
518a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppendf("if (abs(%s.y) == 0.5) "
519a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       "%s.y = cornerSign.y * (1.0 - radii.y);",
520a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       fInputs.attr(Attrib::kShapeCoords), fModifiedShapeCoords);
521a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
522a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
523a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::Backend::initInnerShape(GrGLSLVaryingHandler* varyingHandler,
524a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                    GrGLSLVertexBuilder* v) {
525a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    SkASSERT(!(fBatchInfo.fInnerShapeTypes & (kNinePatch_ShapeFlag | kComplexRRect_ShapeFlag)));
526a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
527a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    this->onInitInnerShape(varyingHandler, v);
528a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
529a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fInnerShapeCoords.vsOut()) {
530a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = innerShapeCoords;", fInnerShapeCoords.vsOut());
531a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
532a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
533a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
5340caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdaltonvoid GLSLInstanceProcessor::Backend::setupInnerSimpleRRect(GrGLSLVertexBuilder* v) {
535a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppend("mat2 innerP = ");
536a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    fInputs.fetchNextParam(kMat22f_GrSLType);
537a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppend(";");
538a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppend("vec2 innerRadii = innerP[0] * 2.0 / innerP[1];");
5390caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton    this->onSetupInnerSimpleRRect(v);
540a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
541a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
542a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::Backend::emitCode(GrGLSLVertexBuilder* v, GrGLSLPPFragmentBuilder* f,
543a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                              const char* outCoverage, const char* outColor) {
544a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    SkASSERT(!fModifiesCoverage || outCoverage);
545a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    this->onEmitCode(v, f, fModifiesCoverage ? outCoverage : nullptr,
546a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                     fModifiesColor ? outColor : nullptr);
547a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (outCoverage && !fModifiesCoverage) {
548a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        // Even though the subclass doesn't use coverage, we are expected to assign some value.
549a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppendf("%s = vec4(1);", outCoverage);
550a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
551a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (!fModifiesColor) {
552a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        // The subclass didn't assign a value to the output color.
553a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppendf("%s = %s;", outColor, fColor.fsIn());
554a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
555a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
556a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
557a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton////////////////////////////////////////////////////////////////////////////////////////////////////
558a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
559a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonclass GLSLInstanceProcessor::BackendNonAA : public Backend {
560a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonpublic:
561a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    BackendNonAA(BatchInfo batchInfo, const VertexInputs& inputs)
562a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        : INHERITED(batchInfo, inputs) {
563a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        if (fBatchInfo.fCannotDiscard && !fBatchInfo.isSimpleRects()) {
564a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            fModifiesColor = !fBatchInfo.fCannotTweakAlphaForCoverage;
565a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            fModifiesCoverage = !fModifiesColor;
566a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
567a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
568a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
569a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonprivate:
570a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void onInit(GrGLSLVaryingHandler*, GrGLSLVertexBuilder*) override;
571a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void setupRect(GrGLSLVertexBuilder*) override;
572a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void setupOval(GrGLSLVertexBuilder*) override;
573a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
574a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void onInitInnerShape(GrGLSLVaryingHandler*, GrGLSLVertexBuilder*) override;
575a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void setupInnerRect(GrGLSLVertexBuilder*) override;
576a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void setupInnerOval(GrGLSLVertexBuilder*) override;
5770caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton    void onSetupInnerSimpleRRect(GrGLSLVertexBuilder*) override;
578a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
579a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void onEmitCode(GrGLSLVertexBuilder*, GrGLSLPPFragmentBuilder*, const char*,
580a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                    const char*) override;
581a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
582a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    typedef Backend INHERITED;
583a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton};
584a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
585a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendNonAA::onInit(GrGLSLVaryingHandler* varyingHandler,
586a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                 GrGLSLVertexBuilder*) {
587a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (kRect_ShapeFlag != fBatchInfo.fShapeTypes) {
588dd57dd796845da6ec2e1f44dc1e0b7821c1e4db1csmartdalton        varyingHandler->addFlatVarying("triangleIsArc", &fTriangleIsArc, kLow_GrSLPrecision);
589a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        varyingHandler->addVarying("arcCoords", &fArcCoords, kMedium_GrSLPrecision);
590a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
591a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
592a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
593a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendNonAA::setupRect(GrGLSLVertexBuilder* v) {
594a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fTriangleIsArc.vsOut()) {
595a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = 0;", fTriangleIsArc.vsOut());
596a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
597a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
598a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
599a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendNonAA::setupOval(GrGLSLVertexBuilder* v) {
600a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    SkASSERT(fArcCoords.vsOut());
601a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    SkASSERT(fTriangleIsArc.vsOut());
602a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppendf("%s = %s;", fArcCoords.vsOut(), this->outShapeCoords());
603a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppendf("%s = %s & 1;", fTriangleIsArc.vsOut(), fInputs.attr(Attrib::kVertexAttrs));
604a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
605a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
606a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendNonAA::onInitInnerShape(GrGLSLVaryingHandler* varyingHandler,
607a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                           GrGLSLVertexBuilder*) {
608a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    varyingHandler->addVarying("innerShapeCoords", &fInnerShapeCoords, kMedium_GrSLPrecision);
609a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (kRect_ShapeFlag != fBatchInfo.fInnerShapeTypes &&
610a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        kOval_ShapeFlag != fBatchInfo.fInnerShapeTypes) {
611a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        varyingHandler->addFlatVarying("innerRRect", &fInnerRRect, kMedium_GrSLPrecision);
612a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
613a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
614a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
615a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendNonAA::setupInnerRect(GrGLSLVertexBuilder* v) {
616a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fInnerRRect.vsOut()) {
617a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = vec4(1);", fInnerRRect.vsOut());
618a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
619a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
620a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
621a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendNonAA::setupInnerOval(GrGLSLVertexBuilder* v) {
622a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fInnerRRect.vsOut()) {
623a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = vec4(0, 0, 1, 1);", fInnerRRect.vsOut());
624a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
625a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
626a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
6270caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdaltonvoid GLSLInstanceProcessor::BackendNonAA::onSetupInnerSimpleRRect(GrGLSLVertexBuilder* v) {
628a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppendf("%s = vec4(1.0 - innerRadii, 1.0 / innerRadii);", fInnerRRect.vsOut());
629a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
630a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
631a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendNonAA::onEmitCode(GrGLSLVertexBuilder*,
632a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                     GrGLSLPPFragmentBuilder* f,
633a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                     const char* outCoverage,
634a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                     const char* outColor) {
635a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    const char* dropFragment = nullptr;
636a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (!fBatchInfo.fCannotDiscard) {
637a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        dropFragment = "discard";
638a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    } else if (fModifiesCoverage) {
639a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->appendPrecisionModifier(kLow_GrSLPrecision);
640a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppend ("float covered = 1.0;");
641a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        dropFragment = "covered = 0.0";
642a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    } else if (fModifiesColor) {
643a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->appendPrecisionModifier(kLow_GrSLPrecision);
644a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppendf("vec4 color = %s;", fColor.fsIn());
645a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        dropFragment = "color = vec4(0)";
646a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
647a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fTriangleIsArc.fsIn()) {
648a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        SkASSERT(dropFragment);
649a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppendf("if (%s != 0 && dot(%s, %s) > 1.0) %s;",
650a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       fTriangleIsArc.fsIn(), fArcCoords.fsIn(), fArcCoords.fsIn(), dropFragment);
651a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
652a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fBatchInfo.fInnerShapeTypes) {
653a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        SkASSERT(dropFragment);
654a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppendf("// Inner shape.\n");
655a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        if (kRect_ShapeFlag == fBatchInfo.fInnerShapeTypes) {
656a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppendf("if (all(lessThanEqual(abs(%s), vec2(1)))) %s;",
657a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                           fInnerShapeCoords.fsIn(), dropFragment);
658a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        } else if (kOval_ShapeFlag == fBatchInfo.fInnerShapeTypes) {
659a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppendf("if ((dot(%s, %s) <= 1.0)) %s;",
660a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                           fInnerShapeCoords.fsIn(), fInnerShapeCoords.fsIn(), dropFragment);
661a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        } else {
662a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppendf("if (all(lessThan(abs(%s), vec2(1)))) {", fInnerShapeCoords.fsIn());
663a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppendf(    "vec2 distanceToArcEdge = abs(%s) - %s.xy;",
664a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                               fInnerShapeCoords.fsIn(), fInnerRRect.fsIn());
665a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppend (    "if (any(lessThan(distanceToArcEdge, vec2(0)))) {");
666a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppendf(        "%s;", dropFragment);
667a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppend (    "} else {");
668a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppendf(        "vec2 rrectCoords = distanceToArcEdge * %s.zw;",
669a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                   fInnerRRect.fsIn());
670a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppend (        "if (dot(rrectCoords, rrectCoords) <= 1.0) {");
671a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppendf(            "%s;", dropFragment);
672a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppend (        "}");
673a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppend (    "}");
674a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppend ("}");
675a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
676a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
677a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fModifiesCoverage) {
678a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppendf("%s = vec4(covered);", outCoverage);
679a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    } else if (fModifiesColor) {
680a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppendf("%s = color;", outColor);
681a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
682a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
683a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
684a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton////////////////////////////////////////////////////////////////////////////////////////////////////
685a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
686a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonclass GLSLInstanceProcessor::BackendCoverage : public Backend {
687a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonpublic:
688a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    BackendCoverage(BatchInfo batchInfo, const VertexInputs& inputs)
689a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        : INHERITED(batchInfo, inputs),
690a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton          fColorTimesRectCoverage(kVec4f_GrSLType),
691a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton          fRectCoverage(kFloat_GrSLType),
692a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton          fEllipseCoords(kVec2f_GrSLType),
693a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton          fEllipseName(kVec2f_GrSLType),
694a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton          fBloatedRadius(kFloat_GrSLType),
695a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton          fDistanceToInnerEdge(kVec2f_GrSLType),
696a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton          fInnerShapeBloatedHalfSize(kVec2f_GrSLType),
697a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton          fInnerEllipseCoords(kVec2f_GrSLType),
698a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton          fInnerEllipseName(kVec2f_GrSLType) {
699a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        fShapeIsCircle = !fBatchInfo.fNonSquare && !(fBatchInfo.fShapeTypes & kRRect_ShapesMask);
700a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        fTweakAlphaForCoverage = !fBatchInfo.fCannotTweakAlphaForCoverage &&
701a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                 !fBatchInfo.fInnerShapeTypes;
702a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        fModifiesCoverage = !fTweakAlphaForCoverage;
703a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        fModifiesColor = fTweakAlphaForCoverage;
704a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        fModifiedShapeCoords = "bloatedShapeCoords";
705a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
706a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
707a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonprivate:
708a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void onInit(GrGLSLVaryingHandler*, GrGLSLVertexBuilder*) override;
709a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void setupRect(GrGLSLVertexBuilder*) override;
710a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void setupOval(GrGLSLVertexBuilder*) override;
711a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void adjustRRectVertices(GrGLSLVertexBuilder*) override;
712a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void onSetupRRect(GrGLSLVertexBuilder*) override;
713a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
714a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void onInitInnerShape(GrGLSLVaryingHandler*, GrGLSLVertexBuilder*) override;
715a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void setupInnerRect(GrGLSLVertexBuilder*) override;
716a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void setupInnerOval(GrGLSLVertexBuilder*) override;
7170caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton    void onSetupInnerSimpleRRect(GrGLSLVertexBuilder*) override;
718a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
719a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void onEmitCode(GrGLSLVertexBuilder*, GrGLSLPPFragmentBuilder*, const char* outCoverage,
720a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                    const char* outColor) override;
721a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
722a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void emitRect(GrGLSLPPFragmentBuilder*, const char* outCoverage, const char* outColor);
723a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void emitCircle(GrGLSLPPFragmentBuilder*, const char* outCoverage);
724a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void emitArc(GrGLSLPPFragmentBuilder* f, const char* ellipseCoords, const char* ellipseName,
725a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                 bool ellipseCoordsNeedClamp, bool ellipseCoordsMayBeNegative,
726a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                 const char* outCoverage);
727a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void emitInnerRect(GrGLSLPPFragmentBuilder*, const char* outCoverage);
728a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
729a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GrGLSLVertToFrag   fColorTimesRectCoverage;
730a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GrGLSLVertToFrag   fRectCoverage;
731a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GrGLSLVertToFrag   fEllipseCoords;
732a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GrGLSLVertToFrag   fEllipseName;
733a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GrGLSLVertToFrag   fBloatedRadius;
734a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GrGLSLVertToFrag   fDistanceToInnerEdge;
735a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GrGLSLVertToFrag   fInnerShapeBloatedHalfSize;
736a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GrGLSLVertToFrag   fInnerEllipseCoords;
737a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GrGLSLVertToFrag   fInnerEllipseName;
738a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    bool               fShapeIsCircle;
739a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    bool               fTweakAlphaForCoverage;
740a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
741a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    typedef Backend INHERITED;
742a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton};
743a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
744a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendCoverage::onInit(GrGLSLVaryingHandler* varyingHandler,
745a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                    GrGLSLVertexBuilder* v) {
746a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppend ("mat2 shapeTransposeMatrix = transpose(mat2(shapeMatrix));");
747a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppend ("vec2 shapeHalfSize = vec2(length(shapeTransposeMatrix[0]), "
748a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                             "length(shapeTransposeMatrix[1]));");
749a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppend ("vec2 bloat = 0.5 / shapeHalfSize;");
750a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppendf("bloatedShapeCoords = %s * (1.0 + bloat);", fInputs.attr(Attrib::kShapeCoords));
751a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
752a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (kOval_ShapeFlag != fBatchInfo.fShapeTypes) {
753a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        if (fTweakAlphaForCoverage) {
754a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            varyingHandler->addVarying("colorTimesRectCoverage", &fColorTimesRectCoverage,
755a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                       kLow_GrSLPrecision);
756a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            if (kRect_ShapeFlag == fBatchInfo.fShapeTypes) {
757a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                fColor = fColorTimesRectCoverage;
758a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            }
759a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        } else {
760a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            varyingHandler->addVarying("rectCoverage", &fRectCoverage, kLow_GrSLPrecision);
761a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
762a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppend("float rectCoverage = 0.0;");
763a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
764a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (kRect_ShapeFlag != fBatchInfo.fShapeTypes) {
765dd57dd796845da6ec2e1f44dc1e0b7821c1e4db1csmartdalton        varyingHandler->addFlatVarying("triangleIsArc", &fTriangleIsArc, kLow_GrSLPrecision);
766a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        if (!fShapeIsCircle) {
767dd57dd796845da6ec2e1f44dc1e0b7821c1e4db1csmartdalton            varyingHandler->addVarying("ellipseCoords", &fEllipseCoords, kMedium_GrSLPrecision);
768a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            varyingHandler->addFlatVarying("ellipseName", &fEllipseName, kHigh_GrSLPrecision);
769a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        } else {
770a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            varyingHandler->addVarying("circleCoords", &fEllipseCoords, kMedium_GrSLPrecision);
771a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            varyingHandler->addFlatVarying("bloatedRadius", &fBloatedRadius, kMedium_GrSLPrecision);
772a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
773a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
774a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
775a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
776a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendCoverage::setupRect(GrGLSLVertexBuilder* v) {
777a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // Make the border one pixel wide. Inner vs outer is indicated by coordAttrs.
778a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppendf("vec2 rectBloat = (%s != 0) ? bloat : -bloat;",
779a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                   fInputs.attr(Attrib::kVertexAttrs));
780a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // Here we use the absolute value, because when the rect is thinner than a pixel, this makes it
781a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // mark the spot where pixel center is within half a pixel of the *opposite* edge. This,
782a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // combined with the "maxCoverage" logic below gives us mathematically correct coverage even for
783a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // subpixel rectangles.
784a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppendf("bloatedShapeCoords = %s * abs(vec2(1.0 + rectBloat));",
785a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                   fInputs.attr(Attrib::kShapeCoords));
786a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
787a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // Determine coverage at the vertex. Coverage naturally ramps from 0 to 1 unless the rect is
788a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // narrower than a pixel.
789a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppend ("float maxCoverage = 4.0 * min(0.5, shapeHalfSize.x) *"
790a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                             "min(0.5, shapeHalfSize.y);");
791a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppendf("rectCoverage = (%s != 0) ? 0.0 : maxCoverage;",
792a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                   fInputs.attr(Attrib::kVertexAttrs));
793a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
794a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fTriangleIsArc.vsOut()) {
795a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = 0;", fTriangleIsArc.vsOut());
796a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
797a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
798a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
799a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendCoverage::setupOval(GrGLSLVertexBuilder* v) {
800a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // Offset the inner and outer octagons by one pixel. Inner vs outer is indicated by coordAttrs.
801a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppendf("vec2 ovalBloat = (%s != 0) ? bloat : -bloat;",
802a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                   fInputs.attr(Attrib::kVertexAttrs));
803a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppendf("bloatedShapeCoords = %s * max(vec2(1.0 + ovalBloat), vec2(0));",
804a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                   fInputs.attr(Attrib::kShapeCoords));
805a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppendf("%s = bloatedShapeCoords * shapeHalfSize;", fEllipseCoords.vsOut());
806a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fEllipseName.vsOut()) {
807a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = 1.0 / (shapeHalfSize * shapeHalfSize);", fEllipseName.vsOut());
808a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
809a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fBloatedRadius.vsOut()) {
810a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        SkASSERT(fShapeIsCircle);
811a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = shapeHalfSize.x + 0.5;", fBloatedRadius.vsOut());
812a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
813a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fTriangleIsArc.vsOut()) {
814a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = int(%s != 0);",
815a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       fTriangleIsArc.vsOut(), fInputs.attr(Attrib::kVertexAttrs));
816a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
817a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fColorTimesRectCoverage.vsOut() || fRectCoverage.vsOut()) {
818a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("rectCoverage = 1.0;");
819a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
820a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
821a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
822a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendCoverage::adjustRRectVertices(GrGLSLVertexBuilder* v) {
823a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // We try to let the AA borders line up with the arc edges on their particular side, but we
824a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // can't allow them to get closer than one half pixel to the edge or they might overlap with
825a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // their neighboring border.
826a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppend("vec2 innerEdge = max(1.0 - bloat, vec2(0));");
827a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppend ("vec2 borderEdge = cornerSign * clamp(1.0 - radii, -innerEdge, innerEdge);");
828a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // 0.5 is a special value that indicates this vertex is an arc edge.
829a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppendf("if (abs(%s.x) == 0.5)"
830a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       "bloatedShapeCoords.x = borderEdge.x;", fInputs.attr(Attrib::kShapeCoords));
831a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppendf("if (abs(%s.y) == 0.5)"
832a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       "bloatedShapeCoords.y = borderEdge.y;", fInputs.attr(Attrib::kShapeCoords));
833a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
834a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // Adjust the interior border vertices to make the border one pixel wide. 0.75 is a special
835a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // value to indicate these points.
836a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppendf("if (abs(%s.x) == 0.75) "
837a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       "bloatedShapeCoords.x = cornerSign.x * innerEdge.x;",
838a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       fInputs.attr(Attrib::kShapeCoords));
839a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppendf("if (abs(%s.y) == 0.75) "
840a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       "bloatedShapeCoords.y = cornerSign.y * innerEdge.y;",
841a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       fInputs.attr(Attrib::kShapeCoords));
842a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
843a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
844a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendCoverage::onSetupRRect(GrGLSLVertexBuilder* v) {
845a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // The geometry is laid out in such a way that rectCoverage will be 0 and 1 on the vertices, but
846a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // we still need to recompute this value because when the rrect gets thinner than one pixel, the
847a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // interior edge of the border will necessarily clamp, and we need to match the AA behavior of
848a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // the arc segments (i.e. distance from bloated edge only; ignoring the fact that the pixel
849a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // actully has less coverage because it's not completely inside the opposite edge.)
850a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppend("vec2 d = shapeHalfSize + 0.5 - abs(bloatedShapeCoords) * shapeHalfSize;");
851a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppend("rectCoverage = min(d.x, d.y);");
852a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
853a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    SkASSERT(!fShapeIsCircle);
854a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // The AA border does not get closer than one half pixel to the edge of the rect, so to get a
855a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // smooth transition from flat edge to arc, we don't allow the radii to be smaller than one half
856a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // pixel. (We don't worry about the transition on the opposite side when a radius is so large
857a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // that the border clamped on that side.)
858a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppendf("vec2 clampedRadii = max(radii, bloat);");
859a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppendf("%s = (cornerSign * bloatedShapeCoords + clampedRadii - vec2(1)) * "
860a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                        "shapeHalfSize;", fEllipseCoords.vsOut());
861a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppendf("%s = 1.0 / (clampedRadii * clampedRadii * shapeHalfSize * shapeHalfSize);",
862a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                   fEllipseName.vsOut());
863a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
864a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
865a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendCoverage::onInitInnerShape(GrGLSLVaryingHandler* varyingHandler,
866a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                              GrGLSLVertexBuilder* v) {
867a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppend("vec2 innerShapeHalfSize = shapeHalfSize / outer2Inner.xy;");
868a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
869a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (kOval_ShapeFlag == fBatchInfo.fInnerShapeTypes) {
870a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        varyingHandler->addVarying("innerEllipseCoords", &fInnerEllipseCoords,
871a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                   kMedium_GrSLPrecision);
872dd57dd796845da6ec2e1f44dc1e0b7821c1e4db1csmartdalton        varyingHandler->addFlatVarying("innerEllipseName", &fInnerEllipseName, kHigh_GrSLPrecision);
873a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    } else {
874a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        varyingHandler->addVarying("distanceToInnerEdge", &fDistanceToInnerEdge,
875a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                   kMedium_GrSLPrecision);
876a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        varyingHandler->addFlatVarying("innerShapeBloatedHalfSize", &fInnerShapeBloatedHalfSize,
877a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                       kMedium_GrSLPrecision);
878a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        if (kRect_ShapeFlag != fBatchInfo.fInnerShapeTypes) {
879dd57dd796845da6ec2e1f44dc1e0b7821c1e4db1csmartdalton            varyingHandler->addVarying("innerShapeCoords", &fInnerShapeCoords,
880dd57dd796845da6ec2e1f44dc1e0b7821c1e4db1csmartdalton                                       kMedium_GrSLPrecision);
881a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            varyingHandler->addFlatVarying("innerEllipseName", &fInnerEllipseName,
882dd57dd796845da6ec2e1f44dc1e0b7821c1e4db1csmartdalton                                           kHigh_GrSLPrecision);
883dd57dd796845da6ec2e1f44dc1e0b7821c1e4db1csmartdalton            varyingHandler->addFlatVarying("innerRRect", &fInnerRRect, kMedium_GrSLPrecision);
884a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
885a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
886a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
887a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
888a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendCoverage::setupInnerRect(GrGLSLVertexBuilder* v) {
889a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fInnerRRect.vsOut()) {
890a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        // The fragment shader will generalize every inner shape as a round rect. Since this one
891a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        // is a rect, we simply emit bogus parameters for the round rect (effectively negative
892a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        // radii) that ensure the fragment shader always takes the "emitRect" codepath.
893a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s.xy = abs(outer2Inner.xy) * (1.0 + bloat) + abs(outer2Inner.zw);",
894a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       fInnerRRect.vsOut());
895a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
896a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
897a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
898a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendCoverage::setupInnerOval(GrGLSLVertexBuilder* v) {
899a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppendf("%s = 1.0 / (innerShapeHalfSize * innerShapeHalfSize);",
900a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                   fInnerEllipseName.vsOut());
901a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fInnerEllipseCoords.vsOut()) {
902a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = innerShapeCoords * innerShapeHalfSize;", fInnerEllipseCoords.vsOut());
903a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
904a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fInnerRRect.vsOut()) {
905a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = vec4(0, 0, innerShapeHalfSize);", fInnerRRect.vsOut());
906a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
907a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
908a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
9090caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdaltonvoid GLSLInstanceProcessor::BackendCoverage::onSetupInnerSimpleRRect(GrGLSLVertexBuilder* v) {
910a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // The distance to ellipse formula doesn't work well when the radii are less than half a pixel.
911a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppend ("innerRadii = max(innerRadii, bloat);");
912a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppendf("%s = 1.0 / (innerRadii * innerRadii * innerShapeHalfSize * "
913a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                               "innerShapeHalfSize);",
914a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                   fInnerEllipseName.vsOut());
915a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppendf("%s = vec4(1.0 - innerRadii, innerShapeHalfSize);", fInnerRRect.vsOut());
916a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
917a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
918a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendCoverage::onEmitCode(GrGLSLVertexBuilder* v,
919a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                        GrGLSLPPFragmentBuilder* f,
920a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                        const char* outCoverage,
921a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                        const char* outColor) {
922a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fColorTimesRectCoverage.vsOut()) {
923a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        SkASSERT(!fRectCoverage.vsOut());
924a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = %s * rectCoverage;",
925a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       fColorTimesRectCoverage.vsOut(), fInputs.attr(Attrib::kColor));
926a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
927a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fRectCoverage.vsOut()) {
928a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        SkASSERT(!fColorTimesRectCoverage.vsOut());
929a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = rectCoverage;", fRectCoverage.vsOut());
930a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
931a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
932a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    SkString coverage("float coverage");
933a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (f->getProgramBuilder()->glslCaps()->usesPrecisionModifiers()) {
934a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        coverage.prependf("lowp ");
935a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
936a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fBatchInfo.fInnerShapeTypes || (!fTweakAlphaForCoverage && fTriangleIsArc.fsIn())) {
937a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppendf("%s;", coverage.c_str());
938a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        coverage = "coverage";
939a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
940a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fTriangleIsArc.fsIn()) {
941a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppendf("if (%s == 0) {", fTriangleIsArc.fsIn());
942a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        this->emitRect(f, coverage.c_str(), outColor);
943a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppend ("} else {");
944a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        if (fShapeIsCircle) {
945a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            this->emitCircle(f, coverage.c_str());
946a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        } else {
947a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            bool ellipseCoordsMayBeNegative = SkToBool(fBatchInfo.fShapeTypes & kOval_ShapeFlag);
948a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            this->emitArc(f, fEllipseCoords.fsIn(), fEllipseName.fsIn(),
949a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                          true /*ellipseCoordsNeedClamp*/, ellipseCoordsMayBeNegative,
950a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                          coverage.c_str());
951a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
952a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        if (fTweakAlphaForCoverage) {
953a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppendf("%s = %s * coverage;", outColor, fColor.fsIn());
954a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
955a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppend ("}");
956a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    } else {
957a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        this->emitRect(f, coverage.c_str(), outColor);
958a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
959a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
960a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fBatchInfo.fInnerShapeTypes) {
961a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppendf("// Inner shape.\n");
962a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        SkString innerCoverageDecl("float innerCoverage");
963a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        if (f->getProgramBuilder()->glslCaps()->usesPrecisionModifiers()) {
964a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            innerCoverageDecl.prependf("lowp ");
965a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
966a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        if (kOval_ShapeFlag == fBatchInfo.fInnerShapeTypes) {
967a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            this->emitArc(f, fInnerEllipseCoords.fsIn(), fInnerEllipseName.fsIn(),
968a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                          true /*ellipseCoordsNeedClamp*/, true /*ellipseCoordsMayBeNegative*/,
969a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                          innerCoverageDecl.c_str());
970a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        } else {
971a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            v->codeAppendf("%s = innerShapeCoords * innerShapeHalfSize;",
972a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                           fDistanceToInnerEdge.vsOut());
973a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            v->codeAppendf("%s = innerShapeHalfSize + 0.5;", fInnerShapeBloatedHalfSize.vsOut());
974a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
975a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            if (kRect_ShapeFlag == fBatchInfo.fInnerShapeTypes) {
976a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                this->emitInnerRect(f, innerCoverageDecl.c_str());
977a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            } else {
978a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                f->codeAppendf("%s = 0.0;", innerCoverageDecl.c_str());
979dd57dd796845da6ec2e1f44dc1e0b7821c1e4db1csmartdalton                f->appendPrecisionModifier(kMedium_GrSLPrecision);
980a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                f->codeAppendf("vec2 distanceToArcEdge = abs(%s) - %s.xy;",
981a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                               fInnerShapeCoords.fsIn(), fInnerRRect.fsIn());
982a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                f->codeAppend ("if (any(lessThan(distanceToArcEdge, vec2(1e-5)))) {");
983a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                this->emitInnerRect(f, "innerCoverage");
984a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                f->codeAppend ("} else {");
985dd57dd796845da6ec2e1f44dc1e0b7821c1e4db1csmartdalton                f->appendPrecisionModifier(kMedium_GrSLPrecision);
986a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                f->codeAppendf(    "vec2 ellipseCoords = distanceToArcEdge * %s.zw;",
987a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                   fInnerRRect.fsIn());
988a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                this->emitArc(f, "ellipseCoords", fInnerEllipseName.fsIn(),
989a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                              false /*ellipseCoordsNeedClamp*/,
990a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                              false /*ellipseCoordsMayBeNegative*/, "innerCoverage");
991a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                f->codeAppend ("}");
992a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            }
993a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
994a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppendf("%s = vec4(max(coverage - innerCoverage, 0.0));", outCoverage);
995a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    } else if (!fTweakAlphaForCoverage) {
996a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppendf("%s = vec4(coverage);", outCoverage);
997a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
998a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
999a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1000a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendCoverage::emitRect(GrGLSLPPFragmentBuilder* f,
1001a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                      const char* outCoverage,
1002a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                      const char* outColor) {
1003a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fColorTimesRectCoverage.fsIn()) {
1004a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppendf("%s = %s;", outColor, fColorTimesRectCoverage.fsIn());
1005a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    } else if (fTweakAlphaForCoverage) {
1006a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        // We are drawing just ovals. The interior rect always has 100% coverage.
1007a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppendf("%s = %s;", outColor, fColor.fsIn());
1008a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    } else if (fRectCoverage.fsIn()) {
1009a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppendf("%s = %s;", outCoverage, fRectCoverage.fsIn());
1010a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    } else {
1011a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppendf("%s = 1.0;", outCoverage);
1012a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1013a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
1014a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1015a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendCoverage::emitCircle(GrGLSLPPFragmentBuilder* f,
1016a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                        const char* outCoverage) {
1017a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // TODO: circleCoords = max(circleCoords, 0) if we decide to do this optimization on rrects.
1018a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    SkASSERT(!(kRRect_ShapesMask & fBatchInfo.fShapeTypes));
1019dd57dd796845da6ec2e1f44dc1e0b7821c1e4db1csmartdalton    f->appendPrecisionModifier(kLow_GrSLPrecision);
1020a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    f->codeAppendf("float distanceToEdge = %s - length(%s);",
1021a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                   fBloatedRadius.fsIn(), fEllipseCoords.fsIn());
1022a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    f->codeAppendf("%s = clamp(distanceToEdge, 0.0, 1.0);", outCoverage);
1023a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
1024a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1025a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendCoverage::emitArc(GrGLSLPPFragmentBuilder* f,
1026a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                     const char* ellipseCoords,
1027a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                     const char* ellipseName,
1028a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                     bool ellipseCoordsNeedClamp,
1029a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                     bool ellipseCoordsMayBeNegative,
1030a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                     const char* outCoverage) {
1031a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    SkASSERT(!ellipseCoordsMayBeNegative || ellipseCoordsNeedClamp);
1032a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (ellipseCoordsNeedClamp) {
1033a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        // This serves two purposes:
1034a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        //  - To restrict the arcs of rounded rects to their positive quadrants.
1035a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        //  - To avoid inversesqrt(0) in the ellipse formula.
1036dd57dd796845da6ec2e1f44dc1e0b7821c1e4db1csmartdalton        f->appendPrecisionModifier(kMedium_GrSLPrecision);
1037a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        if (ellipseCoordsMayBeNegative) {
1038a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppendf("vec2 ellipseClampedCoords = max(abs(%s), vec2(1e-4));", ellipseCoords);
1039a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        } else {
1040a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppendf("vec2 ellipseClampedCoords = max(%s, vec2(1e-4));", ellipseCoords);
1041a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
1042a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        ellipseCoords = "ellipseClampedCoords";
1043a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1044a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // ellipseCoords are in pixel space and ellipseName is 1 / rx^2, 1 / ry^2.
1045dd57dd796845da6ec2e1f44dc1e0b7821c1e4db1csmartdalton    f->appendPrecisionModifier(kHigh_GrSLPrecision);
1046a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    f->codeAppendf("vec2 Z = %s * %s;", ellipseCoords, ellipseName);
1047a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // implicit is the evaluation of (x/rx)^2 + (y/ry)^2 - 1.
1048dd57dd796845da6ec2e1f44dc1e0b7821c1e4db1csmartdalton    f->appendPrecisionModifier(kHigh_GrSLPrecision);
1049a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    f->codeAppendf("float implicit = dot(Z, %s) - 1.0;", ellipseCoords);
1050a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // gradDot is the squared length of the gradient of the implicit.
1051dd57dd796845da6ec2e1f44dc1e0b7821c1e4db1csmartdalton    f->appendPrecisionModifier(kHigh_GrSLPrecision);
1052a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    f->codeAppendf("float gradDot = 4.0 * dot(Z, Z);");
1053dd57dd796845da6ec2e1f44dc1e0b7821c1e4db1csmartdalton    f->appendPrecisionModifier(kMedium_GrSLPrecision);
1054a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    f->codeAppend ("float approxDist = implicit * inversesqrt(gradDot);");
1055a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    f->codeAppendf("%s = clamp(0.5 - approxDist, 0.0, 1.0);", outCoverage);
1056a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
1057a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1058a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendCoverage::emitInnerRect(GrGLSLPPFragmentBuilder* f,
1059a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                           const char* outCoverage) {
1060a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    f->appendPrecisionModifier(kLow_GrSLPrecision);
1061a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    f->codeAppendf("vec2 c = %s - abs(%s);",
1062a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                   fInnerShapeBloatedHalfSize.fsIn(), fDistanceToInnerEdge.fsIn());
1063a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    f->codeAppendf("%s = clamp(min(c.x, c.y), 0.0, 1.0);", outCoverage);
1064a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
1065a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1066a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton////////////////////////////////////////////////////////////////////////////////////////////////////
1067a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1068a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonclass GLSLInstanceProcessor::BackendMultisample : public Backend {
1069a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonpublic:
1070a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    BackendMultisample(BatchInfo batchInfo, const VertexInputs& inputs, int effectiveSampleCnt)
1071a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        : INHERITED(batchInfo, inputs),
1072a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton          fEffectiveSampleCnt(effectiveSampleCnt),
1073a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton          fShapeCoords(kVec2f_GrSLType),
1074a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton          fShapeInverseMatrix(kMat22f_GrSLType),
1075a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton          fFragShapeHalfSpan(kVec2f_GrSLType),
1076a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton          fArcTest(kVec2f_GrSLType),
1077a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton          fArcInverseMatrix(kMat22f_GrSLType),
1078a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton          fFragArcHalfSpan(kVec2f_GrSLType),
1079a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton          fEarlyAccept(kInt_GrSLType),
1080a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton          fInnerShapeInverseMatrix(kMat22f_GrSLType),
1081a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton          fFragInnerShapeHalfSpan(kVec2f_GrSLType) {
1082a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        fRectTrianglesMaySplit = fBatchInfo.fHasPerspective;
1083a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        fNeedsNeighborRadii = this->isMixedSampled() && !fBatchInfo.fHasPerspective;
1084a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1085a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1086a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonprivate:
1087a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    bool isMixedSampled() const { return AntialiasMode::kMixedSamples == fBatchInfo.fAntialiasMode; }
1088a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1089a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void onInit(GrGLSLVaryingHandler*, GrGLSLVertexBuilder*) override;
1090a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void setupRect(GrGLSLVertexBuilder*) override;
1091a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void setupOval(GrGLSLVertexBuilder*) override;
1092a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void adjustRRectVertices(GrGLSLVertexBuilder*) override;
1093a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void onSetupRRect(GrGLSLVertexBuilder*) override;
1094a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1095a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void onInitInnerShape(GrGLSLVaryingHandler*, GrGLSLVertexBuilder*) override;
1096a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void setupInnerRect(GrGLSLVertexBuilder*) override;
1097a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void setupInnerOval(GrGLSLVertexBuilder*) override;
10980caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton    void onSetupInnerSimpleRRect(GrGLSLVertexBuilder*) override;
1099a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1100a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void onEmitCode(GrGLSLVertexBuilder*, GrGLSLPPFragmentBuilder*, const char*,
1101a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                    const char*) override;
1102a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1103a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    struct EmitShapeCoords {
1104a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        const GrGLSLVarying*   fVarying;
1105a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        const char*            fInverseMatrix;
1106a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        const char*            fFragHalfSpan;
1107a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    };
1108a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1109a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    struct EmitShapeOpts {
1110a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        bool fIsTightGeometry;
1111a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        bool fResolveMixedSamples;
1112a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        bool fInvertCoverage;
1113a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    };
1114a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1115a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void emitRect(GrGLSLPPFragmentBuilder*, const EmitShapeCoords&, const EmitShapeOpts&);
1116a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void emitArc(GrGLSLPPFragmentBuilder*, const EmitShapeCoords&, bool coordsMayBeNegative,
1117a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                 bool clampCoords, const EmitShapeOpts&);
1118a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void emitSimpleRRect(GrGLSLPPFragmentBuilder*, const EmitShapeCoords&, const char* rrect,
1119a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                         const EmitShapeOpts&);
1120a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void interpolateAtSample(GrGLSLPPFragmentBuilder*, const GrGLSLVarying&, const char* sampleIdx,
1121a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                             const char* interpolationMatrix);
1122a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void acceptOrRejectWholeFragment(GrGLSLPPFragmentBuilder*, bool inside, const EmitShapeOpts&);
1123a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void acceptCoverageMask(GrGLSLPPFragmentBuilder*, const char* shapeMask, const EmitShapeOpts&,
1124a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                            bool maybeSharedEdge = true);
1125a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1126a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    int                fEffectiveSampleCnt;
1127a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    bool               fRectTrianglesMaySplit;
1128a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GrGLSLVertToFrag   fShapeCoords;
1129a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GrGLSLVertToFrag   fShapeInverseMatrix;
1130a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GrGLSLVertToFrag   fFragShapeHalfSpan;
1131a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GrGLSLVertToFrag   fArcTest;
1132a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GrGLSLVertToFrag   fArcInverseMatrix;
1133a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GrGLSLVertToFrag   fFragArcHalfSpan;
1134a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GrGLSLVertToFrag   fEarlyAccept;
1135a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GrGLSLVertToFrag   fInnerShapeInverseMatrix;
1136a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GrGLSLVertToFrag   fFragInnerShapeHalfSpan;
1137a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    SkString           fSquareFun;
1138a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1139a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    typedef Backend INHERITED;
1140a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton};
1141a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1142a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendMultisample::onInit(GrGLSLVaryingHandler* varyingHandler,
1143a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                       GrGLSLVertexBuilder* v) {
1144a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (!this->isMixedSampled()) {
1145a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        if (kRect_ShapeFlag != fBatchInfo.fShapeTypes) {
1146dd57dd796845da6ec2e1f44dc1e0b7821c1e4db1csmartdalton            varyingHandler->addFlatVarying("triangleIsArc", &fTriangleIsArc, kLow_GrSLPrecision);
1147a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            varyingHandler->addVarying("arcCoords", &fArcCoords, kHigh_GrSLPrecision);
1148a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            if (!fBatchInfo.fHasPerspective) {
1149a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                varyingHandler->addFlatVarying("arcInverseMatrix", &fArcInverseMatrix,
1150a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                               kHigh_GrSLPrecision);
1151a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                varyingHandler->addFlatVarying("fragArcHalfSpan", &fFragArcHalfSpan,
1152a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                               kHigh_GrSLPrecision);
1153a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            }
1154a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        } else if (!fBatchInfo.fInnerShapeTypes) {
1155a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            return;
1156a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
1157a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    } else {
1158a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        varyingHandler->addVarying("shapeCoords", &fShapeCoords, kHigh_GrSLPrecision);
1159a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        if (!fBatchInfo.fHasPerspective) {
1160a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            varyingHandler->addFlatVarying("shapeInverseMatrix", &fShapeInverseMatrix,
1161a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                           kHigh_GrSLPrecision);
1162a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            varyingHandler->addFlatVarying("fragShapeHalfSpan", &fFragShapeHalfSpan,
1163a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                           kHigh_GrSLPrecision);
1164a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
1165a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        if (fBatchInfo.fShapeTypes & kRRect_ShapesMask) {
1166a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            varyingHandler->addVarying("arcCoords", &fArcCoords, kHigh_GrSLPrecision);
1167a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            varyingHandler->addVarying("arcTest", &fArcTest, kHigh_GrSLPrecision);
1168a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            if (!fBatchInfo.fHasPerspective) {
1169a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                varyingHandler->addFlatVarying("arcInverseMatrix", &fArcInverseMatrix,
1170a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                               kHigh_GrSLPrecision);
1171a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                varyingHandler->addFlatVarying("fragArcHalfSpan", &fFragArcHalfSpan,
1172a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                               kHigh_GrSLPrecision);
1173a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            }
1174a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        } else if (fBatchInfo.fShapeTypes & kOval_ShapeFlag) {
1175a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            fArcCoords = fShapeCoords;
1176a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            fArcInverseMatrix = fShapeInverseMatrix;
1177a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            fFragArcHalfSpan = fFragShapeHalfSpan;
1178a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            if (fBatchInfo.fShapeTypes & kRect_ShapeFlag) {
1179a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                varyingHandler->addFlatVarying("triangleIsArc", &fTriangleIsArc,
1180dd57dd796845da6ec2e1f44dc1e0b7821c1e4db1csmartdalton                                               kLow_GrSLPrecision);
1181a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            }
1182a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
1183a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        if (kRect_ShapeFlag != fBatchInfo.fShapeTypes) {
1184a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton           v->definef("SAMPLE_MASK_ALL", "0x%x", (1 << fEffectiveSampleCnt) - 1);
1185a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton           varyingHandler->addFlatVarying("earlyAccept", &fEarlyAccept, kHigh_GrSLPrecision);
1186a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
1187a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1188a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (!fBatchInfo.fHasPerspective) {
1189a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppend("mat2 shapeInverseMatrix = inverse(mat2(shapeMatrix));");
1190a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppend("vec2 fragShapeSpan = abs(vec4(shapeInverseMatrix).xz) + "
1191a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                           "abs(vec4(shapeInverseMatrix).yw);");
1192a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1193a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
1194a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1195a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendMultisample::setupRect(GrGLSLVertexBuilder* v) {
1196a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fShapeCoords.vsOut()) {
1197a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = %s;", fShapeCoords.vsOut(), this->outShapeCoords());
1198a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1199a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fShapeInverseMatrix.vsOut()) {
1200a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = shapeInverseMatrix;", fShapeInverseMatrix.vsOut());
1201a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1202a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fFragShapeHalfSpan.vsOut()) {
1203a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = 0.5 * fragShapeSpan;", fFragShapeHalfSpan.vsOut());
1204a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1205a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fArcTest.vsOut()) {
1206a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        // Pick a value that is not > 0.
1207a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = vec2(0);", fArcTest.vsOut());
1208a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1209a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fTriangleIsArc.vsOut()) {
1210a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = 0;", fTriangleIsArc.vsOut());
1211a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1212a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fEarlyAccept.vsOut()) {
1213a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = SAMPLE_MASK_ALL;", fEarlyAccept.vsOut());
1214a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1215a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
1216a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1217a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendMultisample::setupOval(GrGLSLVertexBuilder* v) {
1218a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppendf("%s = abs(%s);", fArcCoords.vsOut(), this->outShapeCoords());
1219a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fArcInverseMatrix.vsOut()) {
1220a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("vec2 s = sign(%s);", this->outShapeCoords());
1221a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = shapeInverseMatrix * mat2(s.x, 0, 0 , s.y);",
1222a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       fArcInverseMatrix.vsOut());
1223a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1224a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fFragArcHalfSpan.vsOut()) {
1225a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = 0.5 * fragShapeSpan;", fFragArcHalfSpan.vsOut());
1226a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1227a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fArcTest.vsOut()) {
1228a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        // Pick a value that is > 0.
1229a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = vec2(1);", fArcTest.vsOut());
1230a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1231a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fTriangleIsArc.vsOut()) {
1232a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        if (!this->isMixedSampled()) {
1233a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            v->codeAppendf("%s = %s & 1;",
1234a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                           fTriangleIsArc.vsOut(), fInputs.attr(Attrib::kVertexAttrs));
1235a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        } else {
1236a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            v->codeAppendf("%s = 1;", fTriangleIsArc.vsOut());
1237a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
1238a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1239a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fEarlyAccept.vsOut()) {
1240a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = ~%s & SAMPLE_MASK_ALL;",
1241a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       fEarlyAccept.vsOut(), fInputs.attr(Attrib::kVertexAttrs));
1242a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1243a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
1244a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1245a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendMultisample::adjustRRectVertices(GrGLSLVertexBuilder* v) {
1246a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (!this->isMixedSampled()) {
1247a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        INHERITED::adjustRRectVertices(v);
1248a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        return;
1249a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1250a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1251a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (!fBatchInfo.fHasPerspective) {
1252a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        // For the mixed samples algorithm it's best to bloat the corner triangles a bit so that
1253a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        // more of the pixels that cross into the arc region are completely inside the shared edges.
1254a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        // We also snap to a regular rect if the radii shrink smaller than a pixel.
1255a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppend ("vec2 midpt = 0.5 * (neighborRadii - radii);");
1256a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppend ("vec2 cornerSize = any(lessThan(radii, fragShapeSpan)) ? "
1257a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                           "vec2(0) : min(radii + 0.5 * fragShapeSpan, 1.0 - midpt);");
1258a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    } else {
1259a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        // TODO: We could still bloat the corner triangle in the perspective case; we would just
1260a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        // need to find the screen-space derivative of shape coords at this particular point.
1261a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppend ("vec2 cornerSize = any(lessThan(radii, vec2(1e-3))) ? vec2(0) : radii;");
1262a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1263a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1264a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppendf("if (abs(%s.x) == 0.5)"
1265a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       "%s.x = cornerSign.x * (1.0 - cornerSize.x);",
1266a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       fInputs.attr(Attrib::kShapeCoords), fModifiedShapeCoords);
1267a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppendf("if (abs(%s.y) == 0.5)"
1268a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       "%s.y = cornerSign.y * (1.0 - cornerSize.y);",
1269a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       fInputs.attr(Attrib::kShapeCoords), fModifiedShapeCoords);
1270a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
1271a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1272a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendMultisample::onSetupRRect(GrGLSLVertexBuilder* v) {
1273a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fShapeCoords.vsOut()) {
1274a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = %s;", fShapeCoords.vsOut(), this->outShapeCoords());
1275a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1276a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fShapeInverseMatrix.vsOut()) {
1277a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = shapeInverseMatrix;", fShapeInverseMatrix.vsOut());
1278a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1279a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fFragShapeHalfSpan.vsOut()) {
1280a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = 0.5 * fragShapeSpan;", fFragShapeHalfSpan.vsOut());
1281a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1282a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fArcInverseMatrix.vsOut()) {
1283a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppend ("vec2 s = cornerSign / radii;");
1284a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = shapeInverseMatrix * mat2(s.x, 0, 0, s.y);",
1285a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       fArcInverseMatrix.vsOut());
1286a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1287a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fFragArcHalfSpan.vsOut()) {
1288a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = 0.5 * (abs(vec4(%s).xz) + abs(vec4(%s).yw));",
1289a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       fFragArcHalfSpan.vsOut(), fArcInverseMatrix.vsOut(),
1290a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       fArcInverseMatrix.vsOut());
1291a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1292a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fArcTest.vsOut()) {
1293a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        // The interior triangles are laid out as a fan. fArcTest is both distances from shared
1294a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        // edges of a fan triangle to a point within that triangle. fArcTest is used to check if a
1295a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        // fragment is too close to either shared edge, in which case we point sample the shape as a
1296a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        // rect at that point in order to guarantee the mixed samples discard logic works correctly.
1297a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = (cornerSize == vec2(0)) ? vec2(0) : "
1298a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       "cornerSign * %s * mat2(1, cornerSize.x - 1.0, cornerSize.y - 1.0, 1);",
1299a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       fArcTest.vsOut(), fModifiedShapeCoords);
1300a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        if (!fBatchInfo.fHasPerspective) {
1301a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            // Shift the point at which distances to edges are measured from the center of the pixel
1302a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            // to the corner. This way the sign of fArcTest will quickly tell us whether a pixel
1303a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            // is completely inside the shared edge. Perspective mode will accomplish this same task
1304a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            // by finding the derivatives in the fragment shader.
1305a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            v->codeAppendf("%s -= 0.5 * (fragShapeSpan.yx * abs(radii - 1.0) + fragShapeSpan);",
1306a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                           fArcTest.vsOut());
1307a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
1308a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1309a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fEarlyAccept.vsOut()) {
1310a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        SkASSERT(this->isMixedSampled());
1311a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = all(equal(vec2(1), abs(%s))) ? 0 : SAMPLE_MASK_ALL;",
1312a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       fEarlyAccept.vsOut(), fInputs.attr(Attrib::kShapeCoords));
1313a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1314a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
1315a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1316a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid
1317a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonGLSLInstanceProcessor::BackendMultisample::onInitInnerShape(GrGLSLVaryingHandler* varyingHandler,
1318a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                            GrGLSLVertexBuilder* v) {
1319a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    varyingHandler->addVarying("innerShapeCoords", &fInnerShapeCoords, kHigh_GrSLPrecision);
1320a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (kOval_ShapeFlag != fBatchInfo.fInnerShapeTypes &&
1321a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        kRect_ShapeFlag != fBatchInfo.fInnerShapeTypes) {
1322a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        varyingHandler->addFlatVarying("innerRRect", &fInnerRRect, kHigh_GrSLPrecision);
1323a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1324a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (!fBatchInfo.fHasPerspective) {
1325a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        varyingHandler->addFlatVarying("innerShapeInverseMatrix", &fInnerShapeInverseMatrix,
1326a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                       kHigh_GrSLPrecision);
1327a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = shapeInverseMatrix * mat2(outer2Inner.x, 0, 0, outer2Inner.y);",
1328a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       fInnerShapeInverseMatrix.vsOut());
1329a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        varyingHandler->addFlatVarying("fragInnerShapeHalfSpan", &fFragInnerShapeHalfSpan,
1330a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                       kHigh_GrSLPrecision);
1331a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = 0.5 * fragShapeSpan * outer2Inner.xy;",
1332a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       fFragInnerShapeHalfSpan.vsOut());
1333a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1334a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
1335a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1336a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendMultisample::setupInnerRect(GrGLSLVertexBuilder* v) {
1337a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fInnerRRect.vsOut()) {
1338a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        // The fragment shader will generalize every inner shape as a round rect. Since this one
1339a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        // is a rect, we simply emit bogus parameters for the round rect (negative radii) that
1340a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        // ensure the fragment shader always takes the "sample as rect" codepath.
1341a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = vec4(2.0 * (inner.zw - inner.xy) / (outer.zw - outer.xy), vec2(0));",
1342a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       fInnerRRect.vsOut());
1343a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1344a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
1345a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1346a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendMultisample::setupInnerOval(GrGLSLVertexBuilder* v) {
1347a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fInnerRRect.vsOut()) {
1348a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = vec4(0, 0, 1, 1);", fInnerRRect.vsOut());
1349a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1350a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
1351a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
13520caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdaltonvoid GLSLInstanceProcessor::BackendMultisample::onSetupInnerSimpleRRect(GrGLSLVertexBuilder* v) {
1353a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // Avoid numeric instability by not allowing the inner radii to get smaller than 1/10th pixel.
1354a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fFragInnerShapeHalfSpan.vsOut()) {
1355a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("innerRadii = max(innerRadii, 2e-1 * %s);", fFragInnerShapeHalfSpan.vsOut());
1356a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    } else {
1357a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppend ("innerRadii = max(innerRadii, vec2(1e-4));");
1358a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1359a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppendf("%s = vec4(1.0 - innerRadii, 1.0 / innerRadii);", fInnerRRect.vsOut());
1360a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
1361a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1362a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendMultisample::onEmitCode(GrGLSLVertexBuilder*,
1363a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                           GrGLSLPPFragmentBuilder* f,
1364a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                           const char*, const char*) {
1365a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    f->define("SAMPLE_COUNT", fEffectiveSampleCnt);
1366a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (this->isMixedSampled()) {
1367a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->definef("SAMPLE_MASK_ALL", "0x%x", (1 << fEffectiveSampleCnt) - 1);
1368a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->definef("SAMPLE_MASK_MSB", "0x%x", 1 << (fEffectiveSampleCnt - 1));
1369a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1370a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1371a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (kRect_ShapeFlag != (fBatchInfo.fShapeTypes | fBatchInfo.fInnerShapeTypes)) {
1372a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        GrGLSLShaderVar x("x", kVec2f_GrSLType, GrGLSLShaderVar::kNonArray, kHigh_GrSLPrecision);
1373a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->emitFunction(kFloat_GrSLType, "square", 1, &x, "return dot(x, x);", &fSquareFun);
1374a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1375a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1376a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    EmitShapeCoords shapeCoords;
1377a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    shapeCoords.fVarying = &fShapeCoords;
1378a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    shapeCoords.fInverseMatrix = fShapeInverseMatrix.fsIn();
1379a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    shapeCoords.fFragHalfSpan = fFragShapeHalfSpan.fsIn();
1380a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1381a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    EmitShapeCoords arcCoords;
1382a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    arcCoords.fVarying = &fArcCoords;
1383a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    arcCoords.fInverseMatrix = fArcInverseMatrix.fsIn();
1384a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    arcCoords.fFragHalfSpan = fFragArcHalfSpan.fsIn();
1385a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    bool clampArcCoords = this->isMixedSampled() && (fBatchInfo.fShapeTypes & kRRect_ShapesMask);
1386a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1387a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    EmitShapeOpts opts;
1388a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    opts.fIsTightGeometry = true;
1389a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    opts.fResolveMixedSamples = this->isMixedSampled();
1390a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    opts.fInvertCoverage = false;
1391a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1392a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fBatchInfo.fHasPerspective && fBatchInfo.fInnerShapeTypes) {
1393a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        // This determines if the fragment should consider the inner shape in its sample mask.
1394a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        // We take the derivative early in case discards may occur before we get to the inner shape.
1395a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->appendPrecisionModifier(kHigh_GrSLPrecision);
1396a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppendf("vec2 fragInnerShapeApproxHalfSpan = 0.5 * fwidth(%s);",
1397a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       fInnerShapeCoords.fsIn());
1398a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1399a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1400a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (!this->isMixedSampled()) {
1401a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        SkASSERT(!fArcTest.fsIn());
1402a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        if (fTriangleIsArc.fsIn()) {
1403a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppendf("if (%s != 0) {", fTriangleIsArc.fsIn());
1404a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            this->emitArc(f, arcCoords, false, clampArcCoords, opts);
1405a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1406a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppend ("}");
1407a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
1408a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    } else {
1409a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        const char* arcTest = fArcTest.fsIn();
1410a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        SkASSERT(arcTest);
1411a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        if (fBatchInfo.fHasPerspective) {
1412a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            // The non-perspective version accounts for fwith() in the vertex shader.
1413a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            // We make sure to take the derivative here, before a neighbor pixel may early accept.
1414a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->enableFeature(GrGLSLPPFragmentBuilder::kStandardDerivatives_GLSLFeature);
1415a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->appendPrecisionModifier(kHigh_GrSLPrecision);
1416a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppendf("vec2 arcTest = %s - 0.5 * fwidth(%s);",
1417a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                           fArcTest.fsIn(), fArcTest.fsIn());
1418a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            arcTest = "arcTest";
1419a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
1420a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        const char* earlyAccept = fEarlyAccept.fsIn() ? fEarlyAccept.fsIn() : "SAMPLE_MASK_ALL";
1421a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppendf("if (gl_SampleMaskIn[0] == %s) {", earlyAccept);
1422a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->overrideSampleCoverage(earlyAccept);
1423a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppend ("} else {");
1424a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        if (arcTest) {
1425a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            // At this point, if the sample mask is all set it means we are inside an arc triangle.
1426a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppendf("if (gl_SampleMaskIn[0] == SAMPLE_MASK_ALL || "
1427a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                               "all(greaterThan(%s, vec2(0)))) {", arcTest);
1428a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            this->emitArc(f, arcCoords, false, clampArcCoords, opts);
1429a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppend ("} else {");
1430a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            this->emitRect(f, shapeCoords, opts);
1431a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppend ("}");
1432a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        } else if (fTriangleIsArc.fsIn()) {
1433a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppendf("if (%s == 0) {", fTriangleIsArc.fsIn());
1434a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            this->emitRect(f, shapeCoords, opts);
1435a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppend ("} else {");
1436a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            this->emitArc(f, arcCoords, false, clampArcCoords, opts);
1437a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppend ("}");
1438a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        } else if (fBatchInfo.fShapeTypes == kOval_ShapeFlag) {
1439a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            this->emitArc(f, arcCoords, false, clampArcCoords, opts);
1440a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        } else {
1441a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            SkASSERT(fBatchInfo.fShapeTypes == kRect_ShapeFlag);
1442a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            this->emitRect(f, shapeCoords, opts);
1443a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
1444a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppend ("}");
1445a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1446a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1447a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fBatchInfo.fInnerShapeTypes) {
1448a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppendf("// Inner shape.\n");
1449a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1450a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        EmitShapeCoords innerShapeCoords;
1451a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        innerShapeCoords.fVarying = &fInnerShapeCoords;
1452a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        if (!fBatchInfo.fHasPerspective) {
1453a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            innerShapeCoords.fInverseMatrix = fInnerShapeInverseMatrix.fsIn();
1454a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            innerShapeCoords.fFragHalfSpan = fFragInnerShapeHalfSpan.fsIn();
1455a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
1456a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1457a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        EmitShapeOpts innerOpts;
1458a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        innerOpts.fIsTightGeometry = false;
1459a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        innerOpts.fResolveMixedSamples = false; // Mixed samples are resolved in the outer shape.
1460a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        innerOpts.fInvertCoverage = true;
1461a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1462a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        if (kOval_ShapeFlag == fBatchInfo.fInnerShapeTypes) {
1463a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            this->emitArc(f, innerShapeCoords, true, false, innerOpts);
1464a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        } else {
1465a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppendf("if (all(lessThan(abs(%s), 1.0 + %s))) {", fInnerShapeCoords.fsIn(),
1466a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                           !fBatchInfo.fHasPerspective ? innerShapeCoords.fFragHalfSpan
1467a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                       : "fragInnerShapeApproxHalfSpan"); // Above.
1468a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            if (kRect_ShapeFlag == fBatchInfo.fInnerShapeTypes) {
1469a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                this->emitRect(f, innerShapeCoords, innerOpts);
1470a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            } else {
1471a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                this->emitSimpleRRect(f, innerShapeCoords, fInnerRRect.fsIn(), innerOpts);
1472a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            }
1473a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppend ("}");
1474a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
1475a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1476a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
1477a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1478a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendMultisample::emitRect(GrGLSLPPFragmentBuilder* f,
1479a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                         const EmitShapeCoords& coords,
1480a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                         const EmitShapeOpts& opts) {
1481a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // Full MSAA doesn't need to do anything to draw a rect.
1482a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    SkASSERT(!opts.fIsTightGeometry || opts.fResolveMixedSamples);
1483a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (coords.fFragHalfSpan) {
1484a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppendf("if (all(lessThanEqual(abs(%s), 1.0 - %s))) {",
1485a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       coords.fVarying->fsIn(), coords.fFragHalfSpan);
1486a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        // The entire pixel is inside the rect.
1487a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        this->acceptOrRejectWholeFragment(f, true, opts);
1488a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppend ("} else ");
1489a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        if (opts.fIsTightGeometry && !fRectTrianglesMaySplit) {
1490a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppendf("if (any(lessThan(abs(%s), 1.0 - %s))) {",
1491a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                           coords.fVarying->fsIn(), coords.fFragHalfSpan);
1492a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            // The pixel falls on an edge of the rectangle and is known to not be on a shared edge.
1493a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            this->acceptCoverageMask(f, "gl_SampleMaskIn[0]", opts, false);
1494a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppend ("} else");
1495a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
1496a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppend ("{");
1497a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1498a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    f->codeAppend ("int rectMask = 0;");
1499a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    f->codeAppend ("for (int i = 0; i < SAMPLE_COUNT; i++) {");
1500a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    f->appendPrecisionModifier(kHigh_GrSLPrecision);
1501a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    f->codeAppend (    "vec2 pt = ");
1502a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    this->interpolateAtSample(f, *coords.fVarying, "i", coords.fInverseMatrix);
1503a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    f->codeAppend (    ";");
1504a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    f->codeAppend (    "if (all(lessThan(abs(pt), vec2(1)))) rectMask |= (1 << i);");
1505a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    f->codeAppend ("}");
1506a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    this->acceptCoverageMask(f, "rectMask", opts);
1507a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (coords.fFragHalfSpan) {
1508a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppend ("}");
1509a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1510a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
1511a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1512a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendMultisample::emitArc(GrGLSLPPFragmentBuilder* f,
1513a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                        const EmitShapeCoords& coords,
1514a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                        bool coordsMayBeNegative, bool clampCoords,
1515a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                        const EmitShapeOpts& opts) {
1516a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (coords.fFragHalfSpan) {
1517a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        SkString absArcCoords;
1518a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        absArcCoords.printf(coordsMayBeNegative ? "abs(%s)" : "%s", coords.fVarying->fsIn());
1519a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        if (clampCoords) {
1520a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppendf("if (%s(max(%s + %s, vec2(0))) < 1.0) {",
1521a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                           fSquareFun.c_str(), absArcCoords.c_str(), coords.fFragHalfSpan);
1522a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        } else {
1523a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppendf("if (%s(%s + %s) < 1.0) {",
1524a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                           fSquareFun.c_str(), absArcCoords.c_str(), coords.fFragHalfSpan);
1525a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
1526a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        // The entire pixel is inside the arc.
1527a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        this->acceptOrRejectWholeFragment(f, true, opts);
1528a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppendf("} else if (%s(max(%s - %s, vec2(0))) >= 1.0) {",
1529a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       fSquareFun.c_str(), absArcCoords.c_str(), coords.fFragHalfSpan);
1530a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        // The entire pixel is outside the arc.
1531a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        this->acceptOrRejectWholeFragment(f, false, opts);
1532a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppend ("} else {");
1533a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1534a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    f->codeAppend (    "int arcMask = 0;");
1535a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    f->codeAppend (    "for (int i = 0; i < SAMPLE_COUNT; i++) {");
1536a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    f->appendPrecisionModifier(kHigh_GrSLPrecision);
1537a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    f->codeAppend (        "vec2 pt = ");
1538a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    this->interpolateAtSample(f, *coords.fVarying, "i", coords.fInverseMatrix);
1539a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    f->codeAppend (        ";");
1540a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (clampCoords) {
1541a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        SkASSERT(!coordsMayBeNegative);
1542a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppend (    "pt = max(pt, vec2(0));");
1543a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1544a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    f->codeAppendf(        "if (%s(pt) < 1.0) arcMask |= (1 << i);", fSquareFun.c_str());
1545a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    f->codeAppend (    "}");
1546a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    this->acceptCoverageMask(f, "arcMask", opts);
1547a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (coords.fFragHalfSpan) {
1548a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppend ("}");
1549a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1550a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
1551a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1552a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendMultisample::emitSimpleRRect(GrGLSLPPFragmentBuilder* f,
1553a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                                const EmitShapeCoords& coords,
1554a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                                const char* rrect,
1555a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                                const EmitShapeOpts& opts) {
1556a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    f->appendPrecisionModifier(kHigh_GrSLPrecision);
1557a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    f->codeAppendf("vec2 distanceToArcEdge = abs(%s) - %s.xy;", coords.fVarying->fsIn(), rrect);
1558a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    f->codeAppend ("if (any(lessThan(distanceToArcEdge, vec2(0)))) {");
1559a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    this->emitRect(f, coords, opts);
1560a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    f->codeAppend ("} else {");
1561a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (coords.fInverseMatrix && coords.fFragHalfSpan) {
1562a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->appendPrecisionModifier(kHigh_GrSLPrecision);
1563a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppendf("vec2 rrectCoords = distanceToArcEdge * %s.zw;", rrect);
1564a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->appendPrecisionModifier(kHigh_GrSLPrecision);
1565a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppendf("vec2 fragRRectHalfSpan = %s * %s.zw;", coords.fFragHalfSpan, rrect);
1566a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppendf("if (%s(rrectCoords + fragRRectHalfSpan) <= 1.0) {", fSquareFun.c_str());
1567a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        // The entire pixel is inside the round rect.
1568a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        this->acceptOrRejectWholeFragment(f, true, opts);
1569a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppendf("} else if (%s(max(rrectCoords - fragRRectHalfSpan, vec2(0))) >= 1.0) {",
1570a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       fSquareFun.c_str());
1571a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        // The entire pixel is outside the round rect.
1572a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        this->acceptOrRejectWholeFragment(f, false, opts);
1573a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppend ("} else {");
1574a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->appendPrecisionModifier(kHigh_GrSLPrecision);
1575a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppendf(    "vec2 s = %s.zw * sign(%s);", rrect, coords.fVarying->fsIn());
1576a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->appendPrecisionModifier(kHigh_GrSLPrecision);
1577a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppendf(    "mat2 innerRRectInverseMatrix = %s * mat2(s.x, 0, 0, s.y);",
1578a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                           coords.fInverseMatrix);
1579a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->appendPrecisionModifier(kHigh_GrSLPrecision);
1580a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppend (    "int rrectMask = 0;");
1581a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppend (    "for (int i = 0; i < SAMPLE_COUNT; i++) {");
1582a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->appendPrecisionModifier(kHigh_GrSLPrecision);
1583a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppend (        "vec2 pt = rrectCoords + ");
1584a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->appendOffsetToSample("i", GrGLSLFPFragmentBuilder::kSkiaDevice_Coordinates);
1585a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppend (                  "* innerRRectInverseMatrix;");
1586a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppendf(        "if (%s(max(pt, vec2(0))) < 1.0) rrectMask |= (1 << i);",
1587a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                               fSquareFun.c_str());
1588a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppend (    "}");
1589a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        this->acceptCoverageMask(f, "rrectMask", opts);
1590a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppend ("}");
1591a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    } else {
1592a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppend ("int rrectMask = 0;");
1593a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppend ("for (int i = 0; i < SAMPLE_COUNT; i++) {");
1594a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->appendPrecisionModifier(kHigh_GrSLPrecision);
1595a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppend (    "vec2 shapePt = ");
1596a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        this->interpolateAtSample(f, *coords.fVarying, "i", nullptr);
1597a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppend (    ";");
1598a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->appendPrecisionModifier(kHigh_GrSLPrecision);
1599a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppendf(    "vec2 rrectPt = max(abs(shapePt) - %s.xy, vec2(0)) * %s.zw;",
1600a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                           rrect, rrect);
1601a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppendf(    "if (%s(rrectPt) < 1.0) rrectMask |= (1 << i);", fSquareFun.c_str());
1602a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppend ("}");
1603a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        this->acceptCoverageMask(f, "rrectMask", opts);
1604a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1605a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    f->codeAppend ("}");
1606a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
1607a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1608a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendMultisample::interpolateAtSample(GrGLSLPPFragmentBuilder* f,
1609a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                                  const GrGLSLVarying& varying,
1610a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                                  const char* sampleIdx,
1611a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                                  const char* interpolationMatrix) {
1612a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (interpolationMatrix) {
1613a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppendf("(%s + ", varying.fsIn());
1614a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->appendOffsetToSample(sampleIdx, GrGLSLFPFragmentBuilder::kSkiaDevice_Coordinates);
1615a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppendf(" * %s)", interpolationMatrix);
1616a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    } else {
1617a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        SkAssertResult(
1618a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->enableFeature(GrGLSLFragmentBuilder::kMultisampleInterpolation_GLSLFeature));
1619a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppendf("interpolateAtOffset(%s, ", varying.fsIn());
1620a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->appendOffsetToSample(sampleIdx, GrGLSLFPFragmentBuilder::kGLSLWindow_Coordinates);
1621a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppend(")");
1622a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1623a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
1624a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1625a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid
1626a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonGLSLInstanceProcessor::BackendMultisample::acceptOrRejectWholeFragment(GrGLSLPPFragmentBuilder* f,
1627a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                                       bool inside,
1628a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                                       const EmitShapeOpts& opts) {
1629a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (inside != opts.fInvertCoverage) { // Accept the entire fragment.
1630a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        if (opts.fResolveMixedSamples) {
1631a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            // This is a mixed sampled fragment in the interior of the shape. Reassign 100% coverage
1632a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            // to one fragment, and drop all other fragments that may fall on this same pixel. Since
1633a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            // our geometry is water tight and non-overlapping, we can take advantage of the
1634a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            // properties that (1) the incoming sample masks will be disjoint across fragments that
1635a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            // fall on a common pixel, and (2) since the entire fragment is inside the shape, each
1636a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            // sample's corresponding bit will be set in the incoming sample mask of exactly one
1637a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            // fragment.
1638a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppend("if ((gl_SampleMaskIn[0] & SAMPLE_MASK_MSB) == 0) {");
1639a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            // Drop this fragment.
1640a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            if (!fBatchInfo.fCannotDiscard) {
1641a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                f->codeAppend("discard;");
1642a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            } else {
1643a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                f->overrideSampleCoverage("0");
1644a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            }
1645a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppend("} else {");
1646a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            // Override the lone surviving fragment to full coverage.
1647a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->overrideSampleCoverage("-1");
1648a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppend("}");
1649a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
1650a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    } else { // Reject the entire fragment.
1651a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        if (!fBatchInfo.fCannotDiscard) {
1652a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppend("discard;");
1653a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        } else if (opts.fResolveMixedSamples) {
1654a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->overrideSampleCoverage("0");
1655a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        } else {
1656a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->maskSampleCoverage("0");
1657a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
1658a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1659a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
1660a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1661a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendMultisample::acceptCoverageMask(GrGLSLPPFragmentBuilder* f,
1662a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                                   const char* shapeMask,
1663a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                                   const EmitShapeOpts& opts,
1664a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                                   bool maybeSharedEdge) {
1665a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (opts.fResolveMixedSamples) {
1666a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        if (maybeSharedEdge) {
1667a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            // This is a mixed sampled fragment, potentially on the outer edge of the shape, with
1668a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            // only partial shape coverage. Override the coverage of one fragment to "shapeMask",
1669a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            // and drop all other fragments that may fall on this same pixel. Since our geometry is
1670a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            // water tight, non-overlapping, and completely contains the shape, this means that each
1671a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            // "on" bit from shapeMask is guaranteed to be set in the incoming sample mask of one,
1672a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            // and only one, fragment that falls on this same pixel.
1673a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            SkASSERT(!opts.fInvertCoverage);
1674a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppendf("if ((gl_SampleMaskIn[0] & (1 << findMSB(%s))) == 0) {", shapeMask);
1675a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            // Drop this fragment.
1676a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            if (!fBatchInfo.fCannotDiscard) {
1677a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                f->codeAppend ("discard;");
1678a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            } else {
1679a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                f->overrideSampleCoverage("0");
1680a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            }
1681a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppend ("} else {");
1682a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            // Override the coverage of the lone surviving fragment to "shapeMask".
1683a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->overrideSampleCoverage(shapeMask);
1684a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppend ("}");
1685a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        } else {
1686a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->overrideSampleCoverage(shapeMask);
1687a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
1688a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    } else {
1689a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->maskSampleCoverage(shapeMask, opts.fInvertCoverage);
1690a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1691a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
1692a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1693a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton////////////////////////////////////////////////////////////////////////////////////////////////////
1694a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1695a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonGLSLInstanceProcessor::Backend*
1696a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonGLSLInstanceProcessor::Backend::Create(const GrPipeline& pipeline, BatchInfo batchInfo,
1697a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                       const VertexInputs& inputs) {
1698a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    switch (batchInfo.fAntialiasMode) {
1699a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        default:
1700a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            SkFAIL("Unexpected antialias mode.");
1701a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        case AntialiasMode::kNone:
1702a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            return new BackendNonAA(batchInfo, inputs);
1703a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        case AntialiasMode::kCoverage:
1704a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            return new BackendCoverage(batchInfo, inputs);
1705a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        case AntialiasMode::kMSAA:
1706a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        case AntialiasMode::kMixedSamples: {
1707a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            const GrRenderTargetPriv& rtp = pipeline.getRenderTarget()->renderTargetPriv();
1708a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            const GrGpu::MultisampleSpecs& specs = rtp.getMultisampleSpecs(pipeline.getStencil());
1709a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            return new BackendMultisample(batchInfo, inputs, specs.fEffectiveSampleCnt);
1710a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
1711a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1712a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
1713a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1714a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton////////////////////////////////////////////////////////////////////////////////////////////////////
1715a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1716a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonconst ShapeVertex kVertexData[] = {
1717a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // Rectangle.
1718a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+1, +1, ~0},   /*0*/
1719a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-1, +1, ~0},   /*1*/
1720a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-1, -1, ~0},   /*2*/
1721a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+1, -1, ~0},   /*3*/
1722a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // The next 4 are for the bordered version.
1723a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+1, +1,  0},   /*4*/
1724a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-1, +1,  0},   /*5*/
1725a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-1, -1,  0},   /*6*/
1726a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+1, -1,  0},   /*7*/
1727a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1728a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // Octagon that inscribes the unit circle, cut by an interior unit octagon.
1729a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+1.000000f,  0.000000f,  0},   /* 8*/
1730a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+1.000000f, +0.414214f, ~0},   /* 9*/
1731a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+0.707106f, +0.707106f,  0},   /*10*/
1732a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+0.414214f, +1.000000f, ~0},   /*11*/
1733a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    { 0.000000f, +1.000000f,  0},   /*12*/
1734a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-0.414214f, +1.000000f, ~0},   /*13*/
1735a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-0.707106f, +0.707106f,  0},   /*14*/
1736a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-1.000000f, +0.414214f, ~0},   /*15*/
1737a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-1.000000f,  0.000000f,  0},   /*16*/
1738a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-1.000000f, -0.414214f, ~0},   /*17*/
1739a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-0.707106f, -0.707106f,  0},   /*18*/
1740a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-0.414214f, -1.000000f, ~0},   /*19*/
1741a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    { 0.000000f, -1.000000f,  0},   /*20*/
1742a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+0.414214f, -1.000000f, ~0},   /*21*/
1743a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+0.707106f, -0.707106f,  0},   /*22*/
1744a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+1.000000f, -0.414214f, ~0},   /*23*/
1745a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // This vertex is for the fanned versions.
1746a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    { 0.000000f,  0.000000f, ~0},   /*24*/
1747a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1748a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // Rectangle with disjoint corner segments.
1749a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+1.0, +0.5,  0x3},   /*25*/
1750a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+1.0, +1.0,  0x3},   /*26*/
1751a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+0.5, +1.0,  0x3},   /*27*/
1752a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-0.5, +1.0,  0x2},   /*28*/
1753a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-1.0, +1.0,  0x2},   /*29*/
1754a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-1.0, +0.5,  0x2},   /*30*/
1755a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-1.0, -0.5,  0x0},   /*31*/
1756a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-1.0, -1.0,  0x0},   /*32*/
1757a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-0.5, -1.0,  0x0},   /*33*/
1758a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+0.5, -1.0,  0x1},   /*34*/
1759a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+1.0, -1.0,  0x1},   /*35*/
1760a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+1.0, -0.5,  0x1},   /*36*/
1761a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // The next 4 are for the fanned version.
1762a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    { 0.0,  0.0,  0x3},   /*37*/
1763a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    { 0.0,  0.0,  0x2},   /*38*/
1764a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    { 0.0,  0.0,  0x0},   /*39*/
1765a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    { 0.0,  0.0,  0x1},   /*40*/
1766a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // The next 8 are for the bordered version.
1767a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+0.75, +0.50,  0x3},   /*41*/
1768a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+0.50, +0.75,  0x3},   /*42*/
1769a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-0.50, +0.75,  0x2},   /*43*/
1770a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-0.75, +0.50,  0x2},   /*44*/
1771a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-0.75, -0.50,  0x0},   /*45*/
1772a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-0.50, -0.75,  0x0},   /*46*/
1773a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+0.50, -0.75,  0x1},   /*47*/
1774a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+0.75, -0.50,  0x1},   /*48*/
1775a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1776a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // 16-gon that inscribes the unit circle, cut by an interior unit 16-gon.
1777a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+1.000000f, +0.000000f,  0},   /*49*/
1778a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+1.000000f, +0.198913f, ~0},   /*50*/
1779a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+0.923879f, +0.382683f,  0},   /*51*/
1780a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+0.847760f, +0.566455f, ~0},   /*52*/
1781a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+0.707106f, +0.707106f,  0},   /*53*/
1782a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+0.566455f, +0.847760f, ~0},   /*54*/
1783a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+0.382683f, +0.923879f,  0},   /*55*/
1784a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+0.198913f, +1.000000f, ~0},   /*56*/
1785a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+0.000000f, +1.000000f,  0},   /*57*/
1786a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-0.198913f, +1.000000f, ~0},   /*58*/
1787a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-0.382683f, +0.923879f,  0},   /*59*/
1788a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-0.566455f, +0.847760f, ~0},   /*60*/
1789a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-0.707106f, +0.707106f,  0},   /*61*/
1790a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-0.847760f, +0.566455f, ~0},   /*62*/
1791a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-0.923879f, +0.382683f,  0},   /*63*/
1792a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-1.000000f, +0.198913f, ~0},   /*64*/
1793a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-1.000000f, +0.000000f,  0},   /*65*/
1794a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-1.000000f, -0.198913f, ~0},   /*66*/
1795a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-0.923879f, -0.382683f,  0},   /*67*/
1796a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-0.847760f, -0.566455f, ~0},   /*68*/
1797a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-0.707106f, -0.707106f,  0},   /*69*/
1798a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-0.566455f, -0.847760f, ~0},   /*70*/
1799a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-0.382683f, -0.923879f,  0},   /*71*/
1800a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-0.198913f, -1.000000f, ~0},   /*72*/
1801a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-0.000000f, -1.000000f,  0},   /*73*/
1802a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+0.198913f, -1.000000f, ~0},   /*74*/
1803a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+0.382683f, -0.923879f,  0},   /*75*/
1804a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+0.566455f, -0.847760f, ~0},   /*76*/
1805a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+0.707106f, -0.707106f,  0},   /*77*/
1806a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+0.847760f, -0.566455f, ~0},   /*78*/
1807a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+0.923879f, -0.382683f,  0},   /*79*/
1808a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+1.000000f, -0.198913f, ~0},   /*80*/
1809a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton};
1810a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1811a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonconst uint8_t kIndexData[] = {
1812a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // Rectangle.
1813a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    0, 1, 2,
1814a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    0, 2, 3,
1815a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1816a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // Rectangle with a border.
1817a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    0, 1, 5,
1818a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    5, 4, 0,
1819a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    1, 2, 6,
1820a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    6, 5, 1,
1821a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    2, 3, 7,
1822a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    7, 6, 2,
1823a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    3, 0, 4,
1824a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    4, 7, 3,
1825a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    4, 5, 6,
1826a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    6, 7, 4,
1827a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1828a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // Octagon that inscribes the unit circle, cut by an interior unit octagon.
1829a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    10,  8,  9,
1830a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    12, 10, 11,
1831a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    14, 12, 13,
1832a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    16, 14, 15,
1833a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    18, 16, 17,
1834a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    20, 18, 19,
1835a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    22, 20, 21,
1836a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton     8, 22, 23,
1837a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton     8, 10, 12,
1838a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    12, 14, 16,
1839a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    16, 18, 20,
1840a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    20, 22,  8,
1841a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton     8, 12, 16,
1842a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    16, 20,  8,
1843a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1844a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // Same octagons, but with the interior arranged as a fan. Used by mixed samples.
1845a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    10,  8,  9,
1846a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    12, 10, 11,
1847a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    14, 12, 13,
1848a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    16, 14, 15,
1849a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    18, 16, 17,
1850a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    20, 18, 19,
1851a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    22, 20, 21,
1852a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton     8, 22, 23,
1853a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    24,  8, 10,
1854a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    12, 24, 10,
1855a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    24, 12, 14,
1856a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    16, 24, 14,
1857a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    24, 16, 18,
1858a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    20, 24, 18,
1859a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    24, 20, 22,
1860a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton     8, 24, 22,
1861a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1862a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // Same octagons, but with the inner and outer disjoint. Used by coverage AA.
1863a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton     8, 22, 23,
1864a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton     9,  8, 23,
1865a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    10,  8,  9,
1866a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    11, 10,  9,
1867a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    12, 10, 11,
1868a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    13, 12, 11,
1869a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    14, 12, 13,
1870a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    15, 14, 13,
1871a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    16, 14, 15,
1872a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    17, 16, 15,
1873a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    18, 16, 17,
1874a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    19, 18, 17,
1875a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    20, 18, 19,
1876a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    21, 20, 19,
1877a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    22, 20, 21,
1878a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    23, 22, 21,
1879a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    22,  8, 10,
1880a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    10, 12, 14,
1881a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    14, 16, 18,
1882a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    18, 20, 22,
1883a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    22, 10, 14,
1884a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    14, 18, 22,
1885a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1886a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // Rectangle with disjoint corner segments.
1887a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    27, 25, 26,
1888a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    30, 28, 29,
1889a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    33, 31, 32,
1890a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    36, 34, 35,
1891a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    25, 27, 28,
1892a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    28, 30, 31,
1893a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    31, 33, 34,
1894a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    34, 36, 25,
1895a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    25, 28, 31,
1896a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    31, 34, 25,
1897a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1898a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // Same rectangle with disjoint corners, but with the interior arranged as a fan. Used by
1899a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // mixed samples.
1900a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    27, 25, 26,
1901a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    30, 28, 29,
1902a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    33, 31, 32,
1903a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    36, 34, 35,
1904a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    27, 37, 25,
1905a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    28, 37, 27,
1906a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    30, 38, 28,
1907a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    31, 38, 30,
1908a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    33, 39, 31,
1909a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    34, 39, 33,
1910a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    36, 40, 34,
1911a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    25, 40, 36,
1912a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1913a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // Same rectangle with disjoint corners, with a border as well. Used by coverage AA.
1914a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    41, 25, 26,
1915a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    42, 41, 26,
1916a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    27, 42, 26,
1917a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    43, 28, 29,
1918a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    44, 43, 29,
1919a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    30, 44, 29,
1920a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    45, 31, 32,
1921a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    46, 45, 32,
1922a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    33, 46, 32,
1923a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    47, 34, 35,
1924a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    48, 47, 35,
1925a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    36, 48, 35,
1926a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    27, 28, 42,
1927a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    42, 28, 43,
1928a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    30, 31, 44,
1929a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    44, 31, 45,
1930a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    33, 34, 46,
1931a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    46, 34, 47,
1932a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    36, 25, 48,
1933a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    48, 25, 41,
1934a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    41, 42, 43,
1935a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    43, 44, 45,
1936a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    45, 46, 47,
1937a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    47, 48, 41,
1938a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    41, 43, 45,
1939a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    45, 47, 41,
1940a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1941a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // Same as the disjoint octagons, but with 16-gons instead. Used by coverage AA when the oval is
1942a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // sufficiently large.
1943a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    49, 79, 80,
1944a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    50, 49, 80,
1945a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    51, 49, 50,
1946a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    52, 51, 50,
1947a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    53, 51, 52,
1948a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    54, 53, 52,
1949a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    55, 53, 54,
1950a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    56, 55, 54,
1951a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    57, 55, 56,
1952a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    58, 57, 56,
1953a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    59, 57, 58,
1954a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    60, 59, 58,
1955a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    61, 59, 60,
1956a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    62, 61, 60,
1957a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    63, 61, 62,
1958a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    64, 63, 62,
1959a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    65, 63, 64,
1960a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    66, 65, 64,
1961a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    67, 65, 66,
1962a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    68, 67, 66,
1963a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    69, 67, 68,
1964a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    70, 69, 68,
1965a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    71, 69, 70,
1966a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    72, 71, 70,
1967a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    73, 71, 72,
1968a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    74, 73, 72,
1969a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    75, 73, 74,
1970a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    76, 75, 74,
1971a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    77, 75, 76,
1972a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    78, 77, 76,
1973a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    79, 77, 78,
1974a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    80, 79, 78,
1975a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    49, 51, 53,
1976a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    53, 55, 57,
1977a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    57, 59, 61,
1978a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    61, 63, 65,
1979a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    65, 67, 69,
1980a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    69, 71, 73,
1981a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    73, 75, 77,
1982a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    77, 79, 49,
1983a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    49, 53, 57,
1984a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    57, 61, 65,
1985a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    65, 69, 73,
1986a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    73, 77, 49,
1987a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    49, 57, 65,
1988a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    65, 73, 49,
1989a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton};
1990a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1991a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonenum {
1992a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    kRect_FirstIndex = 0,
1993a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    kRect_TriCount = 2,
1994a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1995a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    kFramedRect_FirstIndex = 6,
1996a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    kFramedRect_TriCount = 10,
1997a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1998a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    kOctagons_FirstIndex = 36,
1999a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    kOctagons_TriCount = 14,
2000a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
2001a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    kOctagonsFanned_FirstIndex = 78,
2002a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    kOctagonsFanned_TriCount = 16,
2003a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
2004a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    kDisjointOctagons_FirstIndex = 126,
2005a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    kDisjointOctagons_TriCount = 22,
2006a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
2007a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    kCorneredRect_FirstIndex = 192,
2008a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    kCorneredRect_TriCount = 10,
2009a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
2010a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    kCorneredRectFanned_FirstIndex = 222,
2011a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    kCorneredRectFanned_TriCount = 12,
2012a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
2013a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    kCorneredFramedRect_FirstIndex = 258,
2014a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    kCorneredFramedRect_TriCount = 26,
2015a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
2016a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    kDisjoint16Gons_FirstIndex = 336,
2017a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    kDisjoint16Gons_TriCount = 46,
2018a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton};
2019a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
2020a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonGR_DECLARE_STATIC_UNIQUE_KEY(gShapeVertexBufferKey);
2021a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
2022a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonconst GrBuffer* InstanceProcessor::FindOrCreateVertexBuffer(GrGpu* gpu) {
2023a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GR_DEFINE_STATIC_UNIQUE_KEY(gShapeVertexBufferKey);
2024a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GrResourceCache* cache = gpu->getContext()->getResourceCache();
2025a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (GrGpuResource* cached = cache->findAndRefUniqueResource(gShapeVertexBufferKey)) {
2026a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        return static_cast<GrBuffer*>(cached);
2027a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
2028a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (GrBuffer* buffer = gpu->createBuffer(sizeof(kVertexData), kVertex_GrBufferType,
2029a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                             kStatic_GrAccessPattern, kVertexData)) {
2030a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        buffer->resourcePriv().setUniqueKey(gShapeVertexBufferKey);
2031a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        return buffer;
2032a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
2033a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    return nullptr;
2034a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
2035a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
2036a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonGR_DECLARE_STATIC_UNIQUE_KEY(gShapeIndexBufferKey);
2037a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
2038a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonconst GrBuffer* InstanceProcessor::FindOrCreateIndex8Buffer(GrGpu* gpu) {
2039a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GR_DEFINE_STATIC_UNIQUE_KEY(gShapeIndexBufferKey);
2040a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GrResourceCache* cache = gpu->getContext()->getResourceCache();
2041a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (GrGpuResource* cached = cache->findAndRefUniqueResource(gShapeIndexBufferKey)) {
2042a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        return static_cast<GrBuffer*>(cached);
2043a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
2044a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (GrBuffer* buffer = gpu->createBuffer(sizeof(kIndexData), kIndex_GrBufferType,
2045a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                             kStatic_GrAccessPattern, kIndexData)) {
2046a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        buffer->resourcePriv().setUniqueKey(gShapeIndexBufferKey);
2047a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        return buffer;
2048a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
2049a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    return nullptr;
2050a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
2051a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
2052a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonIndexRange InstanceProcessor::GetIndexRangeForRect(AntialiasMode aa) {
2053a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    static constexpr IndexRange kRectRanges[kNumAntialiasModes] = {
2054a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        {kRect_FirstIndex,        3 * kRect_TriCount},        // kNone
2055a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        {kFramedRect_FirstIndex,  3 * kFramedRect_TriCount},  // kCoverage
2056a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        {kRect_FirstIndex,        3 * kRect_TriCount},        // kMSAA
2057a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        {kRect_FirstIndex,        3 * kRect_TriCount}         // kMixedSamples
2058a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    };
2059a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
2060a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    SkASSERT(aa >= AntialiasMode::kNone && aa <= AntialiasMode::kMixedSamples);
2061a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    return kRectRanges[(int)aa];
2062a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
2063a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GR_STATIC_ASSERT(0 == (int)AntialiasMode::kNone);
2064a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GR_STATIC_ASSERT(1 == (int)AntialiasMode::kCoverage);
2065a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GR_STATIC_ASSERT(2 == (int)AntialiasMode::kMSAA);
2066a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GR_STATIC_ASSERT(3 == (int)AntialiasMode::kMixedSamples);
2067a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
2068a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
2069a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonIndexRange InstanceProcessor::GetIndexRangeForOval(AntialiasMode aa, const SkRect& devBounds) {
2070a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (AntialiasMode::kCoverage == aa && devBounds.height() * devBounds.width() >= 256 * 256) {
2071a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        // This threshold was chosen quasi-scientifically on Tegra X1.
2072a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        return {kDisjoint16Gons_FirstIndex, 3 * kDisjoint16Gons_TriCount};
2073a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
2074a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
2075a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    static constexpr IndexRange kOvalRanges[kNumAntialiasModes] = {
2076a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        {kOctagons_FirstIndex,          3 * kOctagons_TriCount},          // kNone
2077a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        {kDisjointOctagons_FirstIndex,  3 * kDisjointOctagons_TriCount},  // kCoverage
2078a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        {kOctagons_FirstIndex,          3 * kOctagons_TriCount},          // kMSAA
2079a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        {kOctagonsFanned_FirstIndex,    3 * kOctagonsFanned_TriCount}     // kMixedSamples
2080a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    };
2081a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
2082a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    SkASSERT(aa >= AntialiasMode::kNone && aa <= AntialiasMode::kMixedSamples);
2083a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    return kOvalRanges[(int)aa];
2084a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
2085a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GR_STATIC_ASSERT(0 == (int)AntialiasMode::kNone);
2086a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GR_STATIC_ASSERT(1 == (int)AntialiasMode::kCoverage);
2087a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GR_STATIC_ASSERT(2 == (int)AntialiasMode::kMSAA);
2088a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GR_STATIC_ASSERT(3 == (int)AntialiasMode::kMixedSamples);
2089a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
2090a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
2091a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonIndexRange InstanceProcessor::GetIndexRangeForRRect(AntialiasMode aa) {
2092a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    static constexpr IndexRange kRRectRanges[kNumAntialiasModes] = {
2093a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        {kCorneredRect_FirstIndex,        3 * kCorneredRect_TriCount},        // kNone
2094a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        {kCorneredFramedRect_FirstIndex,  3 * kCorneredFramedRect_TriCount},  // kCoverage
2095a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        {kCorneredRect_FirstIndex,        3 * kCorneredRect_TriCount},        // kMSAA
2096a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        {kCorneredRectFanned_FirstIndex,  3 * kCorneredRectFanned_TriCount}   // kMixedSamples
2097a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    };
2098a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
2099a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    SkASSERT(aa >= AntialiasMode::kNone && aa <= AntialiasMode::kMixedSamples);
2100a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    return kRRectRanges[(int)aa];
2101a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
2102a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GR_STATIC_ASSERT(0 == (int)AntialiasMode::kNone);
2103a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GR_STATIC_ASSERT(1 == (int)AntialiasMode::kCoverage);
2104a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GR_STATIC_ASSERT(2 == (int)AntialiasMode::kMSAA);
2105a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GR_STATIC_ASSERT(3 == (int)AntialiasMode::kMixedSamples);
2106a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
2107a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
2108a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonconst char* InstanceProcessor::GetNameOfIndexRange(IndexRange range) {
2109a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    switch (range.fStart) {
2110a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        case kRect_FirstIndex: return "basic_rect";
2111a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        case kFramedRect_FirstIndex: return "coverage_rect";
2112a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
2113a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        case kOctagons_FirstIndex: return "basic_oval";
2114a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        case kDisjointOctagons_FirstIndex: return "coverage_oval";
2115a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        case kDisjoint16Gons_FirstIndex: return "coverage_large_oval";
2116a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        case kOctagonsFanned_FirstIndex: return "mixed_samples_oval";
2117a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
2118a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        case kCorneredRect_FirstIndex: return "basic_round_rect";
2119a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        case kCorneredFramedRect_FirstIndex: return "coverage_round_rect";
2120a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        case kCorneredRectFanned_FirstIndex: return "mixed_samples_round_rect";
2121a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
2122a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        default: return "unknown";
2123a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
2124a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
2125a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
2126a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
2127