GrAAConvexPathRenderer.cpp revision 278dc6929b6481204874dcfcc055e2aaa30a95b2
1fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin 2fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin/* 3fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin * Copyright 2012 Google Inc. 4fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin * 5fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin * Use of this source code is governed by a BSD-style license that can be 6fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin * found in the LICENSE file. 7fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin */ 8fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin 9fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin#include "GrAAConvexPathRenderer.h" 10fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin 11fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin#include "GrContext.h" 12fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin#include "GrDrawState.h" 13fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin#include "GrPathUtils.h" 14fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin#include "SkString.h" 15fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin#include "SkTrace.h" 16fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin 17fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin 18fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz ZavinGrAAConvexPathRenderer::GrAAConvexPathRenderer() { 19fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin} 20fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin 21fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavinbool GrAAConvexPathRenderer::canDrawPath(const GrDrawTarget::Caps& targetCaps, 22fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin const SkPath& path, 23fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin GrPathFill fill, 24fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin bool antiAlias) const { 25b65f253fdc60f6208a54911bee793d225f23cdf8James Dong return targetCaps.fShaderDerivativeSupport && antiAlias && 26fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin kHairLine_PathFill != fill && !GrIsFillInverted(fill) && 27fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin path.isConvex(); 28fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin} 29fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin 30fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavinnamespace { 31b65f253fdc60f6208a54911bee793d225f23cdf8James Dong 32fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavinstruct Segment { 33fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin enum { 34fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin kLine, 35fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin kQuad 36fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin } fType; 37fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin // line uses one pt, quad uses 2 pts 38fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin GrPoint fPts[2]; 39b65f253fdc60f6208a54911bee793d225f23cdf8James Dong // normal to edge ending at each pt 40b65f253fdc60f6208a54911bee793d225f23cdf8James Dong GrVec fNorms[2]; 41b65f253fdc60f6208a54911bee793d225f23cdf8James Dong // is the corner where the previous segment meets this segment 42fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin // sharp. If so, fMid is a normalized bisector facing outward. 43fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin GrVec fMid; 44b65f253fdc60f6208a54911bee793d225f23cdf8James Dong 45b65f253fdc60f6208a54911bee793d225f23cdf8James Dong int countPoints() { 46fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin return (kLine == fType) ? 1 : 2; 47fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin } 48fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin const SkPoint& endPt() const { 49fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin return (kLine == fType) ? fPts[0] : fPts[1]; 50b65f253fdc60f6208a54911bee793d225f23cdf8James Dong }; 51fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin const SkPoint& endNorm() const { 52fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin return (kLine == fType) ? fNorms[0] : fNorms[1]; 53b65f253fdc60f6208a54911bee793d225f23cdf8James Dong }; 54fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin}; 55fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin 56fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavintypedef SkTArray<Segment, true> SegmentArray; 57fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin 58fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavinvoid center_of_mass(const SegmentArray& segments, SkPoint* c) { 59fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin GrScalar area = 0; 60fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin SkPoint center; 61fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin center.set(0, 0); 62fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin int count = segments.count(); 63fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin for (int i = 0; i < count; ++i) { 64fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin const SkPoint& pi = segments[i].endPt(); 65fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin int j = (i + 1) % count; 66fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin const SkPoint& pj = segments[j].endPt(); 67fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin GrScalar t = GrMul(pi.fX, pj.fY) - GrMul(pj.fX, pi.fY); 68fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin area += t; 69fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin center.fX += (pi.fX + pj.fX) * t; 70fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin center.fY += (pi.fY + pj.fY) * t; 71fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin } 72fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin // If the poly has no area then we instead return the average of 73fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin // its points. 74fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin if (SkScalarAbs(area) < SK_ScalarNearlyZero) { 75fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin SkPoint avg; 76fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin avg.set(0, 0); 77fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin for (int i = 0; i < count; ++i) { 78fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin const SkPoint& pt = segments[i].endPt(); 79fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin avg.fX += pt.fX; 80fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin avg.fY += pt.fY; 81fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin } 82fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin SkScalar denom = SK_Scalar1 / count; 83fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin avg.scale(denom); 84b65f253fdc60f6208a54911bee793d225f23cdf8James Dong *c = avg; 85b65f253fdc60f6208a54911bee793d225f23cdf8James Dong } else { 86b65f253fdc60f6208a54911bee793d225f23cdf8James Dong area *= 3; 87b65f253fdc60f6208a54911bee793d225f23cdf8James Dong area = GrScalarDiv(GR_Scalar1, area); 88b65f253fdc60f6208a54911bee793d225f23cdf8James Dong center.fX = GrScalarMul(center.fX, area); 896bf5fadc2cc19bc298c4e998657e35cf03644d3dJames Dong center.fY = GrScalarMul(center.fY, area); 906bf5fadc2cc19bc298c4e998657e35cf03644d3dJames Dong *c = center; 916bf5fadc2cc19bc298c4e998657e35cf03644d3dJames Dong } 926bf5fadc2cc19bc298c4e998657e35cf03644d3dJames Dong GrAssert(!SkScalarIsNaN(c->fX) && !SkScalarIsNaN(c->fY)); 93fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin} 94fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin 95fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavinvoid compute_vectors(SegmentArray* segments, 96fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin SkPoint* fanPt, 97fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin SkPath::Direction dir, 98fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin int* vCount, 99fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin int* iCount) { 100fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin center_of_mass(*segments, fanPt); 101fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin int count = segments->count(); 102fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin 103fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin // Make the normals point towards the outside 104fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin GrPoint::Side normSide; 105fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin if (dir == SkPath::kCCW_Direction) { 106fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin normSide = GrPoint::kRight_Side; 107fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin } else { 108fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin normSide = GrPoint::kLeft_Side; 109fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin } 110fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin 111fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin *vCount = 0; 112fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin *iCount = 0; 113fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin // compute normals at all points 114fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin for (int a = 0; a < count; ++a) { 115fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin const Segment& sega = (*segments)[a]; 116fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin int b = (a + 1) % count; 117fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin Segment& segb = (*segments)[b]; 118fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin 119fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin const GrPoint* prevPt = &sega.endPt(); 120fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin int n = segb.countPoints(); 121fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin for (int p = 0; p < n; ++p) { 122fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin segb.fNorms[p] = segb.fPts[p] - *prevPt; 123fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin segb.fNorms[p].normalize(); 124fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin segb.fNorms[p].setOrthog(segb.fNorms[p], normSide); 125fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin prevPt = &segb.fPts[p]; 126fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin } 127fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin if (Segment::kLine == segb.fType) { 128fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin *vCount += 5; 129fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin *iCount += 9; 130fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin } else { 131fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin *vCount += 6; 132fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin *iCount += 12; 133fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin } 134fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin } 135fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin 136fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin // compute mid-vectors where segments meet. TODO: Detect shallow corners 137b65f253fdc60f6208a54911bee793d225f23cdf8James Dong // and leave out the wedges and close gaps by stitching segments together. 138b65f253fdc60f6208a54911bee793d225f23cdf8James Dong for (int a = 0; a < count; ++a) { 139b65f253fdc60f6208a54911bee793d225f23cdf8James Dong const Segment& sega = (*segments)[a]; 140b65f253fdc60f6208a54911bee793d225f23cdf8James Dong int b = (a + 1) % count; 141b65f253fdc60f6208a54911bee793d225f23cdf8James Dong Segment& segb = (*segments)[b]; 142b65f253fdc60f6208a54911bee793d225f23cdf8James Dong segb.fMid = segb.fNorms[0] + sega.endNorm(); 143b65f253fdc60f6208a54911bee793d225f23cdf8James Dong segb.fMid.normalize(); 144b65f253fdc60f6208a54911bee793d225f23cdf8James Dong // corner wedges 145b65f253fdc60f6208a54911bee793d225f23cdf8James Dong *vCount += 4; 146b65f253fdc60f6208a54911bee793d225f23cdf8James Dong *iCount += 6; 147b65f253fdc60f6208a54911bee793d225f23cdf8James Dong } 148b65f253fdc60f6208a54911bee793d225f23cdf8James Dong} 149b65f253fdc60f6208a54911bee793d225f23cdf8James Dong 150b65f253fdc60f6208a54911bee793d225f23cdf8James Dongstruct DegenerateTestData { 151b65f253fdc60f6208a54911bee793d225f23cdf8James Dong DegenerateTestData() { fStage = kInitial; } 152b65f253fdc60f6208a54911bee793d225f23cdf8James Dong bool isDegenerate() const { return kNonDegenerate != fStage; } 153b65f253fdc60f6208a54911bee793d225f23cdf8James Dong enum { 154b65f253fdc60f6208a54911bee793d225f23cdf8James Dong kInitial, 155b65f253fdc60f6208a54911bee793d225f23cdf8James Dong kPoint, 156b65f253fdc60f6208a54911bee793d225f23cdf8James Dong kLine, 157b65f253fdc60f6208a54911bee793d225f23cdf8James Dong kNonDegenerate 158b65f253fdc60f6208a54911bee793d225f23cdf8James Dong } fStage; 159b65f253fdc60f6208a54911bee793d225f23cdf8James Dong GrPoint fFirstPoint; 160b65f253fdc60f6208a54911bee793d225f23cdf8James Dong GrVec fLineNormal; 161b65f253fdc60f6208a54911bee793d225f23cdf8James Dong GrScalar fLineC; 162b65f253fdc60f6208a54911bee793d225f23cdf8James Dong}; 163b65f253fdc60f6208a54911bee793d225f23cdf8James Dong 164b65f253fdc60f6208a54911bee793d225f23cdf8James Dongvoid update_degenerate_test(DegenerateTestData* data, const GrPoint& pt) { 165b65f253fdc60f6208a54911bee793d225f23cdf8James Dong static const SkScalar TOL = (SK_Scalar1 / 16); 166b65f253fdc60f6208a54911bee793d225f23cdf8James Dong static const SkScalar TOL_SQD = SkScalarMul(TOL, TOL); 167fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin 168fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin switch (data->fStage) { 169b65f253fdc60f6208a54911bee793d225f23cdf8James Dong case DegenerateTestData::kInitial: 170b65f253fdc60f6208a54911bee793d225f23cdf8James Dong data->fFirstPoint = pt; 171b65f253fdc60f6208a54911bee793d225f23cdf8James Dong data->fStage = DegenerateTestData::kPoint; 172b65f253fdc60f6208a54911bee793d225f23cdf8James Dong break; 173b65f253fdc60f6208a54911bee793d225f23cdf8James Dong case DegenerateTestData::kPoint: 174b65f253fdc60f6208a54911bee793d225f23cdf8James Dong if (pt.distanceToSqd(data->fFirstPoint) > TOL_SQD) { 175b65f253fdc60f6208a54911bee793d225f23cdf8James Dong data->fLineNormal = pt - data->fFirstPoint; 176b65f253fdc60f6208a54911bee793d225f23cdf8James Dong data->fLineNormal.normalize(); 177b65f253fdc60f6208a54911bee793d225f23cdf8James Dong data->fLineNormal.setOrthog(data->fLineNormal); 178fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin data->fLineC = -data->fLineNormal.dot(data->fFirstPoint); 179fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin data->fStage = DegenerateTestData::kLine; 180fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin } 181fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin break; 182fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin case DegenerateTestData::kLine: 183fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin if (SkScalarAbs(data->fLineNormal.dot(pt) + data->fLineC) > TOL) { 184fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin data->fStage = DegenerateTestData::kNonDegenerate; 185fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin } 186b65f253fdc60f6208a54911bee793d225f23cdf8James Dong case DegenerateTestData::kNonDegenerate: 187b65f253fdc60f6208a54911bee793d225f23cdf8James Dong break; 188fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin default: 189b65f253fdc60f6208a54911bee793d225f23cdf8James Dong GrCrash("Unexpected degenerate test stage."); 190fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin } 191fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin} 192fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin 193fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavinbool get_segments(const GrPath& path, 194fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin SegmentArray* segments, 195fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin SkPoint* fanPt, 196fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin int* vCount, 197b65f253fdc60f6208a54911bee793d225f23cdf8James Dong int* iCount) { 198b65f253fdc60f6208a54911bee793d225f23cdf8James Dong SkPath::Iter iter(path, true); 199fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin // This renderer overemphasises very thin path regions. We use the distance 200fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin // to the path from the sample to compute coverage. Every pixel intersected 201fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin // by the path will be hit and the maximum distance is sqrt(2)/2. We don't 202b65f253fdc60f6208a54911bee793d225f23cdf8James Dong // notice that the sample may be close to a very thin area of the path and 203fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin // thus should be very light. This is particularly egregious for degenerate 204fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin // line paths. We detect paths that are very close to a line (zero area) and 205b65f253fdc60f6208a54911bee793d225f23cdf8James Dong // draw nothing. 206fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin DegenerateTestData degenerateData; 207fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin 208fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin for (;;) { 209fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin GrPoint pts[4]; 210fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin GrPathCmd cmd = (GrPathCmd)iter.next(pts); 211fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin switch (cmd) { 212fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin case kMove_PathCmd: 213fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin update_degenerate_test(°enerateData, pts[0]); 214fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin break; 215fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin case kLine_PathCmd: { 216fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin update_degenerate_test(°enerateData, pts[1]); 217fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin segments->push_back(); 218b65f253fdc60f6208a54911bee793d225f23cdf8James Dong segments->back().fType = Segment::kLine; 219fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin segments->back().fPts[0] = pts[1]; 220b65f253fdc60f6208a54911bee793d225f23cdf8James Dong break; 221fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin } 222fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin case kQuadratic_PathCmd: 223fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin update_degenerate_test(°enerateData, pts[1]); 224fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin update_degenerate_test(°enerateData, pts[2]); 225fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin segments->push_back(); 226fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin segments->back().fType = Segment::kQuad; 227fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin segments->back().fPts[0] = pts[1]; 228fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin segments->back().fPts[1] = pts[2]; 229fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin break; 230b65f253fdc60f6208a54911bee793d225f23cdf8James Dong case kCubic_PathCmd: { 231fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin update_degenerate_test(°enerateData, pts[1]); 232fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin update_degenerate_test(°enerateData, pts[2]); 233fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin update_degenerate_test(°enerateData, pts[3]); 234fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin SkSTArray<15, SkPoint, true> quads; 235b65f253fdc60f6208a54911bee793d225f23cdf8James Dong GrPathUtils::convertCubicToQuads(pts, SK_Scalar1, &quads); 236fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin int count = quads.count(); 237fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin for (int q = 0; q < count; q += 3) { 238fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin segments->push_back(); 239fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin segments->back().fType = Segment::kQuad; 240b65f253fdc60f6208a54911bee793d225f23cdf8James Dong segments->back().fPts[0] = quads[q + 1]; 241fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin segments->back().fPts[1] = quads[q + 2]; 242fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin } 243fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin break; 244fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin }; 245fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin case kEnd_PathCmd: 246b65f253fdc60f6208a54911bee793d225f23cdf8James Dong if (degenerateData.isDegenerate()) { 247fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin return false; 248fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin } else { 249fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin SkPath::Direction dir; 250fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin GR_DEBUGCODE(bool succeeded = ) 251fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin path.cheapComputeDirection(&dir); 252fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin GrAssert(succeeded); 253fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin compute_vectors(segments, fanPt, dir, vCount, iCount); 254fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin return true; 255fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin } 256fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin default: 257fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin break; 258fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin } 259b65f253fdc60f6208a54911bee793d225f23cdf8James Dong } 260b65f253fdc60f6208a54911bee793d225f23cdf8James Dong} 261b65f253fdc60f6208a54911bee793d225f23cdf8James Dong 262fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavinstruct QuadVertex { 263fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin GrPoint fPos; 264fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin GrPoint fUV; 265b65f253fdc60f6208a54911bee793d225f23cdf8James Dong GrScalar fD0; 266fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin GrScalar fD1; 267fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin}; 268fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin 269fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavinvoid create_vertices(const SegmentArray& segments, 270fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin const SkPoint& fanPt, 271fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin QuadVertex* verts, 272fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin uint16_t* idxs) { 273fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin int v = 0; 274fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin int i = 0; 275fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin 276fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin int count = segments.count(); 277fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin for (int a = 0; a < count; ++a) { 278fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin const Segment& sega = segments[a]; 279fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin int b = (a + 1) % count; 280fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin const Segment& segb = segments[b]; 281fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin 282fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin // FIXME: These tris are inset in the 1 unit arc around the corner 283fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin verts[v + 0].fPos = sega.endPt(); 284fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin verts[v + 1].fPos = verts[v + 0].fPos + sega.endNorm(); 285fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin verts[v + 2].fPos = verts[v + 0].fPos + segb.fMid; 286fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin verts[v + 3].fPos = verts[v + 0].fPos + segb.fNorms[0]; 287fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin verts[v + 0].fUV.set(0,0); 288fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin verts[v + 1].fUV.set(0,-SK_Scalar1); 289fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin verts[v + 2].fUV.set(0,-SK_Scalar1); 290fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin verts[v + 3].fUV.set(0,-SK_Scalar1); 291fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin verts[v + 0].fD0 = verts[v + 0].fD1 = -SK_Scalar1; 292fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin verts[v + 1].fD0 = verts[v + 1].fD1 = -SK_Scalar1; 293fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin verts[v + 2].fD0 = verts[v + 2].fD1 = -SK_Scalar1; 294fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin verts[v + 3].fD0 = verts[v + 3].fD1 = -SK_Scalar1; 295fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin 296fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin idxs[i + 0] = v + 0; 297fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin idxs[i + 1] = v + 2; 298fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin idxs[i + 2] = v + 1; 299b65f253fdc60f6208a54911bee793d225f23cdf8James Dong idxs[i + 3] = v + 0; 300b65f253fdc60f6208a54911bee793d225f23cdf8James Dong idxs[i + 4] = v + 3; 301b65f253fdc60f6208a54911bee793d225f23cdf8James Dong idxs[i + 5] = v + 2; 302b65f253fdc60f6208a54911bee793d225f23cdf8James Dong 303fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin v += 4; 304fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin i += 6; 305fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin 306fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin if (Segment::kLine == segb.fType) { 307fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin verts[v + 0].fPos = fanPt; 308fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin verts[v + 1].fPos = sega.endPt(); 309fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin verts[v + 2].fPos = segb.fPts[0]; 310fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin 311fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin verts[v + 3].fPos = verts[v + 1].fPos + segb.fNorms[0]; 312fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin verts[v + 4].fPos = verts[v + 2].fPos + segb.fNorms[0]; 313fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin 314fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin // we draw the line edge as a degenerate quad (u is 0, v is the 315fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin // signed distance to the edge) 316b65f253fdc60f6208a54911bee793d225f23cdf8James Dong GrScalar dist = fanPt.distanceToLineBetween(verts[v + 1].fPos, 317fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin verts[v + 2].fPos); 318fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin verts[v + 0].fUV.set(0, dist); 319fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin verts[v + 1].fUV.set(0, 0); 320b65f253fdc60f6208a54911bee793d225f23cdf8James Dong verts[v + 2].fUV.set(0, 0); 321b65f253fdc60f6208a54911bee793d225f23cdf8James Dong verts[v + 3].fUV.set(0, -SK_Scalar1); 322b65f253fdc60f6208a54911bee793d225f23cdf8James Dong verts[v + 4].fUV.set(0, -SK_Scalar1); 323b65f253fdc60f6208a54911bee793d225f23cdf8James Dong 324b65f253fdc60f6208a54911bee793d225f23cdf8James Dong verts[v + 0].fD0 = verts[v + 0].fD1 = -SK_Scalar1; 325fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin verts[v + 1].fD0 = verts[v + 1].fD1 = -SK_Scalar1; 326b65f253fdc60f6208a54911bee793d225f23cdf8James Dong verts[v + 2].fD0 = verts[v + 2].fD1 = -SK_Scalar1; 327fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin verts[v + 3].fD0 = verts[v + 3].fD1 = -SK_Scalar1; 328fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin verts[v + 4].fD0 = verts[v + 4].fD1 = -SK_Scalar1; 329fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin 330fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin idxs[i + 0] = v + 0; 331fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin idxs[i + 1] = v + 2; 332fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin idxs[i + 2] = v + 1; 333fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin 334fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin idxs[i + 3] = v + 3; 335fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin idxs[i + 4] = v + 1; 33624ef98f0d3b5d00b1d30c8ebf0791ef708170a32James Dong idxs[i + 5] = v + 2; 337fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin 33824ef98f0d3b5d00b1d30c8ebf0791ef708170a32James Dong idxs[i + 6] = v + 4; 33924ef98f0d3b5d00b1d30c8ebf0791ef708170a32James Dong idxs[i + 7] = v + 3; 34024ef98f0d3b5d00b1d30c8ebf0791ef708170a32James Dong idxs[i + 8] = v + 2; 341b65f253fdc60f6208a54911bee793d225f23cdf8James Dong 342fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin v += 5; 343fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin i += 9; 34424ef98f0d3b5d00b1d30c8ebf0791ef708170a32James Dong } else { 345fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin GrPoint qpts[] = {sega.endPt(), segb.fPts[0], segb.fPts[1]}; 34624ef98f0d3b5d00b1d30c8ebf0791ef708170a32James Dong 34724ef98f0d3b5d00b1d30c8ebf0791ef708170a32James Dong GrVec midVec = segb.fNorms[0] + segb.fNorms[1]; 34824ef98f0d3b5d00b1d30c8ebf0791ef708170a32James Dong midVec.normalize(); 34924ef98f0d3b5d00b1d30c8ebf0791ef708170a32James Dong 350fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin verts[v + 0].fPos = fanPt; 35124ef98f0d3b5d00b1d30c8ebf0791ef708170a32James Dong verts[v + 1].fPos = qpts[0]; 35285e28eec8163c776f2f3a093f4053a96ed2d6f98Steve Block verts[v + 2].fPos = qpts[2]; 35324ef98f0d3b5d00b1d30c8ebf0791ef708170a32James Dong verts[v + 3].fPos = qpts[0] + segb.fNorms[0]; 354b65f253fdc60f6208a54911bee793d225f23cdf8James Dong verts[v + 4].fPos = qpts[2] + segb.fNorms[1]; 35524ef98f0d3b5d00b1d30c8ebf0791ef708170a32James Dong verts[v + 5].fPos = qpts[1] + midVec; 35624ef98f0d3b5d00b1d30c8ebf0791ef708170a32James Dong 35724ef98f0d3b5d00b1d30c8ebf0791ef708170a32James Dong GrScalar c = segb.fNorms[0].dot(qpts[0]); 35824ef98f0d3b5d00b1d30c8ebf0791ef708170a32James Dong verts[v + 0].fD0 = -segb.fNorms[0].dot(fanPt) + c; 35924ef98f0d3b5d00b1d30c8ebf0791ef708170a32James Dong verts[v + 1].fD0 = 0.f; 36024ef98f0d3b5d00b1d30c8ebf0791ef708170a32James Dong verts[v + 2].fD0 = -segb.fNorms[0].dot(qpts[2]) + c; 361fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin verts[v + 3].fD0 = -GR_ScalarMax/100; 36224ef98f0d3b5d00b1d30c8ebf0791ef708170a32James Dong verts[v + 4].fD0 = -GR_ScalarMax/100; 36324ef98f0d3b5d00b1d30c8ebf0791ef708170a32James Dong verts[v + 5].fD0 = -GR_ScalarMax/100; 36424ef98f0d3b5d00b1d30c8ebf0791ef708170a32James Dong 36524ef98f0d3b5d00b1d30c8ebf0791ef708170a32James Dong c = segb.fNorms[1].dot(qpts[2]); 36624ef98f0d3b5d00b1d30c8ebf0791ef708170a32James Dong verts[v + 0].fD1 = -segb.fNorms[1].dot(fanPt) + c; 36724ef98f0d3b5d00b1d30c8ebf0791ef708170a32James Dong verts[v + 1].fD1 = -segb.fNorms[1].dot(qpts[0]) + c; 36885e28eec8163c776f2f3a093f4053a96ed2d6f98Steve Block verts[v + 2].fD1 = 0.f; 369fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin verts[v + 3].fD1 = -GR_ScalarMax/100; 37024ef98f0d3b5d00b1d30c8ebf0791ef708170a32James Dong verts[v + 4].fD1 = -GR_ScalarMax/100; 371fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin verts[v + 5].fD1 = -GR_ScalarMax/100; 372fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin 373fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin GrMatrix toUV; 374fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin GrPathUtils::quadDesignSpaceToUVCoordsMatrix(qpts, &toUV); 375fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin toUV.mapPointsWithStride(&verts[v].fUV, 376fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin &verts[v].fPos, 377fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin sizeof(QuadVertex), 378fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin 6); 379fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin 380fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin idxs[i + 0] = v + 3; 381fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin idxs[i + 1] = v + 1; 382fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin idxs[i + 2] = v + 2; 383b65f253fdc60f6208a54911bee793d225f23cdf8James Dong idxs[i + 3] = v + 4; 384fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin idxs[i + 4] = v + 3; 385fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin idxs[i + 5] = v + 2; 386fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin 387fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin idxs[i + 6] = v + 5; 388b65f253fdc60f6208a54911bee793d225f23cdf8James Dong idxs[i + 7] = v + 3; 389fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin idxs[i + 8] = v + 4; 390b65f253fdc60f6208a54911bee793d225f23cdf8James Dong 391b65f253fdc60f6208a54911bee793d225f23cdf8James Dong idxs[i + 9] = v + 0; 392b65f253fdc60f6208a54911bee793d225f23cdf8James Dong idxs[i + 10] = v + 2; 393b65f253fdc60f6208a54911bee793d225f23cdf8James Dong idxs[i + 11] = v + 1; 394fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin 395fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin v += 6; 396b65f253fdc60f6208a54911bee793d225f23cdf8James Dong i += 12; 397fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin } 398fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin } 399fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin} 400fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin 401fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin} 402fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin 403fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavinvoid GrAAConvexPathRenderer::drawPath(GrDrawState::StageMask stageMask) { 404fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin GrAssert(fPath->isConvex()); 405fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin if (fPath->isEmpty()) { 406fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin return; 407b65f253fdc60f6208a54911bee793d225f23cdf8James Dong } 408fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin GrDrawState* drawState = fTarget->drawState(); 409fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin 410fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin GrDrawTarget::AutoStateRestore asr; 411fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin GrMatrix vm = drawState->getViewMatrix(); 412fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin vm.postTranslate(fTranslate.fX, fTranslate.fY); 413fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin asr.set(fTarget); 414fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin GrMatrix ivm; 415fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin if (vm.invert(&ivm)) { 416fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin drawState->preConcatSamplerMatrices(stageMask, ivm); 417fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin } 418fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin drawState->setViewMatrix(GrMatrix::I()); 419fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin 420b65f253fdc60f6208a54911bee793d225f23cdf8James Dong SkPath path; 421b65f253fdc60f6208a54911bee793d225f23cdf8James Dong fPath->transform(vm, &path); 422fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin 423fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin GrVertexLayout layout = 0; 424fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin for (int s = 0; s < GrDrawState::kNumStages; ++s) { 425fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin if ((1 << s) & stageMask) { 426fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin layout |= GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(s); 427fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin } 428fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin } 429fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin layout |= GrDrawTarget::kEdge_VertexLayoutBit; 430fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin 431fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin QuadVertex *verts; 432fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin uint16_t* idxs; 433fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin 434fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin int vCount; 435b65f253fdc60f6208a54911bee793d225f23cdf8James Dong int iCount; 436fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin SegmentArray segments; 437fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin SkPoint fanPt; 438fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin if (!get_segments(path, &segments, &fanPt, &vCount, &iCount)) { 439b65f253fdc60f6208a54911bee793d225f23cdf8James Dong return; 440fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin } 441b65f253fdc60f6208a54911bee793d225f23cdf8James Dong 442fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin if (!fTarget->reserveVertexSpace(layout, 443fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin vCount, 444fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin reinterpret_cast<void**>(&verts))) { 445fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin return; 446fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin } 447fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin if (!fTarget->reserveIndexSpace(iCount, reinterpret_cast<void**>(&idxs))) { 448fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin fTarget->resetVertexSource(); 449fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin return; 450fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin } 451fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin 452fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin create_vertices(segments, fanPt, verts, idxs); 453fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin 454fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin drawState->setVertexEdgeType(GrDrawState::kQuad_EdgeType); 455fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin fTarget->drawIndexed(kTriangles_PrimitiveType, 456fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin 0, // start vertex 457fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin 0, // start index 458fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin vCount, 459fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin iCount); 460fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin} 461fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin 462fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin