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
70af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon    if (GrAATypeIsHW(fOpInfo.aaType())) {
71af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon        if (!fOpInfo.isSimpleRects() || GrAAType::kMixedSamples == fOpInfo.aaType()) {
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());
11884645e3c679581d191406b2d7ab93c3f6c5e3a63Ethan Nicholas        switch (type) {
11984645e3c679581d191406b2d7ab93c3f6c5e3a63Ethan Nicholas            case kVec2f_GrSLType: // fall through
12084645e3c679581d191406b2d7ab93c3f6c5e3a63Ethan Nicholas            case kVec3f_GrSLType: // fall through
12184645e3c679581d191406b2d7ab93c3f6c5e3a63Ethan Nicholas            case kVec4f_GrSLType:
12284645e3c679581d191406b2d7ab93c3f6c5e3a63Ethan Nicholas                break;
12384645e3c679581d191406b2d7ab93c3f6c5e3a63Ethan Nicholas            default:
12484645e3c679581d191406b2d7ab93c3f6c5e3a63Ethan Nicholas                fVertexBuilder->codeAppendf("%s(", GrGLSLTypeString(type));
125a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
126a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        fVertexBuilder->appendTexelFetch(fParamsBuffer, "paramsIdx++");
12784645e3c679581d191406b2d7ab93c3f6c5e3a63Ethan Nicholas        switch (type) {
12884645e3c679581d191406b2d7ab93c3f6c5e3a63Ethan Nicholas            case kVec2f_GrSLType:
12984645e3c679581d191406b2d7ab93c3f6c5e3a63Ethan Nicholas                fVertexBuilder->codeAppend(".xy");
13084645e3c679581d191406b2d7ab93c3f6c5e3a63Ethan Nicholas                break;
13184645e3c679581d191406b2d7ab93c3f6c5e3a63Ethan Nicholas            case kVec3f_GrSLType:
13284645e3c679581d191406b2d7ab93c3f6c5e3a63Ethan Nicholas                fVertexBuilder->codeAppend(".xyz");
13384645e3c679581d191406b2d7ab93c3f6c5e3a63Ethan Nicholas                break;
13484645e3c679581d191406b2d7ab93c3f6c5e3a63Ethan Nicholas            case kVec4f_GrSLType:
13584645e3c679581d191406b2d7ab93c3f6c5e3a63Ethan Nicholas                break;
13684645e3c679581d191406b2d7ab93c3f6c5e3a63Ethan Nicholas            default:
13784645e3c679581d191406b2d7ab93c3f6c5e3a63Ethan Nicholas                fVertexBuilder->codeAppend(")");
138a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
139a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
140a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
141a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void skipParams(unsigned n) const {
142a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        SkASSERT(fParamsBuffer.isValid());
143a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        fVertexBuilder->codeAppendf("paramsIdx += %u;", n);
144a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
145a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
146a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonprivate:
147a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    const InstanceProcessor&     fInstProc;
148a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GrGLSLVertexBuilder*         fVertexBuilder;
149a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    SamplerHandle                fParamsBuffer;
150a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton};
151a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
152a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonclass GLSLInstanceProcessor::Backend {
153a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonpublic:
15499ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon    static Backend* SK_WARN_UNUSED_RESULT Create(const GrPipeline&, OpInfo, const VertexInputs&);
155a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    virtual ~Backend() {}
156a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
157a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void init(GrGLSLVaryingHandler*, GrGLSLVertexBuilder*);
158a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    virtual void setupRect(GrGLSLVertexBuilder*) = 0;
159a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    virtual void setupOval(GrGLSLVertexBuilder*) = 0;
1600caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton    void setupRRect(GrGLSLVertexBuilder*, int* usedShapeDefinitions);
161a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
162a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void initInnerShape(GrGLSLVaryingHandler*, GrGLSLVertexBuilder*);
163a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    virtual void setupInnerRect(GrGLSLVertexBuilder*) = 0;
164a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    virtual void setupInnerOval(GrGLSLVertexBuilder*) = 0;
1650caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton    void setupInnerSimpleRRect(GrGLSLVertexBuilder*);
166a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
167a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    const char* outShapeCoords() {
168a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        return fModifiedShapeCoords ? fModifiedShapeCoords : fInputs.attr(Attrib::kShapeCoords);
169a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
170a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
171a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void emitCode(GrGLSLVertexBuilder*, GrGLSLPPFragmentBuilder*, const char* outCoverage,
172a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                  const char* outColor);
173a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
174a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonprotected:
17599ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon    Backend(OpInfo opInfo, const VertexInputs& inputs)
17699ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon            : fOpInfo(opInfo)
17799ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon            , fInputs(inputs)
17899ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon            , fModifiesCoverage(false)
17999ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon            , fModifiesColor(false)
18099ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon            , fNeedsNeighborRadii(false)
18199ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon            , fColor(kVec4f_GrSLType)
18299ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon            , fTriangleIsArc(kInt_GrSLType)
18399ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon            , fArcCoords(kVec2f_GrSLType)
18499ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon            , fInnerShapeCoords(kVec2f_GrSLType)
18599ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon            , fInnerRRect(kVec4f_GrSLType)
18699ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon            , fModifiedShapeCoords(nullptr) {
18799ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon        if (fOpInfo.fShapeTypes & kRRect_ShapesMask) {
188a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            fModifiedShapeCoords = "adjustedShapeCoords";
189a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
190a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
191a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
192a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    virtual void onInit(GrGLSLVaryingHandler*, GrGLSLVertexBuilder*) = 0;
193a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    virtual void adjustRRectVertices(GrGLSLVertexBuilder*);
194a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    virtual void onSetupRRect(GrGLSLVertexBuilder*) {}
195a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
196a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    virtual void onInitInnerShape(GrGLSLVaryingHandler*, GrGLSLVertexBuilder*) = 0;
1970caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton    virtual void onSetupInnerSimpleRRect(GrGLSLVertexBuilder*) = 0;
198a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
199a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    virtual void onEmitCode(GrGLSLVertexBuilder*, GrGLSLPPFragmentBuilder*,
200a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                            const char* outCoverage, const char* outColor) = 0;
201a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
202a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void setupSimpleRadii(GrGLSLVertexBuilder*);
203a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void setupNinePatchRadii(GrGLSLVertexBuilder*);
204a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void setupComplexRadii(GrGLSLVertexBuilder*);
205a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
20699ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon    const OpInfo fOpInfo;
20799ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon    const VertexInputs& fInputs;
20899ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon    bool fModifiesCoverage;
20999ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon    bool fModifiesColor;
21099ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon    bool fNeedsNeighborRadii;
21199ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon    GrGLSLVertToFrag fColor;
21299ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon    GrGLSLVertToFrag fTriangleIsArc;
21399ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon    GrGLSLVertToFrag fArcCoords;
21499ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon    GrGLSLVertToFrag fInnerShapeCoords;
21599ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon    GrGLSLVertToFrag fInnerRRect;
21699ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon    const char* fModifiedShapeCoords;
217a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton};
218a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
219a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
220a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    const GrPipeline& pipeline = args.fVertBuilder->getProgramBuilder()->pipeline();
221a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    const InstanceProcessor& ip = args.fGP.cast<InstanceProcessor>();
222a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GrGLSLUniformHandler* uniHandler = args.fUniformHandler;
223a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
224a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GrGLSLVertexBuilder* v = args.fVertBuilder;
225a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GrGLSLPPFragmentBuilder* f = args.fFragBuilder;
226a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
227a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    varyingHandler->emitAttributes(ip);
228a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
229a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    VertexInputs inputs(ip, v);
23099ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon    if (ip.opInfo().fHasParams) {
231a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        SkASSERT(1 == ip.numBuffers());
232a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        inputs.initParams(args.fBufferSamplers[0]);
233a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
234a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
23599ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon    if (!ip.opInfo().fHasPerspective) {
236a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("mat2x3 shapeMatrix = mat2x3(%s, %s);",
237a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       inputs.attr(Attrib::kShapeMatrixX), inputs.attr(Attrib::kShapeMatrixY));
238a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    } else {
2395961bc9278a00e56dacdd9408d0744b5a0a3b493ethannicholas        v->defineConstantf("int", "PERSPECTIVE_FLAG", "0x%x", kPerspective_InfoFlag);
240a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("mat3 shapeMatrix = mat3(%s, %s, vec3(0, 0, 1));",
241a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       inputs.attr(Attrib::kShapeMatrixX), inputs.attr(Attrib::kShapeMatrixY));
2425961bc9278a00e56dacdd9408d0744b5a0a3b493ethannicholas        v->codeAppendf("if (0 != (%s & PERSPECTIVE_FLAG)) {",
243a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       inputs.attr(Attrib::kInstanceInfo));
244a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppend (    "shapeMatrix[2] = ");
245a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        inputs.fetchNextParam(kVec3f_GrSLType);
246a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppend (    ";");
247a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppend ("}");
248a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
249a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
25099ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon    bool hasSingleShapeType = SkIsPow2(ip.opInfo().fShapeTypes);
251a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (!hasSingleShapeType) {
2525961bc9278a00e56dacdd9408d0744b5a0a3b493ethannicholas        v->defineConstant("SHAPE_TYPE_BIT", kShapeType_InfoBit);
253a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("uint shapeType = %s >> SHAPE_TYPE_BIT;",
254a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       inputs.attr(Attrib::kInstanceInfo));
255a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
256a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
25799ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon    std::unique_ptr<Backend> backend(Backend::Create(pipeline, ip.opInfo(), inputs));
258a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    backend->init(varyingHandler, v);
259a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
2600caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton    int usedShapeDefinitions = 0;
2610caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton
26299ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon    if (hasSingleShapeType || !(ip.opInfo().fShapeTypes & ~kRRect_ShapesMask)) {
26399ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon        if (kRect_ShapeFlag == ip.opInfo().fShapeTypes) {
264a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            backend->setupRect(v);
26599ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon        } else if (kOval_ShapeFlag == ip.opInfo().fShapeTypes) {
266a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            backend->setupOval(v);
267a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        } else {
2680caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton            backend->setupRRect(v, &usedShapeDefinitions);
269a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
270a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    } else {
27199ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon        if (ip.opInfo().fShapeTypes & kRRect_ShapesMask) {
2720caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton            v->codeAppend ("if (shapeType >= SIMPLE_R_RECT_SHAPE_TYPE) {");
2730caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton            backend->setupRRect(v, &usedShapeDefinitions);
2740caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton            v->codeAppend ("}");
2750caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton            usedShapeDefinitions |= kSimpleRRect_ShapeFlag;
276a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
27799ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon        if (ip.opInfo().fShapeTypes & kOval_ShapeFlag) {
27899ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon            if (ip.opInfo().fShapeTypes & kRect_ShapeFlag) {
27999ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon                if (ip.opInfo().fShapeTypes & kRRect_ShapesMask) {
2800caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton                    v->codeAppend ("else ");
2810caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton                }
2820caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton                v->codeAppend ("if (OVAL_SHAPE_TYPE == shapeType) {");
2830caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton                usedShapeDefinitions |= kOval_ShapeFlag;
2840caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton            } else {
2850caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton                v->codeAppend ("else {");
2860caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton            }
287a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            backend->setupOval(v);
2880caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton            v->codeAppend ("}");
289a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
29099ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon        if (ip.opInfo().fShapeTypes & kRect_ShapeFlag) {
2910caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton            v->codeAppend ("else {");
2920caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton            backend->setupRect(v);
2930caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton            v->codeAppend ("}");
294a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
295a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
296a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
29799ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon    if (ip.opInfo().fInnerShapeTypes) {
29899ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon        bool hasSingleInnerShapeType = SkIsPow2(ip.opInfo().fInnerShapeTypes);
299a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        if (!hasSingleInnerShapeType) {
3005961bc9278a00e56dacdd9408d0744b5a0a3b493ethannicholas            v->defineConstantf("int", "INNER_SHAPE_TYPE_MASK", "0x%x", kInnerShapeType_InfoMask);
3015961bc9278a00e56dacdd9408d0744b5a0a3b493ethannicholas            v->defineConstant("INNER_SHAPE_TYPE_BIT", kInnerShapeType_InfoBit);
302a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            v->codeAppendf("uint innerShapeType = ((%s & INNER_SHAPE_TYPE_MASK) >> "
303a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                  "INNER_SHAPE_TYPE_BIT);",
304a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                           inputs.attr(Attrib::kInstanceInfo));
305a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
306a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        // Here we take advantage of the fact that outerRect == localRect in recordDRRect.
307a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("vec4 outer = %s;", inputs.attr(Attrib::kLocalRect));
308a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppend ("vec4 inner = ");
309a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        inputs.fetchNextParam();
310a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppend (";");
311a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        // outer2Inner is a transform from shape coords to inner shape coords:
312a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        // e.g. innerShapeCoords = shapeCoords * outer2Inner.xy + outer2Inner.zw
313a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppend ("vec4 outer2Inner = vec4(outer.zw - outer.xy, "
314a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                               "outer.xy + outer.zw - inner.xy - inner.zw) / "
315a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                               "(inner.zw - inner.xy).xyxy;");
316a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("vec2 innerShapeCoords = %s * outer2Inner.xy + outer2Inner.zw;",
317a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       backend->outShapeCoords());
318a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
319a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        backend->initInnerShape(varyingHandler, v);
320a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
32199ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon        SkASSERT(0 == (ip.opInfo().fInnerShapeTypes & kRRect_ShapesMask) ||
32299ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon                 kSimpleRRect_ShapeFlag == (ip.opInfo().fInnerShapeTypes & kRRect_ShapesMask));
3230caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton
324a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        if (hasSingleInnerShapeType) {
32599ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon            if (kRect_ShapeFlag == ip.opInfo().fInnerShapeTypes) {
326a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                backend->setupInnerRect(v);
32799ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon            } else if (kOval_ShapeFlag == ip.opInfo().fInnerShapeTypes) {
328a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                backend->setupInnerOval(v);
329a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            } else {
3300caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton                backend->setupInnerSimpleRRect(v);
331a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            }
332a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        } else {
33399ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon            if (ip.opInfo().fInnerShapeTypes & kSimpleRRect_ShapeFlag) {
3340caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton                v->codeAppend ("if (SIMPLE_R_RECT_SHAPE_TYPE == innerShapeType) {");
3350caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton                backend->setupInnerSimpleRRect(v);
3360caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton                v->codeAppend("}");
3370caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton                usedShapeDefinitions |= kSimpleRRect_ShapeFlag;
338a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            }
33999ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon            if (ip.opInfo().fInnerShapeTypes & kOval_ShapeFlag) {
34099ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon                if (ip.opInfo().fInnerShapeTypes & kRect_ShapeFlag) {
34199ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon                    if (ip.opInfo().fInnerShapeTypes & kSimpleRRect_ShapeFlag) {
3420caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton                        v->codeAppend ("else ");
3430caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton                    }
3440caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton                    v->codeAppend ("if (OVAL_SHAPE_TYPE == innerShapeType) {");
3450caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton                    usedShapeDefinitions |= kOval_ShapeFlag;
3460caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton                } else {
3470caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton                    v->codeAppend ("else {");
3480caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton                }
349a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                backend->setupInnerOval(v);
3500caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton                v->codeAppend("}");
351a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            }
35299ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon            if (ip.opInfo().fInnerShapeTypes & kRect_ShapeFlag) {
3530caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton                v->codeAppend("else {");
3540caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton                backend->setupInnerRect(v);
3550caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton                v->codeAppend("}");
356a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            }
357a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
358a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
359a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
3600caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton    if (usedShapeDefinitions & kOval_ShapeFlag) {
3615961bc9278a00e56dacdd9408d0744b5a0a3b493ethannicholas        v->defineConstant("OVAL_SHAPE_TYPE", (int)ShapeType::kOval);
362a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
3630caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton    if (usedShapeDefinitions & kSimpleRRect_ShapeFlag) {
3645961bc9278a00e56dacdd9408d0744b5a0a3b493ethannicholas        v->defineConstant("SIMPLE_R_RECT_SHAPE_TYPE", (int)ShapeType::kSimpleRRect);
3650caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton    }
3660caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton    if (usedShapeDefinitions & kNinePatch_ShapeFlag) {
3675961bc9278a00e56dacdd9408d0744b5a0a3b493ethannicholas        v->defineConstant("NINE_PATCH_SHAPE_TYPE", (int)ShapeType::kNinePatch);
3680caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton    }
3690caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton    SkASSERT(!(usedShapeDefinitions & (kRect_ShapeFlag | kComplexRRect_ShapeFlag)));
370a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
3718c852be264d003b2e610c5b8634bc0f81c46bbbaBrian Salomon    backend->emitCode(v, f, args.fOutputCoverage, args.fOutputColor);
372a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
373a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    const char* localCoords = nullptr;
37499ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon    if (ip.opInfo().fUsesLocalCoords) {
375a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        localCoords = "localCoords";
376a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("vec2 t = 0.5 * (%s + vec2(1));", backend->outShapeCoords());
377a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("vec2 localCoords = (1.0 - t) * %s.xy + t * %s.zw;",
378a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       inputs.attr(Attrib::kLocalRect), inputs.attr(Attrib::kLocalRect));
379a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
38099ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon    if (ip.opInfo().fHasLocalMatrix && ip.opInfo().fHasParams) {
3815961bc9278a00e56dacdd9408d0744b5a0a3b493ethannicholas        v->defineConstantf("int", "LOCAL_MATRIX_FLAG", "0x%x", kLocalMatrix_InfoFlag);
3825961bc9278a00e56dacdd9408d0744b5a0a3b493ethannicholas        v->codeAppendf("if (0 != (%s & LOCAL_MATRIX_FLAG)) {",
383a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       inputs.attr(Attrib::kInstanceInfo));
38499ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon        if (!ip.opInfo().fUsesLocalCoords) {
385a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            inputs.skipParams(2);
386a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        } else {
387a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            v->codeAppendf(    "mat2x3 localMatrix;");
388a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            v->codeAppend (    "localMatrix[0] = ");
389a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            inputs.fetchNextParam(kVec3f_GrSLType);
390a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            v->codeAppend (    ";");
391a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            v->codeAppend (    "localMatrix[1] = ");
392a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            inputs.fetchNextParam(kVec3f_GrSLType);
393a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            v->codeAppend (    ";");
394a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            v->codeAppend (    "localCoords = (vec3(localCoords, 1) * localMatrix).xy;");
395a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
396a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppend("}");
397a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
398a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
39999ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon    GrSLType positionType = ip.opInfo().fHasPerspective ? kVec3f_GrSLType : kVec2f_GrSLType;
400a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppendf("%s deviceCoords = vec3(%s, 1) * shapeMatrix;",
401a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                   GrGLSLTypeString(positionType), backend->outShapeCoords());
402a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    gpArgs->fPositionVar.set(positionType, "deviceCoords");
403a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
404a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    this->emitTransforms(v, varyingHandler, uniHandler, gpArgs->fPositionVar, localCoords,
405a624bf3d1cb454c1959c5bbbf23a3afdfa3481f3bsalomon                         args.fFPCoordTransformHandler);
406a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
407a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
408a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton////////////////////////////////////////////////////////////////////////////////////////////////////
409a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
410a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::Backend::init(GrGLSLVaryingHandler* varyingHandler,
411a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                          GrGLSLVertexBuilder* v) {
412a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fModifiedShapeCoords) {
413a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("vec2 %s = %s;", fModifiedShapeCoords, fInputs.attr(Attrib::kShapeCoords));
414a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
415a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
416a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    this->onInit(varyingHandler, v);
417a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
418a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (!fColor.vsOut()) {
419a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        varyingHandler->addFlatVarying("color", &fColor, kLow_GrSLPrecision);
420a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = %s;", fColor.vsOut(), fInputs.attr(Attrib::kColor));
421a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
422a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
423a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
4240caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdaltonvoid GLSLInstanceProcessor::Backend::setupRRect(GrGLSLVertexBuilder* v, int* usedShapeDefinitions) {
425a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppendf("uvec2 corner = uvec2(%s & 1, (%s >> 1) & 1);",
426a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                   fInputs.attr(Attrib::kVertexAttrs), fInputs.attr(Attrib::kVertexAttrs));
427a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppend ("vec2 cornerSign = vec2(corner) * 2.0 - 1.0;");
428a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppendf("vec2 radii%s;", fNeedsNeighborRadii ? ", neighborRadii" : "");
429a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppend ("mat2 p = ");
430a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    fInputs.fetchNextParam(kMat22f_GrSLType);
431a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppend (";");
43299ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon    uint8_t types = fOpInfo.fShapeTypes & kRRect_ShapesMask;
433a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (0 == (types & (types - 1))) {
434a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        if (kSimpleRRect_ShapeFlag == types) {
435a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            this->setupSimpleRadii(v);
436a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        } else if (kNinePatch_ShapeFlag == types) {
437a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            this->setupNinePatchRadii(v);
438a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        } else if (kComplexRRect_ShapeFlag == types) {
439a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            this->setupComplexRadii(v);
440a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
441a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    } else {
442a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        if (types & kSimpleRRect_ShapeFlag) {
4430caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton            v->codeAppend ("if (SIMPLE_R_RECT_SHAPE_TYPE == shapeType) {");
444a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            this->setupSimpleRadii(v);
4450caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton            v->codeAppend ("}");
4460caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton            *usedShapeDefinitions |= kSimpleRRect_ShapeFlag;
447a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
448a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        if (types & kNinePatch_ShapeFlag) {
4490caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton            if (types & kComplexRRect_ShapeFlag) {
4500caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton                if (types & kSimpleRRect_ShapeFlag) {
4510caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton                    v->codeAppend ("else ");
4520caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton                }
4530caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton                v->codeAppend ("if (NINE_PATCH_SHAPE_TYPE == shapeType) {");
4540caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton                *usedShapeDefinitions |= kNinePatch_ShapeFlag;
4550caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton            } else {
4560caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton                v->codeAppend ("else {");
4570caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton            }
458a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            this->setupNinePatchRadii(v);
4590caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton            v->codeAppend ("}");
460a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
461a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        if (types & kComplexRRect_ShapeFlag) {
4620caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton            v->codeAppend ("else {");
463a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            this->setupComplexRadii(v);
4640caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton            v->codeAppend ("}");
465a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
466a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
467a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
468a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    this->adjustRRectVertices(v);
469a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
470a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fArcCoords.vsOut()) {
471a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = (cornerSign * %s + radii - vec2(1)) / radii;",
472a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       fArcCoords.vsOut(), fModifiedShapeCoords);
473a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
474a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fTriangleIsArc.vsOut()) {
475a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = int(all(equal(vec2(1), abs(%s))));",
476a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       fTriangleIsArc.vsOut(), fInputs.attr(Attrib::kShapeCoords));
477a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
478a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
479a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    this->onSetupRRect(v);
480a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
481a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
482a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::Backend::setupSimpleRadii(GrGLSLVertexBuilder* v) {
483a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fNeedsNeighborRadii) {
484a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppend ("neighborRadii = ");
485a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
486a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppend("radii = p[0] * 2.0 / p[1];");
487a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
488a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
489a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::Backend::setupNinePatchRadii(GrGLSLVertexBuilder* v) {
490a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppend("radii = vec2(p[0][corner.x], p[1][corner.y]);");
491a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fNeedsNeighborRadii) {
492a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppend("neighborRadii = vec2(p[0][1u - corner.x], p[1][1u - corner.y]);");
493a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
494a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
495a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
496a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::Backend::setupComplexRadii(GrGLSLVertexBuilder* v) {
497a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    /**
498a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton     * The x and y radii of each arc are stored in separate vectors,
499a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton     * in the following order:
500a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton     *
501a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton     *        __x1 _ _ _ x3__
502a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton     *
503a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton     *    y1 |               | y2
504a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton     *
505a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton     *       |               |
506a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton     *
507a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton     *    y3 |__   _ _ _   __| y4
508a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton     *          x2       x4
509a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton     *
510a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton     */
511a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppend("mat2 p2 = ");
512a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    fInputs.fetchNextParam(kMat22f_GrSLType);
513a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppend(";");
514a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppend("radii = vec2(p[corner.x][corner.y], p2[corner.y][corner.x]);");
515a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fNeedsNeighborRadii) {
516a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppend("neighborRadii = vec2(p[1u - corner.x][corner.y], "
517a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                           "p2[1u - corner.y][corner.x]);");
518a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
519a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
520a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
521a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::Backend::adjustRRectVertices(GrGLSLVertexBuilder* v) {
522a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // Resize the 4 triangles that arcs are drawn into so they match their corresponding radii.
523a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // 0.5 is a special value that indicates the edge of an arc triangle.
524a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppendf("if (abs(%s.x) == 0.5)"
525a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       "%s.x = cornerSign.x * (1.0 - radii.x);",
526a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       fInputs.attr(Attrib::kShapeCoords), fModifiedShapeCoords);
527a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppendf("if (abs(%s.y) == 0.5) "
528a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       "%s.y = cornerSign.y * (1.0 - radii.y);",
529a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       fInputs.attr(Attrib::kShapeCoords), fModifiedShapeCoords);
530a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
531a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
532a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::Backend::initInnerShape(GrGLSLVaryingHandler* varyingHandler,
533a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                    GrGLSLVertexBuilder* v) {
53499ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon    SkASSERT(!(fOpInfo.fInnerShapeTypes & (kNinePatch_ShapeFlag | kComplexRRect_ShapeFlag)));
535a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
536a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    this->onInitInnerShape(varyingHandler, v);
537a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
538a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fInnerShapeCoords.vsOut()) {
539a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = innerShapeCoords;", fInnerShapeCoords.vsOut());
540a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
541a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
542a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
5430caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdaltonvoid GLSLInstanceProcessor::Backend::setupInnerSimpleRRect(GrGLSLVertexBuilder* v) {
544a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppend("mat2 innerP = ");
545a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    fInputs.fetchNextParam(kMat22f_GrSLType);
546a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppend(";");
547a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppend("vec2 innerRadii = innerP[0] * 2.0 / innerP[1];");
5480caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton    this->onSetupInnerSimpleRRect(v);
549a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
550a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
551a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::Backend::emitCode(GrGLSLVertexBuilder* v, GrGLSLPPFragmentBuilder* f,
552a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                              const char* outCoverage, const char* outColor) {
553a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    SkASSERT(!fModifiesCoverage || outCoverage);
554a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    this->onEmitCode(v, f, fModifiesCoverage ? outCoverage : nullptr,
555a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                     fModifiesColor ? outColor : nullptr);
556a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (outCoverage && !fModifiesCoverage) {
557a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        // Even though the subclass doesn't use coverage, we are expected to assign some value.
558a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppendf("%s = vec4(1);", outCoverage);
559a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
560a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (!fModifiesColor) {
561a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        // The subclass didn't assign a value to the output color.
562a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppendf("%s = %s;", outColor, fColor.fsIn());
563a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
564a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
565a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
566a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton////////////////////////////////////////////////////////////////////////////////////////////////////
567a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
568a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonclass GLSLInstanceProcessor::BackendNonAA : public Backend {
569a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonpublic:
57099ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon    BackendNonAA(OpInfo opInfo, const VertexInputs& inputs) : INHERITED(opInfo, inputs) {
57199ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon        if (fOpInfo.fCannotDiscard && !fOpInfo.isSimpleRects()) {
57299ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon            fModifiesColor = !fOpInfo.fCannotTweakAlphaForCoverage;
573a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            fModifiesCoverage = !fModifiesColor;
574a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
575a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
576a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
577a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonprivate:
578a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void onInit(GrGLSLVaryingHandler*, GrGLSLVertexBuilder*) override;
579a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void setupRect(GrGLSLVertexBuilder*) override;
580a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void setupOval(GrGLSLVertexBuilder*) override;
581a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
582a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void onInitInnerShape(GrGLSLVaryingHandler*, GrGLSLVertexBuilder*) override;
583a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void setupInnerRect(GrGLSLVertexBuilder*) override;
584a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void setupInnerOval(GrGLSLVertexBuilder*) override;
5850caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton    void onSetupInnerSimpleRRect(GrGLSLVertexBuilder*) override;
586a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
587a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void onEmitCode(GrGLSLVertexBuilder*, GrGLSLPPFragmentBuilder*, const char*,
588a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                    const char*) override;
589a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
590a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    typedef Backend INHERITED;
591a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton};
592a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
593a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendNonAA::onInit(GrGLSLVaryingHandler* varyingHandler,
594a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                 GrGLSLVertexBuilder*) {
59599ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon    if (kRect_ShapeFlag != fOpInfo.fShapeTypes) {
596dd57dd796845da6ec2e1f44dc1e0b7821c1e4db1csmartdalton        varyingHandler->addFlatVarying("triangleIsArc", &fTriangleIsArc, kLow_GrSLPrecision);
597a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        varyingHandler->addVarying("arcCoords", &fArcCoords, kMedium_GrSLPrecision);
598a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
599a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
600a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
601a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendNonAA::setupRect(GrGLSLVertexBuilder* v) {
602a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fTriangleIsArc.vsOut()) {
603a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = 0;", fTriangleIsArc.vsOut());
604a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
605a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
606a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
607a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendNonAA::setupOval(GrGLSLVertexBuilder* v) {
608a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    SkASSERT(fArcCoords.vsOut());
609a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    SkASSERT(fTriangleIsArc.vsOut());
610a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppendf("%s = %s;", fArcCoords.vsOut(), this->outShapeCoords());
611a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppendf("%s = %s & 1;", fTriangleIsArc.vsOut(), fInputs.attr(Attrib::kVertexAttrs));
612a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
613a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
614a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendNonAA::onInitInnerShape(GrGLSLVaryingHandler* varyingHandler,
615a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                           GrGLSLVertexBuilder*) {
616a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    varyingHandler->addVarying("innerShapeCoords", &fInnerShapeCoords, kMedium_GrSLPrecision);
61799ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon    if (kRect_ShapeFlag != fOpInfo.fInnerShapeTypes &&
61899ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon        kOval_ShapeFlag != fOpInfo.fInnerShapeTypes) {
619a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        varyingHandler->addFlatVarying("innerRRect", &fInnerRRect, kMedium_GrSLPrecision);
620a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
621a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
622a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
623a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendNonAA::setupInnerRect(GrGLSLVertexBuilder* v) {
624a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fInnerRRect.vsOut()) {
625a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = vec4(1);", fInnerRRect.vsOut());
626a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
627a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
628a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
629a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendNonAA::setupInnerOval(GrGLSLVertexBuilder* v) {
630a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fInnerRRect.vsOut()) {
631a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = vec4(0, 0, 1, 1);", fInnerRRect.vsOut());
632a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
633a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
634a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
6350caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdaltonvoid GLSLInstanceProcessor::BackendNonAA::onSetupInnerSimpleRRect(GrGLSLVertexBuilder* v) {
636a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppendf("%s = vec4(1.0 - innerRadii, 1.0 / innerRadii);", fInnerRRect.vsOut());
637a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
638a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
639a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendNonAA::onEmitCode(GrGLSLVertexBuilder*,
640a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                     GrGLSLPPFragmentBuilder* f,
641a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                     const char* outCoverage,
642a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                     const char* outColor) {
643a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    const char* dropFragment = nullptr;
64499ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon    if (!fOpInfo.fCannotDiscard) {
645a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        dropFragment = "discard";
646a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    } else if (fModifiesCoverage) {
6471fc83b131afa7c29e971dd3ccc7906006bde6c09Ethan Nicholas        f->codeAppend ("lowp float covered = 1.0;");
648a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        dropFragment = "covered = 0.0";
649a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    } else if (fModifiesColor) {
6501fc83b131afa7c29e971dd3ccc7906006bde6c09Ethan Nicholas        f->codeAppendf("lowp vec4 color = %s;", fColor.fsIn());
651a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        dropFragment = "color = vec4(0)";
652a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
653a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fTriangleIsArc.fsIn()) {
654a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        SkASSERT(dropFragment);
655a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppendf("if (%s != 0 && dot(%s, %s) > 1.0) %s;",
656a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       fTriangleIsArc.fsIn(), fArcCoords.fsIn(), fArcCoords.fsIn(), dropFragment);
657a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
65899ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon    if (fOpInfo.fInnerShapeTypes) {
659a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        SkASSERT(dropFragment);
660a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppendf("// Inner shape.\n");
66199ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon        if (kRect_ShapeFlag == fOpInfo.fInnerShapeTypes) {
662a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppendf("if (all(lessThanEqual(abs(%s), vec2(1)))) %s;",
663a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                           fInnerShapeCoords.fsIn(), dropFragment);
66499ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon        } else if (kOval_ShapeFlag == fOpInfo.fInnerShapeTypes) {
665a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppendf("if ((dot(%s, %s) <= 1.0)) %s;",
666a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                           fInnerShapeCoords.fsIn(), fInnerShapeCoords.fsIn(), dropFragment);
667a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        } else {
668a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppendf("if (all(lessThan(abs(%s), vec2(1)))) {", fInnerShapeCoords.fsIn());
669a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppendf(    "vec2 distanceToArcEdge = abs(%s) - %s.xy;",
670a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                               fInnerShapeCoords.fsIn(), fInnerRRect.fsIn());
671a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppend (    "if (any(lessThan(distanceToArcEdge, vec2(0)))) {");
672a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppendf(        "%s;", dropFragment);
673a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppend (    "} else {");
674a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppendf(        "vec2 rrectCoords = distanceToArcEdge * %s.zw;",
675a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                   fInnerRRect.fsIn());
676a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppend (        "if (dot(rrectCoords, rrectCoords) <= 1.0) {");
677a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppendf(            "%s;", dropFragment);
678a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppend (        "}");
679a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppend (    "}");
680a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppend ("}");
681a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
682a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
683a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fModifiesCoverage) {
684a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppendf("%s = vec4(covered);", outCoverage);
685a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    } else if (fModifiesColor) {
686a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppendf("%s = color;", outColor);
687a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
688a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
689a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
690a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton////////////////////////////////////////////////////////////////////////////////////////////////////
691a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
692a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonclass GLSLInstanceProcessor::BackendCoverage : public Backend {
693a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonpublic:
69499ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon    BackendCoverage(OpInfo opInfo, const VertexInputs& inputs)
69599ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon            : INHERITED(opInfo, inputs)
69699ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon            , fColorTimesRectCoverage(kVec4f_GrSLType)
69799ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon            , fRectCoverage(kFloat_GrSLType)
69899ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon            , fEllipseCoords(kVec2f_GrSLType)
69999ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon            , fEllipseName(kVec2f_GrSLType)
70099ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon            , fBloatedRadius(kFloat_GrSLType)
70199ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon            , fDistanceToInnerEdge(kVec2f_GrSLType)
70299ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon            , fInnerShapeBloatedHalfSize(kVec2f_GrSLType)
70399ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon            , fInnerEllipseCoords(kVec2f_GrSLType)
70499ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon            , fInnerEllipseName(kVec2f_GrSLType) {
70599ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon        fShapeIsCircle = !fOpInfo.fNonSquare && !(fOpInfo.fShapeTypes & kRRect_ShapesMask);
70699ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon        fTweakAlphaForCoverage = !fOpInfo.fCannotTweakAlphaForCoverage && !fOpInfo.fInnerShapeTypes;
707a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        fModifiesCoverage = !fTweakAlphaForCoverage;
708a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        fModifiesColor = fTweakAlphaForCoverage;
709a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        fModifiedShapeCoords = "bloatedShapeCoords";
710a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
711a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
712a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonprivate:
713a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void onInit(GrGLSLVaryingHandler*, GrGLSLVertexBuilder*) override;
714a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void setupRect(GrGLSLVertexBuilder*) override;
715a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void setupOval(GrGLSLVertexBuilder*) override;
716a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void adjustRRectVertices(GrGLSLVertexBuilder*) override;
717a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void onSetupRRect(GrGLSLVertexBuilder*) override;
718a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
719a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void onInitInnerShape(GrGLSLVaryingHandler*, GrGLSLVertexBuilder*) override;
720a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void setupInnerRect(GrGLSLVertexBuilder*) override;
721a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void setupInnerOval(GrGLSLVertexBuilder*) override;
7220caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton    void onSetupInnerSimpleRRect(GrGLSLVertexBuilder*) override;
723a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
724a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void onEmitCode(GrGLSLVertexBuilder*, GrGLSLPPFragmentBuilder*, const char* outCoverage,
725a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                    const char* outColor) override;
726a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
727a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void emitRect(GrGLSLPPFragmentBuilder*, const char* outCoverage, const char* outColor);
728a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void emitCircle(GrGLSLPPFragmentBuilder*, const char* outCoverage);
729a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void emitArc(GrGLSLPPFragmentBuilder* f, const char* ellipseCoords, const char* ellipseName,
730a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                 bool ellipseCoordsNeedClamp, bool ellipseCoordsMayBeNegative,
731a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                 const char* outCoverage);
732a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void emitInnerRect(GrGLSLPPFragmentBuilder*, const char* outCoverage);
733a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
734a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GrGLSLVertToFrag   fColorTimesRectCoverage;
735a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GrGLSLVertToFrag   fRectCoverage;
736a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GrGLSLVertToFrag   fEllipseCoords;
737a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GrGLSLVertToFrag   fEllipseName;
738a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GrGLSLVertToFrag   fBloatedRadius;
739a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GrGLSLVertToFrag   fDistanceToInnerEdge;
740a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GrGLSLVertToFrag   fInnerShapeBloatedHalfSize;
741a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GrGLSLVertToFrag   fInnerEllipseCoords;
742a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GrGLSLVertToFrag   fInnerEllipseName;
743a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    bool               fShapeIsCircle;
744a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    bool               fTweakAlphaForCoverage;
745a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
746a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    typedef Backend INHERITED;
747a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton};
748a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
749a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendCoverage::onInit(GrGLSLVaryingHandler* varyingHandler,
750a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                    GrGLSLVertexBuilder* v) {
751a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppend ("mat2 shapeTransposeMatrix = transpose(mat2(shapeMatrix));");
752a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppend ("vec2 shapeHalfSize = vec2(length(shapeTransposeMatrix[0]), "
753a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                             "length(shapeTransposeMatrix[1]));");
754a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppend ("vec2 bloat = 0.5 / shapeHalfSize;");
755a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppendf("bloatedShapeCoords = %s * (1.0 + bloat);", fInputs.attr(Attrib::kShapeCoords));
756a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
75799ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon    if (kOval_ShapeFlag != fOpInfo.fShapeTypes) {
758a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        if (fTweakAlphaForCoverage) {
759a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            varyingHandler->addVarying("colorTimesRectCoverage", &fColorTimesRectCoverage,
760a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                       kLow_GrSLPrecision);
76199ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon            if (kRect_ShapeFlag == fOpInfo.fShapeTypes) {
762a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                fColor = fColorTimesRectCoverage;
763a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            }
764a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        } else {
765a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            varyingHandler->addVarying("rectCoverage", &fRectCoverage, kLow_GrSLPrecision);
766a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
767a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppend("float rectCoverage = 0.0;");
768a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
76999ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon    if (kRect_ShapeFlag != fOpInfo.fShapeTypes) {
770dd57dd796845da6ec2e1f44dc1e0b7821c1e4db1csmartdalton        varyingHandler->addFlatVarying("triangleIsArc", &fTriangleIsArc, kLow_GrSLPrecision);
771a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        if (!fShapeIsCircle) {
772dd57dd796845da6ec2e1f44dc1e0b7821c1e4db1csmartdalton            varyingHandler->addVarying("ellipseCoords", &fEllipseCoords, kMedium_GrSLPrecision);
773a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            varyingHandler->addFlatVarying("ellipseName", &fEllipseName, kHigh_GrSLPrecision);
774a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        } else {
775e0d362929d6569e8737d80dead791c640390e819csmartdalton            varyingHandler->addVarying("circleCoords", &fEllipseCoords, kHigh_GrSLPrecision);
776e0d362929d6569e8737d80dead791c640390e819csmartdalton            varyingHandler->addFlatVarying("bloatedRadius", &fBloatedRadius, kHigh_GrSLPrecision);
777a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
778a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
779a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
780a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
781a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendCoverage::setupRect(GrGLSLVertexBuilder* v) {
782a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // Make the border one pixel wide. Inner vs outer is indicated by coordAttrs.
783a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppendf("vec2 rectBloat = (%s != 0) ? bloat : -bloat;",
784a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                   fInputs.attr(Attrib::kVertexAttrs));
785a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // Here we use the absolute value, because when the rect is thinner than a pixel, this makes it
786a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // mark the spot where pixel center is within half a pixel of the *opposite* edge. This,
787a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // combined with the "maxCoverage" logic below gives us mathematically correct coverage even for
788a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // subpixel rectangles.
789a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppendf("bloatedShapeCoords = %s * abs(vec2(1.0 + rectBloat));",
790a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                   fInputs.attr(Attrib::kShapeCoords));
791a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
792a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // Determine coverage at the vertex. Coverage naturally ramps from 0 to 1 unless the rect is
793a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // narrower than a pixel.
794a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppend ("float maxCoverage = 4.0 * min(0.5, shapeHalfSize.x) *"
795a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                             "min(0.5, shapeHalfSize.y);");
796a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppendf("rectCoverage = (%s != 0) ? 0.0 : maxCoverage;",
797a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                   fInputs.attr(Attrib::kVertexAttrs));
798a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
799a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fTriangleIsArc.vsOut()) {
800a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = 0;", fTriangleIsArc.vsOut());
801a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
802a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
803a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
804a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendCoverage::setupOval(GrGLSLVertexBuilder* v) {
805a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // Offset the inner and outer octagons by one pixel. Inner vs outer is indicated by coordAttrs.
806a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppendf("vec2 ovalBloat = (%s != 0) ? bloat : -bloat;",
807a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                   fInputs.attr(Attrib::kVertexAttrs));
808a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppendf("bloatedShapeCoords = %s * max(vec2(1.0 + ovalBloat), vec2(0));",
809a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                   fInputs.attr(Attrib::kShapeCoords));
810a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppendf("%s = bloatedShapeCoords * shapeHalfSize;", fEllipseCoords.vsOut());
811a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fEllipseName.vsOut()) {
812a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = 1.0 / (shapeHalfSize * shapeHalfSize);", fEllipseName.vsOut());
813a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
814a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fBloatedRadius.vsOut()) {
815a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        SkASSERT(fShapeIsCircle);
816a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = shapeHalfSize.x + 0.5;", fBloatedRadius.vsOut());
817a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
818a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fTriangleIsArc.vsOut()) {
819a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = int(%s != 0);",
820a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       fTriangleIsArc.vsOut(), fInputs.attr(Attrib::kVertexAttrs));
821a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
822a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fColorTimesRectCoverage.vsOut() || fRectCoverage.vsOut()) {
823a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("rectCoverage = 1.0;");
824a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
825a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
826a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
827a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendCoverage::adjustRRectVertices(GrGLSLVertexBuilder* v) {
828a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // We try to let the AA borders line up with the arc edges on their particular side, but we
829a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // can't allow them to get closer than one half pixel to the edge or they might overlap with
830a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // their neighboring border.
831a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppend("vec2 innerEdge = max(1.0 - bloat, vec2(0));");
832a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppend ("vec2 borderEdge = cornerSign * clamp(1.0 - radii, -innerEdge, innerEdge);");
833a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // 0.5 is a special value that indicates this vertex is an arc edge.
834a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppendf("if (abs(%s.x) == 0.5)"
835a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       "bloatedShapeCoords.x = borderEdge.x;", fInputs.attr(Attrib::kShapeCoords));
836a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppendf("if (abs(%s.y) == 0.5)"
837a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       "bloatedShapeCoords.y = borderEdge.y;", fInputs.attr(Attrib::kShapeCoords));
838a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
839a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // Adjust the interior border vertices to make the border one pixel wide. 0.75 is a special
840a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // value to indicate these points.
841a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppendf("if (abs(%s.x) == 0.75) "
842a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       "bloatedShapeCoords.x = cornerSign.x * innerEdge.x;",
843a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       fInputs.attr(Attrib::kShapeCoords));
844a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppendf("if (abs(%s.y) == 0.75) "
845a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       "bloatedShapeCoords.y = cornerSign.y * innerEdge.y;",
846a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       fInputs.attr(Attrib::kShapeCoords));
847a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
848a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
849a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendCoverage::onSetupRRect(GrGLSLVertexBuilder* v) {
850a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // The geometry is laid out in such a way that rectCoverage will be 0 and 1 on the vertices, but
851a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // we still need to recompute this value because when the rrect gets thinner than one pixel, the
852a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // interior edge of the border will necessarily clamp, and we need to match the AA behavior of
853a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // the arc segments (i.e. distance from bloated edge only; ignoring the fact that the pixel
854a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // actully has less coverage because it's not completely inside the opposite edge.)
855a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppend("vec2 d = shapeHalfSize + 0.5 - abs(bloatedShapeCoords) * shapeHalfSize;");
856a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppend("rectCoverage = min(d.x, d.y);");
857a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
858a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    SkASSERT(!fShapeIsCircle);
859a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // The AA border does not get closer than one half pixel to the edge of the rect, so to get a
860a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // smooth transition from flat edge to arc, we don't allow the radii to be smaller than one half
861a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // pixel. (We don't worry about the transition on the opposite side when a radius is so large
862a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // that the border clamped on that side.)
863a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppendf("vec2 clampedRadii = max(radii, bloat);");
864a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppendf("%s = (cornerSign * bloatedShapeCoords + clampedRadii - vec2(1)) * "
865a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                        "shapeHalfSize;", fEllipseCoords.vsOut());
866a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppendf("%s = 1.0 / (clampedRadii * clampedRadii * shapeHalfSize * shapeHalfSize);",
867a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                   fEllipseName.vsOut());
868a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
869a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
870a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendCoverage::onInitInnerShape(GrGLSLVaryingHandler* varyingHandler,
871a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                              GrGLSLVertexBuilder* v) {
872a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppend("vec2 innerShapeHalfSize = shapeHalfSize / outer2Inner.xy;");
873a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
87499ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon    if (kOval_ShapeFlag == fOpInfo.fInnerShapeTypes) {
875a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        varyingHandler->addVarying("innerEllipseCoords", &fInnerEllipseCoords,
876a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                   kMedium_GrSLPrecision);
877dd57dd796845da6ec2e1f44dc1e0b7821c1e4db1csmartdalton        varyingHandler->addFlatVarying("innerEllipseName", &fInnerEllipseName, kHigh_GrSLPrecision);
878a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    } else {
879a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        varyingHandler->addVarying("distanceToInnerEdge", &fDistanceToInnerEdge,
880a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                   kMedium_GrSLPrecision);
881a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        varyingHandler->addFlatVarying("innerShapeBloatedHalfSize", &fInnerShapeBloatedHalfSize,
882a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                       kMedium_GrSLPrecision);
88399ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon        if (kRect_ShapeFlag != fOpInfo.fInnerShapeTypes) {
884dd57dd796845da6ec2e1f44dc1e0b7821c1e4db1csmartdalton            varyingHandler->addVarying("innerShapeCoords", &fInnerShapeCoords,
885dd57dd796845da6ec2e1f44dc1e0b7821c1e4db1csmartdalton                                       kMedium_GrSLPrecision);
886a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            varyingHandler->addFlatVarying("innerEllipseName", &fInnerEllipseName,
887dd57dd796845da6ec2e1f44dc1e0b7821c1e4db1csmartdalton                                           kHigh_GrSLPrecision);
888dd57dd796845da6ec2e1f44dc1e0b7821c1e4db1csmartdalton            varyingHandler->addFlatVarying("innerRRect", &fInnerRRect, kMedium_GrSLPrecision);
889a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
890a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
891a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
892a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
893a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendCoverage::setupInnerRect(GrGLSLVertexBuilder* v) {
894a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fInnerRRect.vsOut()) {
895a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        // The fragment shader will generalize every inner shape as a round rect. Since this one
896a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        // is a rect, we simply emit bogus parameters for the round rect (effectively negative
897a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        // radii) that ensure the fragment shader always takes the "emitRect" codepath.
898a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s.xy = abs(outer2Inner.xy) * (1.0 + bloat) + abs(outer2Inner.zw);",
899a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       fInnerRRect.vsOut());
900a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
901a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
902a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
903a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendCoverage::setupInnerOval(GrGLSLVertexBuilder* v) {
904a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppendf("%s = 1.0 / (innerShapeHalfSize * innerShapeHalfSize);",
905a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                   fInnerEllipseName.vsOut());
906a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fInnerEllipseCoords.vsOut()) {
907a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = innerShapeCoords * innerShapeHalfSize;", fInnerEllipseCoords.vsOut());
908a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
909a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fInnerRRect.vsOut()) {
910a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = vec4(0, 0, innerShapeHalfSize);", fInnerRRect.vsOut());
911a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
912a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
913a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
9140caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdaltonvoid GLSLInstanceProcessor::BackendCoverage::onSetupInnerSimpleRRect(GrGLSLVertexBuilder* v) {
915a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // The distance to ellipse formula doesn't work well when the radii are less than half a pixel.
916a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppend ("innerRadii = max(innerRadii, bloat);");
917a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppendf("%s = 1.0 / (innerRadii * innerRadii * innerShapeHalfSize * "
918a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                               "innerShapeHalfSize);",
919a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                   fInnerEllipseName.vsOut());
920a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppendf("%s = vec4(1.0 - innerRadii, innerShapeHalfSize);", fInnerRRect.vsOut());
921a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
922a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
923a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendCoverage::onEmitCode(GrGLSLVertexBuilder* v,
924a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                        GrGLSLPPFragmentBuilder* f,
925a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                        const char* outCoverage,
926a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                        const char* outColor) {
927a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fColorTimesRectCoverage.vsOut()) {
928a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        SkASSERT(!fRectCoverage.vsOut());
929a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = %s * rectCoverage;",
930a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       fColorTimesRectCoverage.vsOut(), fInputs.attr(Attrib::kColor));
931a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
932a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fRectCoverage.vsOut()) {
933a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        SkASSERT(!fColorTimesRectCoverage.vsOut());
934a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = rectCoverage;", fRectCoverage.vsOut());
935a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
936a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
9376762dd6f73ec6a0bea0683175d1cf4568680bee4Ethan Nicholas    SkString coverage("lowp float coverage");
93899ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon    if (fOpInfo.fInnerShapeTypes || (!fTweakAlphaForCoverage && fTriangleIsArc.fsIn())) {
939a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppendf("%s;", coverage.c_str());
940a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        coverage = "coverage";
941a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
942a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fTriangleIsArc.fsIn()) {
943a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppendf("if (%s == 0) {", fTriangleIsArc.fsIn());
944a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        this->emitRect(f, coverage.c_str(), outColor);
945a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppend ("} else {");
946a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        if (fShapeIsCircle) {
947a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            this->emitCircle(f, coverage.c_str());
948a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        } else {
94999ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon            bool ellipseCoordsMayBeNegative = SkToBool(fOpInfo.fShapeTypes & kOval_ShapeFlag);
950a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            this->emitArc(f, fEllipseCoords.fsIn(), fEllipseName.fsIn(),
951a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                          true /*ellipseCoordsNeedClamp*/, ellipseCoordsMayBeNegative,
952a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                          coverage.c_str());
953a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
954a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        if (fTweakAlphaForCoverage) {
955a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppendf("%s = %s * coverage;", outColor, fColor.fsIn());
956a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
957a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppend ("}");
958a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    } else {
959a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        this->emitRect(f, coverage.c_str(), outColor);
960a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
961a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
96299ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon    if (fOpInfo.fInnerShapeTypes) {
963a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppendf("// Inner shape.\n");
9646762dd6f73ec6a0bea0683175d1cf4568680bee4Ethan Nicholas        SkString innerCoverageDecl("lowp float innerCoverage");
96599ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon        if (kOval_ShapeFlag == fOpInfo.fInnerShapeTypes) {
966a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            this->emitArc(f, fInnerEllipseCoords.fsIn(), fInnerEllipseName.fsIn(),
967a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                          true /*ellipseCoordsNeedClamp*/, true /*ellipseCoordsMayBeNegative*/,
968a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                          innerCoverageDecl.c_str());
969a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        } else {
970a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            v->codeAppendf("%s = innerShapeCoords * innerShapeHalfSize;",
971a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                           fDistanceToInnerEdge.vsOut());
972a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            v->codeAppendf("%s = innerShapeHalfSize + 0.5;", fInnerShapeBloatedHalfSize.vsOut());
973a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
97499ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon            if (kRect_ShapeFlag == fOpInfo.fInnerShapeTypes) {
975a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                this->emitInnerRect(f, innerCoverageDecl.c_str());
976a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            } else {
977a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                f->codeAppendf("%s = 0.0;", innerCoverageDecl.c_str());
9781fc83b131afa7c29e971dd3ccc7906006bde6c09Ethan Nicholas                f->codeAppendf("mediump vec2 distanceToArcEdge = abs(%s) - %s.xy;",
979a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                               fInnerShapeCoords.fsIn(), fInnerRRect.fsIn());
980a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                f->codeAppend ("if (any(lessThan(distanceToArcEdge, vec2(1e-5)))) {");
981a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                this->emitInnerRect(f, "innerCoverage");
982a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                f->codeAppend ("} else {");
9831fc83b131afa7c29e971dd3ccc7906006bde6c09Ethan Nicholas                f->codeAppendf(    "mediump vec2 ellipseCoords = distanceToArcEdge * %s.zw;",
984a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                   fInnerRRect.fsIn());
985a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                this->emitArc(f, "ellipseCoords", fInnerEllipseName.fsIn(),
986a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                              false /*ellipseCoordsNeedClamp*/,
987a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                              false /*ellipseCoordsMayBeNegative*/, "innerCoverage");
988a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                f->codeAppend ("}");
989a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            }
990a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
991a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppendf("%s = vec4(max(coverage - innerCoverage, 0.0));", outCoverage);
992a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    } else if (!fTweakAlphaForCoverage) {
993a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppendf("%s = vec4(coverage);", outCoverage);
994a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
995a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
996a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
997a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendCoverage::emitRect(GrGLSLPPFragmentBuilder* f,
998a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                      const char* outCoverage,
999a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                      const char* outColor) {
1000a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fColorTimesRectCoverage.fsIn()) {
1001a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppendf("%s = %s;", outColor, fColorTimesRectCoverage.fsIn());
1002a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    } else if (fTweakAlphaForCoverage) {
1003a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        // We are drawing just ovals. The interior rect always has 100% coverage.
1004a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppendf("%s = %s;", outColor, fColor.fsIn());
1005a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    } else if (fRectCoverage.fsIn()) {
1006a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppendf("%s = %s;", outCoverage, fRectCoverage.fsIn());
1007a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    } else {
1008a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppendf("%s = 1.0;", outCoverage);
1009a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1010a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
1011a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1012a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendCoverage::emitCircle(GrGLSLPPFragmentBuilder* f,
1013a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                        const char* outCoverage) {
1014a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // TODO: circleCoords = max(circleCoords, 0) if we decide to do this optimization on rrects.
101599ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon    SkASSERT(!(kRRect_ShapesMask & fOpInfo.fShapeTypes));
10161fc83b131afa7c29e971dd3ccc7906006bde6c09Ethan Nicholas    f->codeAppendf("mediump float distanceToEdge = %s - length(%s);",
1017a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                   fBloatedRadius.fsIn(), fEllipseCoords.fsIn());
1018a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    f->codeAppendf("%s = clamp(distanceToEdge, 0.0, 1.0);", outCoverage);
1019a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
1020a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1021a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendCoverage::emitArc(GrGLSLPPFragmentBuilder* f,
1022a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                     const char* ellipseCoords,
1023a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                     const char* ellipseName,
1024a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                     bool ellipseCoordsNeedClamp,
1025a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                     bool ellipseCoordsMayBeNegative,
1026a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                     const char* outCoverage) {
1027a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    SkASSERT(!ellipseCoordsMayBeNegative || ellipseCoordsNeedClamp);
1028a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (ellipseCoordsNeedClamp) {
1029a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        // This serves two purposes:
1030a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        //  - To restrict the arcs of rounded rects to their positive quadrants.
1031a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        //  - To avoid inversesqrt(0) in the ellipse formula.
1032a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        if (ellipseCoordsMayBeNegative) {
10331fc83b131afa7c29e971dd3ccc7906006bde6c09Ethan Nicholas            f->codeAppendf("mediump vec2 ellipseClampedCoords = max(abs(%s), vec2(1e-4));",
10341fc83b131afa7c29e971dd3ccc7906006bde6c09Ethan Nicholas                           ellipseCoords);
1035a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        } else {
10361fc83b131afa7c29e971dd3ccc7906006bde6c09Ethan Nicholas            f->codeAppendf("mediump vec2 ellipseClampedCoords = max(%s, vec2(1e-4));",
10371fc83b131afa7c29e971dd3ccc7906006bde6c09Ethan Nicholas                           ellipseCoords);
1038a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
1039a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        ellipseCoords = "ellipseClampedCoords";
1040a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1041a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // ellipseCoords are in pixel space and ellipseName is 1 / rx^2, 1 / ry^2.
10421fc83b131afa7c29e971dd3ccc7906006bde6c09Ethan Nicholas    f->codeAppendf("highp vec2 Z = %s * %s;", ellipseCoords, ellipseName);
1043a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // implicit is the evaluation of (x/rx)^2 + (y/ry)^2 - 1.
10441fc83b131afa7c29e971dd3ccc7906006bde6c09Ethan Nicholas    f->codeAppendf("highp float implicit = dot(Z, %s) - 1.0;", ellipseCoords);
1045a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // gradDot is the squared length of the gradient of the implicit.
10461fc83b131afa7c29e971dd3ccc7906006bde6c09Ethan Nicholas    f->codeAppendf("highp float gradDot = 4.0 * dot(Z, Z);");
10471fc83b131afa7c29e971dd3ccc7906006bde6c09Ethan Nicholas    f->codeAppend ("mediump float approxDist = implicit * inversesqrt(gradDot);");
1048a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    f->codeAppendf("%s = clamp(0.5 - approxDist, 0.0, 1.0);", outCoverage);
1049a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
1050a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1051a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendCoverage::emitInnerRect(GrGLSLPPFragmentBuilder* f,
1052a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                           const char* outCoverage) {
10531fc83b131afa7c29e971dd3ccc7906006bde6c09Ethan Nicholas    f->codeAppendf("lowp vec2 c = %s - abs(%s);",
1054a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                   fInnerShapeBloatedHalfSize.fsIn(), fDistanceToInnerEdge.fsIn());
1055a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    f->codeAppendf("%s = clamp(min(c.x, c.y), 0.0, 1.0);", outCoverage);
1056a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
1057a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1058a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton////////////////////////////////////////////////////////////////////////////////////////////////////
1059a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1060a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonclass GLSLInstanceProcessor::BackendMultisample : public Backend {
1061a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonpublic:
106299ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon    BackendMultisample(OpInfo opInfo, const VertexInputs& inputs, int effectiveSampleCnt)
106399ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon            : INHERITED(opInfo, inputs)
106499ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon            , fEffectiveSampleCnt(effectiveSampleCnt)
106599ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon            , fShapeCoords(kVec2f_GrSLType)
106699ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon            , fShapeInverseMatrix(kMat22f_GrSLType)
106799ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon            , fFragShapeHalfSpan(kVec2f_GrSLType)
106899ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon            , fArcTest(kVec2f_GrSLType)
106999ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon            , fArcInverseMatrix(kMat22f_GrSLType)
107099ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon            , fFragArcHalfSpan(kVec2f_GrSLType)
107199ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon            , fEarlyAccept(kInt_GrSLType)
107299ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon            , fInnerShapeInverseMatrix(kMat22f_GrSLType)
107399ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon            , fFragInnerShapeHalfSpan(kVec2f_GrSLType) {
107499ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon        fRectTrianglesMaySplit = fOpInfo.fHasPerspective;
107599ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon        fNeedsNeighborRadii = this->isMixedSampled() && !fOpInfo.fHasPerspective;
1076a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1077a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1078a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonprivate:
1079af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon    bool isMixedSampled() const { return GrAAType::kMixedSamples == fOpInfo.aaType(); }
1080a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1081a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void onInit(GrGLSLVaryingHandler*, GrGLSLVertexBuilder*) override;
1082a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void setupRect(GrGLSLVertexBuilder*) override;
1083a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void setupOval(GrGLSLVertexBuilder*) override;
1084a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void adjustRRectVertices(GrGLSLVertexBuilder*) override;
1085a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void onSetupRRect(GrGLSLVertexBuilder*) override;
1086a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1087a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void onInitInnerShape(GrGLSLVaryingHandler*, GrGLSLVertexBuilder*) override;
1088a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void setupInnerRect(GrGLSLVertexBuilder*) override;
1089a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void setupInnerOval(GrGLSLVertexBuilder*) override;
10900caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton    void onSetupInnerSimpleRRect(GrGLSLVertexBuilder*) override;
1091a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1092a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void onEmitCode(GrGLSLVertexBuilder*, GrGLSLPPFragmentBuilder*, const char*,
1093a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                    const char*) override;
1094a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1095a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    struct EmitShapeCoords {
1096a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        const GrGLSLVarying*   fVarying;
1097a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        const char*            fInverseMatrix;
1098a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        const char*            fFragHalfSpan;
1099a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    };
1100a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1101a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    struct EmitShapeOpts {
1102a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        bool fIsTightGeometry;
1103a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        bool fResolveMixedSamples;
1104a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        bool fInvertCoverage;
1105a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    };
1106a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1107a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void emitRect(GrGLSLPPFragmentBuilder*, const EmitShapeCoords&, const EmitShapeOpts&);
1108a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void emitArc(GrGLSLPPFragmentBuilder*, const EmitShapeCoords&, bool coordsMayBeNegative,
1109a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                 bool clampCoords, const EmitShapeOpts&);
1110a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void emitSimpleRRect(GrGLSLPPFragmentBuilder*, const EmitShapeCoords&, const char* rrect,
1111a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                         const EmitShapeOpts&);
1112a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void interpolateAtSample(GrGLSLPPFragmentBuilder*, const GrGLSLVarying&, const char* sampleIdx,
1113a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                             const char* interpolationMatrix);
1114a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void acceptOrRejectWholeFragment(GrGLSLPPFragmentBuilder*, bool inside, const EmitShapeOpts&);
1115a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    void acceptCoverageMask(GrGLSLPPFragmentBuilder*, const char* shapeMask, const EmitShapeOpts&,
1116a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                            bool maybeSharedEdge = true);
1117a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1118a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    int                fEffectiveSampleCnt;
1119a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    bool               fRectTrianglesMaySplit;
1120a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GrGLSLVertToFrag   fShapeCoords;
1121a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GrGLSLVertToFrag   fShapeInverseMatrix;
1122a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GrGLSLVertToFrag   fFragShapeHalfSpan;
1123a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GrGLSLVertToFrag   fArcTest;
1124a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GrGLSLVertToFrag   fArcInverseMatrix;
1125a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GrGLSLVertToFrag   fFragArcHalfSpan;
1126a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GrGLSLVertToFrag   fEarlyAccept;
1127a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GrGLSLVertToFrag   fInnerShapeInverseMatrix;
1128a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GrGLSLVertToFrag   fFragInnerShapeHalfSpan;
1129a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    SkString           fSquareFun;
1130a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1131a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    typedef Backend INHERITED;
1132a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton};
1133a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1134a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendMultisample::onInit(GrGLSLVaryingHandler* varyingHandler,
1135a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                       GrGLSLVertexBuilder* v) {
1136a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (!this->isMixedSampled()) {
113799ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon        if (kRect_ShapeFlag != fOpInfo.fShapeTypes) {
1138dd57dd796845da6ec2e1f44dc1e0b7821c1e4db1csmartdalton            varyingHandler->addFlatVarying("triangleIsArc", &fTriangleIsArc, kLow_GrSLPrecision);
1139a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            varyingHandler->addVarying("arcCoords", &fArcCoords, kHigh_GrSLPrecision);
114099ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon            if (!fOpInfo.fHasPerspective) {
1141a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                varyingHandler->addFlatVarying("arcInverseMatrix", &fArcInverseMatrix,
1142a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                               kHigh_GrSLPrecision);
1143a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                varyingHandler->addFlatVarying("fragArcHalfSpan", &fFragArcHalfSpan,
1144a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                               kHigh_GrSLPrecision);
1145a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            }
114699ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon        } else if (!fOpInfo.fInnerShapeTypes) {
1147a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            return;
1148a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
1149a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    } else {
1150a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        varyingHandler->addVarying("shapeCoords", &fShapeCoords, kHigh_GrSLPrecision);
115199ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon        if (!fOpInfo.fHasPerspective) {
1152a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            varyingHandler->addFlatVarying("shapeInverseMatrix", &fShapeInverseMatrix,
1153a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                           kHigh_GrSLPrecision);
1154a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            varyingHandler->addFlatVarying("fragShapeHalfSpan", &fFragShapeHalfSpan,
1155a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                           kHigh_GrSLPrecision);
1156a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
115799ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon        if (fOpInfo.fShapeTypes & kRRect_ShapesMask) {
1158a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            varyingHandler->addVarying("arcCoords", &fArcCoords, kHigh_GrSLPrecision);
1159a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            varyingHandler->addVarying("arcTest", &fArcTest, kHigh_GrSLPrecision);
116099ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon            if (!fOpInfo.fHasPerspective) {
1161a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                varyingHandler->addFlatVarying("arcInverseMatrix", &fArcInverseMatrix,
1162a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                               kHigh_GrSLPrecision);
1163a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                varyingHandler->addFlatVarying("fragArcHalfSpan", &fFragArcHalfSpan,
1164a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                               kHigh_GrSLPrecision);
1165a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            }
116699ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon        } else if (fOpInfo.fShapeTypes & kOval_ShapeFlag) {
1167a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            fArcCoords = fShapeCoords;
1168a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            fArcInverseMatrix = fShapeInverseMatrix;
1169a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            fFragArcHalfSpan = fFragShapeHalfSpan;
117099ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon            if (fOpInfo.fShapeTypes & kRect_ShapeFlag) {
1171a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                varyingHandler->addFlatVarying("triangleIsArc", &fTriangleIsArc,
1172dd57dd796845da6ec2e1f44dc1e0b7821c1e4db1csmartdalton                                               kLow_GrSLPrecision);
1173a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            }
1174a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
117599ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon        if (kRect_ShapeFlag != fOpInfo.fShapeTypes) {
117699ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon            v->defineConstantf("int", "SAMPLE_MASK_ALL", "0x%x", (1 << fEffectiveSampleCnt) - 1);
117799ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon            varyingHandler->addFlatVarying("earlyAccept", &fEarlyAccept, kHigh_GrSLPrecision);
1178a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
1179a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
118099ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon    if (!fOpInfo.fHasPerspective) {
1181a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppend("mat2 shapeInverseMatrix = inverse(mat2(shapeMatrix));");
1182a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppend("vec2 fragShapeSpan = abs(vec4(shapeInverseMatrix).xz) + "
1183a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                           "abs(vec4(shapeInverseMatrix).yw);");
1184a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1185a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
1186a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1187a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendMultisample::setupRect(GrGLSLVertexBuilder* v) {
1188a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fShapeCoords.vsOut()) {
1189a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = %s;", fShapeCoords.vsOut(), this->outShapeCoords());
1190a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1191a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fShapeInverseMatrix.vsOut()) {
1192a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = shapeInverseMatrix;", fShapeInverseMatrix.vsOut());
1193a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1194a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fFragShapeHalfSpan.vsOut()) {
1195a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = 0.5 * fragShapeSpan;", fFragShapeHalfSpan.vsOut());
1196a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1197a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fArcTest.vsOut()) {
1198a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        // Pick a value that is not > 0.
1199a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = vec2(0);", fArcTest.vsOut());
1200a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1201a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fTriangleIsArc.vsOut()) {
1202a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = 0;", fTriangleIsArc.vsOut());
1203a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1204a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fEarlyAccept.vsOut()) {
1205a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = SAMPLE_MASK_ALL;", fEarlyAccept.vsOut());
1206a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1207a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
1208a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1209a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendMultisample::setupOval(GrGLSLVertexBuilder* v) {
1210a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppendf("%s = abs(%s);", fArcCoords.vsOut(), this->outShapeCoords());
1211a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fArcInverseMatrix.vsOut()) {
1212a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("vec2 s = sign(%s);", this->outShapeCoords());
1213a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = shapeInverseMatrix * mat2(s.x, 0, 0 , s.y);",
1214a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       fArcInverseMatrix.vsOut());
1215a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1216a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fFragArcHalfSpan.vsOut()) {
1217a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = 0.5 * fragShapeSpan;", fFragArcHalfSpan.vsOut());
1218a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1219a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fArcTest.vsOut()) {
1220a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        // Pick a value that is > 0.
1221a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = vec2(1);", fArcTest.vsOut());
1222a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1223a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fTriangleIsArc.vsOut()) {
1224a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        if (!this->isMixedSampled()) {
1225a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            v->codeAppendf("%s = %s & 1;",
1226a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                           fTriangleIsArc.vsOut(), fInputs.attr(Attrib::kVertexAttrs));
1227a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        } else {
1228a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            v->codeAppendf("%s = 1;", fTriangleIsArc.vsOut());
1229a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
1230a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1231a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fEarlyAccept.vsOut()) {
1232a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = ~%s & SAMPLE_MASK_ALL;",
1233a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       fEarlyAccept.vsOut(), fInputs.attr(Attrib::kVertexAttrs));
1234a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1235a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
1236a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1237a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendMultisample::adjustRRectVertices(GrGLSLVertexBuilder* v) {
1238a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (!this->isMixedSampled()) {
1239a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        INHERITED::adjustRRectVertices(v);
1240a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        return;
1241a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1242a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
124399ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon    if (!fOpInfo.fHasPerspective) {
1244a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        // For the mixed samples algorithm it's best to bloat the corner triangles a bit so that
1245a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        // more of the pixels that cross into the arc region are completely inside the shared edges.
1246a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        // We also snap to a regular rect if the radii shrink smaller than a pixel.
1247a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppend ("vec2 midpt = 0.5 * (neighborRadii - radii);");
1248a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppend ("vec2 cornerSize = any(lessThan(radii, fragShapeSpan)) ? "
1249a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                           "vec2(0) : min(radii + 0.5 * fragShapeSpan, 1.0 - midpt);");
1250a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    } else {
1251a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        // TODO: We could still bloat the corner triangle in the perspective case; we would just
1252a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        // need to find the screen-space derivative of shape coords at this particular point.
1253a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppend ("vec2 cornerSize = any(lessThan(radii, vec2(1e-3))) ? vec2(0) : radii;");
1254a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1255a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1256a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppendf("if (abs(%s.x) == 0.5)"
1257a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       "%s.x = cornerSign.x * (1.0 - cornerSize.x);",
1258a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       fInputs.attr(Attrib::kShapeCoords), fModifiedShapeCoords);
1259a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppendf("if (abs(%s.y) == 0.5)"
1260a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       "%s.y = cornerSign.y * (1.0 - cornerSize.y);",
1261a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       fInputs.attr(Attrib::kShapeCoords), fModifiedShapeCoords);
1262a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
1263a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1264a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendMultisample::onSetupRRect(GrGLSLVertexBuilder* v) {
1265a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fShapeCoords.vsOut()) {
1266a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = %s;", fShapeCoords.vsOut(), this->outShapeCoords());
1267a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1268a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fShapeInverseMatrix.vsOut()) {
1269a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = shapeInverseMatrix;", fShapeInverseMatrix.vsOut());
1270a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1271a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fFragShapeHalfSpan.vsOut()) {
1272a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = 0.5 * fragShapeSpan;", fFragShapeHalfSpan.vsOut());
1273a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1274a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fArcInverseMatrix.vsOut()) {
1275a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppend ("vec2 s = cornerSign / radii;");
1276a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = shapeInverseMatrix * mat2(s.x, 0, 0, s.y);",
1277a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       fArcInverseMatrix.vsOut());
1278a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1279a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fFragArcHalfSpan.vsOut()) {
1280a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = 0.5 * (abs(vec4(%s).xz) + abs(vec4(%s).yw));",
1281a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       fFragArcHalfSpan.vsOut(), fArcInverseMatrix.vsOut(),
1282a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       fArcInverseMatrix.vsOut());
1283a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1284a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fArcTest.vsOut()) {
1285a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        // The interior triangles are laid out as a fan. fArcTest is both distances from shared
1286a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        // edges of a fan triangle to a point within that triangle. fArcTest is used to check if a
1287a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        // fragment is too close to either shared edge, in which case we point sample the shape as a
1288a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        // rect at that point in order to guarantee the mixed samples discard logic works correctly.
1289a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = (cornerSize == vec2(0)) ? vec2(0) : "
1290a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       "cornerSign * %s * mat2(1, cornerSize.x - 1.0, cornerSize.y - 1.0, 1);",
1291a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       fArcTest.vsOut(), fModifiedShapeCoords);
129299ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon        if (!fOpInfo.fHasPerspective) {
1293a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            // Shift the point at which distances to edges are measured from the center of the pixel
1294a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            // to the corner. This way the sign of fArcTest will quickly tell us whether a pixel
1295a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            // is completely inside the shared edge. Perspective mode will accomplish this same task
1296a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            // by finding the derivatives in the fragment shader.
1297a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            v->codeAppendf("%s -= 0.5 * (fragShapeSpan.yx * abs(radii - 1.0) + fragShapeSpan);",
1298a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                           fArcTest.vsOut());
1299a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
1300a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1301a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fEarlyAccept.vsOut()) {
1302a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        SkASSERT(this->isMixedSampled());
1303a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = all(equal(vec2(1), abs(%s))) ? 0 : SAMPLE_MASK_ALL;",
1304a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       fEarlyAccept.vsOut(), fInputs.attr(Attrib::kShapeCoords));
1305a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1306a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
1307a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1308a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid
1309a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonGLSLInstanceProcessor::BackendMultisample::onInitInnerShape(GrGLSLVaryingHandler* varyingHandler,
1310a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                            GrGLSLVertexBuilder* v) {
1311a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    varyingHandler->addVarying("innerShapeCoords", &fInnerShapeCoords, kHigh_GrSLPrecision);
131299ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon    if (kOval_ShapeFlag != fOpInfo.fInnerShapeTypes &&
131399ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon        kRect_ShapeFlag != fOpInfo.fInnerShapeTypes) {
1314a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        varyingHandler->addFlatVarying("innerRRect", &fInnerRRect, kHigh_GrSLPrecision);
1315a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
131699ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon    if (!fOpInfo.fHasPerspective) {
1317a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        varyingHandler->addFlatVarying("innerShapeInverseMatrix", &fInnerShapeInverseMatrix,
1318a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                       kHigh_GrSLPrecision);
1319a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = shapeInverseMatrix * mat2(outer2Inner.x, 0, 0, outer2Inner.y);",
1320a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       fInnerShapeInverseMatrix.vsOut());
1321a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        varyingHandler->addFlatVarying("fragInnerShapeHalfSpan", &fFragInnerShapeHalfSpan,
1322a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                       kHigh_GrSLPrecision);
1323a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = 0.5 * fragShapeSpan * outer2Inner.xy;",
1324a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       fFragInnerShapeHalfSpan.vsOut());
1325a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1326a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
1327a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1328a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendMultisample::setupInnerRect(GrGLSLVertexBuilder* v) {
1329a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fInnerRRect.vsOut()) {
1330a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        // The fragment shader will generalize every inner shape as a round rect. Since this one
1331a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        // is a rect, we simply emit bogus parameters for the round rect (negative radii) that
1332a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        // ensure the fragment shader always takes the "sample as rect" codepath.
1333a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = vec4(2.0 * (inner.zw - inner.xy) / (outer.zw - outer.xy), vec2(0));",
1334a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       fInnerRRect.vsOut());
1335a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1336a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
1337a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1338a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendMultisample::setupInnerOval(GrGLSLVertexBuilder* v) {
1339a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fInnerRRect.vsOut()) {
1340a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("%s = vec4(0, 0, 1, 1);", fInnerRRect.vsOut());
1341a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1342a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
1343a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
13440caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdaltonvoid GLSLInstanceProcessor::BackendMultisample::onSetupInnerSimpleRRect(GrGLSLVertexBuilder* v) {
1345a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // Avoid numeric instability by not allowing the inner radii to get smaller than 1/10th pixel.
1346a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (fFragInnerShapeHalfSpan.vsOut()) {
1347a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppendf("innerRadii = max(innerRadii, 2e-1 * %s);", fFragInnerShapeHalfSpan.vsOut());
1348a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    } else {
1349a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        v->codeAppend ("innerRadii = max(innerRadii, vec2(1e-4));");
1350a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1351a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    v->codeAppendf("%s = vec4(1.0 - innerRadii, 1.0 / innerRadii);", fInnerRRect.vsOut());
1352a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
1353a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1354a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendMultisample::onEmitCode(GrGLSLVertexBuilder*,
1355a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                           GrGLSLPPFragmentBuilder* f,
1356a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                           const char*, const char*) {
13575961bc9278a00e56dacdd9408d0744b5a0a3b493ethannicholas    f->defineConstant("SAMPLE_COUNT", fEffectiveSampleCnt);
1358a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (this->isMixedSampled()) {
13595961bc9278a00e56dacdd9408d0744b5a0a3b493ethannicholas        f->defineConstantf("int", "SAMPLE_MASK_ALL", "0x%x", (1 << fEffectiveSampleCnt) - 1);
13605961bc9278a00e56dacdd9408d0744b5a0a3b493ethannicholas        f->defineConstantf("int", "SAMPLE_MASK_MSB", "0x%x", 1 << (fEffectiveSampleCnt - 1));
1361a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1362a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
136399ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon    if (kRect_ShapeFlag != (fOpInfo.fShapeTypes | fOpInfo.fInnerShapeTypes)) {
136499938a8ef24e2dd5b39f78638742e9b50ab6d9bfBrian Salomon        GrShaderVar x("x", kVec2f_GrSLType, GrShaderVar::kNonArray, kHigh_GrSLPrecision);
1365a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->emitFunction(kFloat_GrSLType, "square", 1, &x, "return dot(x, x);", &fSquareFun);
1366a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1367a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1368a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    EmitShapeCoords shapeCoords;
1369a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    shapeCoords.fVarying = &fShapeCoords;
1370a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    shapeCoords.fInverseMatrix = fShapeInverseMatrix.fsIn();
1371a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    shapeCoords.fFragHalfSpan = fFragShapeHalfSpan.fsIn();
1372a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1373a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    EmitShapeCoords arcCoords;
1374a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    arcCoords.fVarying = &fArcCoords;
1375a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    arcCoords.fInverseMatrix = fArcInverseMatrix.fsIn();
1376a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    arcCoords.fFragHalfSpan = fFragArcHalfSpan.fsIn();
137799ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon    bool clampArcCoords = this->isMixedSampled() && (fOpInfo.fShapeTypes & kRRect_ShapesMask);
1378a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1379a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    EmitShapeOpts opts;
1380a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    opts.fIsTightGeometry = true;
1381a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    opts.fResolveMixedSamples = this->isMixedSampled();
1382a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    opts.fInvertCoverage = false;
1383a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
138499ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon    if (fOpInfo.fHasPerspective && fOpInfo.fInnerShapeTypes) {
1385a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        // This determines if the fragment should consider the inner shape in its sample mask.
1386a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        // We take the derivative early in case discards may occur before we get to the inner shape.
13871fc83b131afa7c29e971dd3ccc7906006bde6c09Ethan Nicholas        f->codeAppendf("highp vec2 fragInnerShapeApproxHalfSpan = 0.5 * fwidth(%s);",
1388a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       fInnerShapeCoords.fsIn());
1389a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1390a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1391a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (!this->isMixedSampled()) {
1392a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        SkASSERT(!fArcTest.fsIn());
1393a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        if (fTriangleIsArc.fsIn()) {
1394a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppendf("if (%s != 0) {", fTriangleIsArc.fsIn());
1395a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            this->emitArc(f, arcCoords, false, clampArcCoords, opts);
1396a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1397a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppend ("}");
1398a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
1399a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    } else {
1400a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        const char* arcTest = fArcTest.fsIn();
140199ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon        if (arcTest && fOpInfo.fHasPerspective) {
1402e0d362929d6569e8737d80dead791c640390e819csmartdalton            // The non-perspective version accounts for fwidth() in the vertex shader.
1403a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            // We make sure to take the derivative here, before a neighbor pixel may early accept.
14041fc83b131afa7c29e971dd3ccc7906006bde6c09Ethan Nicholas            f->codeAppendf("highp vec2 arcTest = %s - 0.5 * fwidth(%s);",
1405a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                           fArcTest.fsIn(), fArcTest.fsIn());
1406a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            arcTest = "arcTest";
1407a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
1408a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        const char* earlyAccept = fEarlyAccept.fsIn() ? fEarlyAccept.fsIn() : "SAMPLE_MASK_ALL";
1409a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppendf("if (gl_SampleMaskIn[0] == %s) {", earlyAccept);
1410a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->overrideSampleCoverage(earlyAccept);
1411a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppend ("} else {");
1412a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        if (arcTest) {
1413a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            // At this point, if the sample mask is all set it means we are inside an arc triangle.
1414a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppendf("if (gl_SampleMaskIn[0] == SAMPLE_MASK_ALL || "
1415a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                               "all(greaterThan(%s, vec2(0)))) {", arcTest);
1416a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            this->emitArc(f, arcCoords, false, clampArcCoords, opts);
1417a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppend ("} else {");
1418a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            this->emitRect(f, shapeCoords, opts);
1419a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppend ("}");
1420a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        } else if (fTriangleIsArc.fsIn()) {
1421a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppendf("if (%s == 0) {", fTriangleIsArc.fsIn());
1422a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            this->emitRect(f, shapeCoords, opts);
1423a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppend ("} else {");
1424a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            this->emitArc(f, arcCoords, false, clampArcCoords, opts);
1425a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppend ("}");
142699ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon        } else if (fOpInfo.fShapeTypes == kOval_ShapeFlag) {
1427a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            this->emitArc(f, arcCoords, false, clampArcCoords, opts);
1428a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        } else {
142999ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon            SkASSERT(fOpInfo.fShapeTypes == kRect_ShapeFlag);
1430a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            this->emitRect(f, shapeCoords, opts);
1431a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
1432a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppend ("}");
1433a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1434a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
143599ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon    if (fOpInfo.fInnerShapeTypes) {
1436a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppendf("// Inner shape.\n");
1437a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1438a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        EmitShapeCoords innerShapeCoords;
1439a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        innerShapeCoords.fVarying = &fInnerShapeCoords;
144099ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon        if (!fOpInfo.fHasPerspective) {
1441a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            innerShapeCoords.fInverseMatrix = fInnerShapeInverseMatrix.fsIn();
1442a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            innerShapeCoords.fFragHalfSpan = fFragInnerShapeHalfSpan.fsIn();
1443a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
1444a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1445a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        EmitShapeOpts innerOpts;
1446a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        innerOpts.fIsTightGeometry = false;
1447a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        innerOpts.fResolveMixedSamples = false; // Mixed samples are resolved in the outer shape.
1448a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        innerOpts.fInvertCoverage = true;
1449a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
145099ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon        if (kOval_ShapeFlag == fOpInfo.fInnerShapeTypes) {
1451a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            this->emitArc(f, innerShapeCoords, true, false, innerOpts);
1452a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        } else {
1453a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppendf("if (all(lessThan(abs(%s), 1.0 + %s))) {", fInnerShapeCoords.fsIn(),
145499ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon                           !fOpInfo.fHasPerspective ? innerShapeCoords.fFragHalfSpan
145599ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon                                                    : "fragInnerShapeApproxHalfSpan");  // Above.
145699ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon            if (kRect_ShapeFlag == fOpInfo.fInnerShapeTypes) {
1457a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                this->emitRect(f, innerShapeCoords, innerOpts);
1458a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            } else {
1459a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                this->emitSimpleRRect(f, innerShapeCoords, fInnerRRect.fsIn(), innerOpts);
1460a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            }
1461a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppend ("}");
1462a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
1463a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1464a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
1465a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1466a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendMultisample::emitRect(GrGLSLPPFragmentBuilder* f,
1467a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                         const EmitShapeCoords& coords,
1468a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                         const EmitShapeOpts& opts) {
1469a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // Full MSAA doesn't need to do anything to draw a rect.
1470a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    SkASSERT(!opts.fIsTightGeometry || opts.fResolveMixedSamples);
1471a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (coords.fFragHalfSpan) {
1472a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppendf("if (all(lessThanEqual(abs(%s), 1.0 - %s))) {",
1473a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       coords.fVarying->fsIn(), coords.fFragHalfSpan);
1474a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        // The entire pixel is inside the rect.
1475a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        this->acceptOrRejectWholeFragment(f, true, opts);
1476a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppend ("} else ");
1477a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        if (opts.fIsTightGeometry && !fRectTrianglesMaySplit) {
1478a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppendf("if (any(lessThan(abs(%s), 1.0 - %s))) {",
1479a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                           coords.fVarying->fsIn(), coords.fFragHalfSpan);
1480a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            // The pixel falls on an edge of the rectangle and is known to not be on a shared edge.
1481a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            this->acceptCoverageMask(f, "gl_SampleMaskIn[0]", opts, false);
1482a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppend ("} else");
1483a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
1484a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppend ("{");
1485a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1486a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    f->codeAppend ("int rectMask = 0;");
1487a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    f->codeAppend ("for (int i = 0; i < SAMPLE_COUNT; i++) {");
14881fc83b131afa7c29e971dd3ccc7906006bde6c09Ethan Nicholas    f->codeAppend (    "highp vec2 pt = ");
1489a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    this->interpolateAtSample(f, *coords.fVarying, "i", coords.fInverseMatrix);
1490a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    f->codeAppend (    ";");
1491a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    f->codeAppend (    "if (all(lessThan(abs(pt), vec2(1)))) rectMask |= (1 << i);");
1492a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    f->codeAppend ("}");
1493a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    this->acceptCoverageMask(f, "rectMask", opts);
1494a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (coords.fFragHalfSpan) {
1495a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppend ("}");
1496a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1497a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
1498a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1499a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendMultisample::emitArc(GrGLSLPPFragmentBuilder* f,
1500a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                        const EmitShapeCoords& coords,
1501a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                        bool coordsMayBeNegative, bool clampCoords,
1502a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                        const EmitShapeOpts& opts) {
1503a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (coords.fFragHalfSpan) {
1504a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        SkString absArcCoords;
1505a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        absArcCoords.printf(coordsMayBeNegative ? "abs(%s)" : "%s", coords.fVarying->fsIn());
1506a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        if (clampCoords) {
1507a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppendf("if (%s(max(%s + %s, vec2(0))) < 1.0) {",
1508a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                           fSquareFun.c_str(), absArcCoords.c_str(), coords.fFragHalfSpan);
1509a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        } else {
1510a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppendf("if (%s(%s + %s) < 1.0) {",
1511a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                           fSquareFun.c_str(), absArcCoords.c_str(), coords.fFragHalfSpan);
1512a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
1513a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        // The entire pixel is inside the arc.
1514a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        this->acceptOrRejectWholeFragment(f, true, opts);
1515a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppendf("} else if (%s(max(%s - %s, vec2(0))) >= 1.0) {",
1516a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       fSquareFun.c_str(), absArcCoords.c_str(), coords.fFragHalfSpan);
1517a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        // The entire pixel is outside the arc.
1518a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        this->acceptOrRejectWholeFragment(f, false, opts);
1519a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppend ("} else {");
1520a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1521a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    f->codeAppend (    "int arcMask = 0;");
1522a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    f->codeAppend (    "for (int i = 0; i < SAMPLE_COUNT; i++) {");
15231fc83b131afa7c29e971dd3ccc7906006bde6c09Ethan Nicholas    f->codeAppend (        "highp vec2 pt = ");
1524a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    this->interpolateAtSample(f, *coords.fVarying, "i", coords.fInverseMatrix);
1525a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    f->codeAppend (        ";");
1526a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (clampCoords) {
1527a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        SkASSERT(!coordsMayBeNegative);
1528a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppend (    "pt = max(pt, vec2(0));");
1529a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1530a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    f->codeAppendf(        "if (%s(pt) < 1.0) arcMask |= (1 << i);", fSquareFun.c_str());
1531a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    f->codeAppend (    "}");
1532a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    this->acceptCoverageMask(f, "arcMask", opts);
1533a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (coords.fFragHalfSpan) {
1534a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppend ("}");
1535a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1536a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
1537a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1538a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendMultisample::emitSimpleRRect(GrGLSLPPFragmentBuilder* f,
1539a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                                const EmitShapeCoords& coords,
1540a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                                const char* rrect,
1541a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                                const EmitShapeOpts& opts) {
15421fc83b131afa7c29e971dd3ccc7906006bde6c09Ethan Nicholas    f->codeAppendf("highp vec2 distanceToArcEdge = abs(%s) - %s.xy;", coords.fVarying->fsIn(),
15431fc83b131afa7c29e971dd3ccc7906006bde6c09Ethan Nicholas                   rrect);
1544a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    f->codeAppend ("if (any(lessThan(distanceToArcEdge, vec2(0)))) {");
1545a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    this->emitRect(f, coords, opts);
1546a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    f->codeAppend ("} else {");
1547a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (coords.fInverseMatrix && coords.fFragHalfSpan) {
15481fc83b131afa7c29e971dd3ccc7906006bde6c09Ethan Nicholas        f->codeAppendf("highp vec2 rrectCoords = distanceToArcEdge * %s.zw;", rrect);
15491fc83b131afa7c29e971dd3ccc7906006bde6c09Ethan Nicholas        f->codeAppendf("highp vec2 fragRRectHalfSpan = %s * %s.zw;", coords.fFragHalfSpan, rrect);
1550a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppendf("if (%s(rrectCoords + fragRRectHalfSpan) <= 1.0) {", fSquareFun.c_str());
1551a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        // The entire pixel is inside the round rect.
1552a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        this->acceptOrRejectWholeFragment(f, true, opts);
1553a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppendf("} else if (%s(max(rrectCoords - fragRRectHalfSpan, vec2(0))) >= 1.0) {",
1554a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                       fSquareFun.c_str());
1555a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        // The entire pixel is outside the round rect.
1556a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        this->acceptOrRejectWholeFragment(f, false, opts);
1557a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppend ("} else {");
15581fc83b131afa7c29e971dd3ccc7906006bde6c09Ethan Nicholas        f->codeAppendf(    "highp vec2 s = %s.zw * sign(%s);", rrect, coords.fVarying->fsIn());
15591fc83b131afa7c29e971dd3ccc7906006bde6c09Ethan Nicholas        f->codeAppendf(    "highp mat2 innerRRectInverseMatrix = %s * mat2(s.x, 0, 0, s.y);",
1560a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                           coords.fInverseMatrix);
15611fc83b131afa7c29e971dd3ccc7906006bde6c09Ethan Nicholas        f->codeAppend (    "highp int rrectMask = 0;");
1562a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppend (    "for (int i = 0; i < SAMPLE_COUNT; i++) {");
15631fc83b131afa7c29e971dd3ccc7906006bde6c09Ethan Nicholas        f->codeAppend (        "highp vec2 pt = rrectCoords + ");
1564a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->appendOffsetToSample("i", GrGLSLFPFragmentBuilder::kSkiaDevice_Coordinates);
1565a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppend (                  "* innerRRectInverseMatrix;");
1566a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppendf(        "if (%s(max(pt, vec2(0))) < 1.0) rrectMask |= (1 << i);",
1567a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                               fSquareFun.c_str());
1568a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppend (    "}");
1569a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        this->acceptCoverageMask(f, "rrectMask", opts);
1570a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppend ("}");
1571a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    } else {
1572a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppend ("int rrectMask = 0;");
1573a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppend ("for (int i = 0; i < SAMPLE_COUNT; i++) {");
15741fc83b131afa7c29e971dd3ccc7906006bde6c09Ethan Nicholas        f->codeAppend (    "highp vec2 shapePt = ");
1575a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        this->interpolateAtSample(f, *coords.fVarying, "i", nullptr);
1576a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppend (    ";");
15771fc83b131afa7c29e971dd3ccc7906006bde6c09Ethan Nicholas        f->codeAppendf(    "highp vec2 rrectPt = max(abs(shapePt) - %s.xy, vec2(0)) * %s.zw;",
1578a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                           rrect, rrect);
1579a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppendf(    "if (%s(rrectPt) < 1.0) rrectMask |= (1 << i);", fSquareFun.c_str());
1580a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppend ("}");
1581a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        this->acceptCoverageMask(f, "rrectMask", opts);
1582a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1583a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    f->codeAppend ("}");
1584a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
1585a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1586a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendMultisample::interpolateAtSample(GrGLSLPPFragmentBuilder* f,
1587a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                                  const GrGLSLVarying& varying,
1588a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                                  const char* sampleIdx,
1589a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                                  const char* interpolationMatrix) {
1590a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (interpolationMatrix) {
1591a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppendf("(%s + ", varying.fsIn());
1592a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->appendOffsetToSample(sampleIdx, GrGLSLFPFragmentBuilder::kSkiaDevice_Coordinates);
1593a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppendf(" * %s)", interpolationMatrix);
1594a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    } else {
1595a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        SkAssertResult(
1596a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->enableFeature(GrGLSLFragmentBuilder::kMultisampleInterpolation_GLSLFeature));
1597a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppendf("interpolateAtOffset(%s, ", varying.fsIn());
1598a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->appendOffsetToSample(sampleIdx, GrGLSLFPFragmentBuilder::kGLSLWindow_Coordinates);
1599a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->codeAppend(")");
1600a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1601a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
1602a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1603a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid
1604a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonGLSLInstanceProcessor::BackendMultisample::acceptOrRejectWholeFragment(GrGLSLPPFragmentBuilder* f,
1605a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                                       bool inside,
1606a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                                       const EmitShapeOpts& opts) {
1607a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (inside != opts.fInvertCoverage) { // Accept the entire fragment.
1608a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        if (opts.fResolveMixedSamples) {
1609a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            // This is a mixed sampled fragment in the interior of the shape. Reassign 100% coverage
1610a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            // to one fragment, and drop all other fragments that may fall on this same pixel. Since
1611a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            // our geometry is water tight and non-overlapping, we can take advantage of the
1612a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            // properties that (1) the incoming sample masks will be disjoint across fragments that
1613a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            // fall on a common pixel, and (2) since the entire fragment is inside the shape, each
1614a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            // sample's corresponding bit will be set in the incoming sample mask of exactly one
1615a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            // fragment.
1616a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppend("if ((gl_SampleMaskIn[0] & SAMPLE_MASK_MSB) == 0) {");
1617a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            // Drop this fragment.
161899ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon            if (!fOpInfo.fCannotDiscard) {
1619a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                f->codeAppend("discard;");
1620a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            } else {
1621a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                f->overrideSampleCoverage("0");
1622a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            }
1623a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppend("} else {");
1624a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            // Override the lone surviving fragment to full coverage.
1625a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->overrideSampleCoverage("-1");
1626a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppend("}");
1627a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
1628a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    } else { // Reject the entire fragment.
162999ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon        if (!fOpInfo.fCannotDiscard) {
1630a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppend("discard;");
1631a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        } else if (opts.fResolveMixedSamples) {
1632a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->overrideSampleCoverage("0");
1633a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        } else {
1634a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->maskSampleCoverage("0");
1635a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
1636a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1637a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
1638a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1639a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendMultisample::acceptCoverageMask(GrGLSLPPFragmentBuilder* f,
1640a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                                   const char* shapeMask,
1641a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                                   const EmitShapeOpts& opts,
1642a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                                                   bool maybeSharedEdge) {
1643a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (opts.fResolveMixedSamples) {
1644a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        if (maybeSharedEdge) {
1645a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            // This is a mixed sampled fragment, potentially on the outer edge of the shape, with
1646a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            // only partial shape coverage. Override the coverage of one fragment to "shapeMask",
1647a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            // and drop all other fragments that may fall on this same pixel. Since our geometry is
1648a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            // water tight, non-overlapping, and completely contains the shape, this means that each
1649a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            // "on" bit from shapeMask is guaranteed to be set in the incoming sample mask of one,
1650a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            // and only one, fragment that falls on this same pixel.
1651a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            SkASSERT(!opts.fInvertCoverage);
1652a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppendf("if ((gl_SampleMaskIn[0] & (1 << findMSB(%s))) == 0) {", shapeMask);
1653a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            // Drop this fragment.
165499ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon            if (!fOpInfo.fCannotDiscard) {
1655a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                f->codeAppend ("discard;");
1656a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            } else {
1657a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                f->overrideSampleCoverage("0");
1658a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            }
1659a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppend ("} else {");
1660a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            // Override the coverage of the lone surviving fragment to "shapeMask".
1661a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->overrideSampleCoverage(shapeMask);
1662a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->codeAppend ("}");
1663a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        } else {
1664a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            f->overrideSampleCoverage(shapeMask);
1665a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
1666a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    } else {
1667a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        f->maskSampleCoverage(shapeMask, opts.fInvertCoverage);
1668a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1669a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
1670a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1671a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton////////////////////////////////////////////////////////////////////////////////////////////////////
1672a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
167399ad164886ba39f688ebabecd5fe20dd5d923ba0Brian SalomonGLSLInstanceProcessor::Backend* GLSLInstanceProcessor::Backend::Create(const GrPipeline& pipeline,
167499ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon                                                                       OpInfo opInfo,
167599ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon                                                                       const VertexInputs& inputs) {
1676af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon    switch (opInfo.aaType()) {
1677a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        default:
1678a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            SkFAIL("Unexpected antialias mode.");
1679af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon        case GrAAType::kNone:
168099ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon            return new BackendNonAA(opInfo, inputs);
1681af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon        case GrAAType::kCoverage:
168299ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon            return new BackendCoverage(opInfo, inputs);
1683af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon        case GrAAType::kMSAA:
1684af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon        case GrAAType::kMixedSamples: {
1685a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton            const GrRenderTargetPriv& rtp = pipeline.getRenderTarget()->renderTargetPriv();
1686c633abbb342e3af0e56382e8cb7e7d9fed71e237csmartdalton            const GrGpu::MultisampleSpecs& specs = rtp.getMultisampleSpecs(pipeline);
168799ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon            return new BackendMultisample(opInfo, inputs, specs.fEffectiveSampleCnt);
1688a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        }
1689a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
1690a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
1691a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1692a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton////////////////////////////////////////////////////////////////////////////////////////////////////
1693a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1694a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonconst ShapeVertex kVertexData[] = {
1695a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // Rectangle.
1696a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+1, +1, ~0},   /*0*/
1697a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-1, +1, ~0},   /*1*/
1698a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-1, -1, ~0},   /*2*/
1699a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+1, -1, ~0},   /*3*/
1700a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // The next 4 are for the bordered version.
1701a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+1, +1,  0},   /*4*/
1702a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-1, +1,  0},   /*5*/
1703a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-1, -1,  0},   /*6*/
1704a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+1, -1,  0},   /*7*/
1705a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1706a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // Octagon that inscribes the unit circle, cut by an interior unit octagon.
1707a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+1.000000f,  0.000000f,  0},   /* 8*/
1708a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+1.000000f, +0.414214f, ~0},   /* 9*/
1709a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+0.707106f, +0.707106f,  0},   /*10*/
1710a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+0.414214f, +1.000000f, ~0},   /*11*/
1711a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    { 0.000000f, +1.000000f,  0},   /*12*/
1712a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-0.414214f, +1.000000f, ~0},   /*13*/
1713a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-0.707106f, +0.707106f,  0},   /*14*/
1714a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-1.000000f, +0.414214f, ~0},   /*15*/
1715a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-1.000000f,  0.000000f,  0},   /*16*/
1716a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-1.000000f, -0.414214f, ~0},   /*17*/
1717a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-0.707106f, -0.707106f,  0},   /*18*/
1718a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-0.414214f, -1.000000f, ~0},   /*19*/
1719a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    { 0.000000f, -1.000000f,  0},   /*20*/
1720a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+0.414214f, -1.000000f, ~0},   /*21*/
1721a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+0.707106f, -0.707106f,  0},   /*22*/
1722a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+1.000000f, -0.414214f, ~0},   /*23*/
1723a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // This vertex is for the fanned versions.
1724a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    { 0.000000f,  0.000000f, ~0},   /*24*/
1725a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1726a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // Rectangle with disjoint corner segments.
1727a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+1.0, +0.5,  0x3},   /*25*/
1728a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+1.0, +1.0,  0x3},   /*26*/
1729a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+0.5, +1.0,  0x3},   /*27*/
1730a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-0.5, +1.0,  0x2},   /*28*/
1731a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-1.0, +1.0,  0x2},   /*29*/
1732a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-1.0, +0.5,  0x2},   /*30*/
1733a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-1.0, -0.5,  0x0},   /*31*/
1734a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-1.0, -1.0,  0x0},   /*32*/
1735a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-0.5, -1.0,  0x0},   /*33*/
1736a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+0.5, -1.0,  0x1},   /*34*/
1737a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+1.0, -1.0,  0x1},   /*35*/
1738a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+1.0, -0.5,  0x1},   /*36*/
1739a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // The next 4 are for the fanned version.
1740a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    { 0.0,  0.0,  0x3},   /*37*/
1741a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    { 0.0,  0.0,  0x2},   /*38*/
1742a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    { 0.0,  0.0,  0x0},   /*39*/
1743a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    { 0.0,  0.0,  0x1},   /*40*/
1744a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // The next 8 are for the bordered version.
1745a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+0.75, +0.50,  0x3},   /*41*/
1746a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+0.50, +0.75,  0x3},   /*42*/
1747a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-0.50, +0.75,  0x2},   /*43*/
1748a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-0.75, +0.50,  0x2},   /*44*/
1749a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-0.75, -0.50,  0x0},   /*45*/
1750a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-0.50, -0.75,  0x0},   /*46*/
1751a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+0.50, -0.75,  0x1},   /*47*/
1752a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+0.75, -0.50,  0x1},   /*48*/
1753a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1754a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // 16-gon that inscribes the unit circle, cut by an interior unit 16-gon.
1755a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+1.000000f, +0.000000f,  0},   /*49*/
1756a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+1.000000f, +0.198913f, ~0},   /*50*/
1757a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+0.923879f, +0.382683f,  0},   /*51*/
1758a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+0.847760f, +0.566455f, ~0},   /*52*/
1759a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+0.707106f, +0.707106f,  0},   /*53*/
1760a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+0.566455f, +0.847760f, ~0},   /*54*/
1761a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+0.382683f, +0.923879f,  0},   /*55*/
1762a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+0.198913f, +1.000000f, ~0},   /*56*/
1763a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+0.000000f, +1.000000f,  0},   /*57*/
1764a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-0.198913f, +1.000000f, ~0},   /*58*/
1765a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-0.382683f, +0.923879f,  0},   /*59*/
1766a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-0.566455f, +0.847760f, ~0},   /*60*/
1767a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-0.707106f, +0.707106f,  0},   /*61*/
1768a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-0.847760f, +0.566455f, ~0},   /*62*/
1769a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-0.923879f, +0.382683f,  0},   /*63*/
1770a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-1.000000f, +0.198913f, ~0},   /*64*/
1771a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-1.000000f, +0.000000f,  0},   /*65*/
1772a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-1.000000f, -0.198913f, ~0},   /*66*/
1773a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-0.923879f, -0.382683f,  0},   /*67*/
1774a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-0.847760f, -0.566455f, ~0},   /*68*/
1775a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-0.707106f, -0.707106f,  0},   /*69*/
1776a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-0.566455f, -0.847760f, ~0},   /*70*/
1777a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-0.382683f, -0.923879f,  0},   /*71*/
1778a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-0.198913f, -1.000000f, ~0},   /*72*/
1779a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {-0.000000f, -1.000000f,  0},   /*73*/
1780a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+0.198913f, -1.000000f, ~0},   /*74*/
1781a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+0.382683f, -0.923879f,  0},   /*75*/
1782a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+0.566455f, -0.847760f, ~0},   /*76*/
1783a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+0.707106f, -0.707106f,  0},   /*77*/
1784a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+0.847760f, -0.566455f, ~0},   /*78*/
1785a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+0.923879f, -0.382683f,  0},   /*79*/
1786a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    {+1.000000f, -0.198913f, ~0},   /*80*/
1787a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton};
1788a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1789a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonconst uint8_t kIndexData[] = {
1790a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // Rectangle.
1791a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    0, 1, 2,
1792a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    0, 2, 3,
1793a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1794a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // Rectangle with a border.
1795a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    0, 1, 5,
1796a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    5, 4, 0,
1797a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    1, 2, 6,
1798a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    6, 5, 1,
1799a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    2, 3, 7,
1800a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    7, 6, 2,
1801a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    3, 0, 4,
1802a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    4, 7, 3,
1803a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    4, 5, 6,
1804a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    6, 7, 4,
1805a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1806a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // Octagon that inscribes the unit circle, cut by an interior unit octagon.
1807a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    10,  8,  9,
1808a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    12, 10, 11,
1809a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    14, 12, 13,
1810a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    16, 14, 15,
1811a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    18, 16, 17,
1812a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    20, 18, 19,
1813a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    22, 20, 21,
1814a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton     8, 22, 23,
1815a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton     8, 10, 12,
1816a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    12, 14, 16,
1817a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    16, 18, 20,
1818a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    20, 22,  8,
1819a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton     8, 12, 16,
1820a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    16, 20,  8,
1821a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1822a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // Same octagons, but with the interior arranged as a fan. Used by mixed samples.
1823a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    10,  8,  9,
1824a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    12, 10, 11,
1825a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    14, 12, 13,
1826a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    16, 14, 15,
1827a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    18, 16, 17,
1828a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    20, 18, 19,
1829a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    22, 20, 21,
1830a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton     8, 22, 23,
1831a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    24,  8, 10,
1832a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    12, 24, 10,
1833a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    24, 12, 14,
1834a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    16, 24, 14,
1835a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    24, 16, 18,
1836a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    20, 24, 18,
1837a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    24, 20, 22,
1838a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton     8, 24, 22,
1839a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1840a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // Same octagons, but with the inner and outer disjoint. Used by coverage AA.
1841a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton     8, 22, 23,
1842a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton     9,  8, 23,
1843a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    10,  8,  9,
1844a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    11, 10,  9,
1845a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    12, 10, 11,
1846a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    13, 12, 11,
1847a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    14, 12, 13,
1848a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    15, 14, 13,
1849a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    16, 14, 15,
1850a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    17, 16, 15,
1851a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    18, 16, 17,
1852a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    19, 18, 17,
1853a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    20, 18, 19,
1854a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    21, 20, 19,
1855a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    22, 20, 21,
1856a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    23, 22, 21,
1857a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    22,  8, 10,
1858a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    10, 12, 14,
1859a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    14, 16, 18,
1860a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    18, 20, 22,
1861a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    22, 10, 14,
1862a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    14, 18, 22,
1863a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1864a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // Rectangle with disjoint corner segments.
1865a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    27, 25, 26,
1866a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    30, 28, 29,
1867a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    33, 31, 32,
1868a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    36, 34, 35,
1869a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    25, 27, 28,
1870a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    28, 30, 31,
1871a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    31, 33, 34,
1872a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    34, 36, 25,
1873a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    25, 28, 31,
1874a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    31, 34, 25,
1875a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1876a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // Same rectangle with disjoint corners, but with the interior arranged as a fan. Used by
1877a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // mixed samples.
1878a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    27, 25, 26,
1879a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    30, 28, 29,
1880a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    33, 31, 32,
1881a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    36, 34, 35,
1882a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    27, 37, 25,
1883a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    28, 37, 27,
1884a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    30, 38, 28,
1885a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    31, 38, 30,
1886a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    33, 39, 31,
1887a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    34, 39, 33,
1888a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    36, 40, 34,
1889a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    25, 40, 36,
1890a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1891a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // Same rectangle with disjoint corners, with a border as well. Used by coverage AA.
1892a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    41, 25, 26,
1893a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    42, 41, 26,
1894a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    27, 42, 26,
1895a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    43, 28, 29,
1896a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    44, 43, 29,
1897a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    30, 44, 29,
1898a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    45, 31, 32,
1899a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    46, 45, 32,
1900a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    33, 46, 32,
1901a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    47, 34, 35,
1902a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    48, 47, 35,
1903a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    36, 48, 35,
1904a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    27, 28, 42,
1905a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    42, 28, 43,
1906a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    30, 31, 44,
1907a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    44, 31, 45,
1908a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    33, 34, 46,
1909a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    46, 34, 47,
1910a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    36, 25, 48,
1911a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    48, 25, 41,
1912a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    41, 42, 43,
1913a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    43, 44, 45,
1914a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    45, 46, 47,
1915a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    47, 48, 41,
1916a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    41, 43, 45,
1917a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    45, 47, 41,
1918a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1919a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // Same as the disjoint octagons, but with 16-gons instead. Used by coverage AA when the oval is
1920a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    // sufficiently large.
1921a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    49, 79, 80,
1922a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    50, 49, 80,
1923a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    51, 49, 50,
1924a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    52, 51, 50,
1925a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    53, 51, 52,
1926a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    54, 53, 52,
1927a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    55, 53, 54,
1928a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    56, 55, 54,
1929a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    57, 55, 56,
1930a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    58, 57, 56,
1931a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    59, 57, 58,
1932a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    60, 59, 58,
1933a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    61, 59, 60,
1934a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    62, 61, 60,
1935a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    63, 61, 62,
1936a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    64, 63, 62,
1937a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    65, 63, 64,
1938a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    66, 65, 64,
1939a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    67, 65, 66,
1940a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    68, 67, 66,
1941a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    69, 67, 68,
1942a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    70, 69, 68,
1943a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    71, 69, 70,
1944a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    72, 71, 70,
1945a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    73, 71, 72,
1946a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    74, 73, 72,
1947a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    75, 73, 74,
1948a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    76, 75, 74,
1949a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    77, 75, 76,
1950a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    78, 77, 76,
1951a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    79, 77, 78,
1952a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    80, 79, 78,
1953a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    49, 51, 53,
1954a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    53, 55, 57,
1955a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    57, 59, 61,
1956a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    61, 63, 65,
1957a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    65, 67, 69,
1958a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    69, 71, 73,
1959a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    73, 75, 77,
1960a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    77, 79, 49,
1961a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    49, 53, 57,
1962a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    57, 61, 65,
1963a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    65, 69, 73,
1964a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    73, 77, 49,
1965a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    49, 57, 65,
1966a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    65, 73, 49,
1967a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton};
1968a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1969a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonenum {
1970a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    kRect_FirstIndex = 0,
1971a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    kRect_TriCount = 2,
1972a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1973a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    kFramedRect_FirstIndex = 6,
1974a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    kFramedRect_TriCount = 10,
1975a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1976a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    kOctagons_FirstIndex = 36,
1977a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    kOctagons_TriCount = 14,
1978a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1979a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    kOctagonsFanned_FirstIndex = 78,
1980a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    kOctagonsFanned_TriCount = 16,
1981a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1982a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    kDisjointOctagons_FirstIndex = 126,
1983a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    kDisjointOctagons_TriCount = 22,
1984a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1985a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    kCorneredRect_FirstIndex = 192,
1986a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    kCorneredRect_TriCount = 10,
1987a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1988a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    kCorneredRectFanned_FirstIndex = 222,
1989a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    kCorneredRectFanned_TriCount = 12,
1990a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1991a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    kCorneredFramedRect_FirstIndex = 258,
1992a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    kCorneredFramedRect_TriCount = 26,
1993a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1994a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    kDisjoint16Gons_FirstIndex = 336,
1995a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    kDisjoint16Gons_TriCount = 46,
1996a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton};
1997a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
1998a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonGR_DECLARE_STATIC_UNIQUE_KEY(gShapeVertexBufferKey);
1999a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
2000a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonconst GrBuffer* InstanceProcessor::FindOrCreateVertexBuffer(GrGpu* gpu) {
2001a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GR_DEFINE_STATIC_UNIQUE_KEY(gShapeVertexBufferKey);
2002a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GrResourceCache* cache = gpu->getContext()->getResourceCache();
2003a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (GrGpuResource* cached = cache->findAndRefUniqueResource(gShapeVertexBufferKey)) {
2004a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        return static_cast<GrBuffer*>(cached);
2005a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
2006a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (GrBuffer* buffer = gpu->createBuffer(sizeof(kVertexData), kVertex_GrBufferType,
2007a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                             kStatic_GrAccessPattern, kVertexData)) {
2008a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        buffer->resourcePriv().setUniqueKey(gShapeVertexBufferKey);
2009a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        return buffer;
2010a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
2011a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    return nullptr;
2012a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
2013a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
2014a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonGR_DECLARE_STATIC_UNIQUE_KEY(gShapeIndexBufferKey);
2015a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
2016a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonconst GrBuffer* InstanceProcessor::FindOrCreateIndex8Buffer(GrGpu* gpu) {
2017a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GR_DEFINE_STATIC_UNIQUE_KEY(gShapeIndexBufferKey);
2018a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    GrResourceCache* cache = gpu->getContext()->getResourceCache();
2019a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (GrGpuResource* cached = cache->findAndRefUniqueResource(gShapeIndexBufferKey)) {
2020a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        return static_cast<GrBuffer*>(cached);
2021a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
2022a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    if (GrBuffer* buffer = gpu->createBuffer(sizeof(kIndexData), kIndex_GrBufferType,
2023a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton                                             kStatic_GrAccessPattern, kIndexData)) {
2024a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        buffer->resourcePriv().setUniqueKey(gShapeIndexBufferKey);
2025a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        return buffer;
2026a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
2027a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    return nullptr;
2028a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
2029a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
2030af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian SalomonIndexRange InstanceProcessor::GetIndexRangeForRect(GrAAType aaType) {
2031af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon    switch (aaType) {
2032af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon        case GrAAType::kCoverage:
2033af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon            return {kFramedRect_FirstIndex, 3 * kFramedRect_TriCount};
2034af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon        case GrAAType::kNone:
2035af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon        case GrAAType::kMSAA:
2036af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon        case GrAAType::kMixedSamples:
2037af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon            return {kRect_FirstIndex, 3 * kRect_TriCount};
2038af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon    }
2039af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon    SkFAIL("Unexpected aa type!");
2040af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon    return {0, 0};
2041a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
2042a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
2043af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian SalomonIndexRange InstanceProcessor::GetIndexRangeForOval(GrAAType aaType, const SkRect& devBounds) {
2044af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon    if (GrAAType::kCoverage == aaType && devBounds.height() * devBounds.width() >= 256 * 256) {
2045a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        // This threshold was chosen quasi-scientifically on Tegra X1.
2046a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        return {kDisjoint16Gons_FirstIndex, 3 * kDisjoint16Gons_TriCount};
2047a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
2048a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
2049af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon    switch (aaType) {
2050af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon        case GrAAType::kNone:
2051af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon        case GrAAType::kMSAA:
2052af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon            return {kOctagons_FirstIndex, 3 * kOctagons_TriCount};
2053af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon        case GrAAType::kCoverage:
2054af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon            return {kDisjointOctagons_FirstIndex, 3 * kDisjointOctagons_TriCount};
2055af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon        case GrAAType::kMixedSamples:
2056af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon            return {kOctagonsFanned_FirstIndex, 3 * kOctagonsFanned_TriCount};
2057af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon    }
2058af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon    SkFAIL("Unexpected aa type!");
2059af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon    return {0, 0};
2060a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
2061a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
2062af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian SalomonIndexRange InstanceProcessor::GetIndexRangeForRRect(GrAAType aaType) {
2063af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon    switch (aaType) {
2064af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon        case GrAAType::kNone:
2065af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon        case GrAAType::kMSAA:
2066af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon            return {kCorneredRect_FirstIndex, 3 * kCorneredRect_TriCount};
2067af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon        case GrAAType::kCoverage:
2068af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon            return {kCorneredFramedRect_FirstIndex, 3 * kCorneredFramedRect_TriCount};
2069af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon        case GrAAType::kMixedSamples:
2070af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon            return {kCorneredRectFanned_FirstIndex, 3 * kCorneredRectFanned_TriCount};
2071af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon    }
2072af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon    SkFAIL("Unexpected aa type!");
2073af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon    return {0, 0};
2074a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
2075a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
2076a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonconst char* InstanceProcessor::GetNameOfIndexRange(IndexRange range) {
2077a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    switch (range.fStart) {
2078a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        case kRect_FirstIndex: return "basic_rect";
2079a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        case kFramedRect_FirstIndex: return "coverage_rect";
2080a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
2081a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        case kOctagons_FirstIndex: return "basic_oval";
2082a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        case kDisjointOctagons_FirstIndex: return "coverage_oval";
2083a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        case kDisjoint16Gons_FirstIndex: return "coverage_large_oval";
2084a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        case kOctagonsFanned_FirstIndex: return "mixed_samples_oval";
2085a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
2086a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        case kCorneredRect_FirstIndex: return "basic_round_rect";
2087a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        case kCorneredFramedRect_FirstIndex: return "coverage_round_rect";
2088a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        case kCorneredRectFanned_FirstIndex: return "mixed_samples_round_rect";
2089a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
2090a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton        default: return "unknown";
2091a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
2092a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
2093a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton
2094a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}
2095