16536ae590e3873694cb02cf25dab8001a71f269eethannicholas/*
26536ae590e3873694cb02cf25dab8001a71f269eethannicholas * Copyright 2016 Google Inc.
36536ae590e3873694cb02cf25dab8001a71f269eethannicholas *
46536ae590e3873694cb02cf25dab8001a71f269eethannicholas * Use of this source code is governed by a BSD-style license that can be
56536ae590e3873694cb02cf25dab8001a71f269eethannicholas * found in the LICENSE file.
66536ae590e3873694cb02cf25dab8001a71f269eethannicholas */
76536ae590e3873694cb02cf25dab8001a71f269eethannicholas
86536ae590e3873694cb02cf25dab8001a71f269eethannicholas#include "GrMSAAPathRenderer.h"
96536ae590e3873694cb02cf25dab8001a71f269eethannicholas
10976f5f0dc5e907d1ca50685fad117bd15d7fc87brobertphillips#include "GrAuditTrail.h"
11976f5f0dc5e907d1ca50685fad117bd15d7fc87brobertphillips#include "GrClip.h"
126536ae590e3873694cb02cf25dab8001a71f269eethannicholas#include "GrDefaultGeoProcFactory.h"
1302fa32c6d1ef4b7b05aa06df8be4add42a1712d3csmartdalton#include "GrFixedClip.h"
14dad2923b8ec9270d810c1e8e76da8e6768d8f9ddBrian Salomon#include "GrMesh.h"
15742e31de1599f3902810aecdf2e2e3eed3b40a09Brian Salomon#include "GrOpFlushState.h"
166536ae590e3873694cb02cf25dab8001a71f269eethannicholas#include "GrPathStencilSettings.h"
176536ae590e3873694cb02cf25dab8001a71f269eethannicholas#include "GrPathUtils.h"
18bb24383abb724c516e472af4eec68f2c3f17a6d0bsalomon#include "GrPipelineBuilder.h"
1995e3c058ef633782f7549e9e1c2727d60dbc8ee5Hal Canary#include "SkAutoMalloc.h"
206536ae590e3873694cb02cf25dab8001a71f269eethannicholas#include "SkGeometry.h"
216536ae590e3873694cb02cf25dab8001a71f269eethannicholas#include "SkTraceEvent.h"
22dad2923b8ec9270d810c1e8e76da8e6768d8f9ddBrian Salomon#include "gl/GrGLVaryingHandler.h"
236536ae590e3873694cb02cf25dab8001a71f269eethannicholas#include "glsl/GrGLSLFragmentShaderBuilder.h"
24dad2923b8ec9270d810c1e8e76da8e6768d8f9ddBrian Salomon#include "glsl/GrGLSLGeometryProcessor.h"
256536ae590e3873694cb02cf25dab8001a71f269eethannicholas#include "glsl/GrGLSLProgramDataManager.h"
266536ae590e3873694cb02cf25dab8001a71f269eethannicholas#include "glsl/GrGLSLUtil.h"
27dad2923b8ec9270d810c1e8e76da8e6768d8f9ddBrian Salomon#include "glsl/GrGLSLVertexShaderBuilder.h"
28895274391db8df7357334aec260edca2e1735626Brian Salomon#include "ops/GrMeshDrawOp.h"
29895274391db8df7357334aec260edca2e1735626Brian Salomon#include "ops/GrRectOpFactory.h"
306536ae590e3873694cb02cf25dab8001a71f269eethannicholas
316536ae590e3873694cb02cf25dab8001a71f269eethannicholasstatic const float kTolerance = 0.5f;
326536ae590e3873694cb02cf25dab8001a71f269eethannicholas
336536ae590e3873694cb02cf25dab8001a71f269eethannicholas////////////////////////////////////////////////////////////////////////////////
346536ae590e3873694cb02cf25dab8001a71f269eethannicholas// Helpers for drawPath
356536ae590e3873694cb02cf25dab8001a71f269eethannicholas
368acedde5970ce70de6d9791ffeda87a65af4ed07bsalomonstatic inline bool single_pass_shape(const GrShape& shape) {
378acedde5970ce70de6d9791ffeda87a65af4ed07bsalomon    if (!shape.inverseFilled()) {
388acedde5970ce70de6d9791ffeda87a65af4ed07bsalomon        return shape.knownToBeConvex();
396536ae590e3873694cb02cf25dab8001a71f269eethannicholas    }
406536ae590e3873694cb02cf25dab8001a71f269eethannicholas    return false;
416536ae590e3873694cb02cf25dab8001a71f269eethannicholas}
426536ae590e3873694cb02cf25dab8001a71f269eethannicholas
438acedde5970ce70de6d9791ffeda87a65af4ed07bsalomonGrPathRenderer::StencilSupport GrMSAAPathRenderer::onGetStencilSupport(const GrShape& shape) const {
448acedde5970ce70de6d9791ffeda87a65af4ed07bsalomon    if (single_pass_shape(shape)) {
456536ae590e3873694cb02cf25dab8001a71f269eethannicholas        return GrPathRenderer::kNoRestriction_StencilSupport;
466536ae590e3873694cb02cf25dab8001a71f269eethannicholas    } else {
476536ae590e3873694cb02cf25dab8001a71f269eethannicholas        return GrPathRenderer::kStencilOnly_StencilSupport;
486536ae590e3873694cb02cf25dab8001a71f269eethannicholas    }
496536ae590e3873694cb02cf25dab8001a71f269eethannicholas}
506536ae590e3873694cb02cf25dab8001a71f269eethannicholas
516536ae590e3873694cb02cf25dab8001a71f269eethannicholasstruct MSAALineVertices {
526536ae590e3873694cb02cf25dab8001a71f269eethannicholas    struct Vertex {
536536ae590e3873694cb02cf25dab8001a71f269eethannicholas        SkPoint fPosition;
546536ae590e3873694cb02cf25dab8001a71f269eethannicholas        SkColor fColor;
556536ae590e3873694cb02cf25dab8001a71f269eethannicholas    };
566536ae590e3873694cb02cf25dab8001a71f269eethannicholas    Vertex* vertices;
576536ae590e3873694cb02cf25dab8001a71f269eethannicholas    Vertex* nextVertex;
586536ae590e3873694cb02cf25dab8001a71f269eethannicholas#ifdef SK_DEBUG
596536ae590e3873694cb02cf25dab8001a71f269eethannicholas    Vertex* verticesEnd;
606536ae590e3873694cb02cf25dab8001a71f269eethannicholas#endif
616536ae590e3873694cb02cf25dab8001a71f269eethannicholas    uint16_t* indices;
626536ae590e3873694cb02cf25dab8001a71f269eethannicholas    uint16_t* nextIndex;
636536ae590e3873694cb02cf25dab8001a71f269eethannicholas};
646536ae590e3873694cb02cf25dab8001a71f269eethannicholas
656536ae590e3873694cb02cf25dab8001a71f269eethannicholasstruct MSAAQuadVertices {
666536ae590e3873694cb02cf25dab8001a71f269eethannicholas    struct Vertex {
676536ae590e3873694cb02cf25dab8001a71f269eethannicholas        SkPoint fPosition;
686536ae590e3873694cb02cf25dab8001a71f269eethannicholas        SkPoint fUV;
696536ae590e3873694cb02cf25dab8001a71f269eethannicholas        SkColor fColor;
706536ae590e3873694cb02cf25dab8001a71f269eethannicholas    };
716536ae590e3873694cb02cf25dab8001a71f269eethannicholas    Vertex* vertices;
726536ae590e3873694cb02cf25dab8001a71f269eethannicholas    Vertex* nextVertex;
736536ae590e3873694cb02cf25dab8001a71f269eethannicholas#ifdef SK_DEBUG
746536ae590e3873694cb02cf25dab8001a71f269eethannicholas    Vertex* verticesEnd;
756536ae590e3873694cb02cf25dab8001a71f269eethannicholas#endif
766536ae590e3873694cb02cf25dab8001a71f269eethannicholas    uint16_t* indices;
776536ae590e3873694cb02cf25dab8001a71f269eethannicholas    uint16_t* nextIndex;
786536ae590e3873694cb02cf25dab8001a71f269eethannicholas};
796536ae590e3873694cb02cf25dab8001a71f269eethannicholas
806536ae590e3873694cb02cf25dab8001a71f269eethannicholasstatic inline void append_contour_edge_indices(uint16_t fanCenterIdx,
816536ae590e3873694cb02cf25dab8001a71f269eethannicholas                                               uint16_t edgeV0Idx,
826536ae590e3873694cb02cf25dab8001a71f269eethannicholas                                               MSAALineVertices& lines) {
836536ae590e3873694cb02cf25dab8001a71f269eethannicholas    *(lines.nextIndex++) = fanCenterIdx;
846536ae590e3873694cb02cf25dab8001a71f269eethannicholas    *(lines.nextIndex++) = edgeV0Idx;
856536ae590e3873694cb02cf25dab8001a71f269eethannicholas    *(lines.nextIndex++) = edgeV0Idx + 1;
866536ae590e3873694cb02cf25dab8001a71f269eethannicholas}
876536ae590e3873694cb02cf25dab8001a71f269eethannicholas
8806ca8ec87cf6fab57cadd043a5ac18c4154a4129bungemanstatic inline void add_quad(MSAALineVertices& lines, MSAAQuadVertices& quads, const SkPoint pts[],
896536ae590e3873694cb02cf25dab8001a71f269eethannicholas                            SkColor color, bool indexed, uint16_t subpathLineIdxStart) {
906536ae590e3873694cb02cf25dab8001a71f269eethannicholas    SkASSERT(lines.nextVertex < lines.verticesEnd);
916536ae590e3873694cb02cf25dab8001a71f269eethannicholas    *lines.nextVertex = { pts[2], color };
926536ae590e3873694cb02cf25dab8001a71f269eethannicholas    if (indexed) {
936536ae590e3873694cb02cf25dab8001a71f269eethannicholas        int prevIdx = (uint16_t) (lines.nextVertex - lines.vertices - 1);
946536ae590e3873694cb02cf25dab8001a71f269eethannicholas        if (prevIdx > subpathLineIdxStart) {
956536ae590e3873694cb02cf25dab8001a71f269eethannicholas            append_contour_edge_indices(subpathLineIdxStart, prevIdx, lines);
966536ae590e3873694cb02cf25dab8001a71f269eethannicholas        }
976536ae590e3873694cb02cf25dab8001a71f269eethannicholas    }
986536ae590e3873694cb02cf25dab8001a71f269eethannicholas    lines.nextVertex++;
996536ae590e3873694cb02cf25dab8001a71f269eethannicholas
1006536ae590e3873694cb02cf25dab8001a71f269eethannicholas    SkASSERT(quads.nextVertex + 2 < quads.verticesEnd);
1016536ae590e3873694cb02cf25dab8001a71f269eethannicholas    // the texture coordinates are drawn from the Loop-Blinn rendering algorithm
1026536ae590e3873694cb02cf25dab8001a71f269eethannicholas    *(quads.nextVertex++) = { pts[0], SkPoint::Make(0.0, 0.0), color };
1036536ae590e3873694cb02cf25dab8001a71f269eethannicholas    *(quads.nextVertex++) = { pts[1], SkPoint::Make(0.5, 0.0), color };
1046536ae590e3873694cb02cf25dab8001a71f269eethannicholas    *(quads.nextVertex++) = { pts[2], SkPoint::Make(1.0, 1.0), color };
1056536ae590e3873694cb02cf25dab8001a71f269eethannicholas    if (indexed) {
1066536ae590e3873694cb02cf25dab8001a71f269eethannicholas        uint16_t offset = (uint16_t) (quads.nextVertex - quads.vertices) - 3;
1076536ae590e3873694cb02cf25dab8001a71f269eethannicholas        *(quads.nextIndex++) = offset++;
1086536ae590e3873694cb02cf25dab8001a71f269eethannicholas        *(quads.nextIndex++) = offset++;
1096536ae590e3873694cb02cf25dab8001a71f269eethannicholas        *(quads.nextIndex++) = offset++;
1106536ae590e3873694cb02cf25dab8001a71f269eethannicholas    }
1116536ae590e3873694cb02cf25dab8001a71f269eethannicholas}
1126536ae590e3873694cb02cf25dab8001a71f269eethannicholas
1136536ae590e3873694cb02cf25dab8001a71f269eethannicholasclass MSAAQuadProcessor : public GrGeometryProcessor {
1146536ae590e3873694cb02cf25dab8001a71f269eethannicholaspublic:
1156536ae590e3873694cb02cf25dab8001a71f269eethannicholas    static GrGeometryProcessor* Create(const SkMatrix& viewMatrix) {
1166536ae590e3873694cb02cf25dab8001a71f269eethannicholas        return new MSAAQuadProcessor(viewMatrix);
1176536ae590e3873694cb02cf25dab8001a71f269eethannicholas    }
1186536ae590e3873694cb02cf25dab8001a71f269eethannicholas
119d3b65972aad96453ff4510caa3e25a2b847c6d1eBrian Salomon    ~MSAAQuadProcessor() override {}
1206536ae590e3873694cb02cf25dab8001a71f269eethannicholas
1216536ae590e3873694cb02cf25dab8001a71f269eethannicholas    const char* name() const override { return "MSAAQuadProcessor"; }
1226536ae590e3873694cb02cf25dab8001a71f269eethannicholas
1236536ae590e3873694cb02cf25dab8001a71f269eethannicholas    const Attribute* inPosition() const { return fInPosition; }
1246536ae590e3873694cb02cf25dab8001a71f269eethannicholas    const Attribute* inUV() const { return fInUV; }
1256536ae590e3873694cb02cf25dab8001a71f269eethannicholas    const Attribute* inColor() const { return fInColor; }
1266536ae590e3873694cb02cf25dab8001a71f269eethannicholas    const SkMatrix& viewMatrix() const { return fViewMatrix; }
1276536ae590e3873694cb02cf25dab8001a71f269eethannicholas
1286536ae590e3873694cb02cf25dab8001a71f269eethannicholas    class GLSLProcessor : public GrGLSLGeometryProcessor {
1296536ae590e3873694cb02cf25dab8001a71f269eethannicholas    public:
1306536ae590e3873694cb02cf25dab8001a71f269eethannicholas        GLSLProcessor(const GrGeometryProcessor& qpr) {}
1316536ae590e3873694cb02cf25dab8001a71f269eethannicholas
1326536ae590e3873694cb02cf25dab8001a71f269eethannicholas        void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override {
1336536ae590e3873694cb02cf25dab8001a71f269eethannicholas            const MSAAQuadProcessor& qp = args.fGP.cast<MSAAQuadProcessor>();
1346536ae590e3873694cb02cf25dab8001a71f269eethannicholas            GrGLSLVertexBuilder* vsBuilder = args.fVertBuilder;
1356536ae590e3873694cb02cf25dab8001a71f269eethannicholas            GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
1366536ae590e3873694cb02cf25dab8001a71f269eethannicholas            GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
1376536ae590e3873694cb02cf25dab8001a71f269eethannicholas
1386536ae590e3873694cb02cf25dab8001a71f269eethannicholas            // emit attributes
1396536ae590e3873694cb02cf25dab8001a71f269eethannicholas            varyingHandler->emitAttributes(qp);
1406536ae590e3873694cb02cf25dab8001a71f269eethannicholas            varyingHandler->addPassThroughAttribute(qp.inColor(), args.fOutputColor);
1416536ae590e3873694cb02cf25dab8001a71f269eethannicholas
1426536ae590e3873694cb02cf25dab8001a71f269eethannicholas            GrGLSLVertToFrag uv(kVec2f_GrSLType);
1436536ae590e3873694cb02cf25dab8001a71f269eethannicholas            varyingHandler->addVarying("uv", &uv, kHigh_GrSLPrecision);
1446536ae590e3873694cb02cf25dab8001a71f269eethannicholas            vsBuilder->codeAppendf("%s = %s;", uv.vsOut(), qp.inUV()->fName);
1456536ae590e3873694cb02cf25dab8001a71f269eethannicholas
1466536ae590e3873694cb02cf25dab8001a71f269eethannicholas            // Setup position
14706ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman            this->setupPosition(vsBuilder, uniformHandler, gpArgs, qp.inPosition()->fName,
1486536ae590e3873694cb02cf25dab8001a71f269eethannicholas                                qp.viewMatrix(), &fViewMatrixUniform);
1496536ae590e3873694cb02cf25dab8001a71f269eethannicholas
1506536ae590e3873694cb02cf25dab8001a71f269eethannicholas            // emit transforms
15106ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman            this->emitTransforms(vsBuilder, varyingHandler, uniformHandler, gpArgs->fPositionVar,
152a624bf3d1cb454c1959c5bbbf23a3afdfa3481f3bsalomon                                 qp.inPosition()->fName, SkMatrix::I(),
153a624bf3d1cb454c1959c5bbbf23a3afdfa3481f3bsalomon                                 args.fFPCoordTransformHandler);
1546536ae590e3873694cb02cf25dab8001a71f269eethannicholas
1556536ae590e3873694cb02cf25dab8001a71f269eethannicholas            GrGLSLPPFragmentBuilder* fsBuilder = args.fFragBuilder;
15606ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman            fsBuilder->codeAppendf("if (%s.x * %s.x >= %s.y) discard;", uv.fsIn(), uv.fsIn(),
1576536ae590e3873694cb02cf25dab8001a71f269eethannicholas                                                                        uv.fsIn());
1586536ae590e3873694cb02cf25dab8001a71f269eethannicholas            fsBuilder->codeAppendf("%s = vec4(1.0);", args.fOutputCoverage);
1596536ae590e3873694cb02cf25dab8001a71f269eethannicholas        }
1606536ae590e3873694cb02cf25dab8001a71f269eethannicholas
1616536ae590e3873694cb02cf25dab8001a71f269eethannicholas        static inline void GenKey(const GrGeometryProcessor& gp,
16294efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon                                  const GrShaderCaps&,
1636536ae590e3873694cb02cf25dab8001a71f269eethannicholas                                  GrProcessorKeyBuilder* b) {
1646536ae590e3873694cb02cf25dab8001a71f269eethannicholas            const MSAAQuadProcessor& qp = gp.cast<MSAAQuadProcessor>();
1656536ae590e3873694cb02cf25dab8001a71f269eethannicholas            uint32_t key = 0;
1666536ae590e3873694cb02cf25dab8001a71f269eethannicholas            key |= qp.viewMatrix().hasPerspective() ? 0x1 : 0x0;
1676536ae590e3873694cb02cf25dab8001a71f269eethannicholas            key |= qp.viewMatrix().isIdentity() ? 0x2: 0x0;
1686536ae590e3873694cb02cf25dab8001a71f269eethannicholas            b->add32(key);
1696536ae590e3873694cb02cf25dab8001a71f269eethannicholas        }
1706536ae590e3873694cb02cf25dab8001a71f269eethannicholas
171a624bf3d1cb454c1959c5bbbf23a3afdfa3481f3bsalomon        void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& gp,
172a624bf3d1cb454c1959c5bbbf23a3afdfa3481f3bsalomon                     FPCoordTransformIter&& transformIter) override {
1736536ae590e3873694cb02cf25dab8001a71f269eethannicholas            const MSAAQuadProcessor& qp = gp.cast<MSAAQuadProcessor>();
1746536ae590e3873694cb02cf25dab8001a71f269eethannicholas            if (!qp.viewMatrix().isIdentity()) {
1756536ae590e3873694cb02cf25dab8001a71f269eethannicholas                float viewMatrix[3 * 3];
1766536ae590e3873694cb02cf25dab8001a71f269eethannicholas                GrGLSLGetMatrix<3>(viewMatrix, qp.viewMatrix());
1776536ae590e3873694cb02cf25dab8001a71f269eethannicholas                pdman.setMatrix3f(fViewMatrixUniform, viewMatrix);
1786536ae590e3873694cb02cf25dab8001a71f269eethannicholas            }
179a624bf3d1cb454c1959c5bbbf23a3afdfa3481f3bsalomon            this->setTransformDataHelper(SkMatrix::I(), pdman, &transformIter);
1806536ae590e3873694cb02cf25dab8001a71f269eethannicholas        }
1816536ae590e3873694cb02cf25dab8001a71f269eethannicholas
1826536ae590e3873694cb02cf25dab8001a71f269eethannicholas    private:
1836536ae590e3873694cb02cf25dab8001a71f269eethannicholas        typedef GrGLSLGeometryProcessor INHERITED;
1846536ae590e3873694cb02cf25dab8001a71f269eethannicholas
1856536ae590e3873694cb02cf25dab8001a71f269eethannicholas        UniformHandle fViewMatrixUniform;
1866536ae590e3873694cb02cf25dab8001a71f269eethannicholas    };
1876536ae590e3873694cb02cf25dab8001a71f269eethannicholas
18894efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon    virtual void getGLSLProcessorKey(const GrShaderCaps& caps,
1896536ae590e3873694cb02cf25dab8001a71f269eethannicholas                                   GrProcessorKeyBuilder* b) const override {
1906536ae590e3873694cb02cf25dab8001a71f269eethannicholas        GLSLProcessor::GenKey(*this, caps, b);
1916536ae590e3873694cb02cf25dab8001a71f269eethannicholas    }
1926536ae590e3873694cb02cf25dab8001a71f269eethannicholas
19394efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon    virtual GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const override {
1946536ae590e3873694cb02cf25dab8001a71f269eethannicholas        return new GLSLProcessor(*this);
1956536ae590e3873694cb02cf25dab8001a71f269eethannicholas    }
1966536ae590e3873694cb02cf25dab8001a71f269eethannicholas
1976536ae590e3873694cb02cf25dab8001a71f269eethannicholasprivate:
1986536ae590e3873694cb02cf25dab8001a71f269eethannicholas    MSAAQuadProcessor(const SkMatrix& viewMatrix)
1996536ae590e3873694cb02cf25dab8001a71f269eethannicholas        : fViewMatrix(viewMatrix) {
2006536ae590e3873694cb02cf25dab8001a71f269eethannicholas        this->initClassID<MSAAQuadProcessor>();
2016cb807bf99ac0f8f166e1790f91bcb3afbfb5458bsalomon        fInPosition = &this->addVertexAttrib("inPosition", kVec2f_GrVertexAttribType,
2026cb807bf99ac0f8f166e1790f91bcb3afbfb5458bsalomon                                             kHigh_GrSLPrecision);
2036cb807bf99ac0f8f166e1790f91bcb3afbfb5458bsalomon        fInUV = &this->addVertexAttrib("inUV", kVec2f_GrVertexAttribType, kHigh_GrSLPrecision);
2046cb807bf99ac0f8f166e1790f91bcb3afbfb5458bsalomon        fInColor = &this->addVertexAttrib("inColor", kVec4ub_GrVertexAttribType);
2056536ae590e3873694cb02cf25dab8001a71f269eethannicholas        this->setSampleShading(1.0f);
2066536ae590e3873694cb02cf25dab8001a71f269eethannicholas    }
2076536ae590e3873694cb02cf25dab8001a71f269eethannicholas
2086536ae590e3873694cb02cf25dab8001a71f269eethannicholas    const Attribute* fInPosition;
2096536ae590e3873694cb02cf25dab8001a71f269eethannicholas    const Attribute* fInUV;
2106536ae590e3873694cb02cf25dab8001a71f269eethannicholas    const Attribute* fInColor;
2116536ae590e3873694cb02cf25dab8001a71f269eethannicholas    SkMatrix         fViewMatrix;
21206ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman
2136536ae590e3873694cb02cf25dab8001a71f269eethannicholas    GR_DECLARE_GEOMETRY_PROCESSOR_TEST;
2146536ae590e3873694cb02cf25dab8001a71f269eethannicholas
2156536ae590e3873694cb02cf25dab8001a71f269eethannicholas    typedef GrGeometryProcessor INHERITED;
2166536ae590e3873694cb02cf25dab8001a71f269eethannicholas};
2176536ae590e3873694cb02cf25dab8001a71f269eethannicholas
218780dad1ab9469828e3ef317ad9aea12f9c0a270aBrian Salomonclass MSAAPathOp final : public GrMeshDrawOp {
2196536ae590e3873694cb02cf25dab8001a71f269eethannicholaspublic:
22025a880960a9a689a745a01071ecba3fe494b5940Brian Salomon    DEFINE_OP_CLASS_ID
221649a3411f99a8aea3c46e4ef1f495f61b9801164Brian Salomon    static std::unique_ptr<GrMeshDrawOp> Make(GrColor color, const SkPath& path,
222649a3411f99a8aea3c46e4ef1f495f61b9801164Brian Salomon                                              const SkMatrix& viewMatrix, const SkRect& devBounds) {
22350c56a39db30a4eb6b80e75db90ce9c1efe36b4fbsalomon        int contourCount;
224780dad1ab9469828e3ef317ad9aea12f9c0a270aBrian Salomon        int maxLineVertices;
225780dad1ab9469828e3ef317ad9aea12f9c0a270aBrian Salomon        int maxQuadVertices;
226780dad1ab9469828e3ef317ad9aea12f9c0a270aBrian Salomon        ComputeWorstCasePointCount(path, &contourCount, &maxLineVertices, &maxQuadVertices);
227780dad1ab9469828e3ef317ad9aea12f9c0a270aBrian Salomon        bool isIndexed = contourCount > 1;
228780dad1ab9469828e3ef317ad9aea12f9c0a270aBrian Salomon        if (isIndexed &&
229780dad1ab9469828e3ef317ad9aea12f9c0a270aBrian Salomon            (maxLineVertices > kMaxIndexedVertexCnt || maxQuadVertices > kMaxIndexedVertexCnt)) {
230780dad1ab9469828e3ef317ad9aea12f9c0a270aBrian Salomon            return nullptr;
231780dad1ab9469828e3ef317ad9aea12f9c0a270aBrian Salomon        }
232780dad1ab9469828e3ef317ad9aea12f9c0a270aBrian Salomon
233649a3411f99a8aea3c46e4ef1f495f61b9801164Brian Salomon        return std::unique_ptr<GrMeshDrawOp>(new MSAAPathOp(
234f8334781914363caf537f22f012fcd5c03c60dadBrian Salomon                color, path, viewMatrix, devBounds, maxLineVertices, maxQuadVertices, isIndexed));
2356536ae590e3873694cb02cf25dab8001a71f269eethannicholas    }
2366536ae590e3873694cb02cf25dab8001a71f269eethannicholas
237780dad1ab9469828e3ef317ad9aea12f9c0a270aBrian Salomon    const char* name() const override { return "MSAAPathOp"; }
2386536ae590e3873694cb02cf25dab8001a71f269eethannicholas
2397c3e7180948766321c51d165737555e78910de51Brian Salomon    SkString dumpInfo() const override {
2407c3e7180948766321c51d165737555e78910de51Brian Salomon        SkString string;
2417c3e7180948766321c51d165737555e78910de51Brian Salomon        string.appendf("Indexed: %d\n", fIsIndexed);
2427c3e7180948766321c51d165737555e78910de51Brian Salomon        for (const auto& path : fPaths) {
2437c3e7180948766321c51d165737555e78910de51Brian Salomon            string.appendf("Color: 0x%08x\n", path.fColor);
2447c3e7180948766321c51d165737555e78910de51Brian Salomon        }
2457c3e7180948766321c51d165737555e78910de51Brian Salomon        string.append(DumpPipelineInfo(*this->pipeline()));
2467c3e7180948766321c51d165737555e78910de51Brian Salomon        string.append(INHERITED::dumpInfo());
2477c3e7180948766321c51d165737555e78910de51Brian Salomon        return string;
2487c3e7180948766321c51d165737555e78910de51Brian Salomon    }
2497c3e7180948766321c51d165737555e78910de51Brian Salomon
250780dad1ab9469828e3ef317ad9aea12f9c0a270aBrian Salomonprivate:
251780dad1ab9469828e3ef317ad9aea12f9c0a270aBrian Salomon    MSAAPathOp(GrColor color, const SkPath& path, const SkMatrix& viewMatrix,
252780dad1ab9469828e3ef317ad9aea12f9c0a270aBrian Salomon               const SkRect& devBounds, int maxLineVertices, int maxQuadVertices, bool isIndexed)
253780dad1ab9469828e3ef317ad9aea12f9c0a270aBrian Salomon            : INHERITED(ClassID())
254780dad1ab9469828e3ef317ad9aea12f9c0a270aBrian Salomon            , fViewMatrix(viewMatrix)
255780dad1ab9469828e3ef317ad9aea12f9c0a270aBrian Salomon            , fMaxLineVertices(maxLineVertices)
256780dad1ab9469828e3ef317ad9aea12f9c0a270aBrian Salomon            , fMaxQuadVertices(maxQuadVertices)
257780dad1ab9469828e3ef317ad9aea12f9c0a270aBrian Salomon            , fIsIndexed(isIndexed) {
258780dad1ab9469828e3ef317ad9aea12f9c0a270aBrian Salomon        fPaths.emplace_back(PathInfo{color, path});
259780dad1ab9469828e3ef317ad9aea12f9c0a270aBrian Salomon        this->setBounds(devBounds, HasAABloat::kNo, IsZeroArea::kNo);
2606536ae590e3873694cb02cf25dab8001a71f269eethannicholas    }
2616536ae590e3873694cb02cf25dab8001a71f269eethannicholas
262c0b642ca48d58416409e555549434066f09692b7Brian Salomon    void getFragmentProcessorAnalysisInputs(GrPipelineAnalysisColor* color,
263c0b642ca48d58416409e555549434066f09692b7Brian Salomon                                            GrPipelineAnalysisCoverage* coverage) const override {
264c0b642ca48d58416409e555549434066f09692b7Brian Salomon        color->setToConstant(fPaths[0].fColor);
265c0b642ca48d58416409e555549434066f09692b7Brian Salomon        *coverage = GrPipelineAnalysisCoverage::kNone;
26692aee3d6857386f2b5b8e1148e680a7b58e9b1fcBrian Salomon    }
26792aee3d6857386f2b5b8e1148e680a7b58e9b1fcBrian Salomon
26892aee3d6857386f2b5b8e1148e680a7b58e9b1fcBrian Salomon    void applyPipelineOptimizations(const GrPipelineOptimizations& optimizations) override {
26992aee3d6857386f2b5b8e1148e680a7b58e9b1fcBrian Salomon        optimizations.getOverrideColorIfSet(&fPaths[0].fColor);
2706536ae590e3873694cb02cf25dab8001a71f269eethannicholas    }
2716536ae590e3873694cb02cf25dab8001a71f269eethannicholas
272780dad1ab9469828e3ef317ad9aea12f9c0a270aBrian Salomon    static void ComputeWorstCasePointCount(const SkPath& path, int* subpaths,
273780dad1ab9469828e3ef317ad9aea12f9c0a270aBrian Salomon                                           int* outLinePointCount, int* outQuadPointCount) {
2746536ae590e3873694cb02cf25dab8001a71f269eethannicholas        int linePointCount = 0;
2756536ae590e3873694cb02cf25dab8001a71f269eethannicholas        int quadPointCount = 0;
2766536ae590e3873694cb02cf25dab8001a71f269eethannicholas        *subpaths = 1;
2776536ae590e3873694cb02cf25dab8001a71f269eethannicholas
2786536ae590e3873694cb02cf25dab8001a71f269eethannicholas        bool first = true;
2796536ae590e3873694cb02cf25dab8001a71f269eethannicholas
2808eb43e5f63306a22570b977bbb69e4ec78432d24bsalomon        SkPath::Iter iter(path, true);
2816536ae590e3873694cb02cf25dab8001a71f269eethannicholas        SkPath::Verb verb;
2826536ae590e3873694cb02cf25dab8001a71f269eethannicholas
2836536ae590e3873694cb02cf25dab8001a71f269eethannicholas        SkPoint pts[4];
2846536ae590e3873694cb02cf25dab8001a71f269eethannicholas        while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
2856536ae590e3873694cb02cf25dab8001a71f269eethannicholas            switch (verb) {
2866536ae590e3873694cb02cf25dab8001a71f269eethannicholas                case SkPath::kLine_Verb:
2876536ae590e3873694cb02cf25dab8001a71f269eethannicholas                    linePointCount += 1;
2886536ae590e3873694cb02cf25dab8001a71f269eethannicholas                    break;
2896536ae590e3873694cb02cf25dab8001a71f269eethannicholas                case SkPath::kConic_Verb: {
2906536ae590e3873694cb02cf25dab8001a71f269eethannicholas                    SkScalar weight = iter.conicWeight();
2916536ae590e3873694cb02cf25dab8001a71f269eethannicholas                    SkAutoConicToQuads converter;
2926536ae590e3873694cb02cf25dab8001a71f269eethannicholas                    converter.computeQuads(pts, weight, kTolerance);
2936536ae590e3873694cb02cf25dab8001a71f269eethannicholas                    int quadPts = converter.countQuads();
2946536ae590e3873694cb02cf25dab8001a71f269eethannicholas                    linePointCount += quadPts;
2956536ae590e3873694cb02cf25dab8001a71f269eethannicholas                    quadPointCount += 3 * quadPts;
2966536ae590e3873694cb02cf25dab8001a71f269eethannicholas                }
2976536ae590e3873694cb02cf25dab8001a71f269eethannicholas                case SkPath::kQuad_Verb:
2986536ae590e3873694cb02cf25dab8001a71f269eethannicholas                    linePointCount += 1;
2996536ae590e3873694cb02cf25dab8001a71f269eethannicholas                    quadPointCount += 3;
3006536ae590e3873694cb02cf25dab8001a71f269eethannicholas                    break;
3016536ae590e3873694cb02cf25dab8001a71f269eethannicholas                case SkPath::kCubic_Verb: {
3026536ae590e3873694cb02cf25dab8001a71f269eethannicholas                    SkSTArray<15, SkPoint, true> quadPts;
3036536ae590e3873694cb02cf25dab8001a71f269eethannicholas                    GrPathUtils::convertCubicToQuads(pts, kTolerance, &quadPts);
3046536ae590e3873694cb02cf25dab8001a71f269eethannicholas                    int count = quadPts.count();
3056536ae590e3873694cb02cf25dab8001a71f269eethannicholas                    linePointCount += count / 3;
3066536ae590e3873694cb02cf25dab8001a71f269eethannicholas                    quadPointCount += count;
3076536ae590e3873694cb02cf25dab8001a71f269eethannicholas                    break;
3086536ae590e3873694cb02cf25dab8001a71f269eethannicholas                }
3096536ae590e3873694cb02cf25dab8001a71f269eethannicholas                case SkPath::kMove_Verb:
3106536ae590e3873694cb02cf25dab8001a71f269eethannicholas                    linePointCount += 1;
3116536ae590e3873694cb02cf25dab8001a71f269eethannicholas                    if (!first) {
3126536ae590e3873694cb02cf25dab8001a71f269eethannicholas                        ++(*subpaths);
3136536ae590e3873694cb02cf25dab8001a71f269eethannicholas                    }
3146536ae590e3873694cb02cf25dab8001a71f269eethannicholas                    break;
3156536ae590e3873694cb02cf25dab8001a71f269eethannicholas                default:
3166536ae590e3873694cb02cf25dab8001a71f269eethannicholas                    break;
3176536ae590e3873694cb02cf25dab8001a71f269eethannicholas            }
3186536ae590e3873694cb02cf25dab8001a71f269eethannicholas            first = false;
3196536ae590e3873694cb02cf25dab8001a71f269eethannicholas        }
3206536ae590e3873694cb02cf25dab8001a71f269eethannicholas        *outLinePointCount = linePointCount;
3216536ae590e3873694cb02cf25dab8001a71f269eethannicholas        *outQuadPointCount = quadPointCount;
3226536ae590e3873694cb02cf25dab8001a71f269eethannicholas    }
3236536ae590e3873694cb02cf25dab8001a71f269eethannicholas
3246536ae590e3873694cb02cf25dab8001a71f269eethannicholas    void onPrepareDraws(Target* target) const override {
3256536ae590e3873694cb02cf25dab8001a71f269eethannicholas        if (fMaxLineVertices == 0) {
3266536ae590e3873694cb02cf25dab8001a71f269eethannicholas            SkASSERT(fMaxQuadVertices == 0);
3276536ae590e3873694cb02cf25dab8001a71f269eethannicholas            return;
3286536ae590e3873694cb02cf25dab8001a71f269eethannicholas        }
3296536ae590e3873694cb02cf25dab8001a71f269eethannicholas
33006ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman        GrPrimitiveType primitiveType = fIsIndexed ? kTriangles_GrPrimitiveType
3316536ae590e3873694cb02cf25dab8001a71f269eethannicholas                                                   : kTriangleFan_GrPrimitiveType;
3326536ae590e3873694cb02cf25dab8001a71f269eethannicholas
3336536ae590e3873694cb02cf25dab8001a71f269eethannicholas        // allocate vertex / index buffers
3346536ae590e3873694cb02cf25dab8001a71f269eethannicholas        const GrBuffer* lineVertexBuffer;
3356536ae590e3873694cb02cf25dab8001a71f269eethannicholas        int firstLineVertex;
3366536ae590e3873694cb02cf25dab8001a71f269eethannicholas        MSAALineVertices lines;
3376536ae590e3873694cb02cf25dab8001a71f269eethannicholas        size_t lineVertexStride = sizeof(MSAALineVertices::Vertex);
33806ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman        lines.vertices = (MSAALineVertices::Vertex*) target->makeVertexSpace(lineVertexStride,
3396536ae590e3873694cb02cf25dab8001a71f269eethannicholas                                                                             fMaxLineVertices,
34006ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman                                                                             &lineVertexBuffer,
3416536ae590e3873694cb02cf25dab8001a71f269eethannicholas                                                                             &firstLineVertex);
3426536ae590e3873694cb02cf25dab8001a71f269eethannicholas        if (!lines.vertices) {
3436536ae590e3873694cb02cf25dab8001a71f269eethannicholas            SkDebugf("Could not allocate vertices\n");
3446536ae590e3873694cb02cf25dab8001a71f269eethannicholas            return;
3456536ae590e3873694cb02cf25dab8001a71f269eethannicholas        }
3466536ae590e3873694cb02cf25dab8001a71f269eethannicholas        lines.nextVertex = lines.vertices;
3476536ae590e3873694cb02cf25dab8001a71f269eethannicholas        SkDEBUGCODE(lines.verticesEnd = lines.vertices + fMaxLineVertices;)
3486536ae590e3873694cb02cf25dab8001a71f269eethannicholas
3496536ae590e3873694cb02cf25dab8001a71f269eethannicholas        MSAAQuadVertices quads;
3506536ae590e3873694cb02cf25dab8001a71f269eethannicholas        size_t quadVertexStride = sizeof(MSAAQuadVertices::Vertex);
35195e3c058ef633782f7549e9e1c2727d60dbc8ee5Hal Canary        SkAutoMalloc quadVertexPtr(fMaxQuadVertices * quadVertexStride);
3526536ae590e3873694cb02cf25dab8001a71f269eethannicholas        quads.vertices = (MSAAQuadVertices::Vertex*) quadVertexPtr.get();
3536536ae590e3873694cb02cf25dab8001a71f269eethannicholas        quads.nextVertex = quads.vertices;
3546536ae590e3873694cb02cf25dab8001a71f269eethannicholas        SkDEBUGCODE(quads.verticesEnd = quads.vertices + fMaxQuadVertices;)
3556536ae590e3873694cb02cf25dab8001a71f269eethannicholas
3566536ae590e3873694cb02cf25dab8001a71f269eethannicholas        const GrBuffer* lineIndexBuffer = nullptr;
3576536ae590e3873694cb02cf25dab8001a71f269eethannicholas        int firstLineIndex;
3586536ae590e3873694cb02cf25dab8001a71f269eethannicholas        if (fIsIndexed) {
359780dad1ab9469828e3ef317ad9aea12f9c0a270aBrian Salomon            lines.indices =
360780dad1ab9469828e3ef317ad9aea12f9c0a270aBrian Salomon                    target->makeIndexSpace(3 * fMaxLineVertices, &lineIndexBuffer, &firstLineIndex);
3616536ae590e3873694cb02cf25dab8001a71f269eethannicholas            if (!lines.indices) {
3626536ae590e3873694cb02cf25dab8001a71f269eethannicholas                SkDebugf("Could not allocate indices\n");
3636536ae590e3873694cb02cf25dab8001a71f269eethannicholas                return;
3646536ae590e3873694cb02cf25dab8001a71f269eethannicholas            }
3656536ae590e3873694cb02cf25dab8001a71f269eethannicholas            lines.nextIndex = lines.indices;
3666536ae590e3873694cb02cf25dab8001a71f269eethannicholas        } else {
3676536ae590e3873694cb02cf25dab8001a71f269eethannicholas            lines.indices = nullptr;
3686536ae590e3873694cb02cf25dab8001a71f269eethannicholas            lines.nextIndex = nullptr;
3696536ae590e3873694cb02cf25dab8001a71f269eethannicholas        }
3706536ae590e3873694cb02cf25dab8001a71f269eethannicholas
3716536ae590e3873694cb02cf25dab8001a71f269eethannicholas        SkAutoFree quadIndexPtr;
3726536ae590e3873694cb02cf25dab8001a71f269eethannicholas        if (fIsIndexed) {
373780dad1ab9469828e3ef317ad9aea12f9c0a270aBrian Salomon            quads.indices = (uint16_t*)sk_malloc_throw(3 * fMaxQuadVertices * sizeof(uint16_t));
37495e3c058ef633782f7549e9e1c2727d60dbc8ee5Hal Canary            quadIndexPtr.reset(quads.indices);
3756536ae590e3873694cb02cf25dab8001a71f269eethannicholas            quads.nextIndex = quads.indices;
3766536ae590e3873694cb02cf25dab8001a71f269eethannicholas        } else {
3776536ae590e3873694cb02cf25dab8001a71f269eethannicholas            quads.indices = nullptr;
3786536ae590e3873694cb02cf25dab8001a71f269eethannicholas            quads.nextIndex = nullptr;
3796536ae590e3873694cb02cf25dab8001a71f269eethannicholas        }
3806536ae590e3873694cb02cf25dab8001a71f269eethannicholas
3816536ae590e3873694cb02cf25dab8001a71f269eethannicholas        // fill buffers
38250c56a39db30a4eb6b80e75db90ce9c1efe36b4fbsalomon        for (int i = 0; i < fPaths.count(); i++) {
38350c56a39db30a4eb6b80e75db90ce9c1efe36b4fbsalomon            const PathInfo& pathInfo = fPaths[i];
3846536ae590e3873694cb02cf25dab8001a71f269eethannicholas
3856536ae590e3873694cb02cf25dab8001a71f269eethannicholas            if (!this->createGeom(lines,
3866536ae590e3873694cb02cf25dab8001a71f269eethannicholas                                  quads,
38750c56a39db30a4eb6b80e75db90ce9c1efe36b4fbsalomon                                  pathInfo.fPath,
3886536ae590e3873694cb02cf25dab8001a71f269eethannicholas                                  fViewMatrix,
38950c56a39db30a4eb6b80e75db90ce9c1efe36b4fbsalomon                                  pathInfo.fColor,
3906536ae590e3873694cb02cf25dab8001a71f269eethannicholas                                  fIsIndexed)) {
3916536ae590e3873694cb02cf25dab8001a71f269eethannicholas                return;
3926536ae590e3873694cb02cf25dab8001a71f269eethannicholas            }
3936536ae590e3873694cb02cf25dab8001a71f269eethannicholas        }
3946536ae590e3873694cb02cf25dab8001a71f269eethannicholas        int lineVertexOffset = (int) (lines.nextVertex - lines.vertices);
3956536ae590e3873694cb02cf25dab8001a71f269eethannicholas        int lineIndexOffset = (int) (lines.nextIndex - lines.indices);
396780dad1ab9469828e3ef317ad9aea12f9c0a270aBrian Salomon        SkASSERT(lineVertexOffset <= fMaxLineVertices && lineIndexOffset <= 3 * fMaxLineVertices);
3976536ae590e3873694cb02cf25dab8001a71f269eethannicholas        int quadVertexOffset = (int) (quads.nextVertex - quads.vertices);
3986536ae590e3873694cb02cf25dab8001a71f269eethannicholas        int quadIndexOffset = (int) (quads.nextIndex - quads.indices);
399780dad1ab9469828e3ef317ad9aea12f9c0a270aBrian Salomon        SkASSERT(quadVertexOffset <= fMaxQuadVertices && quadIndexOffset <= 3 * fMaxQuadVertices);
4006536ae590e3873694cb02cf25dab8001a71f269eethannicholas
4016536ae590e3873694cb02cf25dab8001a71f269eethannicholas        if (lineVertexOffset) {
40206ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman            sk_sp<GrGeometryProcessor> lineGP;
4036536ae590e3873694cb02cf25dab8001a71f269eethannicholas            {
4046536ae590e3873694cb02cf25dab8001a71f269eethannicholas                using namespace GrDefaultGeoProcFactory;
4053de0aee181b8fe0013b15100cba7381eb0468db4Brian Salomon                lineGP = GrDefaultGeoProcFactory::Make(Color(Color::kPremulGrColorAttribute_Type),
4068c852be264d003b2e610c5b8634bc0f81c46bbbaBrian Salomon                                                       Coverage::kSolid_Type,
40706ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman                                                       LocalCoords(LocalCoords::kUnused_Type),
40806ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman                                                       fViewMatrix);
4096536ae590e3873694cb02cf25dab8001a71f269eethannicholas            }
4106536ae590e3873694cb02cf25dab8001a71f269eethannicholas            SkASSERT(lineVertexStride == lineGP->getVertexStride());
4116536ae590e3873694cb02cf25dab8001a71f269eethannicholas
4126536ae590e3873694cb02cf25dab8001a71f269eethannicholas            GrMesh lineMeshes;
4136536ae590e3873694cb02cf25dab8001a71f269eethannicholas            if (fIsIndexed) {
41406ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman                lineMeshes.initIndexed(primitiveType, lineVertexBuffer, lineIndexBuffer,
41506ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman                                         firstLineVertex, firstLineIndex, lineVertexOffset,
4166536ae590e3873694cb02cf25dab8001a71f269eethannicholas                                         lineIndexOffset);
4176536ae590e3873694cb02cf25dab8001a71f269eethannicholas            } else {
41806ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman                lineMeshes.init(primitiveType, lineVertexBuffer, firstLineVertex,
4196536ae590e3873694cb02cf25dab8001a71f269eethannicholas                                  lineVertexOffset);
4206536ae590e3873694cb02cf25dab8001a71f269eethannicholas            }
42106ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman            target->draw(lineGP.get(), lineMeshes);
4226536ae590e3873694cb02cf25dab8001a71f269eethannicholas        }
4236536ae590e3873694cb02cf25dab8001a71f269eethannicholas
4246536ae590e3873694cb02cf25dab8001a71f269eethannicholas        if (quadVertexOffset) {
425144caf55ffc692bcda77703a73bb9a894f7d024fHal Canary            sk_sp<const GrGeometryProcessor> quadGP(MSAAQuadProcessor::Create(fViewMatrix));
4266536ae590e3873694cb02cf25dab8001a71f269eethannicholas            SkASSERT(quadVertexStride == quadGP->getVertexStride());
4276536ae590e3873694cb02cf25dab8001a71f269eethannicholas
4286536ae590e3873694cb02cf25dab8001a71f269eethannicholas            const GrBuffer* quadVertexBuffer;
4296536ae590e3873694cb02cf25dab8001a71f269eethannicholas            int firstQuadVertex;
43006ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman            MSAAQuadVertices::Vertex* quadVertices = (MSAAQuadVertices::Vertex*)
4316536ae590e3873694cb02cf25dab8001a71f269eethannicholas                    target->makeVertexSpace(quadVertexStride, quadVertexOffset, &quadVertexBuffer,
4326536ae590e3873694cb02cf25dab8001a71f269eethannicholas                                            &firstQuadVertex);
4336536ae590e3873694cb02cf25dab8001a71f269eethannicholas            memcpy(quadVertices, quads.vertices, quadVertexStride * quadVertexOffset);
4346536ae590e3873694cb02cf25dab8001a71f269eethannicholas            GrMesh quadMeshes;
4356536ae590e3873694cb02cf25dab8001a71f269eethannicholas            if (fIsIndexed) {
4366536ae590e3873694cb02cf25dab8001a71f269eethannicholas                const GrBuffer* quadIndexBuffer;
4376536ae590e3873694cb02cf25dab8001a71f269eethannicholas                int firstQuadIndex;
43806ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman                uint16_t* quadIndices = (uint16_t*) target->makeIndexSpace(quadIndexOffset,
43906ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman                                                                           &quadIndexBuffer,
4406536ae590e3873694cb02cf25dab8001a71f269eethannicholas                                                                           &firstQuadIndex);
4416536ae590e3873694cb02cf25dab8001a71f269eethannicholas                memcpy(quadIndices, quads.indices, sizeof(uint16_t) * quadIndexOffset);
44206ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman                quadMeshes.initIndexed(kTriangles_GrPrimitiveType, quadVertexBuffer,
44306ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman                                       quadIndexBuffer, firstQuadVertex, firstQuadIndex,
4446536ae590e3873694cb02cf25dab8001a71f269eethannicholas                                       quadVertexOffset, quadIndexOffset);
4456536ae590e3873694cb02cf25dab8001a71f269eethannicholas            } else {
44606ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman                quadMeshes.init(kTriangles_GrPrimitiveType, quadVertexBuffer, firstQuadVertex,
4476536ae590e3873694cb02cf25dab8001a71f269eethannicholas                                quadVertexOffset);
4486536ae590e3873694cb02cf25dab8001a71f269eethannicholas            }
449144caf55ffc692bcda77703a73bb9a894f7d024fHal Canary            target->draw(quadGP.get(), quadMeshes);
4506536ae590e3873694cb02cf25dab8001a71f269eethannicholas        }
4516536ae590e3873694cb02cf25dab8001a71f269eethannicholas    }
4526536ae590e3873694cb02cf25dab8001a71f269eethannicholas
45325a880960a9a689a745a01071ecba3fe494b5940Brian Salomon    bool onCombineIfPossible(GrOp* t, const GrCaps& caps) override {
454780dad1ab9469828e3ef317ad9aea12f9c0a270aBrian Salomon        MSAAPathOp* that = t->cast<MSAAPathOp>();
4556536ae590e3873694cb02cf25dab8001a71f269eethannicholas        if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pipeline(),
4569e50f7b11e9a9d3dc23c924bbb0f0b85c6f1d6cbBrian Salomon                                    that->bounds(), caps)) {
4576536ae590e3873694cb02cf25dab8001a71f269eethannicholas            return false;
4589d01fbc9649361cec873863d25dc9095b937a6eeJim Van Verth        }
4599d01fbc9649361cec873863d25dc9095b937a6eeJim Van Verth
4609d01fbc9649361cec873863d25dc9095b937a6eeJim Van Verth        if (this->bounds().intersects(that->bounds())) {
4619d01fbc9649361cec873863d25dc9095b937a6eeJim Van Verth            return false;
4626536ae590e3873694cb02cf25dab8001a71f269eethannicholas        }
4636536ae590e3873694cb02cf25dab8001a71f269eethannicholas
4646536ae590e3873694cb02cf25dab8001a71f269eethannicholas        if (!fViewMatrix.cheapEqualTo(that->fViewMatrix)) {
4656536ae590e3873694cb02cf25dab8001a71f269eethannicholas            return false;
4666536ae590e3873694cb02cf25dab8001a71f269eethannicholas        }
4676536ae590e3873694cb02cf25dab8001a71f269eethannicholas
468780dad1ab9469828e3ef317ad9aea12f9c0a270aBrian Salomon        // If we grow to include 2+ paths we will be indexed.
469780dad1ab9469828e3ef317ad9aea12f9c0a270aBrian Salomon        if (((fMaxLineVertices + that->fMaxLineVertices) > kMaxIndexedVertexCnt) ||
470780dad1ab9469828e3ef317ad9aea12f9c0a270aBrian Salomon            ((fMaxQuadVertices + that->fMaxQuadVertices) > kMaxIndexedVertexCnt)) {
4716536ae590e3873694cb02cf25dab8001a71f269eethannicholas            return false;
4726536ae590e3873694cb02cf25dab8001a71f269eethannicholas        }
4736536ae590e3873694cb02cf25dab8001a71f269eethannicholas
47450c56a39db30a4eb6b80e75db90ce9c1efe36b4fbsalomon        fPaths.push_back_n(that->fPaths.count(), that->fPaths.begin());
47588cf17d099085b8085ab11571b5094163dbb2c84bsalomon        this->joinBounds(*that);
4766536ae590e3873694cb02cf25dab8001a71f269eethannicholas        fIsIndexed = true;
4776536ae590e3873694cb02cf25dab8001a71f269eethannicholas        fMaxLineVertices += that->fMaxLineVertices;
4786536ae590e3873694cb02cf25dab8001a71f269eethannicholas        fMaxQuadVertices += that->fMaxQuadVertices;
4796536ae590e3873694cb02cf25dab8001a71f269eethannicholas        return true;
4806536ae590e3873694cb02cf25dab8001a71f269eethannicholas    }
4816536ae590e3873694cb02cf25dab8001a71f269eethannicholas
4826536ae590e3873694cb02cf25dab8001a71f269eethannicholas    bool createGeom(MSAALineVertices& lines,
4836536ae590e3873694cb02cf25dab8001a71f269eethannicholas                    MSAAQuadVertices& quads,
4846536ae590e3873694cb02cf25dab8001a71f269eethannicholas                    const SkPath& path,
4856536ae590e3873694cb02cf25dab8001a71f269eethannicholas                    const SkMatrix& m,
4866536ae590e3873694cb02cf25dab8001a71f269eethannicholas                    SkColor color,
4876536ae590e3873694cb02cf25dab8001a71f269eethannicholas                    bool isIndexed) const {
4886536ae590e3873694cb02cf25dab8001a71f269eethannicholas        {
4896536ae590e3873694cb02cf25dab8001a71f269eethannicholas            uint16_t subpathIdxStart = (uint16_t) (lines.nextVertex - lines.vertices);
4906536ae590e3873694cb02cf25dab8001a71f269eethannicholas
4916536ae590e3873694cb02cf25dab8001a71f269eethannicholas            SkPoint pts[4];
4926536ae590e3873694cb02cf25dab8001a71f269eethannicholas
4936536ae590e3873694cb02cf25dab8001a71f269eethannicholas            bool first = true;
4948eb43e5f63306a22570b977bbb69e4ec78432d24bsalomon            SkPath::Iter iter(path, true);
4956536ae590e3873694cb02cf25dab8001a71f269eethannicholas
4966536ae590e3873694cb02cf25dab8001a71f269eethannicholas            bool done = false;
4976536ae590e3873694cb02cf25dab8001a71f269eethannicholas            while (!done) {
4986536ae590e3873694cb02cf25dab8001a71f269eethannicholas                SkPath::Verb verb = iter.next(pts);
4996536ae590e3873694cb02cf25dab8001a71f269eethannicholas                switch (verb) {
5006536ae590e3873694cb02cf25dab8001a71f269eethannicholas                    case SkPath::kMove_Verb:
5016536ae590e3873694cb02cf25dab8001a71f269eethannicholas                        if (!first) {
5026536ae590e3873694cb02cf25dab8001a71f269eethannicholas                            uint16_t currIdx = (uint16_t) (lines.nextVertex - lines.vertices);
5036536ae590e3873694cb02cf25dab8001a71f269eethannicholas                            subpathIdxStart = currIdx;
5046536ae590e3873694cb02cf25dab8001a71f269eethannicholas                        }
5056536ae590e3873694cb02cf25dab8001a71f269eethannicholas                        SkASSERT(lines.nextVertex < lines.verticesEnd);
5066536ae590e3873694cb02cf25dab8001a71f269eethannicholas                        *(lines.nextVertex++) = { pts[0], color };
5076536ae590e3873694cb02cf25dab8001a71f269eethannicholas                        break;
5086536ae590e3873694cb02cf25dab8001a71f269eethannicholas                    case SkPath::kLine_Verb:
5096536ae590e3873694cb02cf25dab8001a71f269eethannicholas                        if (isIndexed) {
5106536ae590e3873694cb02cf25dab8001a71f269eethannicholas                            uint16_t prevIdx = (uint16_t) (lines.nextVertex - lines.vertices - 1);
5116536ae590e3873694cb02cf25dab8001a71f269eethannicholas                            if (prevIdx > subpathIdxStart) {
5126536ae590e3873694cb02cf25dab8001a71f269eethannicholas                                append_contour_edge_indices(subpathIdxStart, prevIdx, lines);
5136536ae590e3873694cb02cf25dab8001a71f269eethannicholas                            }
5146536ae590e3873694cb02cf25dab8001a71f269eethannicholas                        }
5156536ae590e3873694cb02cf25dab8001a71f269eethannicholas                        SkASSERT(lines.nextVertex < lines.verticesEnd);
5166536ae590e3873694cb02cf25dab8001a71f269eethannicholas                        *(lines.nextVertex++) = { pts[1], color };
5176536ae590e3873694cb02cf25dab8001a71f269eethannicholas                        break;
5186536ae590e3873694cb02cf25dab8001a71f269eethannicholas                    case SkPath::kConic_Verb: {
5196536ae590e3873694cb02cf25dab8001a71f269eethannicholas                        SkScalar weight = iter.conicWeight();
5206536ae590e3873694cb02cf25dab8001a71f269eethannicholas                        SkAutoConicToQuads converter;
52150c56a39db30a4eb6b80e75db90ce9c1efe36b4fbsalomon                        const SkPoint* quadPts = converter.computeQuads(pts, weight, kTolerance);
5226536ae590e3873694cb02cf25dab8001a71f269eethannicholas                        for (int i = 0; i < converter.countQuads(); ++i) {
52306ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman                            add_quad(lines, quads, quadPts + i * 2, color, isIndexed,
5246536ae590e3873694cb02cf25dab8001a71f269eethannicholas                                     subpathIdxStart);
5256536ae590e3873694cb02cf25dab8001a71f269eethannicholas                        }
5266536ae590e3873694cb02cf25dab8001a71f269eethannicholas                        break;
5276536ae590e3873694cb02cf25dab8001a71f269eethannicholas                    }
5286536ae590e3873694cb02cf25dab8001a71f269eethannicholas                    case SkPath::kQuad_Verb: {
5296536ae590e3873694cb02cf25dab8001a71f269eethannicholas                        add_quad(lines, quads, pts, color, isIndexed, subpathIdxStart);
53006ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman                        break;
5316536ae590e3873694cb02cf25dab8001a71f269eethannicholas                    }
5326536ae590e3873694cb02cf25dab8001a71f269eethannicholas                    case SkPath::kCubic_Verb: {
5336536ae590e3873694cb02cf25dab8001a71f269eethannicholas                        SkSTArray<15, SkPoint, true> quadPts;
5346536ae590e3873694cb02cf25dab8001a71f269eethannicholas                        GrPathUtils::convertCubicToQuads(pts, kTolerance, &quadPts);
5356536ae590e3873694cb02cf25dab8001a71f269eethannicholas                        int count = quadPts.count();
5366536ae590e3873694cb02cf25dab8001a71f269eethannicholas                        for (int i = 0; i < count; i += 3) {
5376536ae590e3873694cb02cf25dab8001a71f269eethannicholas                            add_quad(lines, quads, &quadPts[i], color, isIndexed, subpathIdxStart);
5386536ae590e3873694cb02cf25dab8001a71f269eethannicholas                        }
5396536ae590e3873694cb02cf25dab8001a71f269eethannicholas                        break;
5406536ae590e3873694cb02cf25dab8001a71f269eethannicholas                    }
5416536ae590e3873694cb02cf25dab8001a71f269eethannicholas                    case SkPath::kClose_Verb:
5426536ae590e3873694cb02cf25dab8001a71f269eethannicholas                        break;
5436536ae590e3873694cb02cf25dab8001a71f269eethannicholas                    case SkPath::kDone_Verb:
5446536ae590e3873694cb02cf25dab8001a71f269eethannicholas                        done = true;
5456536ae590e3873694cb02cf25dab8001a71f269eethannicholas                }
5466536ae590e3873694cb02cf25dab8001a71f269eethannicholas                first = false;
5476536ae590e3873694cb02cf25dab8001a71f269eethannicholas            }
5486536ae590e3873694cb02cf25dab8001a71f269eethannicholas        }
5496536ae590e3873694cb02cf25dab8001a71f269eethannicholas        return true;
5506536ae590e3873694cb02cf25dab8001a71f269eethannicholas    }
5516536ae590e3873694cb02cf25dab8001a71f269eethannicholas
552780dad1ab9469828e3ef317ad9aea12f9c0a270aBrian Salomon    // Lines and quads may render with an index buffer. However, we don't have any support for
553780dad1ab9469828e3ef317ad9aea12f9c0a270aBrian Salomon    // overflowing the max index.
554780dad1ab9469828e3ef317ad9aea12f9c0a270aBrian Salomon    static constexpr int kMaxIndexedVertexCnt = SK_MaxU16 / 3;
55550c56a39db30a4eb6b80e75db90ce9c1efe36b4fbsalomon    struct PathInfo {
55650c56a39db30a4eb6b80e75db90ce9c1efe36b4fbsalomon        GrColor  fColor;
55750c56a39db30a4eb6b80e75db90ce9c1efe36b4fbsalomon        SkPath   fPath;
55850c56a39db30a4eb6b80e75db90ce9c1efe36b4fbsalomon    };
55950c56a39db30a4eb6b80e75db90ce9c1efe36b4fbsalomon
56050c56a39db30a4eb6b80e75db90ce9c1efe36b4fbsalomon    SkSTArray<1, PathInfo, true> fPaths;
5616536ae590e3873694cb02cf25dab8001a71f269eethannicholas
5626536ae590e3873694cb02cf25dab8001a71f269eethannicholas    SkMatrix fViewMatrix;
5636536ae590e3873694cb02cf25dab8001a71f269eethannicholas    int fMaxLineVertices;
5646536ae590e3873694cb02cf25dab8001a71f269eethannicholas    int fMaxQuadVertices;
5656536ae590e3873694cb02cf25dab8001a71f269eethannicholas    bool fIsIndexed;
5666536ae590e3873694cb02cf25dab8001a71f269eethannicholas
567dad2923b8ec9270d810c1e8e76da8e6768d8f9ddBrian Salomon    typedef GrMeshDrawOp INHERITED;
5686536ae590e3873694cb02cf25dab8001a71f269eethannicholas};
5696536ae590e3873694cb02cf25dab8001a71f269eethannicholas
5701105224f9701e57ec5ce0354d6a380b664f5c638Brian Osmanbool GrMSAAPathRenderer::internalDrawPath(GrRenderTargetContext* renderTargetContext,
57182f44319159bb98dcacdbbec7ea643dde5ed024bBrian Salomon                                          GrPaint&& paint,
5720e8fc8b9e6a138cf4a66b421fb824679df717329Brian Salomon                                          GrAAType aaType,
573d2b6d6486ed9d00df779f6b337d756c9a818006frobertphillips                                          const GrUserStencilSettings& userStencilSettings,
574862cff30eaa16206d76d7de7594c9167375ca87ecdalton                                          const GrClip& clip,
5756536ae590e3873694cb02cf25dab8001a71f269eethannicholas                                          const SkMatrix& viewMatrix,
5768acedde5970ce70de6d9791ffeda87a65af4ed07bsalomon                                          const GrShape& shape,
5776536ae590e3873694cb02cf25dab8001a71f269eethannicholas                                          bool stencilOnly) {
5788acedde5970ce70de6d9791ffeda87a65af4ed07bsalomon    SkASSERT(shape.style().isSimpleFill());
5798acedde5970ce70de6d9791ffeda87a65af4ed07bsalomon    SkPath path;
5808acedde5970ce70de6d9791ffeda87a65af4ed07bsalomon    shape.asPath(&path);
5818acedde5970ce70de6d9791ffeda87a65af4ed07bsalomon
58282f44319159bb98dcacdbbec7ea643dde5ed024bBrian Salomon    const GrUserStencilSettings* passes[2] = {nullptr, nullptr};
58393a379bd4d6b30d86c270b879cf172d80172a72bcdalton    bool                         reverse = false;
5846536ae590e3873694cb02cf25dab8001a71f269eethannicholas
5858acedde5970ce70de6d9791ffeda87a65af4ed07bsalomon    if (single_pass_shape(shape)) {
5866536ae590e3873694cb02cf25dab8001a71f269eethannicholas        if (stencilOnly) {
5876536ae590e3873694cb02cf25dab8001a71f269eethannicholas            passes[0] = &gDirectToStencil;
5886536ae590e3873694cb02cf25dab8001a71f269eethannicholas        } else {
589d2b6d6486ed9d00df779f6b337d756c9a818006frobertphillips            passes[0] = &userStencilSettings;
5906536ae590e3873694cb02cf25dab8001a71f269eethannicholas        }
5916536ae590e3873694cb02cf25dab8001a71f269eethannicholas    } else {
5926536ae590e3873694cb02cf25dab8001a71f269eethannicholas        switch (path.getFillType()) {
5936536ae590e3873694cb02cf25dab8001a71f269eethannicholas            case SkPath::kInverseEvenOdd_FillType:
5946536ae590e3873694cb02cf25dab8001a71f269eethannicholas                reverse = true;
5956536ae590e3873694cb02cf25dab8001a71f269eethannicholas                // fallthrough
5966536ae590e3873694cb02cf25dab8001a71f269eethannicholas            case SkPath::kEvenOdd_FillType:
5976536ae590e3873694cb02cf25dab8001a71f269eethannicholas                passes[0] = &gEOStencilPass;
59882f44319159bb98dcacdbbec7ea643dde5ed024bBrian Salomon                if (!stencilOnly) {
59982f44319159bb98dcacdbbec7ea643dde5ed024bBrian Salomon                    passes[1] = reverse ? &gInvEOColorPass : &gEOColorPass;
6006536ae590e3873694cb02cf25dab8001a71f269eethannicholas                }
6016536ae590e3873694cb02cf25dab8001a71f269eethannicholas                break;
6026536ae590e3873694cb02cf25dab8001a71f269eethannicholas
6036536ae590e3873694cb02cf25dab8001a71f269eethannicholas            case SkPath::kInverseWinding_FillType:
6046536ae590e3873694cb02cf25dab8001a71f269eethannicholas                reverse = true;
6056536ae590e3873694cb02cf25dab8001a71f269eethannicholas                // fallthrough
6066536ae590e3873694cb02cf25dab8001a71f269eethannicholas            case SkPath::kWinding_FillType:
6076536ae590e3873694cb02cf25dab8001a71f269eethannicholas                passes[0] = &gWindStencilSeparateWithWrap;
60882f44319159bb98dcacdbbec7ea643dde5ed024bBrian Salomon                if (!stencilOnly) {
60982f44319159bb98dcacdbbec7ea643dde5ed024bBrian Salomon                    passes[1] = reverse ? &gInvWindColorPass : &gWindColorPass;
6106536ae590e3873694cb02cf25dab8001a71f269eethannicholas                }
6116536ae590e3873694cb02cf25dab8001a71f269eethannicholas                break;
6126536ae590e3873694cb02cf25dab8001a71f269eethannicholas            default:
6136536ae590e3873694cb02cf25dab8001a71f269eethannicholas                SkDEBUGFAIL("Unknown path fFill!");
6146536ae590e3873694cb02cf25dab8001a71f269eethannicholas                return false;
6156536ae590e3873694cb02cf25dab8001a71f269eethannicholas        }
6166536ae590e3873694cb02cf25dab8001a71f269eethannicholas    }
6176536ae590e3873694cb02cf25dab8001a71f269eethannicholas
6186536ae590e3873694cb02cf25dab8001a71f269eethannicholas    SkRect devBounds;
6191105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman    GetPathDevBounds(path, renderTargetContext->width(), renderTargetContext->height(), viewMatrix,
6201105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman                     &devBounds);
6216536ae590e3873694cb02cf25dab8001a71f269eethannicholas
622d4652ca1b7989af5ef4e81b0de4eba529f804618Brian Salomon    SkASSERT(passes[0]);
623d4652ca1b7989af5ef4e81b0de4eba529f804618Brian Salomon    {  // First pass
624649a3411f99a8aea3c46e4ef1f495f61b9801164Brian Salomon        std::unique_ptr<GrMeshDrawOp> op =
625d4652ca1b7989af5ef4e81b0de4eba529f804618Brian Salomon                MSAAPathOp::Make(paint.getColor(), path, viewMatrix, devBounds);
626d4652ca1b7989af5ef4e81b0de4eba529f804618Brian Salomon        if (!op) {
627d4652ca1b7989af5ef4e81b0de4eba529f804618Brian Salomon            return false;
628d4652ca1b7989af5ef4e81b0de4eba529f804618Brian Salomon        }
629d4652ca1b7989af5ef4e81b0de4eba529f804618Brian Salomon        bool firstPassIsStencil = stencilOnly || passes[1];
630d4652ca1b7989af5ef4e81b0de4eba529f804618Brian Salomon        // If we have a cover pass then we ignore the paint in the first pass and apply it in the
631d4652ca1b7989af5ef4e81b0de4eba529f804618Brian Salomon        // second.
632d4652ca1b7989af5ef4e81b0de4eba529f804618Brian Salomon        GrPaint::MoveOrNew firstPassPaint(paint, firstPassIsStencil);
633d4652ca1b7989af5ef4e81b0de4eba529f804618Brian Salomon        if (firstPassIsStencil) {
634d4652ca1b7989af5ef4e81b0de4eba529f804618Brian Salomon            firstPassPaint.paint().setXPFactory(GrDisableColorXPFactory::Get());
635d4652ca1b7989af5ef4e81b0de4eba529f804618Brian Salomon        }
636d4652ca1b7989af5ef4e81b0de4eba529f804618Brian Salomon        GrPipelineBuilder pipelineBuilder(std::move(firstPassPaint), aaType);
637d4652ca1b7989af5ef4e81b0de4eba529f804618Brian Salomon        pipelineBuilder.setUserStencil(passes[0]);
638649a3411f99a8aea3c46e4ef1f495f61b9801164Brian Salomon        renderTargetContext->addMeshDrawOp(pipelineBuilder, clip, std::move(op));
63982f44319159bb98dcacdbbec7ea643dde5ed024bBrian Salomon    }
64082f44319159bb98dcacdbbec7ea643dde5ed024bBrian Salomon
64182f44319159bb98dcacdbbec7ea643dde5ed024bBrian Salomon    if (passes[1]) {
64282f44319159bb98dcacdbbec7ea643dde5ed024bBrian Salomon        SkRect bounds;
64382f44319159bb98dcacdbbec7ea643dde5ed024bBrian Salomon        SkMatrix localMatrix = SkMatrix::I();
64482f44319159bb98dcacdbbec7ea643dde5ed024bBrian Salomon        if (reverse) {
64582f44319159bb98dcacdbbec7ea643dde5ed024bBrian Salomon            // draw over the dev bounds (which will be the whole dst surface for inv fill).
64682f44319159bb98dcacdbbec7ea643dde5ed024bBrian Salomon            bounds = devBounds;
64782f44319159bb98dcacdbbec7ea643dde5ed024bBrian Salomon            SkMatrix vmi;
64882f44319159bb98dcacdbbec7ea643dde5ed024bBrian Salomon            // mapRect through persp matrix may not be correct
64982f44319159bb98dcacdbbec7ea643dde5ed024bBrian Salomon            if (!viewMatrix.hasPerspective() && viewMatrix.invert(&vmi)) {
65082f44319159bb98dcacdbbec7ea643dde5ed024bBrian Salomon                vmi.mapRect(&bounds);
6516536ae590e3873694cb02cf25dab8001a71f269eethannicholas            } else {
65282f44319159bb98dcacdbbec7ea643dde5ed024bBrian Salomon                if (!viewMatrix.invert(&localMatrix)) {
65382f44319159bb98dcacdbbec7ea643dde5ed024bBrian Salomon                    return false;
65482f44319159bb98dcacdbbec7ea643dde5ed024bBrian Salomon                }
6556536ae590e3873694cb02cf25dab8001a71f269eethannicholas            }
656976f5f0dc5e907d1ca50685fad117bd15d7fc87brobertphillips        } else {
65782f44319159bb98dcacdbbec7ea643dde5ed024bBrian Salomon            bounds = path.getBounds();
6586536ae590e3873694cb02cf25dab8001a71f269eethannicholas        }
65982f44319159bb98dcacdbbec7ea643dde5ed024bBrian Salomon        const SkMatrix& viewM =
66082f44319159bb98dcacdbbec7ea643dde5ed024bBrian Salomon                (reverse && viewMatrix.hasPerspective()) ? SkMatrix::I() : viewMatrix;
661649a3411f99a8aea3c46e4ef1f495f61b9801164Brian Salomon        std::unique_ptr<GrMeshDrawOp> op(GrRectOpFactory::MakeNonAAFill(
662649a3411f99a8aea3c46e4ef1f495f61b9801164Brian Salomon                paint.getColor(), viewM, bounds, nullptr, &localMatrix));
66382f44319159bb98dcacdbbec7ea643dde5ed024bBrian Salomon
66482f44319159bb98dcacdbbec7ea643dde5ed024bBrian Salomon        GrPipelineBuilder pipelineBuilder(std::move(paint), aaType);
66582f44319159bb98dcacdbbec7ea643dde5ed024bBrian Salomon        pipelineBuilder.setUserStencil(passes[1]);
66682f44319159bb98dcacdbbec7ea643dde5ed024bBrian Salomon
667649a3411f99a8aea3c46e4ef1f495f61b9801164Brian Salomon        renderTargetContext->addMeshDrawOp(pipelineBuilder, clip, std::move(op));
6686536ae590e3873694cb02cf25dab8001a71f269eethannicholas    }
6696536ae590e3873694cb02cf25dab8001a71f269eethannicholas    return true;
6706536ae590e3873694cb02cf25dab8001a71f269eethannicholas}
6716536ae590e3873694cb02cf25dab8001a71f269eethannicholas
6726536ae590e3873694cb02cf25dab8001a71f269eethannicholasbool GrMSAAPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
673ee43241d72148545e4e3b75aa4338c491b39cc0cbsalomon    // This path renderer only fills and relies on MSAA for antialiasing. Stroked shapes are
674ee43241d72148545e4e3b75aa4338c491b39cc0cbsalomon    // handled by passing on the original shape and letting the caller compute the stroked shape
675ee43241d72148545e4e3b75aa4338c491b39cc0cbsalomon    // which will have a fill style.
6760e8fc8b9e6a138cf4a66b421fb824679df717329Brian Salomon    return args.fShape->style().isSimpleFill() && (GrAAType::kCoverage != args.fAAType);
6776536ae590e3873694cb02cf25dab8001a71f269eethannicholas}
6786536ae590e3873694cb02cf25dab8001a71f269eethannicholas
6796536ae590e3873694cb02cf25dab8001a71f269eethannicholasbool GrMSAAPathRenderer::onDrawPath(const DrawPathArgs& args) {
6801105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman    GR_AUDIT_TRAIL_AUTO_FRAME(args.fRenderTargetContext->auditTrail(),
681976f5f0dc5e907d1ca50685fad117bd15d7fc87brobertphillips                              "GrMSAAPathRenderer::onDrawPath");
6828acedde5970ce70de6d9791ffeda87a65af4ed07bsalomon    SkTLazy<GrShape> tmpShape;
6838acedde5970ce70de6d9791ffeda87a65af4ed07bsalomon    const GrShape* shape = args.fShape;
6848acedde5970ce70de6d9791ffeda87a65af4ed07bsalomon    if (shape->style().applies()) {
6856663acff010ce752e4bf778da81fa97448c9db31bsalomon        SkScalar styleScale = GrStyle::MatrixToScaleFactor(*args.fViewMatrix);
6868acedde5970ce70de6d9791ffeda87a65af4ed07bsalomon        tmpShape.init(args.fShape->applyStyle(GrStyle::Apply::kPathEffectAndStrokeRec, styleScale));
6878acedde5970ce70de6d9791ffeda87a65af4ed07bsalomon        shape = tmpShape.get();
6886536ae590e3873694cb02cf25dab8001a71f269eethannicholas    }
6891105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman    return this->internalDrawPath(args.fRenderTargetContext,
69082f44319159bb98dcacdbbec7ea643dde5ed024bBrian Salomon                                  std::move(args.fPaint),
6910e8fc8b9e6a138cf4a66b421fb824679df717329Brian Salomon                                  args.fAAType,
692d2b6d6486ed9d00df779f6b337d756c9a818006frobertphillips                                  *args.fUserStencilSettings,
693862cff30eaa16206d76d7de7594c9167375ca87ecdalton                                  *args.fClip,
6946536ae590e3873694cb02cf25dab8001a71f269eethannicholas                                  *args.fViewMatrix,
6958acedde5970ce70de6d9791ffeda87a65af4ed07bsalomon                                  *shape,
6966536ae590e3873694cb02cf25dab8001a71f269eethannicholas                                  false);
6976536ae590e3873694cb02cf25dab8001a71f269eethannicholas}
6986536ae590e3873694cb02cf25dab8001a71f269eethannicholas
6996536ae590e3873694cb02cf25dab8001a71f269eethannicholasvoid GrMSAAPathRenderer::onStencilPath(const StencilPathArgs& args) {
7001105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman    GR_AUDIT_TRAIL_AUTO_FRAME(args.fRenderTargetContext->auditTrail(),
701976f5f0dc5e907d1ca50685fad117bd15d7fc87brobertphillips                              "GrMSAAPathRenderer::onStencilPath");
7028acedde5970ce70de6d9791ffeda87a65af4ed07bsalomon    SkASSERT(args.fShape->style().isSimpleFill());
7038acedde5970ce70de6d9791ffeda87a65af4ed07bsalomon    SkASSERT(!args.fShape->mayBeInverseFilledAfterStyling());
704976f5f0dc5e907d1ca50685fad117bd15d7fc87brobertphillips
705976f5f0dc5e907d1ca50685fad117bd15d7fc87brobertphillips    GrPaint paint;
706a16339297859f37df69230e64f05624cef511ad3Brian Salomon    paint.setXPFactory(GrDisableColorXPFactory::Get());
707976f5f0dc5e907d1ca50685fad117bd15d7fc87brobertphillips
70882f44319159bb98dcacdbbec7ea643dde5ed024bBrian Salomon    this->internalDrawPath(args.fRenderTargetContext, std::move(paint), args.fAAType,
7090e8fc8b9e6a138cf4a66b421fb824679df717329Brian Salomon                           GrUserStencilSettings::kUnused, *args.fClip, *args.fViewMatrix,
7100e8fc8b9e6a138cf4a66b421fb824679df717329Brian Salomon                           *args.fShape, true);
7116536ae590e3873694cb02cf25dab8001a71f269eethannicholas}
7126536ae590e3873694cb02cf25dab8001a71f269eethannicholas
7136536ae590e3873694cb02cf25dab8001a71f269eethannicholas///////////////////////////////////////////////////////////////////////////////////////////////////
714