GrAALinearizingConvexPathRenderer.cpp revision 1a1b3ac0d4feecb0fefa8a07c7abf3471c96f545
11a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas 21a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas/* 31a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas * Copyright 2015 Google Inc. 41a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas * 51a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas * Use of this source code is governed by a BSD-style license that can be 61a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas * found in the LICENSE file. 71a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas */ 81a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas 91a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas#include "GrAALinearizingConvexPathRenderer.h" 101a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas 111a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas#include "GrAAConvexTessellator.h" 121a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas#include "GrBatch.h" 131a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas#include "GrBatchTarget.h" 141a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas#include "GrBatchTest.h" 151a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas#include "GrContext.h" 161a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas#include "GrDefaultGeoProcFactory.h" 171a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas#include "GrGeometryProcessor.h" 181a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas#include "GrInvariantOutput.h" 191a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas#include "GrPathUtils.h" 201a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas#include "GrProcessor.h" 211a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas#include "GrPipelineBuilder.h" 221a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas#include "GrStrokeInfo.h" 231a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas#include "SkGeometry.h" 241a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas#include "SkString.h" 251a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas#include "SkTraceEvent.h" 261a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas#include "gl/GrGLProcessor.h" 271a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas#include "gl/GrGLSL.h" 281a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas#include "gl/GrGLGeometryProcessor.h" 291a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas#include "gl/builders/GrGLProgramBuilder.h" 301a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas 311a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas#define DEFAULT_BUFFER_SIZE 100 321a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas 331a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholasGrAALinearizingConvexPathRenderer::GrAALinearizingConvexPathRenderer() { 341a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas} 351a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas 361a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas/////////////////////////////////////////////////////////////////////////////// 371a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas 381a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholasbool GrAALinearizingConvexPathRenderer::canDrawPath(const GrDrawTarget* target, 391a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas const GrPipelineBuilder*, 401a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas const SkMatrix& viewMatrix, 411a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas const SkPath& path, 421a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas const GrStrokeInfo& stroke, 431a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas bool antiAlias) const { 441a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas return (antiAlias && stroke.isFillStyle() && !path.isInverseFillType() && path.isConvex()); 451a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas} 461a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas 471a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas// extract the result vertices and indices from the GrAAConvexTessellator 481a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholasstatic void extract_verts(const GrAAConvexTessellator& tess, 491a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas void* vertices, 501a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas size_t vertexStride, 511a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas GrColor color, 521a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas uint16_t firstIndex, 531a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas uint16_t* idxs, 541a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas bool tweakAlphaForCoverage) { 551a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas intptr_t verts = reinterpret_cast<intptr_t>(vertices); 561a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas 571a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas for (int i = 0; i < tess.numPts(); ++i) { 581a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas *((SkPoint*)((intptr_t)verts + i * vertexStride)) = tess.point(i); 591a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas } 601a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas 611a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas // Make 'verts' point to the colors 621a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas verts += sizeof(SkPoint); 631a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas for (int i = 0; i < tess.numPts(); ++i) { 641a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas SkASSERT(tess.depth(i) >= -0.5f && tess.depth(i) <= 0.5f); 651a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas if (tweakAlphaForCoverage) { 661a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas SkASSERT(SkScalarRoundToInt(255.0f * (tess.depth(i) + 0.5f)) <= 255); 671a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas unsigned scale = SkScalarRoundToInt(255.0f * (tess.depth(i) + 0.5f)); 681a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas GrColor scaledColor = (0xff == scale) ? color : SkAlphaMulQ(color, scale); 691a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas *reinterpret_cast<GrColor*>(verts + i * vertexStride) = scaledColor; 701a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas } else { 711a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas *reinterpret_cast<GrColor*>(verts + i * vertexStride) = color; 721a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas *reinterpret_cast<float*>(verts + i * vertexStride + sizeof(GrColor)) = 731a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas tess.depth(i) + 0.5f; 741a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas } 751a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas } 761a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas 771a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas for (int i = 0; i < tess.numIndices(); ++i) { 781a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas idxs[i] = tess.index(i) + firstIndex; 791a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas } 801a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas} 811a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas 821a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholasstatic const GrGeometryProcessor* create_fill_gp(bool tweakAlphaForCoverage, 831a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas const SkMatrix& localMatrix, 841a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas bool usesLocalCoords, 851a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas bool coverageIgnored) { 861a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas uint32_t flags = GrDefaultGeoProcFactory::kColor_GPType; 871a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas if (!tweakAlphaForCoverage) { 881a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas flags |= GrDefaultGeoProcFactory::kCoverage_GPType; 891a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas } 901a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas 911a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas return GrDefaultGeoProcFactory::Create(flags, GrColor_WHITE, usesLocalCoords, coverageIgnored, 921a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas SkMatrix::I(), localMatrix); 931a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas} 941a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas 951a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholasclass AAFlatteningConvexPathBatch : public GrBatch { 961a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholaspublic: 971a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas struct Geometry { 981a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas GrColor fColor; 991a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas SkMatrix fViewMatrix; 1001a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas SkPath fPath; 1011a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas }; 1021a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas 1031a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas static GrBatch* Create(const Geometry& geometry) { 1041a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas return SkNEW_ARGS(AAFlatteningConvexPathBatch, (geometry)); 1051a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas } 1061a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas 1071a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas const char* name() const override { return "AAConvexBatch"; } 1081a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas 1091a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas void getInvariantOutputColor(GrInitInvariantOutput* out) const override { 1101a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas // When this is called on a batch, there is only one geometry bundle 1111a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas out->setKnownFourComponents(fGeoData[0].fColor); 1121a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas } 1131a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override { 1141a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas out->setUnknownSingleComponent(); 1151a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas } 1161a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas 1171a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas void initBatchTracker(const GrPipelineInfo& init) override { 1181a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas // Handle any color overrides 1191a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas if (init.fColorIgnored) { 1201a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas fGeoData[0].fColor = GrColor_ILLEGAL; 1211a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas } else if (GrColor_ILLEGAL != init.fOverrideColor) { 1221a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas fGeoData[0].fColor = init.fOverrideColor; 1231a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas } 1241a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas 1251a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas // setup batch properties 1261a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas fBatch.fColorIgnored = init.fColorIgnored; 1271a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas fBatch.fColor = fGeoData[0].fColor; 1281a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas fBatch.fUsesLocalCoords = init.fUsesLocalCoords; 1291a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas fBatch.fCoverageIgnored = init.fCoverageIgnored; 1301a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas fBatch.fLinesOnly = SkPath::kLine_SegmentMask == fGeoData[0].fPath.getSegmentMasks(); 1311a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas fBatch.fCanTweakAlphaForCoverage = init.fCanTweakAlphaForCoverage; 1321a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas } 1331a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas 1341a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas void draw(GrBatchTarget* batchTarget, const GrPipeline* pipeline, int vertexCount, 1351a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas size_t vertexStride, void* vertices, int indexCount, uint16_t* indices) { 1361a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas if (vertexCount == 0 || indexCount == 0) { 1371a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas return; 1381a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas } 1391a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas const GrVertexBuffer* vertexBuffer; 1401a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas GrVertices info; 1411a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas int firstVertex; 1421a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas void* verts = batchTarget->makeVertSpace(vertexStride, vertexCount, &vertexBuffer, 1431a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas &firstVertex); 1441a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas if (!verts) { 1451a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas SkDebugf("Could not allocate vertices\n"); 1461a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas return; 1471a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas } 1481a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas memcpy(verts, vertices, vertexCount * vertexStride); 1491a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas 1501a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas const GrIndexBuffer* indexBuffer; 1511a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas int firstIndex; 1521a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas uint16_t* idxs = batchTarget->makeIndexSpace(indexCount, &indexBuffer, &firstIndex); 1531a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas if (!idxs) { 1541a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas SkDebugf("Could not allocate indices\n"); 1551a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas return; 1561a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas } 1571a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas memcpy(idxs, indices, indexCount * sizeof(uint16_t)); 1581a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas info.initIndexed(kTriangles_GrPrimitiveType, vertexBuffer, indexBuffer, firstVertex, 1591a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas firstIndex, vertexCount, indexCount); 1601a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas batchTarget->draw(info); 1611a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas } 1621a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas 1631a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas void generateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline) override { 1641a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas bool canTweakAlphaForCoverage = this->canTweakAlphaForCoverage(); 1651a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas 1661a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas SkMatrix invert; 1671a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas if (this->usesLocalCoords() && !this->viewMatrix().invert(&invert)) { 1681a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas SkDebugf("Could not invert viewmatrix\n"); 1691a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas return; 1701a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas } 1711a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas 1721a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas // Setup GrGeometryProcessor 1731a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas SkAutoTUnref<const GrGeometryProcessor> gp( 1741a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas create_fill_gp(canTweakAlphaForCoverage, invert, 1751a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas this->usesLocalCoords(), 1761a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas this->coverageIgnored())); 1771a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas 1781a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas batchTarget->initDraw(gp, pipeline); 1791a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas 1801a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas size_t vertexStride = gp->getVertexStride(); 1811a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas 1821a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas SkASSERT(canTweakAlphaForCoverage ? 1831a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorAttr) : 1841a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorCoverageAttr)); 1851a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas 1861a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas GrAAConvexTessellator tess; 1871a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas 1881a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas int instanceCount = fGeoData.count(); 1891a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas 1901a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas int vertexCount = 0; 1911a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas int indexCount = 0; 1921a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas int maxVertices = DEFAULT_BUFFER_SIZE; 1931a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas int maxIndices = DEFAULT_BUFFER_SIZE; 1941a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas uint8_t* vertices = (uint8_t*) malloc(maxVertices * vertexStride); 1951a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas uint16_t* indices = (uint16_t*) malloc(maxIndices * sizeof(uint16_t)); 1961a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas for (int i = 0; i < instanceCount; i++) { 1971a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas tess.rewind(); 1981a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas 1991a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas Geometry& args = fGeoData[i]; 2001a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas 2011a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas if (!tess.tessellate(args.fViewMatrix, args.fPath)) { 2021a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas continue; 2031a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas } 2041a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas 2051a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas int currentIndices = tess.numIndices(); 2061a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas SkASSERT(currentIndices <= UINT16_MAX); 2071a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas if (indexCount + currentIndices > UINT16_MAX) { 2081a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas // if we added the current instance, we would overflow the indices we can store in a 2091a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas // uint16_t. Draw what we've got so far and reset. 2101a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas draw(batchTarget, pipeline, vertexCount, vertexStride, vertices, indexCount, 2111a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas indices); 2121a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas vertexCount = 0; 2131a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas indexCount = 0; 2141a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas } 2151a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas int currentVertices = tess.numPts(); 2161a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas if (vertexCount + currentVertices > maxVertices) { 2171a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas maxVertices = SkTMax(vertexCount + currentVertices, maxVertices * 2); 2181a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas vertices = (uint8_t*) realloc(vertices, maxVertices * vertexStride); 2191a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas } 2201a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas if (indexCount + currentIndices > maxIndices) { 2211a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas maxIndices = SkTMax(indexCount + currentIndices, maxIndices * 2); 2221a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas indices = (uint16_t*) realloc(indices, maxIndices * sizeof(uint16_t)); 2231a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas } 2241a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas 2251a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas extract_verts(tess, vertices + vertexStride * vertexCount, vertexStride, args.fColor, 2261a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas vertexCount, indices + indexCount, canTweakAlphaForCoverage); 2271a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas vertexCount += currentVertices; 2281a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas indexCount += currentIndices; 2291a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas } 2301a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas draw(batchTarget, pipeline, vertexCount, vertexStride, vertices, indexCount, indices); 2311a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas free(vertices); 2321a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas free(indices); 2331a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas } 2341a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas 2351a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } 2361a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas 2371a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholasprivate: 2381a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas AAFlatteningConvexPathBatch(const Geometry& geometry) { 2391a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas this->initClassID<AAFlatteningConvexPathBatch>(); 2401a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas fGeoData.push_back(geometry); 2411a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas 2421a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas // compute bounds 2431a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas fBounds = geometry.fPath.getBounds(); 2441a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas geometry.fViewMatrix.mapRect(&fBounds); 2451a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas } 2461a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas 2471a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas bool onCombineIfPossible(GrBatch* t) override { 2481a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas AAFlatteningConvexPathBatch* that = t->cast<AAFlatteningConvexPathBatch>(); 2491a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas 2501a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas SkASSERT(this->usesLocalCoords() == that->usesLocalCoords()); 2511a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas if (this->usesLocalCoords() && !this->viewMatrix().cheapEqualTo(that->viewMatrix())) { 2521a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas return false; 2531a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas } 2541a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas 2551a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas // In the event of two batches, one who can tweak, one who cannot, we just fall back to 2561a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas // not tweaking 2571a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas if (this->canTweakAlphaForCoverage() != that->canTweakAlphaForCoverage()) { 2581a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas fBatch.fCanTweakAlphaForCoverage = false; 2591a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas } 2601a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas 2611a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin()); 2621a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas this->joinBounds(that->bounds()); 2631a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas return true; 2641a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas } 2651a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas 2661a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas GrColor color() const { return fBatch.fColor; } 2671a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas bool linesOnly() const { return fBatch.fLinesOnly; } 2681a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; } 2691a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas bool canTweakAlphaForCoverage() const { return fBatch.fCanTweakAlphaForCoverage; } 2701a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas const SkMatrix& viewMatrix() const { return fGeoData[0].fViewMatrix; } 2711a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas bool coverageIgnored() const { return fBatch.fCoverageIgnored; } 2721a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas 2731a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas struct BatchTracker { 2741a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas GrColor fColor; 2751a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas bool fUsesLocalCoords; 2761a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas bool fColorIgnored; 2771a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas bool fCoverageIgnored; 2781a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas bool fLinesOnly; 2791a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas bool fCanTweakAlphaForCoverage; 2801a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas }; 2811a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas 2821a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas BatchTracker fBatch; 2831a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas SkSTArray<1, Geometry, true> fGeoData; 2841a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas}; 2851a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas 2861a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholasbool GrAALinearizingConvexPathRenderer::onDrawPath(GrDrawTarget* target, 2871a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas GrPipelineBuilder* pipelineBuilder, 2881a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas GrColor color, 2891a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas const SkMatrix& vm, 2901a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas const SkPath& path, 2911a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas const GrStrokeInfo&, 2921a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas bool antiAlias) { 2931a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas if (path.isEmpty()) { 2941a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas return true; 2951a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas } 2961a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas AAFlatteningConvexPathBatch::Geometry geometry; 2971a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas geometry.fColor = color; 2981a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas geometry.fViewMatrix = vm; 2991a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas geometry.fPath = path; 3001a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas 3011a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas SkAutoTUnref<GrBatch> batch(AAFlatteningConvexPathBatch::Create(geometry)); 3021a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas target->drawBatch(pipelineBuilder, batch); 3031a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas 3041a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas return true; 3051a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas} 3061a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas 3071a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas/////////////////////////////////////////////////////////////////////////////////////////////////// 3081a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas 3091a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas#ifdef GR_TEST_UTILS 3101a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas 3111a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholasBATCH_TEST_DEFINE(AAFlatteningConvexPathBatch) { 3121a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas AAFlatteningConvexPathBatch::Geometry geometry; 3131a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas geometry.fColor = GrRandomColor(random); 3141a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas geometry.fViewMatrix = GrTest::TestMatrixInvertible(random); 3151a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas geometry.fPath = GrTest::TestPathConvex(random); 3161a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas 3171a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas return AAFlatteningConvexPathBatch::Create(geometry); 3181a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas} 3191a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas 3201a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas#endif 321