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