169cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com 269cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com/* 369cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com * Copyright 2012 Google Inc. 469cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com * 569cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com * Use of this source code is governed by a BSD-style license that can be 669cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com * found in the LICENSE file. 769cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com */ 869cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com 969cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com#include "GrAAConvexPathRenderer.h" 1069cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com 11e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips#include "GrAAConvexTessellator.h" 1227f398f04dff306418a142c27175eaa35d21a915joshualitt#include "GrBatch.h" 1327f398f04dff306418a142c27175eaa35d21a915joshualitt#include "GrBatchTarget.h" 148e5c177c8589e00f630ac6fae763c65cb9cae896joshualitt#include "GrBatchTest.h" 1569cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com#include "GrContext.h" 16e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips#include "GrDefaultGeoProcFactory.h" 17c26d94fd7dc0b00cd6d0e42d28285f4a38aff021bsalomon@google.com#include "GrDrawTargetCaps.h" 18eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt#include "GrGeometryProcessor.h" 19605dd0fbce9dbb2a0d3313e13e161f2bd54870d7egdaniel#include "GrInvariantOutput.h" 2069cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com#include "GrPathUtils.h" 218dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel#include "GrProcessor.h" 228dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel#include "GrPipelineBuilder.h" 231899651ffc459f5462aa989cd6d08507947b67e4kkinnunen#include "GrStrokeInfo.h" 24af18a09d13611526c4217656c98947f9067cb07aegdaniel#include "SkGeometry.h" 2569cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com#include "SkString.h" 26933e65d914eb86b1fbbf8ea9cf1da58ac7c42500commit-bot@chromium.org#include "SkTraceEvent.h" 27b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt#include "gl/GrGLProcessor.h" 2890c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org#include "gl/GrGLSL.h" 29249af15fb82833d2274850c589812b6e69df0033joshualitt#include "gl/GrGLGeometryProcessor.h" 30eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt#include "gl/builders/GrGLProgramBuilder.h" 31234d4fba75aac009e34c088037fcd9e244798c40commit-bot@chromium.org 3269cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.comGrAAConvexPathRenderer::GrAAConvexPathRenderer() { 3369cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com} 3469cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com 3569cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.comstruct Segment { 3669cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com enum { 379b1517edc7eb3e116902a3b3da447a73aaa56585bsalomon@google.com // These enum values are assumed in member functions below. 389b1517edc7eb3e116902a3b3da447a73aaa56585bsalomon@google.com kLine = 0, 399b1517edc7eb3e116902a3b3da447a73aaa56585bsalomon@google.com kQuad = 1, 4069cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com } fType; 419b1517edc7eb3e116902a3b3da447a73aaa56585bsalomon@google.com 429aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com // line uses one pt, quad uses 2 pts 43972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org SkPoint fPts[2]; 449aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com // normal to edge ending at each pt 45972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org SkVector fNorms[2]; 469aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com // is the corner where the previous segment meets this segment 479aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com // sharp. If so, fMid is a normalized bisector facing outward. 48972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org SkVector fMid; 499aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com 509aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com int countPoints() { 519b1517edc7eb3e116902a3b3da447a73aaa56585bsalomon@google.com GR_STATIC_ASSERT(0 == kLine && 1 == kQuad); 529b1517edc7eb3e116902a3b3da447a73aaa56585bsalomon@google.com return fType + 1; 539aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com } 549aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com const SkPoint& endPt() const { 559b1517edc7eb3e116902a3b3da447a73aaa56585bsalomon@google.com GR_STATIC_ASSERT(0 == kLine && 1 == kQuad); 569b1517edc7eb3e116902a3b3da447a73aaa56585bsalomon@google.com return fPts[fType]; 579aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com }; 589aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com const SkPoint& endNorm() const { 599b1517edc7eb3e116902a3b3da447a73aaa56585bsalomon@google.com GR_STATIC_ASSERT(0 == kLine && 1 == kQuad); 609b1517edc7eb3e116902a3b3da447a73aaa56585bsalomon@google.com return fNorms[fType]; 619aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com }; 6269cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com}; 6369cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com 6469cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.comtypedef SkTArray<Segment, true> SegmentArray; 6569cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com 66fdfbb9d5f0d29cb4a956a693c499653f87f04ac4commit-bot@chromium.orgstatic void center_of_mass(const SegmentArray& segments, SkPoint* c) { 6781712883419f76e25d2ffec38a9438284a45a48dbsalomon@google.com SkScalar area = 0; 686390c72cfb3e371a774a627d5f496dc67558e119vandebo@chromium.org SkPoint center = {0, 0}; 699aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com int count = segments.count(); 706390c72cfb3e371a774a627d5f496dc67558e119vandebo@chromium.org SkPoint p0 = {0, 0}; 715b56d9e43fee4393f25f41d400981ce3960cd1aabsalomon@google.com if (count > 2) { 725b56d9e43fee4393f25f41d400981ce3960cd1aabsalomon@google.com // We translate the polygon so that the first point is at the origin. 735b56d9e43fee4393f25f41d400981ce3960cd1aabsalomon@google.com // This avoids some precision issues with small area polygons far away 745b56d9e43fee4393f25f41d400981ce3960cd1aabsalomon@google.com // from the origin. 755b56d9e43fee4393f25f41d400981ce3960cd1aabsalomon@google.com p0 = segments[0].endPt(); 765b56d9e43fee4393f25f41d400981ce3960cd1aabsalomon@google.com SkPoint pi; 775b56d9e43fee4393f25f41d400981ce3960cd1aabsalomon@google.com SkPoint pj; 78a51ab8416db9772a2eae3122f4f69801642daeb5bsalomon@google.com // the first and last iteration of the below loop would compute 795b56d9e43fee4393f25f41d400981ce3960cd1aabsalomon@google.com // zeros since the starting / ending point is (0,0). So instead we start 805b56d9e43fee4393f25f41d400981ce3960cd1aabsalomon@google.com // at i=1 and make the last iteration i=count-2. 815b56d9e43fee4393f25f41d400981ce3960cd1aabsalomon@google.com pj = segments[1].endPt() - p0; 825b56d9e43fee4393f25f41d400981ce3960cd1aabsalomon@google.com for (int i = 1; i < count - 1; ++i) { 835b56d9e43fee4393f25f41d400981ce3960cd1aabsalomon@google.com pi = pj; 845b56d9e43fee4393f25f41d400981ce3960cd1aabsalomon@google.com const SkPoint pj = segments[i + 1].endPt() - p0; 855b56d9e43fee4393f25f41d400981ce3960cd1aabsalomon@google.com 8681712883419f76e25d2ffec38a9438284a45a48dbsalomon@google.com SkScalar t = SkScalarMul(pi.fX, pj.fY) - SkScalarMul(pj.fX, pi.fY); 875b56d9e43fee4393f25f41d400981ce3960cd1aabsalomon@google.com area += t; 885b56d9e43fee4393f25f41d400981ce3960cd1aabsalomon@google.com center.fX += (pi.fX + pj.fX) * t; 895b56d9e43fee4393f25f41d400981ce3960cd1aabsalomon@google.com center.fY += (pi.fY + pj.fY) * t; 905b56d9e43fee4393f25f41d400981ce3960cd1aabsalomon@google.com 915b56d9e43fee4393f25f41d400981ce3960cd1aabsalomon@google.com } 929aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com } 93278dc6929b6481204874dcfcc055e2aaa30a95b2bsalomon@google.com // If the poly has no area then we instead return the average of 94278dc6929b6481204874dcfcc055e2aaa30a95b2bsalomon@google.com // its points. 955b56d9e43fee4393f25f41d400981ce3960cd1aabsalomon@google.com if (SkScalarNearlyZero(area)) { 96278dc6929b6481204874dcfcc055e2aaa30a95b2bsalomon@google.com SkPoint avg; 97278dc6929b6481204874dcfcc055e2aaa30a95b2bsalomon@google.com avg.set(0, 0); 98278dc6929b6481204874dcfcc055e2aaa30a95b2bsalomon@google.com for (int i = 0; i < count; ++i) { 99278dc6929b6481204874dcfcc055e2aaa30a95b2bsalomon@google.com const SkPoint& pt = segments[i].endPt(); 100278dc6929b6481204874dcfcc055e2aaa30a95b2bsalomon@google.com avg.fX += pt.fX; 101278dc6929b6481204874dcfcc055e2aaa30a95b2bsalomon@google.com avg.fY += pt.fY; 102278dc6929b6481204874dcfcc055e2aaa30a95b2bsalomon@google.com } 103278dc6929b6481204874dcfcc055e2aaa30a95b2bsalomon@google.com SkScalar denom = SK_Scalar1 / count; 104278dc6929b6481204874dcfcc055e2aaa30a95b2bsalomon@google.com avg.scale(denom); 105278dc6929b6481204874dcfcc055e2aaa30a95b2bsalomon@google.com *c = avg; 106278dc6929b6481204874dcfcc055e2aaa30a95b2bsalomon@google.com } else { 107278dc6929b6481204874dcfcc055e2aaa30a95b2bsalomon@google.com area *= 3; 10880ea19ca4bdd68c1493666a5fe7e4ce9d43ded8breed area = SkScalarInvert(area); 10981712883419f76e25d2ffec38a9438284a45a48dbsalomon@google.com center.fX = SkScalarMul(center.fX, area); 11081712883419f76e25d2ffec38a9438284a45a48dbsalomon@google.com center.fY = SkScalarMul(center.fY, area); 1115b56d9e43fee4393f25f41d400981ce3960cd1aabsalomon@google.com // undo the translate of p0 to the origin. 1125b56d9e43fee4393f25f41d400981ce3960cd1aabsalomon@google.com *c = center + p0; 113278dc6929b6481204874dcfcc055e2aaa30a95b2bsalomon@google.com } 114f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(!SkScalarIsNaN(c->fX) && !SkScalarIsNaN(c->fY)); 1159aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com} 1169aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com 117fdfbb9d5f0d29cb4a956a693c499653f87f04ac4commit-bot@chromium.orgstatic void compute_vectors(SegmentArray* segments, 118fdfbb9d5f0d29cb4a956a693c499653f87f04ac4commit-bot@chromium.org SkPoint* fanPt, 119fdfbb9d5f0d29cb4a956a693c499653f87f04ac4commit-bot@chromium.org SkPath::Direction dir, 120fdfbb9d5f0d29cb4a956a693c499653f87f04ac4commit-bot@chromium.org int* vCount, 121fdfbb9d5f0d29cb4a956a693c499653f87f04ac4commit-bot@chromium.org int* iCount) { 1229aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com center_of_mass(*segments, fanPt); 1239aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com int count = segments->count(); 1249aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com 125278dc6929b6481204874dcfcc055e2aaa30a95b2bsalomon@google.com // Make the normals point towards the outside 126972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org SkPoint::Side normSide; 127278dc6929b6481204874dcfcc055e2aaa30a95b2bsalomon@google.com if (dir == SkPath::kCCW_Direction) { 128972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org normSide = SkPoint::kRight_Side; 129278dc6929b6481204874dcfcc055e2aaa30a95b2bsalomon@google.com } else { 130972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org normSide = SkPoint::kLeft_Side; 131278dc6929b6481204874dcfcc055e2aaa30a95b2bsalomon@google.com } 1329aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com 1339aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com *vCount = 0; 1349aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com *iCount = 0; 1359aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com // compute normals at all points 1369aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com for (int a = 0; a < count; ++a) { 1377d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com Segment& sega = (*segments)[a]; 1389aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com int b = (a + 1) % count; 1399aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com Segment& segb = (*segments)[b]; 1409aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com 141972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org const SkPoint* prevPt = &sega.endPt(); 1429aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com int n = segb.countPoints(); 1439aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com for (int p = 0; p < n; ++p) { 1449aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com segb.fNorms[p] = segb.fPts[p] - *prevPt; 1459aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com segb.fNorms[p].normalize(); 1469aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com segb.fNorms[p].setOrthog(segb.fNorms[p], normSide); 1479aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com prevPt = &segb.fPts[p]; 1489aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com } 1499aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com if (Segment::kLine == segb.fType) { 1509aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com *vCount += 5; 1519aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com *iCount += 9; 1529aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com } else { 1539aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com *vCount += 6; 1549aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com *iCount += 12; 1559aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com } 1569aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com } 1579aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com 1589aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com // compute mid-vectors where segments meet. TODO: Detect shallow corners 1599aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com // and leave out the wedges and close gaps by stitching segments together. 1609aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com for (int a = 0; a < count; ++a) { 1619aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com const Segment& sega = (*segments)[a]; 1629aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com int b = (a + 1) % count; 1639aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com Segment& segb = (*segments)[b]; 1649aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com segb.fMid = segb.fNorms[0] + sega.endNorm(); 1659aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com segb.fMid.normalize(); 1669aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com // corner wedges 1679aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com *vCount += 4; 1689aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com *iCount += 6; 1699aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com } 1709aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com} 1719aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com 1729732f62eaec427e0d4a8de06748ebb59450dfe31bsalomon@google.comstruct DegenerateTestData { 1739732f62eaec427e0d4a8de06748ebb59450dfe31bsalomon@google.com DegenerateTestData() { fStage = kInitial; } 1749732f62eaec427e0d4a8de06748ebb59450dfe31bsalomon@google.com bool isDegenerate() const { return kNonDegenerate != fStage; } 1759732f62eaec427e0d4a8de06748ebb59450dfe31bsalomon@google.com enum { 1769732f62eaec427e0d4a8de06748ebb59450dfe31bsalomon@google.com kInitial, 1779732f62eaec427e0d4a8de06748ebb59450dfe31bsalomon@google.com kPoint, 1789732f62eaec427e0d4a8de06748ebb59450dfe31bsalomon@google.com kLine, 1799732f62eaec427e0d4a8de06748ebb59450dfe31bsalomon@google.com kNonDegenerate 1809732f62eaec427e0d4a8de06748ebb59450dfe31bsalomon@google.com } fStage; 181972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org SkPoint fFirstPoint; 182972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org SkVector fLineNormal; 18381712883419f76e25d2ffec38a9438284a45a48dbsalomon@google.com SkScalar fLineC; 1849732f62eaec427e0d4a8de06748ebb59450dfe31bsalomon@google.com}; 1859732f62eaec427e0d4a8de06748ebb59450dfe31bsalomon@google.com 186fdfbb9d5f0d29cb4a956a693c499653f87f04ac4commit-bot@chromium.orgstatic const SkScalar kClose = (SK_Scalar1 / 16); 187fdfbb9d5f0d29cb4a956a693c499653f87f04ac4commit-bot@chromium.orgstatic const SkScalar kCloseSqd = SkScalarMul(kClose, kClose); 1889732f62eaec427e0d4a8de06748ebb59450dfe31bsalomon@google.com 189972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.orgstatic void update_degenerate_test(DegenerateTestData* data, const SkPoint& pt) { 1909732f62eaec427e0d4a8de06748ebb59450dfe31bsalomon@google.com switch (data->fStage) { 1919732f62eaec427e0d4a8de06748ebb59450dfe31bsalomon@google.com case DegenerateTestData::kInitial: 1929732f62eaec427e0d4a8de06748ebb59450dfe31bsalomon@google.com data->fFirstPoint = pt; 1939732f62eaec427e0d4a8de06748ebb59450dfe31bsalomon@google.com data->fStage = DegenerateTestData::kPoint; 1949732f62eaec427e0d4a8de06748ebb59450dfe31bsalomon@google.com break; 1959732f62eaec427e0d4a8de06748ebb59450dfe31bsalomon@google.com case DegenerateTestData::kPoint: 196fdfbb9d5f0d29cb4a956a693c499653f87f04ac4commit-bot@chromium.org if (pt.distanceToSqd(data->fFirstPoint) > kCloseSqd) { 1979732f62eaec427e0d4a8de06748ebb59450dfe31bsalomon@google.com data->fLineNormal = pt - data->fFirstPoint; 1989732f62eaec427e0d4a8de06748ebb59450dfe31bsalomon@google.com data->fLineNormal.normalize(); 1999732f62eaec427e0d4a8de06748ebb59450dfe31bsalomon@google.com data->fLineNormal.setOrthog(data->fLineNormal); 2009732f62eaec427e0d4a8de06748ebb59450dfe31bsalomon@google.com data->fLineC = -data->fLineNormal.dot(data->fFirstPoint); 2019732f62eaec427e0d4a8de06748ebb59450dfe31bsalomon@google.com data->fStage = DegenerateTestData::kLine; 2029732f62eaec427e0d4a8de06748ebb59450dfe31bsalomon@google.com } 2039732f62eaec427e0d4a8de06748ebb59450dfe31bsalomon@google.com break; 2049732f62eaec427e0d4a8de06748ebb59450dfe31bsalomon@google.com case DegenerateTestData::kLine: 205fdfbb9d5f0d29cb4a956a693c499653f87f04ac4commit-bot@chromium.org if (SkScalarAbs(data->fLineNormal.dot(pt) + data->fLineC) > kClose) { 2069732f62eaec427e0d4a8de06748ebb59450dfe31bsalomon@google.com data->fStage = DegenerateTestData::kNonDegenerate; 2079732f62eaec427e0d4a8de06748ebb59450dfe31bsalomon@google.com } 2089732f62eaec427e0d4a8de06748ebb59450dfe31bsalomon@google.com case DegenerateTestData::kNonDegenerate: 2099732f62eaec427e0d4a8de06748ebb59450dfe31bsalomon@google.com break; 2109732f62eaec427e0d4a8de06748ebb59450dfe31bsalomon@google.com default: 21188cb22b6b4816c7a9ca6c5b795965b4606f9eb7bcommit-bot@chromium.org SkFAIL("Unexpected degenerate test stage."); 2129732f62eaec427e0d4a8de06748ebb59450dfe31bsalomon@google.com } 2139732f62eaec427e0d4a8de06748ebb59450dfe31bsalomon@google.com} 2149732f62eaec427e0d4a8de06748ebb59450dfe31bsalomon@google.com 215fdfbb9d5f0d29cb4a956a693c499653f87f04ac4commit-bot@chromium.orgstatic inline bool get_direction(const SkPath& path, const SkMatrix& m, SkPath::Direction* dir) { 216a51ab8416db9772a2eae3122f4f69801642daeb5bsalomon@google.com if (!path.cheapComputeDirection(dir)) { 217a51ab8416db9772a2eae3122f4f69801642daeb5bsalomon@google.com return false; 218a51ab8416db9772a2eae3122f4f69801642daeb5bsalomon@google.com } 219af90f7f142a3939ca34f55b39460688e8eb5dc6bbsalomon@google.com // check whether m reverses the orientation 220f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(!m.hasPerspective()); 22181712883419f76e25d2ffec38a9438284a45a48dbsalomon@google.com SkScalar det2x2 = SkScalarMul(m.get(SkMatrix::kMScaleX), m.get(SkMatrix::kMScaleY)) - 22281712883419f76e25d2ffec38a9438284a45a48dbsalomon@google.com SkScalarMul(m.get(SkMatrix::kMSkewX), m.get(SkMatrix::kMSkewY)); 223af90f7f142a3939ca34f55b39460688e8eb5dc6bbsalomon@google.com if (det2x2 < 0) { 22430c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com *dir = SkPath::OppositeDirection(*dir); 225af90f7f142a3939ca34f55b39460688e8eb5dc6bbsalomon@google.com } 226a51ab8416db9772a2eae3122f4f69801642daeb5bsalomon@google.com return true; 227af90f7f142a3939ca34f55b39460688e8eb5dc6bbsalomon@google.com} 228af90f7f142a3939ca34f55b39460688e8eb5dc6bbsalomon@google.com 229106655efdf2516f7084c19d6d5a7bc59fd8b866ccommit-bot@chromium.orgstatic inline void add_line_to_segment(const SkPoint& pt, 23027f398f04dff306418a142c27175eaa35d21a915joshualitt SegmentArray* segments) { 231fdfbb9d5f0d29cb4a956a693c499653f87f04ac4commit-bot@chromium.org segments->push_back(); 232fdfbb9d5f0d29cb4a956a693c499653f87f04ac4commit-bot@chromium.org segments->back().fType = Segment::kLine; 233fdfbb9d5f0d29cb4a956a693c499653f87f04ac4commit-bot@chromium.org segments->back().fPts[0] = pt; 234fdfbb9d5f0d29cb4a956a693c499653f87f04ac4commit-bot@chromium.org} 235fdfbb9d5f0d29cb4a956a693c499653f87f04ac4commit-bot@chromium.org 236106655efdf2516f7084c19d6d5a7bc59fd8b866ccommit-bot@chromium.orgstatic inline void add_quad_segment(const SkPoint pts[3], 23727f398f04dff306418a142c27175eaa35d21a915joshualitt SegmentArray* segments) { 238fdfbb9d5f0d29cb4a956a693c499653f87f04ac4commit-bot@chromium.org if (pts[0].distanceToSqd(pts[1]) < kCloseSqd || pts[1].distanceToSqd(pts[2]) < kCloseSqd) { 239fdfbb9d5f0d29cb4a956a693c499653f87f04ac4commit-bot@chromium.org if (pts[0] != pts[2]) { 24027f398f04dff306418a142c27175eaa35d21a915joshualitt add_line_to_segment(pts[2], segments); 241fdfbb9d5f0d29cb4a956a693c499653f87f04ac4commit-bot@chromium.org } 242fdfbb9d5f0d29cb4a956a693c499653f87f04ac4commit-bot@chromium.org } else { 243fdfbb9d5f0d29cb4a956a693c499653f87f04ac4commit-bot@chromium.org segments->push_back(); 244fdfbb9d5f0d29cb4a956a693c499653f87f04ac4commit-bot@chromium.org segments->back().fType = Segment::kQuad; 245fdfbb9d5f0d29cb4a956a693c499653f87f04ac4commit-bot@chromium.org segments->back().fPts[0] = pts[1]; 246fdfbb9d5f0d29cb4a956a693c499653f87f04ac4commit-bot@chromium.org segments->back().fPts[1] = pts[2]; 247fdfbb9d5f0d29cb4a956a693c499653f87f04ac4commit-bot@chromium.org } 248fdfbb9d5f0d29cb4a956a693c499653f87f04ac4commit-bot@chromium.org} 249fdfbb9d5f0d29cb4a956a693c499653f87f04ac4commit-bot@chromium.org 250fdfbb9d5f0d29cb4a956a693c499653f87f04ac4commit-bot@chromium.orgstatic inline void add_cubic_segments(const SkPoint pts[4], 251fdfbb9d5f0d29cb4a956a693c499653f87f04ac4commit-bot@chromium.org SkPath::Direction dir, 25227f398f04dff306418a142c27175eaa35d21a915joshualitt SegmentArray* segments) { 253fdfbb9d5f0d29cb4a956a693c499653f87f04ac4commit-bot@chromium.org SkSTArray<15, SkPoint, true> quads; 254fdfbb9d5f0d29cb4a956a693c499653f87f04ac4commit-bot@chromium.org GrPathUtils::convertCubicToQuads(pts, SK_Scalar1, true, dir, &quads); 255fdfbb9d5f0d29cb4a956a693c499653f87f04ac4commit-bot@chromium.org int count = quads.count(); 256fdfbb9d5f0d29cb4a956a693c499653f87f04ac4commit-bot@chromium.org for (int q = 0; q < count; q += 3) { 25727f398f04dff306418a142c27175eaa35d21a915joshualitt add_quad_segment(&quads[q], segments); 258fdfbb9d5f0d29cb4a956a693c499653f87f04ac4commit-bot@chromium.org } 259fdfbb9d5f0d29cb4a956a693c499653f87f04ac4commit-bot@chromium.org} 260fdfbb9d5f0d29cb4a956a693c499653f87f04ac4commit-bot@chromium.org 261fdfbb9d5f0d29cb4a956a693c499653f87f04ac4commit-bot@chromium.orgstatic bool get_segments(const SkPath& path, 262fdfbb9d5f0d29cb4a956a693c499653f87f04ac4commit-bot@chromium.org const SkMatrix& m, 263fdfbb9d5f0d29cb4a956a693c499653f87f04ac4commit-bot@chromium.org SegmentArray* segments, 264fdfbb9d5f0d29cb4a956a693c499653f87f04ac4commit-bot@chromium.org SkPoint* fanPt, 265fdfbb9d5f0d29cb4a956a693c499653f87f04ac4commit-bot@chromium.org int* vCount, 26627f398f04dff306418a142c27175eaa35d21a915joshualitt int* iCount) { 26769cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com SkPath::Iter iter(path, true); 26830c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com // This renderer over-emphasizes very thin path regions. We use the distance 2695cc90d132220a69c1d5734178d851f9c7cd57f16bsalomon@google.com // to the path from the sample to compute coverage. Every pixel intersected 2705cc90d132220a69c1d5734178d851f9c7cd57f16bsalomon@google.com // by the path will be hit and the maximum distance is sqrt(2)/2. We don't 271fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com // notice that the sample may be close to a very thin area of the path and 2725cc90d132220a69c1d5734178d851f9c7cd57f16bsalomon@google.com // thus should be very light. This is particularly egregious for degenerate 2735cc90d132220a69c1d5734178d851f9c7cd57f16bsalomon@google.com // line paths. We detect paths that are very close to a line (zero area) and 2745cc90d132220a69c1d5734178d851f9c7cd57f16bsalomon@google.com // draw nothing. 2759732f62eaec427e0d4a8de06748ebb59450dfe31bsalomon@google.com DegenerateTestData degenerateData; 276a51ab8416db9772a2eae3122f4f69801642daeb5bsalomon@google.com SkPath::Direction dir; 277a51ab8416db9772a2eae3122f4f69801642daeb5bsalomon@google.com // get_direction can fail for some degenerate paths. 278a51ab8416db9772a2eae3122f4f69801642daeb5bsalomon@google.com if (!get_direction(path, m, &dir)) { 279a51ab8416db9772a2eae3122f4f69801642daeb5bsalomon@google.com return false; 280a51ab8416db9772a2eae3122f4f69801642daeb5bsalomon@google.com } 2819732f62eaec427e0d4a8de06748ebb59450dfe31bsalomon@google.com 28269cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com for (;;) { 283972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org SkPoint pts[4]; 28494b284d719ee5ccd3e2efbd1d7084ec554583bacbsalomon@google.com SkPath::Verb verb = iter.next(pts); 28594b284d719ee5ccd3e2efbd1d7084ec554583bacbsalomon@google.com switch (verb) { 28694b284d719ee5ccd3e2efbd1d7084ec554583bacbsalomon@google.com case SkPath::kMove_Verb: 2871a38d5508f7a0e2c186d3aa8ea807045a46b663dbsalomon@google.com m.mapPoints(pts, 1); 2889732f62eaec427e0d4a8de06748ebb59450dfe31bsalomon@google.com update_degenerate_test(°enerateData, pts[0]); 2899732f62eaec427e0d4a8de06748ebb59450dfe31bsalomon@google.com break; 29094b284d719ee5ccd3e2efbd1d7084ec554583bacbsalomon@google.com case SkPath::kLine_Verb: { 291fdfbb9d5f0d29cb4a956a693c499653f87f04ac4commit-bot@chromium.org m.mapPoints(&pts[1], 1); 2921a38d5508f7a0e2c186d3aa8ea807045a46b663dbsalomon@google.com update_degenerate_test(°enerateData, pts[1]); 29327f398f04dff306418a142c27175eaa35d21a915joshualitt add_line_to_segment(pts[1], segments); 29469cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com break; 29569cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com } 29694b284d719ee5ccd3e2efbd1d7084ec554583bacbsalomon@google.com case SkPath::kQuad_Verb: 297fdfbb9d5f0d29cb4a956a693c499653f87f04ac4commit-bot@chromium.org m.mapPoints(pts, 3); 2989732f62eaec427e0d4a8de06748ebb59450dfe31bsalomon@google.com update_degenerate_test(°enerateData, pts[1]); 2999732f62eaec427e0d4a8de06748ebb59450dfe31bsalomon@google.com update_degenerate_test(°enerateData, pts[2]); 30027f398f04dff306418a142c27175eaa35d21a915joshualitt add_quad_segment(pts, segments); 30169cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com break; 302af18a09d13611526c4217656c98947f9067cb07aegdaniel case SkPath::kConic_Verb: { 303af18a09d13611526c4217656c98947f9067cb07aegdaniel m.mapPoints(pts, 3); 304af18a09d13611526c4217656c98947f9067cb07aegdaniel SkScalar weight = iter.conicWeight(); 305af18a09d13611526c4217656c98947f9067cb07aegdaniel SkAutoConicToQuads converter; 306af18a09d13611526c4217656c98947f9067cb07aegdaniel const SkPoint* quadPts = converter.computeQuads(pts, weight, 0.5f); 307af18a09d13611526c4217656c98947f9067cb07aegdaniel for (int i = 0; i < converter.countQuads(); ++i) { 308af18a09d13611526c4217656c98947f9067cb07aegdaniel update_degenerate_test(°enerateData, quadPts[2*i + 1]); 309af18a09d13611526c4217656c98947f9067cb07aegdaniel update_degenerate_test(°enerateData, quadPts[2*i + 2]); 31027f398f04dff306418a142c27175eaa35d21a915joshualitt add_quad_segment(quadPts + 2*i, segments); 311af18a09d13611526c4217656c98947f9067cb07aegdaniel } 312af18a09d13611526c4217656c98947f9067cb07aegdaniel break; 313af18a09d13611526c4217656c98947f9067cb07aegdaniel } 31494b284d719ee5ccd3e2efbd1d7084ec554583bacbsalomon@google.com case SkPath::kCubic_Verb: { 3151a38d5508f7a0e2c186d3aa8ea807045a46b663dbsalomon@google.com m.mapPoints(pts, 4); 3169732f62eaec427e0d4a8de06748ebb59450dfe31bsalomon@google.com update_degenerate_test(°enerateData, pts[1]); 3179732f62eaec427e0d4a8de06748ebb59450dfe31bsalomon@google.com update_degenerate_test(°enerateData, pts[2]); 3189732f62eaec427e0d4a8de06748ebb59450dfe31bsalomon@google.com update_degenerate_test(°enerateData, pts[3]); 31927f398f04dff306418a142c27175eaa35d21a915joshualitt add_cubic_segments(pts, dir, segments); 32069cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com break; 32169cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com }; 32294b284d719ee5ccd3e2efbd1d7084ec554583bacbsalomon@google.com case SkPath::kDone_Verb: 3239732f62eaec427e0d4a8de06748ebb59450dfe31bsalomon@google.com if (degenerateData.isDegenerate()) { 3249732f62eaec427e0d4a8de06748ebb59450dfe31bsalomon@google.com return false; 3259732f62eaec427e0d4a8de06748ebb59450dfe31bsalomon@google.com } else { 326278dc6929b6481204874dcfcc055e2aaa30a95b2bsalomon@google.com compute_vectors(segments, fanPt, dir, vCount, iCount); 3279732f62eaec427e0d4a8de06748ebb59450dfe31bsalomon@google.com return true; 3289732f62eaec427e0d4a8de06748ebb59450dfe31bsalomon@google.com } 32969cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com default: 33069cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com break; 33169cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com } 33269cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com } 33369cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com} 33469cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com 33569cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.comstruct QuadVertex { 336972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org SkPoint fPos; 337972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org SkPoint fUV; 33881712883419f76e25d2ffec38a9438284a45a48dbsalomon@google.com SkScalar fD0; 33981712883419f76e25d2ffec38a9438284a45a48dbsalomon@google.com SkScalar fD1; 34069cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com}; 341fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 3427d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.comstruct Draw { 3437d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com Draw() : fVertexCnt(0), fIndexCnt(0) {} 3447d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com int fVertexCnt; 3457d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com int fIndexCnt; 3467d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com}; 3477d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com 3487d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.comtypedef SkTArray<Draw, true> DrawArray; 3497d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com 350fdfbb9d5f0d29cb4a956a693c499653f87f04ac4commit-bot@chromium.orgstatic void create_vertices(const SegmentArray& segments, 351fdfbb9d5f0d29cb4a956a693c499653f87f04ac4commit-bot@chromium.org const SkPoint& fanPt, 352fdfbb9d5f0d29cb4a956a693c499653f87f04ac4commit-bot@chromium.org DrawArray* draws, 353fdfbb9d5f0d29cb4a956a693c499653f87f04ac4commit-bot@chromium.org QuadVertex* verts, 354fdfbb9d5f0d29cb4a956a693c499653f87f04ac4commit-bot@chromium.org uint16_t* idxs) { 3557d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com Draw* draw = &draws->push_back(); 3567d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com // alias just to make vert/index assignments easier to read. 3577d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com int* v = &draw->fVertexCnt; 3587d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com int* i = &draw->fIndexCnt; 35969cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com 3609aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com int count = segments.count(); 3619aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com for (int a = 0; a < count; ++a) { 3629aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com const Segment& sega = segments[a]; 3639aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com int b = (a + 1) % count; 3649aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com const Segment& segb = segments[b]; 365fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 3667d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com // Check whether adding the verts for this segment to the current draw would cause index 3677d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com // values to overflow. 3687d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com int vCount = 4; 3697d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com if (Segment::kLine == segb.fType) { 3707d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com vCount += 5; 3717d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com } else { 3727d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com vCount += 6; 3737d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com } 3747d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com if (draw->fVertexCnt + vCount > (1 << 16)) { 3757d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com verts += *v; 3767d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com idxs += *i; 3777d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com draw = &draws->push_back(); 3787d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com v = &draw->fVertexCnt; 3797d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com i = &draw->fIndexCnt; 3807d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com } 3817d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com 3829aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com // FIXME: These tris are inset in the 1 unit arc around the corner 3837d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com verts[*v + 0].fPos = sega.endPt(); 3847d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com verts[*v + 1].fPos = verts[*v + 0].fPos + sega.endNorm(); 3857d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com verts[*v + 2].fPos = verts[*v + 0].fPos + segb.fMid; 3867d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com verts[*v + 3].fPos = verts[*v + 0].fPos + segb.fNorms[0]; 3877d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com verts[*v + 0].fUV.set(0,0); 3887d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com verts[*v + 1].fUV.set(0,-SK_Scalar1); 3897d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com verts[*v + 2].fUV.set(0,-SK_Scalar1); 3907d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com verts[*v + 3].fUV.set(0,-SK_Scalar1); 3917d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com verts[*v + 0].fD0 = verts[*v + 0].fD1 = -SK_Scalar1; 3927d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com verts[*v + 1].fD0 = verts[*v + 1].fD1 = -SK_Scalar1; 3937d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com verts[*v + 2].fD0 = verts[*v + 2].fD1 = -SK_Scalar1; 3947d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com verts[*v + 3].fD0 = verts[*v + 3].fD1 = -SK_Scalar1; 3957d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com 3967d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com idxs[*i + 0] = *v + 0; 3977d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com idxs[*i + 1] = *v + 2; 3987d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com idxs[*i + 2] = *v + 1; 3997d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com idxs[*i + 3] = *v + 0; 4007d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com idxs[*i + 4] = *v + 3; 4017d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com idxs[*i + 5] = *v + 2; 4027d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com 4037d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com *v += 4; 4047d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com *i += 6; 40569cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com 4069aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com if (Segment::kLine == segb.fType) { 4077d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com verts[*v + 0].fPos = fanPt; 4087d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com verts[*v + 1].fPos = sega.endPt(); 4097d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com verts[*v + 2].fPos = segb.fPts[0]; 4109aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com 4117d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com verts[*v + 3].fPos = verts[*v + 1].fPos + segb.fNorms[0]; 4127d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com verts[*v + 4].fPos = verts[*v + 2].fPos + segb.fNorms[0]; 4139aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com 4149aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com // we draw the line edge as a degenerate quad (u is 0, v is the 4159aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com // signed distance to the edge) 4167d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com SkScalar dist = fanPt.distanceToLineBetween(verts[*v + 1].fPos, 4177d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com verts[*v + 2].fPos); 4187d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com verts[*v + 0].fUV.set(0, dist); 4197d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com verts[*v + 1].fUV.set(0, 0); 4207d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com verts[*v + 2].fUV.set(0, 0); 4217d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com verts[*v + 3].fUV.set(0, -SK_Scalar1); 4227d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com verts[*v + 4].fUV.set(0, -SK_Scalar1); 4237d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com 4247d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com verts[*v + 0].fD0 = verts[*v + 0].fD1 = -SK_Scalar1; 4257d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com verts[*v + 1].fD0 = verts[*v + 1].fD1 = -SK_Scalar1; 4267d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com verts[*v + 2].fD0 = verts[*v + 2].fD1 = -SK_Scalar1; 4277d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com verts[*v + 3].fD0 = verts[*v + 3].fD1 = -SK_Scalar1; 4287d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com verts[*v + 4].fD0 = verts[*v + 4].fD1 = -SK_Scalar1; 4297d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com 4303596482cc7b36c9f45f59c304dfb28a841229525cdalton idxs[*i + 0] = *v + 3; 4313596482cc7b36c9f45f59c304dfb28a841229525cdalton idxs[*i + 1] = *v + 1; 4323596482cc7b36c9f45f59c304dfb28a841229525cdalton idxs[*i + 2] = *v + 2; 4337d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com 4343596482cc7b36c9f45f59c304dfb28a841229525cdalton idxs[*i + 3] = *v + 4; 4353596482cc7b36c9f45f59c304dfb28a841229525cdalton idxs[*i + 4] = *v + 3; 4367d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com idxs[*i + 5] = *v + 2; 4377d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com 4383596482cc7b36c9f45f59c304dfb28a841229525cdalton *i += 6; 4393596482cc7b36c9f45f59c304dfb28a841229525cdalton 4403596482cc7b36c9f45f59c304dfb28a841229525cdalton // Draw the interior fan if it exists. 4413596482cc7b36c9f45f59c304dfb28a841229525cdalton // TODO: Detect and combine colinear segments. This will ensure we catch every case 4423596482cc7b36c9f45f59c304dfb28a841229525cdalton // with no interior, and that the resulting shared edge uses the same endpoints. 4433596482cc7b36c9f45f59c304dfb28a841229525cdalton if (count >= 3) { 4443596482cc7b36c9f45f59c304dfb28a841229525cdalton idxs[*i + 0] = *v + 0; 4453596482cc7b36c9f45f59c304dfb28a841229525cdalton idxs[*i + 1] = *v + 2; 4463596482cc7b36c9f45f59c304dfb28a841229525cdalton idxs[*i + 2] = *v + 1; 4473596482cc7b36c9f45f59c304dfb28a841229525cdalton 4483596482cc7b36c9f45f59c304dfb28a841229525cdalton *i += 3; 4493596482cc7b36c9f45f59c304dfb28a841229525cdalton } 4507d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com 4517d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com *v += 5; 452068096148179062c4343138c112b87518e4ab3b1bsalomon@google.com } else { 453972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org SkPoint qpts[] = {sega.endPt(), segb.fPts[0], segb.fPts[1]}; 4549aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com 455972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org SkVector midVec = segb.fNorms[0] + segb.fNorms[1]; 4569aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com midVec.normalize(); 4579aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com 4587d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com verts[*v + 0].fPos = fanPt; 4597d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com verts[*v + 1].fPos = qpts[0]; 4607d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com verts[*v + 2].fPos = qpts[2]; 4617d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com verts[*v + 3].fPos = qpts[0] + segb.fNorms[0]; 4627d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com verts[*v + 4].fPos = qpts[2] + segb.fNorms[1]; 4637d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com verts[*v + 5].fPos = qpts[1] + midVec; 4649aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com 46581712883419f76e25d2ffec38a9438284a45a48dbsalomon@google.com SkScalar c = segb.fNorms[0].dot(qpts[0]); 4667d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com verts[*v + 0].fD0 = -segb.fNorms[0].dot(fanPt) + c; 4677d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com verts[*v + 1].fD0 = 0.f; 4687d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com verts[*v + 2].fD0 = -segb.fNorms[0].dot(qpts[2]) + c; 4697d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com verts[*v + 3].fD0 = -SK_ScalarMax/100; 4707d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com verts[*v + 4].fD0 = -SK_ScalarMax/100; 4717d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com verts[*v + 5].fD0 = -SK_ScalarMax/100; 4729aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com 4739aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com c = segb.fNorms[1].dot(qpts[2]); 4747d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com verts[*v + 0].fD1 = -segb.fNorms[1].dot(fanPt) + c; 4757d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com verts[*v + 1].fD1 = -segb.fNorms[1].dot(qpts[0]) + c; 4767d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com verts[*v + 2].fD1 = 0.f; 4777d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com verts[*v + 3].fD1 = -SK_ScalarMax/100; 4787d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com verts[*v + 4].fD1 = -SK_ScalarMax/100; 4797d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com verts[*v + 5].fD1 = -SK_ScalarMax/100; 4809aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com 4811971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com GrPathUtils::QuadUVMatrix toUV(qpts); 482972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org toUV.apply<6, sizeof(QuadVertex), sizeof(SkPoint)>(verts + *v); 4839aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com 4847d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com idxs[*i + 0] = *v + 3; 4857d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com idxs[*i + 1] = *v + 1; 4867d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com idxs[*i + 2] = *v + 2; 4877d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com idxs[*i + 3] = *v + 4; 4887d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com idxs[*i + 4] = *v + 3; 4897d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com idxs[*i + 5] = *v + 2; 4909aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com 4917d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com idxs[*i + 6] = *v + 5; 4927d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com idxs[*i + 7] = *v + 3; 4937d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com idxs[*i + 8] = *v + 4; 4949aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com 4953596482cc7b36c9f45f59c304dfb28a841229525cdalton *i += 9; 4963596482cc7b36c9f45f59c304dfb28a841229525cdalton 4973596482cc7b36c9f45f59c304dfb28a841229525cdalton // Draw the interior fan if it exists. 4983596482cc7b36c9f45f59c304dfb28a841229525cdalton // TODO: Detect and combine colinear segments. This will ensure we catch every case 4993596482cc7b36c9f45f59c304dfb28a841229525cdalton // with no interior, and that the resulting shared edge uses the same endpoints. 5003596482cc7b36c9f45f59c304dfb28a841229525cdalton if (count >= 3) { 5013596482cc7b36c9f45f59c304dfb28a841229525cdalton idxs[*i + 0] = *v + 0; 5023596482cc7b36c9f45f59c304dfb28a841229525cdalton idxs[*i + 1] = *v + 2; 5033596482cc7b36c9f45f59c304dfb28a841229525cdalton idxs[*i + 2] = *v + 1; 5043596482cc7b36c9f45f59c304dfb28a841229525cdalton 5053596482cc7b36c9f45f59c304dfb28a841229525cdalton *i += 3; 5063596482cc7b36c9f45f59c304dfb28a841229525cdalton } 5079aed114505a06679bbc7fa836e224aae82b3e5f4bsalomon@google.com 5087d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com *v += 6; 50969cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com } 51069cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com } 51169cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com} 51269cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com 51390c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////// 51490c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 51590c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org/* 51690c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org * Quadratic specified by 0=u^2-v canonical coords. u and v are the first 51790c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org * two components of the vertex attribute. Coverage is based on signed 51890c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org * distance with negative being inside, positive outside. The edge is specified in 51990c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org * window space (y-down). If either the third or fourth component of the interpolated 52090c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org * vertex coord is > 0 then the pixel is considered outside the edge. This is used to 521041e2dbc0614e3341e1349fd0e962744a45b6194skia.committer@gmail.com * attempt to trim to a portion of the infinite quad. 522041e2dbc0614e3341e1349fd0e962744a45b6194skia.committer@gmail.com * Requires shader derivative instruction support. 52390c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org */ 52490c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 525249af15fb82833d2274850c589812b6e69df0033joshualittclass QuadEdgeEffect : public GrGeometryProcessor { 52690c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.orgpublic: 52790c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 528d27f73ef27ff65a6a0a5d00aa8e5b784b1a0b47ejoshualitt static GrGeometryProcessor* Create(GrColor color, const SkMatrix& localMatrix) { 529d27f73ef27ff65a6a0a5d00aa8e5b784b1a0b47ejoshualitt return SkNEW_ARGS(QuadEdgeEffect, (color, localMatrix)); 53090c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org } 53190c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 53290c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org virtual ~QuadEdgeEffect() {} 53390c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 53436352bf5e38f45a70ee4f4fc132a38048d38206dmtklein const char* name() const override { return "QuadEdge"; } 53590c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 53671c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt const Attribute* inPosition() const { return fInPosition; } 53771c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt const Attribute* inQuadEdge() const { return fInQuadEdge; } 53888c23fc6e8ed0243159fd17d815b4f813805647bjoshualitt GrColor color() const { return fColor; } 539e3ababe44315452cd33b96a18ce316ede09ff3c3joshualitt const SkMatrix& localMatrix() const { return fLocalMatrix; } 540249af15fb82833d2274850c589812b6e69df0033joshualitt 541b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt class GLProcessor : public GrGLGeometryProcessor { 54290c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org public: 543eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt GLProcessor(const GrGeometryProcessor&, 5449b98932adaceb7ad0a617ade16616923f6bffe84joshualitt const GrBatchTracker&) 5459b98932adaceb7ad0a617ade16616923f6bffe84joshualitt : fColor(GrColor_ILLEGAL) {} 54690c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 54736352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override { 5482dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt const QuadEdgeEffect& qe = args.fGP.cast<QuadEdgeEffect>(); 5499b98932adaceb7ad0a617ade16616923f6bffe84joshualitt GrGLGPBuilder* pb = args.fPB; 5509b98932adaceb7ad0a617ade16616923f6bffe84joshualitt GrGLVertexBuilder* vsBuilder = pb->getVertexShaderBuilder(); 5512dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt 552abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt // emit attributes 553abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt vsBuilder->emitAttributes(qe); 554abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt 55574077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt GrGLVertToFrag v(kVec4f_GrSLType); 55674077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt args.fPB->addVarying("QuadEdge", &v); 5572dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt vsBuilder->codeAppendf("%s = %s;", v.vsOut(), qe.inQuadEdge()->fName); 5582dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt 5599b98932adaceb7ad0a617ade16616923f6bffe84joshualitt const BatchTracker& local = args.fBT.cast<BatchTracker>(); 5609b98932adaceb7ad0a617ade16616923f6bffe84joshualitt 5619b98932adaceb7ad0a617ade16616923f6bffe84joshualitt // Setup pass through color 5629b98932adaceb7ad0a617ade16616923f6bffe84joshualitt this->setupColorPassThrough(pb, local.fInputColorType, args.fOutputColor, NULL, 5639b98932adaceb7ad0a617ade16616923f6bffe84joshualitt &fColorUniform); 5649b98932adaceb7ad0a617ade16616923f6bffe84joshualitt 565abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt // Setup position 566e578a95d3ab16544794b94da4e7ae13fc2ce6244joshualitt this->setupPosition(pb, gpArgs, qe.inPosition()->fName); 567abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt 568abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt // emit transforms 56946d36f0e7b709a077c647841eee23bd3efdc4117robertphillips this->emitTransforms(args.fPB, gpArgs->fPositionVar, qe.inPosition()->fName, 570abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt qe.localMatrix(), args.fTransformsIn, args.fTransformsOut); 57190c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 57229bee0fe657fabf7c396502b69c9167fba13eaaaegdaniel GrGLFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); 57330ba436f04e61d4505fb854d5fc56079636e0788joshualitt 57430ba436f04e61d4505fb854d5fc56079636e0788joshualitt SkAssertResult(fsBuilder->enableFeature( 57530ba436f04e61d4505fb854d5fc56079636e0788joshualitt GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)); 57674077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt fsBuilder->codeAppendf("float edgeAlpha;"); 57730ba436f04e61d4505fb854d5fc56079636e0788joshualitt 57890c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org // keep the derivative instructions outside the conditional 57974077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt fsBuilder->codeAppendf("vec2 duvdx = dFdx(%s.xy);", v.fsIn()); 58074077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt fsBuilder->codeAppendf("vec2 duvdy = dFdy(%s.xy);", v.fsIn()); 58174077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt fsBuilder->codeAppendf("if (%s.z > 0.0 && %s.w > 0.0) {", v.fsIn(), v.fsIn()); 58290c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org // today we know z and w are in device space. We could use derivatives 58374077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt fsBuilder->codeAppendf("edgeAlpha = min(min(%s.z, %s.w) + 0.5, 1.0);", v.fsIn(), 58474077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt v.fsIn()); 58574077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt fsBuilder->codeAppendf ("} else {"); 58674077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt fsBuilder->codeAppendf("vec2 gF = vec2(2.0*%s.x*duvdx.x - duvdx.y," 58774077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt " 2.0*%s.x*duvdy.x - duvdy.y);", 58874077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt v.fsIn(), v.fsIn()); 58974077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt fsBuilder->codeAppendf("edgeAlpha = (%s.x*%s.x - %s.y);", v.fsIn(), v.fsIn(), 59074077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt v.fsIn()); 59174077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt fsBuilder->codeAppendf("edgeAlpha = " 59274077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt "clamp(0.5 - edgeAlpha / length(gF), 0.0, 1.0);}"); 59374077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt 5942dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt fsBuilder->codeAppendf("%s = vec4(edgeAlpha);", args.fOutputCoverage); 59590c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org } 59690c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 5979b98932adaceb7ad0a617ade16616923f6bffe84joshualitt static inline void GenKey(const GrGeometryProcessor& gp, 5989b98932adaceb7ad0a617ade16616923f6bffe84joshualitt const GrBatchTracker& bt, 599cfc18867d982119d9dc2888bf09f1093012daaddjvanverth const GrGLSLCaps&, 6009b98932adaceb7ad0a617ade16616923f6bffe84joshualitt GrProcessorKeyBuilder* b) { 6019b98932adaceb7ad0a617ade16616923f6bffe84joshualitt const BatchTracker& local = bt.cast<BatchTracker>(); 602e3ababe44315452cd33b96a18ce316ede09ff3c3joshualitt const QuadEdgeEffect& qee = gp.cast<QuadEdgeEffect>(); 60346d36f0e7b709a077c647841eee23bd3efdc4117robertphillips uint32_t key = local.fInputColorType << 16; 604e3ababe44315452cd33b96a18ce316ede09ff3c3joshualitt key |= local.fUsesLocalCoords && qee.localMatrix().hasPerspective() ? 0x1 : 0x0; 60546d36f0e7b709a077c647841eee23bd3efdc4117robertphillips b->add32(key); 6069b98932adaceb7ad0a617ade16616923f6bffe84joshualitt } 60790c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 6089b98932adaceb7ad0a617ade16616923f6bffe84joshualitt virtual void setData(const GrGLProgramDataManager& pdman, 6099b98932adaceb7ad0a617ade16616923f6bffe84joshualitt const GrPrimitiveProcessor& gp, 61036352bf5e38f45a70ee4f4fc132a38048d38206dmtklein const GrBatchTracker& bt) override { 6119b98932adaceb7ad0a617ade16616923f6bffe84joshualitt const BatchTracker& local = bt.cast<BatchTracker>(); 6129b98932adaceb7ad0a617ade16616923f6bffe84joshualitt if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) { 6139b98932adaceb7ad0a617ade16616923f6bffe84joshualitt GrGLfloat c[4]; 6149b98932adaceb7ad0a617ade16616923f6bffe84joshualitt GrColorToRGBAFloat(local.fColor, c); 6159b98932adaceb7ad0a617ade16616923f6bffe84joshualitt pdman.set4fv(fColorUniform, 1, c); 6169b98932adaceb7ad0a617ade16616923f6bffe84joshualitt fColor = local.fColor; 6179b98932adaceb7ad0a617ade16616923f6bffe84joshualitt } 6189b98932adaceb7ad0a617ade16616923f6bffe84joshualitt } 61990c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 620e3ababe44315452cd33b96a18ce316ede09ff3c3joshualitt void setTransformData(const GrPrimitiveProcessor& primProc, 621e3ababe44315452cd33b96a18ce316ede09ff3c3joshualitt const GrGLProgramDataManager& pdman, 622e3ababe44315452cd33b96a18ce316ede09ff3c3joshualitt int index, 623e3ababe44315452cd33b96a18ce316ede09ff3c3joshualitt const SkTArray<const GrCoordTransform*, true>& transforms) override { 624e3ababe44315452cd33b96a18ce316ede09ff3c3joshualitt this->setTransformDataHelper<QuadEdgeEffect>(primProc, pdman, index, transforms); 625e3ababe44315452cd33b96a18ce316ede09ff3c3joshualitt } 626e3ababe44315452cd33b96a18ce316ede09ff3c3joshualitt 62790c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org private: 6289b98932adaceb7ad0a617ade16616923f6bffe84joshualitt GrColor fColor; 6299b98932adaceb7ad0a617ade16616923f6bffe84joshualitt UniformHandle fColorUniform; 6309b98932adaceb7ad0a617ade16616923f6bffe84joshualitt 631249af15fb82833d2274850c589812b6e69df0033joshualitt typedef GrGLGeometryProcessor INHERITED; 63290c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org }; 633041e2dbc0614e3341e1349fd0e962744a45b6194skia.committer@gmail.com 634eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt virtual void getGLProcessorKey(const GrBatchTracker& bt, 635cfc18867d982119d9dc2888bf09f1093012daaddjvanverth const GrGLSLCaps& caps, 63636352bf5e38f45a70ee4f4fc132a38048d38206dmtklein GrProcessorKeyBuilder* b) const override { 637eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt GLProcessor::GenKey(*this, bt, caps, b); 638eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt } 639eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt 640abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt virtual GrGLPrimitiveProcessor* createGLInstance(const GrBatchTracker& bt, 641cfc18867d982119d9dc2888bf09f1093012daaddjvanverth const GrGLSLCaps&) const override { 642eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt return SkNEW_ARGS(GLProcessor, (*this, bt)); 643eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt } 644eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt 64536352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void initBatchTracker(GrBatchTracker* bt, const GrPipelineInfo& init) const override { 6469b98932adaceb7ad0a617ade16616923f6bffe84joshualitt BatchTracker* local = bt->cast<BatchTracker>(); 6479b98932adaceb7ad0a617ade16616923f6bffe84joshualitt local->fInputColorType = GetColorInputType(&local->fColor, this->color(), init, false); 648290c09b8bbd8d221d363150e2ce87158f4668df0joshualitt local->fUsesLocalCoords = init.fUsesLocalCoords; 6499b98932adaceb7ad0a617ade16616923f6bffe84joshualitt } 6509b98932adaceb7ad0a617ade16616923f6bffe84joshualitt 65190c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.orgprivate: 652d27f73ef27ff65a6a0a5d00aa8e5b784b1a0b47ejoshualitt QuadEdgeEffect(GrColor color, const SkMatrix& localMatrix) 653e3ababe44315452cd33b96a18ce316ede09ff3c3joshualitt : fColor(color) 654e3ababe44315452cd33b96a18ce316ede09ff3c3joshualitt , fLocalMatrix(localMatrix) { 655eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt this->initClassID<QuadEdgeEffect>(); 65671c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertexAttribType)); 65771c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt fInQuadEdge = &this->addVertexAttrib(Attribute("inQuadEdge", kVec4f_GrVertexAttribType)); 65890c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org } 65990c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 6609b98932adaceb7ad0a617ade16616923f6bffe84joshualitt struct BatchTracker { 6619b98932adaceb7ad0a617ade16616923f6bffe84joshualitt GrGPInput fInputColorType; 6629b98932adaceb7ad0a617ade16616923f6bffe84joshualitt GrColor fColor; 663290c09b8bbd8d221d363150e2ce87158f4668df0joshualitt bool fUsesLocalCoords; 6649b98932adaceb7ad0a617ade16616923f6bffe84joshualitt }; 6659b98932adaceb7ad0a617ade16616923f6bffe84joshualitt 66671c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt const Attribute* fInPosition; 66771c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt const Attribute* fInQuadEdge; 66888c23fc6e8ed0243159fd17d815b4f813805647bjoshualitt GrColor fColor; 669e3ababe44315452cd33b96a18ce316ede09ff3c3joshualitt SkMatrix fLocalMatrix; 670249af15fb82833d2274850c589812b6e69df0033joshualitt 671b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GR_DECLARE_GEOMETRY_PROCESSOR_TEST; 67290c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 6732e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt typedef GrGeometryProcessor INHERITED; 67490c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org}; 67590c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 676b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGR_DEFINE_GEOMETRY_PROCESSOR_TEST(QuadEdgeEffect); 67790c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 678b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGrGeometryProcessor* QuadEdgeEffect::TestCreate(SkRandom* random, 679b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrContext*, 680b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrDrawTargetCaps& caps, 681b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrTexture*[]) { 68290c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org // Doesn't work without derivative instructions. 683e9c0fc616d2a1632c285885b9b656b68ca8d4f24jvanverth return caps.shaderCaps()->shaderDerivativeSupport() ? 684d27f73ef27ff65a6a0a5d00aa8e5b784b1a0b47ejoshualitt QuadEdgeEffect::Create(GrRandomColor(random), 6854eaf9cef5a76098f78efac30beb966ac833d32c2joshualitt GrTest::TestMatrix(random)) : NULL; 68690c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org} 68790c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 68890c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////// 68990c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 6909853ccef19c200be93a6211f32589fa82a53067cjoshualittbool GrAAConvexPathRenderer::canDrawPath(const GrDrawTarget* target, 6918dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel const GrPipelineBuilder*, 6928059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt const SkMatrix& viewMatrix, 6939853ccef19c200be93a6211f32589fa82a53067cjoshualitt const SkPath& path, 6941899651ffc459f5462aa989cd6d08507947b67e4kkinnunen const GrStrokeInfo& stroke, 6958a4fc40b02fa0a8300ade26863f4ddae69197d62robertphillips@google.com bool antiAlias) const { 696e9c0fc616d2a1632c285885b9b656b68ca8d4f24jvanverth return (target->caps()->shaderCaps()->shaderDerivativeSupport() && antiAlias && 697e79f320ed6c5ec9f6164ba84be1ff586532e6517robertphillips@google.com stroke.isFillStyle() && !path.isInverseFillType() && path.isConvex()); 698c2099d2707abcc94e139627399aed4b8894b69bbbsalomon@google.com} 699c2099d2707abcc94e139627399aed4b8894b69bbbsalomon@google.com 700e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips// extract the result vertices and indices from the GrAAConvexTessellator 701e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillipsstatic void extract_verts(const GrAAConvexTessellator& tess, 702e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips void* vertices, 703e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips size_t vertexStride, 704e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips GrColor color, 705e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips uint16_t* idxs, 706e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips bool tweakAlphaForCoverage) { 707e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips intptr_t verts = reinterpret_cast<intptr_t>(vertices); 708e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips 709e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips for (int i = 0; i < tess.numPts(); ++i) { 710e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips *((SkPoint*)((intptr_t)verts + i * vertexStride)) = tess.point(i); 711e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips } 712e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips 713e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips // Make 'verts' point to the colors 714e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips verts += sizeof(SkPoint); 715e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips for (int i = 0; i < tess.numPts(); ++i) { 716e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips SkASSERT(tess.depth(i) >= -0.5f && tess.depth(i) <= 0.5f); 717e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips if (tweakAlphaForCoverage) { 718e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips SkASSERT(SkScalarRoundToInt(255.0f * (tess.depth(i) + 0.5f)) <= 255); 719e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips unsigned scale = SkScalarRoundToInt(255.0f * (tess.depth(i) + 0.5f)); 720e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips GrColor scaledColor = (0xff == scale) ? color : SkAlphaMulQ(color, scale); 721e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips *reinterpret_cast<GrColor*>(verts + i * vertexStride) = scaledColor; 722e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips } else { 723e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips *reinterpret_cast<GrColor*>(verts + i * vertexStride) = color; 724e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips *reinterpret_cast<float*>(verts + i * vertexStride + sizeof(GrColor)) = 725e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips tess.depth(i) + 0.5f; 726e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips } 727e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips } 728e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips 729e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips for (int i = 0; i < tess.numIndices(); ++i) { 730e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips idxs[i] = tess.index(i); 731e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips } 732e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips} 733e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips 734e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillipsstatic const GrGeometryProcessor* create_fill_gp(bool tweakAlphaForCoverage, 735e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips const SkMatrix& localMatrix) { 736e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips uint32_t flags = GrDefaultGeoProcFactory::kColor_GPType; 737e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips if (!tweakAlphaForCoverage) { 738e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips flags |= GrDefaultGeoProcFactory::kCoverage_GPType; 739e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips } 740e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips 7411ba8cc9193f13a812401e14b8037fdcf3f3acbacjoshualitt return GrDefaultGeoProcFactory::Create(flags, GrColor_WHITE, SkMatrix::I(), localMatrix); 742e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips} 743e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips 74427f398f04dff306418a142c27175eaa35d21a915joshualittclass AAConvexPathBatch : public GrBatch { 74527f398f04dff306418a142c27175eaa35d21a915joshualittpublic: 74627f398f04dff306418a142c27175eaa35d21a915joshualitt struct Geometry { 74727f398f04dff306418a142c27175eaa35d21a915joshualitt GrColor fColor; 74827f398f04dff306418a142c27175eaa35d21a915joshualitt SkMatrix fViewMatrix; 74927f398f04dff306418a142c27175eaa35d21a915joshualitt SkPath fPath; 75027f398f04dff306418a142c27175eaa35d21a915joshualitt }; 751c2099d2707abcc94e139627399aed4b8894b69bbbsalomon@google.com 75227f398f04dff306418a142c27175eaa35d21a915joshualitt static GrBatch* Create(const Geometry& geometry) { 75327f398f04dff306418a142c27175eaa35d21a915joshualitt return SkNEW_ARGS(AAConvexPathBatch, (geometry)); 75469cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com } 7554647f9059825c062169d4d454c12640d82ae16c0bsalomon@google.com 75636352bf5e38f45a70ee4f4fc132a38048d38206dmtklein const char* name() const override { return "AAConvexBatch"; } 75769cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com 75836352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void getInvariantOutputColor(GrInitInvariantOutput* out) const override { 75927f398f04dff306418a142c27175eaa35d21a915joshualitt // When this is called on a batch, there is only one geometry bundle 76027f398f04dff306418a142c27175eaa35d21a915joshualitt out->setKnownFourComponents(fGeoData[0].fColor); 76127f398f04dff306418a142c27175eaa35d21a915joshualitt } 76236352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override { 76327f398f04dff306418a142c27175eaa35d21a915joshualitt out->setUnknownSingleComponent(); 764af90f7f142a3939ca34f55b39460688e8eb5dc6bbsalomon@google.com } 765af90f7f142a3939ca34f55b39460688e8eb5dc6bbsalomon@google.com 76636352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void initBatchTracker(const GrPipelineInfo& init) override { 76727f398f04dff306418a142c27175eaa35d21a915joshualitt // Handle any color overrides 76827f398f04dff306418a142c27175eaa35d21a915joshualitt if (init.fColorIgnored) { 76927f398f04dff306418a142c27175eaa35d21a915joshualitt fGeoData[0].fColor = GrColor_ILLEGAL; 77027f398f04dff306418a142c27175eaa35d21a915joshualitt } else if (GrColor_ILLEGAL != init.fOverrideColor) { 77127f398f04dff306418a142c27175eaa35d21a915joshualitt fGeoData[0].fColor = init.fOverrideColor; 77227f398f04dff306418a142c27175eaa35d21a915joshualitt } 773af90f7f142a3939ca34f55b39460688e8eb5dc6bbsalomon@google.com 77427f398f04dff306418a142c27175eaa35d21a915joshualitt // setup batch properties 77527f398f04dff306418a142c27175eaa35d21a915joshualitt fBatch.fColorIgnored = init.fColorIgnored; 77627f398f04dff306418a142c27175eaa35d21a915joshualitt fBatch.fColor = fGeoData[0].fColor; 77727f398f04dff306418a142c27175eaa35d21a915joshualitt fBatch.fUsesLocalCoords = init.fUsesLocalCoords; 77827f398f04dff306418a142c27175eaa35d21a915joshualitt fBatch.fCoverageIgnored = init.fCoverageIgnored; 779e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips fBatch.fLinesOnly = SkPath::kLine_SegmentMask == fGeoData[0].fPath.getSegmentMasks(); 780e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips fBatch.fCanTweakAlphaForCoverage = init.fCanTweakAlphaForCoverage; 781e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips } 782e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips 783e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips void generateGeometryLinesOnly(GrBatchTarget* batchTarget, const GrPipeline* pipeline) { 784e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips bool canTweakAlphaForCoverage = this->canTweakAlphaForCoverage(); 785e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips 786e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips SkMatrix invert; 787e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips if (this->usesLocalCoords() && !this->viewMatrix().invert(&invert)) { 788e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips SkDebugf("Could not invert viewmatrix\n"); 789e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips return; 790e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips } 791e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips 792e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips // Setup GrGeometryProcessor 793e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips SkAutoTUnref<const GrGeometryProcessor> gp( 794e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips create_fill_gp(canTweakAlphaForCoverage, invert)); 795e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips 796e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips batchTarget->initDraw(gp, pipeline); 797e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips 798e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips // TODO remove this when batch is everywhere 799e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips GrPipelineInfo init; 800e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips init.fColorIgnored = fBatch.fColorIgnored; 801e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips init.fOverrideColor = GrColor_ILLEGAL; 802e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips init.fCoverageIgnored = fBatch.fCoverageIgnored; 803e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips init.fUsesLocalCoords = this->usesLocalCoords(); 804e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips gp->initBatchTracker(batchTarget->currentBatchTracker(), init); 805e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips 806e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips size_t vertexStride = gp->getVertexStride(); 807e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips 808e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips SkASSERT(canTweakAlphaForCoverage ? 809e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorAttr) : 810e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorCoverageAttr)); 811e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips 812e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips GrAAConvexTessellator tess; 813e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips 814e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips int instanceCount = fGeoData.count(); 815e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips 816e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips for (int i = 0; i < instanceCount; i++) { 817e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips tess.rewind(); 818e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips 819e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips Geometry& args = fGeoData[i]; 820e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips 821e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips if (!tess.tessellate(args.fViewMatrix, args.fPath)) { 822e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips continue; 823e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips } 824e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips 825e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips const GrVertexBuffer* vertexBuffer; 826e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips int firstVertex; 827e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips 828e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips void* verts = batchTarget->makeVertSpace(vertexStride, tess.numPts(), 829e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips &vertexBuffer, &firstVertex); 830e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips if (!verts) { 831e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips SkDebugf("Could not allocate vertices\n"); 832e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips return; 833e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips } 834e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips 835e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips const GrIndexBuffer* indexBuffer; 836e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips int firstIndex; 837e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips 838e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips uint16_t* idxs = batchTarget->makeIndexSpace(tess.numIndices(), 839e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips &indexBuffer, &firstIndex); 840e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips if (!idxs) { 841e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips SkDebugf("Could not allocate indices\n"); 842e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips return; 843e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips } 844e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips 845e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips extract_verts(tess, verts, vertexStride, args.fColor, idxs, canTweakAlphaForCoverage); 846e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips 847e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips GrVertices info; 848e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips info.initIndexed(kTriangles_GrPrimitiveType, 849e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips vertexBuffer, indexBuffer, 850e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips firstVertex, firstIndex, 851e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips tess.numPts(), tess.numIndices()); 852e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips batchTarget->draw(info); 853e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips } 85469cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com } 85569cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com 85636352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void generateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline) override { 857e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips#ifndef SK_IGNORE_LINEONLY_AA_CONVEX_PATH_OPTS 858e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips if (this->linesOnly()) { 859e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips this->generateGeometryLinesOnly(batchTarget, pipeline); 860e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips return; 861e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips } 862e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips#endif 863e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips 86427f398f04dff306418a142c27175eaa35d21a915joshualitt int instanceCount = fGeoData.count(); 865106655efdf2516f7084c19d6d5a7bc59fd8b866ccommit-bot@chromium.org 86627f398f04dff306418a142c27175eaa35d21a915joshualitt SkMatrix invert; 8677abe15d7a905e9a0d70809ebabfaac201bfae6f0joshualitt if (this->usesLocalCoords() && !this->viewMatrix().invert(&invert)) { 86827f398f04dff306418a142c27175eaa35d21a915joshualitt SkDebugf("Could not invert viewmatrix\n"); 86927f398f04dff306418a142c27175eaa35d21a915joshualitt return; 87027f398f04dff306418a142c27175eaa35d21a915joshualitt } 8714647f9059825c062169d4d454c12640d82ae16c0bsalomon@google.com 87227f398f04dff306418a142c27175eaa35d21a915joshualitt // Setup GrGeometryProcessor 87327f398f04dff306418a142c27175eaa35d21a915joshualitt SkAutoTUnref<GrGeometryProcessor> quadProcessor(QuadEdgeEffect::Create(this->color(), 87427f398f04dff306418a142c27175eaa35d21a915joshualitt invert)); 87527f398f04dff306418a142c27175eaa35d21a915joshualitt 87627f398f04dff306418a142c27175eaa35d21a915joshualitt batchTarget->initDraw(quadProcessor, pipeline); 87727f398f04dff306418a142c27175eaa35d21a915joshualitt 87827f398f04dff306418a142c27175eaa35d21a915joshualitt // TODO remove this when batch is everywhere 87927f398f04dff306418a142c27175eaa35d21a915joshualitt GrPipelineInfo init; 88027f398f04dff306418a142c27175eaa35d21a915joshualitt init.fColorIgnored = fBatch.fColorIgnored; 88127f398f04dff306418a142c27175eaa35d21a915joshualitt init.fOverrideColor = GrColor_ILLEGAL; 88227f398f04dff306418a142c27175eaa35d21a915joshualitt init.fCoverageIgnored = fBatch.fCoverageIgnored; 88327f398f04dff306418a142c27175eaa35d21a915joshualitt init.fUsesLocalCoords = this->usesLocalCoords(); 88427f398f04dff306418a142c27175eaa35d21a915joshualitt quadProcessor->initBatchTracker(batchTarget->currentBatchTracker(), init); 88527f398f04dff306418a142c27175eaa35d21a915joshualitt 88627f398f04dff306418a142c27175eaa35d21a915joshualitt // TODO generate all segments for all paths and use one vertex buffer 88727f398f04dff306418a142c27175eaa35d21a915joshualitt for (int i = 0; i < instanceCount; i++) { 88827f398f04dff306418a142c27175eaa35d21a915joshualitt Geometry& args = fGeoData[i]; 88927f398f04dff306418a142c27175eaa35d21a915joshualitt 89027f398f04dff306418a142c27175eaa35d21a915joshualitt // We use the fact that SkPath::transform path does subdivision based on 89127f398f04dff306418a142c27175eaa35d21a915joshualitt // perspective. Otherwise, we apply the view matrix when copying to the 89227f398f04dff306418a142c27175eaa35d21a915joshualitt // segment representation. 89327f398f04dff306418a142c27175eaa35d21a915joshualitt const SkMatrix* viewMatrix = &args.fViewMatrix; 89427f398f04dff306418a142c27175eaa35d21a915joshualitt if (viewMatrix->hasPerspective()) { 89527f398f04dff306418a142c27175eaa35d21a915joshualitt args.fPath.transform(*viewMatrix); 89627f398f04dff306418a142c27175eaa35d21a915joshualitt viewMatrix = &SkMatrix::I(); 89727f398f04dff306418a142c27175eaa35d21a915joshualitt } 89827f398f04dff306418a142c27175eaa35d21a915joshualitt 89927f398f04dff306418a142c27175eaa35d21a915joshualitt int vertexCount; 90027f398f04dff306418a142c27175eaa35d21a915joshualitt int indexCount; 90127f398f04dff306418a142c27175eaa35d21a915joshualitt enum { 90227f398f04dff306418a142c27175eaa35d21a915joshualitt kPreallocSegmentCnt = 512 / sizeof(Segment), 90327f398f04dff306418a142c27175eaa35d21a915joshualitt kPreallocDrawCnt = 4, 90427f398f04dff306418a142c27175eaa35d21a915joshualitt }; 90527f398f04dff306418a142c27175eaa35d21a915joshualitt SkSTArray<kPreallocSegmentCnt, Segment, true> segments; 90627f398f04dff306418a142c27175eaa35d21a915joshualitt SkPoint fanPt; 90727f398f04dff306418a142c27175eaa35d21a915joshualitt 90827f398f04dff306418a142c27175eaa35d21a915joshualitt if (!get_segments(args.fPath, *viewMatrix, &segments, &fanPt, &vertexCount, 90927f398f04dff306418a142c27175eaa35d21a915joshualitt &indexCount)) { 91027f398f04dff306418a142c27175eaa35d21a915joshualitt continue; 91127f398f04dff306418a142c27175eaa35d21a915joshualitt } 91227f398f04dff306418a142c27175eaa35d21a915joshualitt 91327f398f04dff306418a142c27175eaa35d21a915joshualitt const GrVertexBuffer* vertexBuffer; 91427f398f04dff306418a142c27175eaa35d21a915joshualitt int firstVertex; 91527f398f04dff306418a142c27175eaa35d21a915joshualitt 91627f398f04dff306418a142c27175eaa35d21a915joshualitt size_t vertexStride = quadProcessor->getVertexStride(); 917e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon QuadVertex* verts = reinterpret_cast<QuadVertex*>(batchTarget->makeVertSpace( 918e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon vertexStride, vertexCount, &vertexBuffer, &firstVertex)); 919e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon 920e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon if (!verts) { 9214b31de8328bbf3ee789157ae1dc6fe7cc74c796ajoshualitt SkDebugf("Could not allocate vertices\n"); 9224b31de8328bbf3ee789157ae1dc6fe7cc74c796ajoshualitt return; 9234b31de8328bbf3ee789157ae1dc6fe7cc74c796ajoshualitt } 9244b31de8328bbf3ee789157ae1dc6fe7cc74c796ajoshualitt 92527f398f04dff306418a142c27175eaa35d21a915joshualitt const GrIndexBuffer* indexBuffer; 92627f398f04dff306418a142c27175eaa35d21a915joshualitt int firstIndex; 92727f398f04dff306418a142c27175eaa35d21a915joshualitt 928e40d39725908d99d255496025411e5c9ca32663erobertphillips uint16_t *idxs = batchTarget->makeIndexSpace(indexCount, &indexBuffer, &firstIndex); 929e40d39725908d99d255496025411e5c9ca32663erobertphillips if (!idxs) { 9304b31de8328bbf3ee789157ae1dc6fe7cc74c796ajoshualitt SkDebugf("Could not allocate indices\n"); 9314b31de8328bbf3ee789157ae1dc6fe7cc74c796ajoshualitt return; 9324b31de8328bbf3ee789157ae1dc6fe7cc74c796ajoshualitt } 9334b31de8328bbf3ee789157ae1dc6fe7cc74c796ajoshualitt 93427f398f04dff306418a142c27175eaa35d21a915joshualitt SkSTArray<kPreallocDrawCnt, Draw, true> draws; 93527f398f04dff306418a142c27175eaa35d21a915joshualitt create_vertices(segments, fanPt, &draws, verts, idxs); 9367d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com 937e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon GrVertices vertices; 93827f398f04dff306418a142c27175eaa35d21a915joshualitt 93927f398f04dff306418a142c27175eaa35d21a915joshualitt for (int i = 0; i < draws.count(); ++i) { 94027f398f04dff306418a142c27175eaa35d21a915joshualitt const Draw& draw = draws[i]; 941e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon vertices.initIndexed(kTriangles_GrPrimitiveType, vertexBuffer, indexBuffer, 942e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon firstVertex, firstIndex, draw.fVertexCnt, draw.fIndexCnt); 943e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon batchTarget->draw(vertices); 944b5238a7571c243ba4a154a62575570c3078b3741bsalomon firstVertex += draw.fVertexCnt; 945b5238a7571c243ba4a154a62575570c3078b3741bsalomon firstIndex += draw.fIndexCnt; 94627f398f04dff306418a142c27175eaa35d21a915joshualitt } 94727f398f04dff306418a142c27175eaa35d21a915joshualitt } 94827f398f04dff306418a142c27175eaa35d21a915joshualitt } 94927f398f04dff306418a142c27175eaa35d21a915joshualitt 95027f398f04dff306418a142c27175eaa35d21a915joshualitt SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } 95127f398f04dff306418a142c27175eaa35d21a915joshualitt 95227f398f04dff306418a142c27175eaa35d21a915joshualittprivate: 95327f398f04dff306418a142c27175eaa35d21a915joshualitt AAConvexPathBatch(const Geometry& geometry) { 95427f398f04dff306418a142c27175eaa35d21a915joshualitt this->initClassID<AAConvexPathBatch>(); 95527f398f04dff306418a142c27175eaa35d21a915joshualitt fGeoData.push_back(geometry); 95699c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt 95799c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt // compute bounds 95899c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt fBounds = geometry.fPath.getBounds(); 95999c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt geometry.fViewMatrix.mapRect(&fBounds); 96027f398f04dff306418a142c27175eaa35d21a915joshualitt } 96127f398f04dff306418a142c27175eaa35d21a915joshualitt 96236352bf5e38f45a70ee4f4fc132a38048d38206dmtklein bool onCombineIfPossible(GrBatch* t) override { 96327f398f04dff306418a142c27175eaa35d21a915joshualitt AAConvexPathBatch* that = t->cast<AAConvexPathBatch>(); 96427f398f04dff306418a142c27175eaa35d21a915joshualitt 96527f398f04dff306418a142c27175eaa35d21a915joshualitt if (this->color() != that->color()) { 96627f398f04dff306418a142c27175eaa35d21a915joshualitt return false; 96727f398f04dff306418a142c27175eaa35d21a915joshualitt } 96827f398f04dff306418a142c27175eaa35d21a915joshualitt 96927f398f04dff306418a142c27175eaa35d21a915joshualitt SkASSERT(this->usesLocalCoords() == that->usesLocalCoords()); 97027f398f04dff306418a142c27175eaa35d21a915joshualitt if (this->usesLocalCoords() && !this->viewMatrix().cheapEqualTo(that->viewMatrix())) { 97127f398f04dff306418a142c27175eaa35d21a915joshualitt return false; 97227f398f04dff306418a142c27175eaa35d21a915joshualitt } 97327f398f04dff306418a142c27175eaa35d21a915joshualitt 974e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips if (this->linesOnly() != that->linesOnly()) { 975e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips return false; 976e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips } 977e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips 978e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips // In the event of two batches, one who can tweak, one who cannot, we just fall back to 979e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips // not tweaking 980e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips if (this->canTweakAlphaForCoverage() != that->canTweakAlphaForCoverage()) { 981e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips fBatch.fCanTweakAlphaForCoverage = false; 982e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips } 983e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips 98427f398f04dff306418a142c27175eaa35d21a915joshualitt fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin()); 98599c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt this->joinBounds(that->bounds()); 98627f398f04dff306418a142c27175eaa35d21a915joshualitt return true; 98727f398f04dff306418a142c27175eaa35d21a915joshualitt } 98827f398f04dff306418a142c27175eaa35d21a915joshualitt 98927f398f04dff306418a142c27175eaa35d21a915joshualitt GrColor color() const { return fBatch.fColor; } 990e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips bool linesOnly() const { return fBatch.fLinesOnly; } 99127f398f04dff306418a142c27175eaa35d21a915joshualitt bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; } 992e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips bool canTweakAlphaForCoverage() const { return fBatch.fCanTweakAlphaForCoverage; } 99327f398f04dff306418a142c27175eaa35d21a915joshualitt const SkMatrix& viewMatrix() const { return fGeoData[0].fViewMatrix; } 99427f398f04dff306418a142c27175eaa35d21a915joshualitt 99527f398f04dff306418a142c27175eaa35d21a915joshualitt struct BatchTracker { 99627f398f04dff306418a142c27175eaa35d21a915joshualitt GrColor fColor; 99727f398f04dff306418a142c27175eaa35d21a915joshualitt bool fUsesLocalCoords; 99827f398f04dff306418a142c27175eaa35d21a915joshualitt bool fColorIgnored; 99927f398f04dff306418a142c27175eaa35d21a915joshualitt bool fCoverageIgnored; 1000e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips bool fLinesOnly; 1001e16dfdbeadcb659e2ff4c56669fc08ee69e3f18frobertphillips bool fCanTweakAlphaForCoverage; 100227f398f04dff306418a142c27175eaa35d21a915joshualitt }; 100327f398f04dff306418a142c27175eaa35d21a915joshualitt 100427f398f04dff306418a142c27175eaa35d21a915joshualitt BatchTracker fBatch; 100527f398f04dff306418a142c27175eaa35d21a915joshualitt SkSTArray<1, Geometry, true> fGeoData; 100627f398f04dff306418a142c27175eaa35d21a915joshualitt}; 100727f398f04dff306418a142c27175eaa35d21a915joshualitt 100827f398f04dff306418a142c27175eaa35d21a915joshualittbool GrAAConvexPathRenderer::onDrawPath(GrDrawTarget* target, 100927f398f04dff306418a142c27175eaa35d21a915joshualitt GrPipelineBuilder* pipelineBuilder, 101027f398f04dff306418a142c27175eaa35d21a915joshualitt GrColor color, 101127f398f04dff306418a142c27175eaa35d21a915joshualitt const SkMatrix& vm, 101227f398f04dff306418a142c27175eaa35d21a915joshualitt const SkPath& path, 10131899651ffc459f5462aa989cd6d08507947b67e4kkinnunen const GrStrokeInfo&, 101427f398f04dff306418a142c27175eaa35d21a915joshualitt bool antiAlias) { 101527f398f04dff306418a142c27175eaa35d21a915joshualitt if (path.isEmpty()) { 101627f398f04dff306418a142c27175eaa35d21a915joshualitt return true; 10177d9ffc8a04533d0207efe5511b587e89ecb9d898bsalomon@google.com } 1018a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com 101927f398f04dff306418a142c27175eaa35d21a915joshualitt AAConvexPathBatch::Geometry geometry; 102027f398f04dff306418a142c27175eaa35d21a915joshualitt geometry.fColor = color; 102127f398f04dff306418a142c27175eaa35d21a915joshualitt geometry.fViewMatrix = vm; 102227f398f04dff306418a142c27175eaa35d21a915joshualitt geometry.fPath = path; 102327f398f04dff306418a142c27175eaa35d21a915joshualitt 102427f398f04dff306418a142c27175eaa35d21a915joshualitt SkAutoTUnref<GrBatch> batch(AAConvexPathBatch::Create(geometry)); 102599c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt target->drawBatch(pipelineBuilder, batch); 102627f398f04dff306418a142c27175eaa35d21a915joshualitt 1027c2099d2707abcc94e139627399aed4b8894b69bbbsalomon@google.com return true; 102827f398f04dff306418a142c27175eaa35d21a915joshualitt 102969cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com} 10308e5c177c8589e00f630ac6fae763c65cb9cae896joshualitt 10318e5c177c8589e00f630ac6fae763c65cb9cae896joshualitt/////////////////////////////////////////////////////////////////////////////////////////////////// 10328e5c177c8589e00f630ac6fae763c65cb9cae896joshualitt 10338e5c177c8589e00f630ac6fae763c65cb9cae896joshualitt#ifdef GR_TEST_UTILS 10348e5c177c8589e00f630ac6fae763c65cb9cae896joshualitt 10356c891107ce0a8431f2327cb8b2f1bfd363cabbbejoshualittBATCH_TEST_DEFINE(AAConvexPathBatch) { 10368e5c177c8589e00f630ac6fae763c65cb9cae896joshualitt AAConvexPathBatch::Geometry geometry; 10378e5c177c8589e00f630ac6fae763c65cb9cae896joshualitt geometry.fColor = GrRandomColor(random); 10386c891107ce0a8431f2327cb8b2f1bfd363cabbbejoshualitt geometry.fViewMatrix = GrTest::TestMatrixInvertible(random); 10398e5c177c8589e00f630ac6fae763c65cb9cae896joshualitt geometry.fPath = GrTest::TestPathConvex(random); 10408e5c177c8589e00f630ac6fae763c65cb9cae896joshualitt 10418e5c177c8589e00f630ac6fae763c65cb9cae896joshualitt return AAConvexPathBatch::Create(geometry); 10428e5c177c8589e00f630ac6fae763c65cb9cae896joshualitt} 10438e5c177c8589e00f630ac6fae763c65cb9cae896joshualitt 10448e5c177c8589e00f630ac6fae763c65cb9cae896joshualitt#endif 1045