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