GrAALinearizingConvexPathRenderer.cpp revision 1105224f9701e57ec5ce0354d6a380b664f5c638
11a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas/*
21a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas * Copyright 2015 Google Inc.
31a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas *
41a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas * Use of this source code is governed by a BSD-style license that can be
51a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas * found in the LICENSE file.
61a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas */
71a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas
81a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas#include "GrAALinearizingConvexPathRenderer.h"
91a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas
101a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas#include "GrAAConvexTessellator.h"
117539856c1b9cbb1886a6a498cc534b77fc83ddb2bsalomon#include "GrBatchFlushState.h"
121a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas#include "GrBatchTest.h"
131a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas#include "GrContext.h"
141a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas#include "GrDefaultGeoProcFactory.h"
151a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas#include "GrGeometryProcessor.h"
161a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas#include "GrInvariantOutput.h"
171a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas#include "GrPathUtils.h"
181a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas#include "GrProcessor.h"
19bb24383abb724c516e472af4eec68f2c3f17a6d0bsalomon#include "GrPipelineBuilder.h"
206663acff010ce752e4bf778da81fa97448c9db31bsalomon#include "GrStyle.h"
211a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas#include "SkGeometry.h"
221a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas#include "SkString.h"
231a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas#include "SkTraceEvent.h"
24bd5d7e75c1ef08816bfd8eed52150cd716e15d5bfmalita#include "SkPathPriv.h"
2516b991390bb988b194a868ab8de66db4c21c7c13bsalomon#include "batches/GrVertexBatch.h"
26e659a581f63fdccb64dce2dc8a478cf56831feeaegdaniel#include "glsl/GrGLSLGeometryProcessor.h"
271a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas
28bd5d7e75c1ef08816bfd8eed52150cd716e15d5bfmalitastatic const int DEFAULT_BUFFER_SIZE = 100;
29bd5d7e75c1ef08816bfd8eed52150cd716e15d5bfmalita
30bd5d7e75c1ef08816bfd8eed52150cd716e15d5bfmalita// The thicker the stroke, the harder it is to produce high-quality results using tessellation. For
31bd5d7e75c1ef08816bfd8eed52150cd716e15d5bfmalita// the time being, we simply drop back to software rendering above this stroke width.
32bd5d7e75c1ef08816bfd8eed52150cd716e15d5bfmalitastatic const SkScalar kMaxStrokeWidth = 20.0;
331a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas
341a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholasGrAALinearizingConvexPathRenderer::GrAALinearizingConvexPathRenderer() {
351a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas}
361a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas
371a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas///////////////////////////////////////////////////////////////////////////////
381a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas
390aff2fa82a5fa9f99aa77327dac3e9e803b4ed07bsalomonbool GrAALinearizingConvexPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
400aff2fa82a5fa9f99aa77327dac3e9e803b4ed07bsalomon    if (!args.fAntiAlias) {
41bd5d7e75c1ef08816bfd8eed52150cd716e15d5bfmalita        return false;
42bd5d7e75c1ef08816bfd8eed52150cd716e15d5bfmalita    }
438acedde5970ce70de6d9791ffeda87a65af4ed07bsalomon    if (!args.fShape->knownToBeConvex()) {
44bd5d7e75c1ef08816bfd8eed52150cd716e15d5bfmalita        return false;
45bd5d7e75c1ef08816bfd8eed52150cd716e15d5bfmalita    }
468acedde5970ce70de6d9791ffeda87a65af4ed07bsalomon    if (args.fShape->style().pathEffect()) {
47bd5d7e75c1ef08816bfd8eed52150cd716e15d5bfmalita        return false;
48bd5d7e75c1ef08816bfd8eed52150cd716e15d5bfmalita    }
498acedde5970ce70de6d9791ffeda87a65af4ed07bsalomon    if (args.fShape->inverseFilled()) {
506663acff010ce752e4bf778da81fa97448c9db31bsalomon        return false;
516663acff010ce752e4bf778da81fa97448c9db31bsalomon    }
528acedde5970ce70de6d9791ffeda87a65af4ed07bsalomon    const SkStrokeRec& stroke = args.fShape->style().strokeRec();
538c170971f182d47bc9af71fc88a607740d03dfd5robertphillips
548c170971f182d47bc9af71fc88a607740d03dfd5robertphillips    if (stroke.getStyle() == SkStrokeRec::kStroke_Style ||
558c170971f182d47bc9af71fc88a607740d03dfd5robertphillips        stroke.getStyle() == SkStrokeRec::kStrokeAndFill_Style) {
56fea7763140ba74b78f2c30028452e250140b6f21ethannicholas        if (!args.fViewMatrix->isSimilarity()) {
57fea7763140ba74b78f2c30028452e250140b6f21ethannicholas            return false;
58fea7763140ba74b78f2c30028452e250140b6f21ethannicholas        }
596663acff010ce752e4bf778da81fa97448c9db31bsalomon        SkScalar strokeWidth = args.fViewMatrix->getMaxScale() * stroke.getWidth();
608c170971f182d47bc9af71fc88a607740d03dfd5robertphillips        if (strokeWidth < 1.0f && stroke.getStyle() == SkStrokeRec::kStroke_Style) {
618c170971f182d47bc9af71fc88a607740d03dfd5robertphillips            return false;
628c170971f182d47bc9af71fc88a607740d03dfd5robertphillips        }
638c170971f182d47bc9af71fc88a607740d03dfd5robertphillips        return strokeWidth <= kMaxStrokeWidth &&
648acedde5970ce70de6d9791ffeda87a65af4ed07bsalomon               args.fShape->knownToBeClosed() &&
656663acff010ce752e4bf778da81fa97448c9db31bsalomon               stroke.getJoin() != SkPaint::Join::kRound_Join;
66bd5d7e75c1ef08816bfd8eed52150cd716e15d5bfmalita    }
676663acff010ce752e4bf778da81fa97448c9db31bsalomon    return stroke.getStyle() == SkStrokeRec::kFill_Style;
681a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas}
691a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas
701a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas// extract the result vertices and indices from the GrAAConvexTessellator
711a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholasstatic void extract_verts(const GrAAConvexTessellator& tess,
721a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas                          void* vertices,
731a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas                          size_t vertexStride,
741a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas                          GrColor color,
751a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas                          uint16_t firstIndex,
761a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas                          uint16_t* idxs,
771a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas                          bool tweakAlphaForCoverage) {
781a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas    intptr_t verts = reinterpret_cast<intptr_t>(vertices);
791a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas
801a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas    for (int i = 0; i < tess.numPts(); ++i) {
811a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas        *((SkPoint*)((intptr_t)verts + i * vertexStride)) = tess.point(i);
821a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas    }
831a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas
841a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas    // Make 'verts' point to the colors
851a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas    verts += sizeof(SkPoint);
861a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas    for (int i = 0; i < tess.numPts(); ++i) {
871a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas        if (tweakAlphaForCoverage) {
88bd5d7e75c1ef08816bfd8eed52150cd716e15d5bfmalita            SkASSERT(SkScalarRoundToInt(255.0f * tess.coverage(i)) <= 255);
89bd5d7e75c1ef08816bfd8eed52150cd716e15d5bfmalita            unsigned scale = SkScalarRoundToInt(255.0f * tess.coverage(i));
901a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas            GrColor scaledColor = (0xff == scale) ? color : SkAlphaMulQ(color, scale);
911a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas            *reinterpret_cast<GrColor*>(verts + i * vertexStride) = scaledColor;
921a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas        } else {
931a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas            *reinterpret_cast<GrColor*>(verts + i * vertexStride) = color;
94002c2ce66be69d41632c9603ce62c50f04156518mtklein            *reinterpret_cast<float*>(verts + i * vertexStride + sizeof(GrColor)) =
95bd5d7e75c1ef08816bfd8eed52150cd716e15d5bfmalita                    tess.coverage(i);
961a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas        }
971a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas    }
981a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas
991a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas    for (int i = 0; i < tess.numIndices(); ++i) {
1001a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas        idxs[i] = tess.index(i) + firstIndex;
1011a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas    }
1021a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas}
1031a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas
10406ca8ec87cf6fab57cadd043a5ac18c4154a4129bungemanstatic sk_sp<GrGeometryProcessor> create_fill_gp(bool tweakAlphaForCoverage,
105df0c55785033c191d2d509c22662861588e4acd8joshualitt                                                 const SkMatrix& viewMatrix,
1061a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas                                                 bool usesLocalCoords,
1071a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas                                                 bool coverageIgnored) {
108df0c55785033c191d2d509c22662861588e4acd8joshualitt    using namespace GrDefaultGeoProcFactory;
109df0c55785033c191d2d509c22662861588e4acd8joshualitt
110df0c55785033c191d2d509c22662861588e4acd8joshualitt    Color color(Color::kAttribute_Type);
111df0c55785033c191d2d509c22662861588e4acd8joshualitt    Coverage::Type coverageType;
112df0c55785033c191d2d509c22662861588e4acd8joshualitt    // TODO remove coverage if coverage is ignored
113df0c55785033c191d2d509c22662861588e4acd8joshualitt    /*if (coverageIgnored) {
114df0c55785033c191d2d509c22662861588e4acd8joshualitt        coverageType = Coverage::kNone_Type;
115df0c55785033c191d2d509c22662861588e4acd8joshualitt    } else*/ if (tweakAlphaForCoverage) {
116df0c55785033c191d2d509c22662861588e4acd8joshualitt        coverageType = Coverage::kSolid_Type;
117df0c55785033c191d2d509c22662861588e4acd8joshualitt    } else {
118df0c55785033c191d2d509c22662861588e4acd8joshualitt        coverageType = Coverage::kAttribute_Type;
1191a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas    }
120df0c55785033c191d2d509c22662861588e4acd8joshualitt    Coverage coverage(coverageType);
121df0c55785033c191d2d509c22662861588e4acd8joshualitt    LocalCoords localCoords(usesLocalCoords ? LocalCoords::kUsePosition_Type :
122df0c55785033c191d2d509c22662861588e4acd8joshualitt                                              LocalCoords::kUnused_Type);
12306ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman    return MakeForDeviceSpace(color, coverage, localCoords, viewMatrix);
1241a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas}
1251a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas
126abd30f54b7ff1704a8930c4307ea242d09425d02bsalomonclass AAFlatteningConvexPathBatch : public GrVertexBatch {
1271a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholaspublic:
1281b55a963a2374a14bb82eb887bb99ee91680f0ebreed    DEFINE_BATCH_CLASS_ID
1291b55a963a2374a14bb82eb887bb99ee91680f0ebreed
1300432dd6ee62d0c1c1ca67b7f6f6fcf3de75aaf77bsalomon    AAFlatteningConvexPathBatch(GrColor color,
1310432dd6ee62d0c1c1ca67b7f6f6fcf3de75aaf77bsalomon                                const SkMatrix& viewMatrix,
1320432dd6ee62d0c1c1ca67b7f6f6fcf3de75aaf77bsalomon                                const SkPath& path,
1330432dd6ee62d0c1c1ca67b7f6f6fcf3de75aaf77bsalomon                                SkScalar strokeWidth,
1348c170971f182d47bc9af71fc88a607740d03dfd5robertphillips                                SkStrokeRec::Style style,
1350432dd6ee62d0c1c1ca67b7f6f6fcf3de75aaf77bsalomon                                SkPaint::Join join,
1360432dd6ee62d0c1c1ca67b7f6f6fcf3de75aaf77bsalomon                                SkScalar miterLimit) : INHERITED(ClassID()) {
1378c170971f182d47bc9af71fc88a607740d03dfd5robertphillips        fGeoData.emplace_back(Geometry{ color, viewMatrix, path,
1388c170971f182d47bc9af71fc88a607740d03dfd5robertphillips                                        strokeWidth, style, join, miterLimit });
1391a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas
1400432dd6ee62d0c1c1ca67b7f6f6fcf3de75aaf77bsalomon        // compute bounds
14188cf17d099085b8085ab11571b5094163dbb2c84bsalomon        SkRect bounds = path.getBounds();
1420432dd6ee62d0c1c1ca67b7f6f6fcf3de75aaf77bsalomon        SkScalar w = strokeWidth;
1430432dd6ee62d0c1c1ca67b7f6f6fcf3de75aaf77bsalomon        if (w > 0) {
1440432dd6ee62d0c1c1ca67b7f6f6fcf3de75aaf77bsalomon            w /= 2;
1450432dd6ee62d0c1c1ca67b7f6f6fcf3de75aaf77bsalomon            // If the half stroke width is < 1 then we effectively fallback to bevel joins.
1460432dd6ee62d0c1c1ca67b7f6f6fcf3de75aaf77bsalomon            if (SkPaint::kMiter_Join == join && w > 1.f) {
1470432dd6ee62d0c1c1ca67b7f6f6fcf3de75aaf77bsalomon                w *= miterLimit;
1480432dd6ee62d0c1c1ca67b7f6f6fcf3de75aaf77bsalomon            }
14988cf17d099085b8085ab11571b5094163dbb2c84bsalomon            bounds.outset(w, w);
1500432dd6ee62d0c1c1ca67b7f6f6fcf3de75aaf77bsalomon        }
15188cf17d099085b8085ab11571b5094163dbb2c84bsalomon        this->setTransformedBounds(bounds, viewMatrix, HasAABloat::kYes, IsZeroArea::kNo);
1521a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas    }
1531a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas
1541a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas    const char* name() const override { return "AAConvexBatch"; }
1551a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas
1569d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary    void computePipelineOptimizations(GrInitInvariantOutput* color,
157ff2103200bad7abcf8929ae22ac78a9f4f725142ethannicholas                                      GrInitInvariantOutput* coverage,
158ff2103200bad7abcf8929ae22ac78a9f4f725142ethannicholas                                      GrBatchToXPOverrides* overrides) const override {
1591a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas        // When this is called on a batch, there is only one geometry bundle
160ff2103200bad7abcf8929ae22ac78a9f4f725142ethannicholas        color->setKnownFourComponents(fGeoData[0].fColor);
161ff2103200bad7abcf8929ae22ac78a9f4f725142ethannicholas        coverage->setUnknownSingleComponent();
1621a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas    }
1631a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas
164e46f9feb44780a6269c6dcfe993f4215427fd98ebsalomonprivate:
165ff2103200bad7abcf8929ae22ac78a9f4f725142ethannicholas    void initBatchTracker(const GrXPOverridesForBatch& overrides) override {
1661a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas        // Handle any color overrides
167ff2103200bad7abcf8929ae22ac78a9f4f725142ethannicholas        if (!overrides.readsColor()) {
1681a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas            fGeoData[0].fColor = GrColor_ILLEGAL;
1691a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas        }
170ff2103200bad7abcf8929ae22ac78a9f4f725142ethannicholas        overrides.getOverrideColorIfSet(&fGeoData[0].fColor);
1711a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas
1721a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas        // setup batch properties
173ff2103200bad7abcf8929ae22ac78a9f4f725142ethannicholas        fBatch.fColorIgnored = !overrides.readsColor();
1741a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas        fBatch.fColor = fGeoData[0].fColor;
175ff2103200bad7abcf8929ae22ac78a9f4f725142ethannicholas        fBatch.fUsesLocalCoords = overrides.readsLocalCoords();
176ff2103200bad7abcf8929ae22ac78a9f4f725142ethannicholas        fBatch.fCoverageIgnored = !overrides.readsCoverage();
1771a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas        fBatch.fLinesOnly = SkPath::kLine_SegmentMask == fGeoData[0].fPath.getSegmentMasks();
178ff2103200bad7abcf8929ae22ac78a9f4f725142ethannicholas        fBatch.fCanTweakAlphaForCoverage = overrides.canTweakAlphaForCoverage();
1791a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas    }
1801a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas
181342bfc25de5b0452b1551bf9db4bf45eac7718b2bsalomon    void draw(GrVertexBatch::Target* target, const GrGeometryProcessor* gp, int vertexCount,
182144c3c8b7ff3ebc389b41211f3388fb24a7ff0c2joshualitt              size_t vertexStride, void* vertices, int indexCount, uint16_t* indices) const {
1831a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas        if (vertexCount == 0 || indexCount == 0) {
1841a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas            return;
1851a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas        }
186397536cabe12a9936659870dd220c869789424bacdalton        const GrBuffer* vertexBuffer;
1870e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel        GrMesh mesh;
1881a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas        int firstVertex;
189002c2ce66be69d41632c9603ce62c50f04156518mtklein        void* verts = target->makeVertexSpace(vertexStride, vertexCount, &vertexBuffer,
1907539856c1b9cbb1886a6a498cc534b77fc83ddb2bsalomon                                              &firstVertex);
1911a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas        if (!verts) {
1921a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas            SkDebugf("Could not allocate vertices\n");
1931a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas            return;
1941a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas        }
1951a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas        memcpy(verts, vertices, vertexCount * vertexStride);
1961a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas
197397536cabe12a9936659870dd220c869789424bacdalton        const GrBuffer* indexBuffer;
1981a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas        int firstIndex;
1997539856c1b9cbb1886a6a498cc534b77fc83ddb2bsalomon        uint16_t* idxs = target->makeIndexSpace(indexCount, &indexBuffer, &firstIndex);
2001a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas        if (!idxs) {
2011a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas            SkDebugf("Could not allocate indices\n");
2021a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas            return;
2031a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas        }
2041a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas        memcpy(idxs, indices, indexCount * sizeof(uint16_t));
2050e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel        mesh.initIndexed(kTriangles_GrPrimitiveType, vertexBuffer, indexBuffer, firstVertex,
2060e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel                         firstIndex, vertexCount, indexCount);
207342bfc25de5b0452b1551bf9db4bf45eac7718b2bsalomon        target->draw(gp, mesh);
2081a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas    }
209002c2ce66be69d41632c9603ce62c50f04156518mtklein
210144c3c8b7ff3ebc389b41211f3388fb24a7ff0c2joshualitt    void onPrepareDraws(Target* target) const override {
2111a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas        bool canTweakAlphaForCoverage = this->canTweakAlphaForCoverage();
2121a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas
213df0c55785033c191d2d509c22662861588e4acd8joshualitt        // Setup GrGeometryProcessor
21406ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman        sk_sp<GrGeometryProcessor> gp(create_fill_gp(canTweakAlphaForCoverage,
21506ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman                                                     this->viewMatrix(),
21606ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman                                                     this->usesLocalCoords(),
21706ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman                                                     this->coverageIgnored()));
218df0c55785033c191d2d509c22662861588e4acd8joshualitt        if (!gp) {
219df0c55785033c191d2d509c22662861588e4acd8joshualitt            SkDebugf("Couldn't create a GrGeometryProcessor\n");
2201a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas            return;
2211a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas        }
2221a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas
2231a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas        size_t vertexStride = gp->getVertexStride();
2241a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas
2251a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas        SkASSERT(canTweakAlphaForCoverage ?
2261a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas                 vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorAttr) :
2271a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas                 vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorCoverageAttr));
2281a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas
2291a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas        int instanceCount = fGeoData.count();
2301a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas
2311a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas        int vertexCount = 0;
2321a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas        int indexCount = 0;
2331a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas        int maxVertices = DEFAULT_BUFFER_SIZE;
2341a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas        int maxIndices = DEFAULT_BUFFER_SIZE;
235002c2ce66be69d41632c9603ce62c50f04156518mtklein        uint8_t* vertices = (uint8_t*) sk_malloc_throw(maxVertices * vertexStride);
236002c2ce66be69d41632c9603ce62c50f04156518mtklein        uint16_t* indices = (uint16_t*) sk_malloc_throw(maxIndices * sizeof(uint16_t));
2371a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas        for (int i = 0; i < instanceCount; i++) {
238144c3c8b7ff3ebc389b41211f3388fb24a7ff0c2joshualitt            const Geometry& args = fGeoData[i];
2398c170971f182d47bc9af71fc88a607740d03dfd5robertphillips            GrAAConvexTessellator tess(args.fStyle, args.fStrokeWidth,
2408c170971f182d47bc9af71fc88a607740d03dfd5robertphillips                                       args.fJoin, args.fMiterLimit);
2411a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas
2421a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas            if (!tess.tessellate(args.fViewMatrix, args.fPath)) {
2431a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas                continue;
2441a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas            }
2451a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas
2461a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas            int currentIndices = tess.numIndices();
2471a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas            SkASSERT(currentIndices <= UINT16_MAX);
2481a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas            if (indexCount + currentIndices > UINT16_MAX) {
249002c2ce66be69d41632c9603ce62c50f04156518mtklein                // if we added the current instance, we would overflow the indices we can store in a
2501a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas                // uint16_t. Draw what we've got so far and reset.
25106ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman                this->draw(target, gp.get(),
25206ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman                           vertexCount, vertexStride, vertices, indexCount, indices);
2531a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas                vertexCount = 0;
2541a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas                indexCount = 0;
2551a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas            }
2561a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas            int currentVertices = tess.numPts();
2571a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas            if (vertexCount + currentVertices > maxVertices) {
2581a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas                maxVertices = SkTMax(vertexCount + currentVertices, maxVertices * 2);
259002c2ce66be69d41632c9603ce62c50f04156518mtklein                vertices = (uint8_t*) sk_realloc_throw(vertices, maxVertices * vertexStride);
2601a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas            }
2611a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas            if (indexCount + currentIndices > maxIndices) {
2621a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas                maxIndices = SkTMax(indexCount + currentIndices, maxIndices * 2);
263002c2ce66be69d41632c9603ce62c50f04156518mtklein                indices = (uint16_t*) sk_realloc_throw(indices, maxIndices * sizeof(uint16_t));
2641a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas            }
2651a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas
266002c2ce66be69d41632c9603ce62c50f04156518mtklein            extract_verts(tess, vertices + vertexStride * vertexCount, vertexStride, args.fColor,
2671a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas                    vertexCount, indices + indexCount, canTweakAlphaForCoverage);
2681a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas            vertexCount += currentVertices;
2691a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas            indexCount += currentIndices;
2701a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas        }
27106ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman        this->draw(target, gp.get(), vertexCount, vertexStride, vertices, indexCount, indices);
272002c2ce66be69d41632c9603ce62c50f04156518mtklein        sk_free(vertices);
273002c2ce66be69d41632c9603ce62c50f04156518mtklein        sk_free(indices);
2741a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas    }
2751a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas
276cb02b38b2c48bfde333ce3c699dd0451e2d867fabsalomon    bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override {
277abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon        AAFlatteningConvexPathBatch* that = t->cast<AAFlatteningConvexPathBatch>();
278abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon        if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pipeline(),
279abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon                                    that->bounds(), caps)) {
2808cab9a7685e872427e6f0388f149575a9b6016eejoshualitt            return false;
2818cab9a7685e872427e6f0388f149575a9b6016eejoshualitt        }
2828cab9a7685e872427e6f0388f149575a9b6016eejoshualitt
2831a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas        SkASSERT(this->usesLocalCoords() == that->usesLocalCoords());
2841a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas        if (this->usesLocalCoords() && !this->viewMatrix().cheapEqualTo(that->viewMatrix())) {
2851a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas            return false;
2861a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas        }
2871a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas
2881a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas        // In the event of two batches, one who can tweak, one who cannot, we just fall back to
2891a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas        // not tweaking
2901a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas        if (this->canTweakAlphaForCoverage() != that->canTweakAlphaForCoverage()) {
2911a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas            fBatch.fCanTweakAlphaForCoverage = false;
2921a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas        }
2931a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas
2940432dd6ee62d0c1c1ca67b7f6f6fcf3de75aaf77bsalomon        fGeoData.push_back_n(that->fGeoData.count(), that->fGeoData.begin());
29588cf17d099085b8085ab11571b5094163dbb2c84bsalomon        this->joinBounds(*that);
2961a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas        return true;
2971a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas    }
2981a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas
2991a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas    GrColor color() const { return fBatch.fColor; }
3001a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas    bool linesOnly() const { return fBatch.fLinesOnly; }
3011a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas    bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; }
3021a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas    bool canTweakAlphaForCoverage() const { return fBatch.fCanTweakAlphaForCoverage; }
3031a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas    const SkMatrix& viewMatrix() const { return fGeoData[0].fViewMatrix; }
3041a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas    bool coverageIgnored() const { return fBatch.fCoverageIgnored; }
3051a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas
3061a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas    struct BatchTracker {
3071a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas        GrColor fColor;
3081a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas        bool fUsesLocalCoords;
3091a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas        bool fColorIgnored;
3101a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas        bool fCoverageIgnored;
3111a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas        bool fLinesOnly;
3121a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas        bool fCanTweakAlphaForCoverage;
3131a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas    };
3141a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas
3150432dd6ee62d0c1c1ca67b7f6f6fcf3de75aaf77bsalomon    struct Geometry {
3160432dd6ee62d0c1c1ca67b7f6f6fcf3de75aaf77bsalomon        GrColor fColor;
3170432dd6ee62d0c1c1ca67b7f6f6fcf3de75aaf77bsalomon        SkMatrix fViewMatrix;
3180432dd6ee62d0c1c1ca67b7f6f6fcf3de75aaf77bsalomon        SkPath fPath;
3190432dd6ee62d0c1c1ca67b7f6f6fcf3de75aaf77bsalomon        SkScalar fStrokeWidth;
3208c170971f182d47bc9af71fc88a607740d03dfd5robertphillips        SkStrokeRec::Style fStyle;
3210432dd6ee62d0c1c1ca67b7f6f6fcf3de75aaf77bsalomon        SkPaint::Join fJoin;
3220432dd6ee62d0c1c1ca67b7f6f6fcf3de75aaf77bsalomon        SkScalar fMiterLimit;
3230432dd6ee62d0c1c1ca67b7f6f6fcf3de75aaf77bsalomon    };
3240432dd6ee62d0c1c1ca67b7f6f6fcf3de75aaf77bsalomon
3251a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas    BatchTracker fBatch;
3261a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas    SkSTArray<1, Geometry, true> fGeoData;
3271b55a963a2374a14bb82eb887bb99ee91680f0ebreed
3281b55a963a2374a14bb82eb887bb99ee91680f0ebreed    typedef GrVertexBatch INHERITED;
3291a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas};
3301a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas
3310aff2fa82a5fa9f99aa77327dac3e9e803b4ed07bsalomonbool GrAALinearizingConvexPathRenderer::onDrawPath(const DrawPathArgs& args) {
3321105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman    GR_AUDIT_TRAIL_AUTO_FRAME(args.fRenderTargetContext->auditTrail(),
333de83b41cc7fc5bd1398e06c011e698215261665fjoshualitt                              "GrAALinearizingConvexPathRenderer::onDrawPath");
3341105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman    SkASSERT(!args.fRenderTargetContext->isUnifiedMultisampled());
3358acedde5970ce70de6d9791ffeda87a65af4ed07bsalomon    SkASSERT(!args.fShape->isEmpty());
3368c170971f182d47bc9af71fc88a607740d03dfd5robertphillips    SkASSERT(!args.fShape->style().pathEffect());
337ecbc12b1c1c72de0cf7bba4a3f6a7cce4f43bf41csmartdalton
3380432dd6ee62d0c1c1ca67b7f6f6fcf3de75aaf77bsalomon    SkPath path;
3390432dd6ee62d0c1c1ca67b7f6f6fcf3de75aaf77bsalomon    args.fShape->asPath(&path);
3408acedde5970ce70de6d9791ffeda87a65af4ed07bsalomon    bool fill = args.fShape->style().isSimpleFill();
3418acedde5970ce70de6d9791ffeda87a65af4ed07bsalomon    const SkStrokeRec& stroke = args.fShape->style().strokeRec();
3420432dd6ee62d0c1c1ca67b7f6f6fcf3de75aaf77bsalomon    SkScalar strokeWidth = fill ? -1.0f : stroke.getWidth();
3430432dd6ee62d0c1c1ca67b7f6f6fcf3de75aaf77bsalomon    SkPaint::Join join = fill ? SkPaint::Join::kMiter_Join : stroke.getJoin();
3440432dd6ee62d0c1c1ca67b7f6f6fcf3de75aaf77bsalomon    SkScalar miterLimit = stroke.getMiter();
3451a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas
3463950f0d7239c05687ac96c211e49ceab9ab9ff4drobertphillips    SkAutoTUnref<GrDrawBatch> batch(new AAFlatteningConvexPathBatch(args.fPaint->getColor(),
3473950f0d7239c05687ac96c211e49ceab9ab9ff4drobertphillips                                                                    *args.fViewMatrix,
3488c170971f182d47bc9af71fc88a607740d03dfd5robertphillips                                                                    path, strokeWidth,
3498c170971f182d47bc9af71fc88a607740d03dfd5robertphillips                                                                    stroke.getStyle(),
3508c170971f182d47bc9af71fc88a607740d03dfd5robertphillips                                                                    join, miterLimit));
351976f5f0dc5e907d1ca50685fad117bd15d7fc87brobertphillips
352bb24383abb724c516e472af4eec68f2c3f17a6d0bsalomon    GrPipelineBuilder pipelineBuilder(*args.fPaint);
353bb24383abb724c516e472af4eec68f2c3f17a6d0bsalomon    pipelineBuilder.setUserStencil(args.fUserStencilSettings);
354bb24383abb724c516e472af4eec68f2c3f17a6d0bsalomon
3551105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman    args.fRenderTargetContext->drawBatch(pipelineBuilder, *args.fClip, batch);
356bb24383abb724c516e472af4eec68f2c3f17a6d0bsalomon
3571a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas    return true;
3581a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas}
3591a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas
3601a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas///////////////////////////////////////////////////////////////////////////////////////////////////
3611a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas
3621a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas#ifdef GR_TEST_UTILS
3631a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas
364abd30f54b7ff1704a8930c4307ea242d09425d02bsalomonDRAW_BATCH_TEST_DEFINE(AAFlatteningConvexPathBatch) {
3650432dd6ee62d0c1c1ca67b7f6f6fcf3de75aaf77bsalomon    GrColor color = GrRandomColor(random);
3660432dd6ee62d0c1c1ca67b7f6f6fcf3de75aaf77bsalomon    SkMatrix viewMatrix = GrTest::TestMatrixInvertible(random);
3670432dd6ee62d0c1c1ca67b7f6f6fcf3de75aaf77bsalomon    SkPath path = GrTest::TestPathConvex(random);
3688c170971f182d47bc9af71fc88a607740d03dfd5robertphillips
3698c170971f182d47bc9af71fc88a607740d03dfd5robertphillips    SkStrokeRec::Style styles[3] = { SkStrokeRec::kFill_Style,
3708c170971f182d47bc9af71fc88a607740d03dfd5robertphillips                                     SkStrokeRec::kStroke_Style,
3718c170971f182d47bc9af71fc88a607740d03dfd5robertphillips                                     SkStrokeRec::kStrokeAndFill_Style };
3728c170971f182d47bc9af71fc88a607740d03dfd5robertphillips
3738c170971f182d47bc9af71fc88a607740d03dfd5robertphillips    SkStrokeRec::Style style = styles[random->nextU() % 3];
3748c170971f182d47bc9af71fc88a607740d03dfd5robertphillips
3758c170971f182d47bc9af71fc88a607740d03dfd5robertphillips    SkScalar strokeWidth = -1.f;
3760432dd6ee62d0c1c1ca67b7f6f6fcf3de75aaf77bsalomon    SkPaint::Join join = SkPaint::kMiter_Join;
3770432dd6ee62d0c1c1ca67b7f6f6fcf3de75aaf77bsalomon    SkScalar miterLimit = 0.5f;
3788c170971f182d47bc9af71fc88a607740d03dfd5robertphillips
3798c170971f182d47bc9af71fc88a607740d03dfd5robertphillips    if (SkStrokeRec::kFill_Style != style) {
3808c170971f182d47bc9af71fc88a607740d03dfd5robertphillips        strokeWidth = random->nextRangeF(1.0f, 10.0f);
3818c170971f182d47bc9af71fc88a607740d03dfd5robertphillips        if (random->nextBool()) {
3828c170971f182d47bc9af71fc88a607740d03dfd5robertphillips            join = SkPaint::kMiter_Join;
3838c170971f182d47bc9af71fc88a607740d03dfd5robertphillips        } else {
3848c170971f182d47bc9af71fc88a607740d03dfd5robertphillips            join = SkPaint::kBevel_Join;
3858c170971f182d47bc9af71fc88a607740d03dfd5robertphillips        }
3868c170971f182d47bc9af71fc88a607740d03dfd5robertphillips        miterLimit = random->nextRangeF(0.5f, 2.0f);
3878c170971f182d47bc9af71fc88a607740d03dfd5robertphillips    }
3888c170971f182d47bc9af71fc88a607740d03dfd5robertphillips
3898c170971f182d47bc9af71fc88a607740d03dfd5robertphillips    return new AAFlatteningConvexPathBatch(color, viewMatrix, path, strokeWidth,
3908c170971f182d47bc9af71fc88a607740d03dfd5robertphillips                                           style, join, miterLimit);
3911a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas}
3921a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas
3931a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas#endif
394