Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(52)

Side by Side Diff: src/gpu/GrAAHairLinePathRenderer.cpp

Issue 1126613003: Revert of Move instanced index buffer creation to flush time (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/gpu/GrAAHairLinePathRenderer.h ('k') | src/gpu/GrAARectRenderer.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2011 Google Inc. 2 * Copyright 2011 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "GrAAHairLinePathRenderer.h" 8 #include "GrAAHairLinePathRenderer.h"
9 9
10 #include "GrBatch.h" 10 #include "GrBatch.h"
11 #include "GrBatchTarget.h" 11 #include "GrBatchTarget.h"
12 #include "GrBatchTest.h" 12 #include "GrBatchTest.h"
13 #include "GrBufferAllocPool.h" 13 #include "GrBufferAllocPool.h"
14 #include "GrContext.h" 14 #include "GrContext.h"
15 #include "GrDefaultGeoProcFactory.h" 15 #include "GrDefaultGeoProcFactory.h"
16 #include "GrDrawTargetCaps.h" 16 #include "GrDrawTargetCaps.h"
17 #include "GrGpu.h"
17 #include "GrIndexBuffer.h" 18 #include "GrIndexBuffer.h"
18 #include "GrPathUtils.h" 19 #include "GrPathUtils.h"
19 #include "GrPipelineBuilder.h" 20 #include "GrPipelineBuilder.h"
20 #include "GrProcessor.h" 21 #include "GrProcessor.h"
21 #include "GrResourceProvider.h"
22 #include "GrVertexBuffer.h" 22 #include "GrVertexBuffer.h"
23 #include "SkGeometry.h" 23 #include "SkGeometry.h"
24 #include "SkStroke.h" 24 #include "SkStroke.h"
25 #include "SkTemplates.h" 25 #include "SkTemplates.h"
26 26
27 #include "effects/GrBezierEffect.h" 27 #include "effects/GrBezierEffect.h"
28 28
29 #define PREALLOC_PTARRAY(N) SkSTArray<(N),SkPoint, true>
30
31 // quadratics are rendered as 5-sided polys in order to bound the 29 // quadratics are rendered as 5-sided polys in order to bound the
32 // AA stroke around the center-curve. See comments in push_quad_index_buffer and 30 // AA stroke around the center-curve. See comments in push_quad_index_buffer and
33 // bloat_quad. Quadratics and conics share an index buffer 31 // bloat_quad. Quadratics and conics share an index buffer
34 32
35 // lines are rendered as: 33 // lines are rendered as:
36 // *______________* 34 // *______________*
37 // |\ -_______ /| 35 // |\ -_______ /|
38 // | \ \ / | 36 // | \ \ / |
39 // | *--------* | 37 // | *--------* |
40 // | / ______/ \ | 38 // | / ______/ \ |
(...skipping 15 matching lines...) Expand all
56 // specified by these 9 indices: 54 // specified by these 9 indices:
57 static const uint16_t kQuadIdxBufPattern[] = { 55 static const uint16_t kQuadIdxBufPattern[] = {
58 0, 1, 2, 56 0, 1, 2,
59 2, 4, 3, 57 2, 4, 3,
60 1, 4, 2 58 1, 4, 2
61 }; 59 };
62 60
63 static const int kIdxsPerQuad = SK_ARRAY_COUNT(kQuadIdxBufPattern); 61 static const int kIdxsPerQuad = SK_ARRAY_COUNT(kQuadIdxBufPattern);
64 static const int kQuadNumVertices = 5; 62 static const int kQuadNumVertices = 5;
65 static const int kQuadsNumInIdxBuffer = 256; 63 static const int kQuadsNumInIdxBuffer = 256;
66 GR_DECLARE_STATIC_UNIQUE_KEY(gQuadsIndexBufferKey);
67
68 static const GrIndexBuffer* ref_quads_index_buffer(GrResourceProvider* resourceP rovider) {
69 GR_DEFINE_STATIC_UNIQUE_KEY(gQuadsIndexBufferKey);
70 return resourceProvider->refOrCreateInstancedIndexBuffer(
71 kQuadIdxBufPattern, kIdxsPerQuad, kQuadsNumInIdxBuffer, kQuadNumVertices ,
72 gQuadsIndexBufferKey);
73 }
74 64
75 65
76 // Each line segment is rendered as two quads and two triangles. 66 // Each line segment is rendered as two quads and two triangles.
77 // p0 and p1 have alpha = 1 while all other points have alpha = 0. 67 // p0 and p1 have alpha = 1 while all other points have alpha = 0.
78 // The four external points are offset 1 pixel perpendicular to the 68 // The four external points are offset 1 pixel perpendicular to the
79 // line and half a pixel parallel to the line. 69 // line and half a pixel parallel to the line.
80 // 70 //
81 // p4 p5 71 // p4 p5
82 // p0 p1 72 // p0 p1
83 // p2 p3 73 // p2 p3
84 // 74 //
85 // Each is drawn as six triangles specified by these 18 indices: 75 // Each is drawn as six triangles specified by these 18 indices:
86 76
87 static const uint16_t kLineSegIdxBufPattern[] = { 77 static const uint16_t kLineSegIdxBufPattern[] = {
88 0, 1, 3, 78 0, 1, 3,
89 0, 3, 2, 79 0, 3, 2,
90 0, 4, 5, 80 0, 4, 5,
91 0, 5, 1, 81 0, 5, 1,
92 0, 2, 4, 82 0, 2, 4,
93 1, 5, 3 83 1, 5, 3
94 }; 84 };
95 85
96 static const int kIdxsPerLineSeg = SK_ARRAY_COUNT(kLineSegIdxBufPattern); 86 static const int kIdxsPerLineSeg = SK_ARRAY_COUNT(kLineSegIdxBufPattern);
97 static const int kLineSegNumVertices = 6; 87 static const int kLineSegNumVertices = 6;
98 static const int kLineSegsNumInIdxBuffer = 256; 88 static const int kLineSegsNumInIdxBuffer = 256;
99 89
100 GR_DECLARE_STATIC_UNIQUE_KEY(gLinesIndexBufferKey); 90 GrPathRenderer* GrAAHairLinePathRenderer::Create(GrContext* context) {
101 91 GrGpu* gpu = context->getGpu();
102 static const GrIndexBuffer* ref_lines_index_buffer(GrResourceProvider* resourceP rovider) { 92 GrIndexBuffer* qIdxBuf = gpu->createInstancedIndexBuffer(kQuadIdxBufPattern,
103 GR_DEFINE_STATIC_UNIQUE_KEY(gLinesIndexBufferKey); 93 kIdxsPerQuad,
104 return resourceProvider->refOrCreateInstancedIndexBuffer( 94 kQuadsNumInIdxBuffe r,
105 kLineSegIdxBufPattern, kIdxsPerLineSeg, kLineSegsNumInIdxBuffer, kLineS egNumVertices, 95 kQuadNumVertices);
106 gLinesIndexBufferKey); 96 SkAutoTUnref<GrIndexBuffer> qIdxBuffer(qIdxBuf);
97 GrIndexBuffer* lIdxBuf = gpu->createInstancedIndexBuffer(kLineSegIdxBufPatte rn,
98 kIdxsPerLineSeg,
99 kLineSegsNumInIdxBu ffer,
100 kLineSegNumVertices );
101 SkAutoTUnref<GrIndexBuffer> lIdxBuffer(lIdxBuf);
102 return SkNEW_ARGS(GrAAHairLinePathRenderer,
103 (context, lIdxBuf, qIdxBuf));
107 } 104 }
108 105
106 GrAAHairLinePathRenderer::GrAAHairLinePathRenderer(
107 const GrContext* context,
108 const GrIndexBuffer* linesIndexBuffer,
109 const GrIndexBuffer* quadsIndexBuffer) {
110 fLinesIndexBuffer = linesIndexBuffer;
111 linesIndexBuffer->ref();
112 fQuadsIndexBuffer = quadsIndexBuffer;
113 quadsIndexBuffer->ref();
114 }
115
116 GrAAHairLinePathRenderer::~GrAAHairLinePathRenderer() {
117 fLinesIndexBuffer->unref();
118 fQuadsIndexBuffer->unref();
119 }
120
121 namespace {
122
123 #define PREALLOC_PTARRAY(N) SkSTArray<(N),SkPoint, true>
124
109 // Takes 178th time of logf on Z600 / VC2010 125 // Takes 178th time of logf on Z600 / VC2010
110 static int get_float_exp(float x) { 126 int get_float_exp(float x) {
111 GR_STATIC_ASSERT(sizeof(int) == sizeof(float)); 127 GR_STATIC_ASSERT(sizeof(int) == sizeof(float));
112 #ifdef SK_DEBUG 128 #ifdef SK_DEBUG
113 static bool tested; 129 static bool tested;
114 if (!tested) { 130 if (!tested) {
115 tested = true; 131 tested = true;
116 SkASSERT(get_float_exp(0.25f) == -2); 132 SkASSERT(get_float_exp(0.25f) == -2);
117 SkASSERT(get_float_exp(0.3f) == -2); 133 SkASSERT(get_float_exp(0.3f) == -2);
118 SkASSERT(get_float_exp(0.5f) == -1); 134 SkASSERT(get_float_exp(0.5f) == -1);
119 SkASSERT(get_float_exp(1.f) == 0); 135 SkASSERT(get_float_exp(1.f) == 0);
120 SkASSERT(get_float_exp(2.f) == 1); 136 SkASSERT(get_float_exp(2.f) == 1);
121 SkASSERT(get_float_exp(2.5f) == 1); 137 SkASSERT(get_float_exp(2.5f) == 1);
122 SkASSERT(get_float_exp(8.f) == 3); 138 SkASSERT(get_float_exp(8.f) == 3);
123 SkASSERT(get_float_exp(100.f) == 6); 139 SkASSERT(get_float_exp(100.f) == 6);
124 SkASSERT(get_float_exp(1000.f) == 9); 140 SkASSERT(get_float_exp(1000.f) == 9);
125 SkASSERT(get_float_exp(1024.f) == 10); 141 SkASSERT(get_float_exp(1024.f) == 10);
126 SkASSERT(get_float_exp(3000000.f) == 21); 142 SkASSERT(get_float_exp(3000000.f) == 21);
127 } 143 }
128 #endif 144 #endif
129 const int* iptr = (const int*)&x; 145 const int* iptr = (const int*)&x;
130 return (((*iptr) & 0x7f800000) >> 23) - 127; 146 return (((*iptr) & 0x7f800000) >> 23) - 127;
131 } 147 }
132 148
133 // Uses the max curvature function for quads to estimate 149 // Uses the max curvature function for quads to estimate
134 // where to chop the conic. If the max curvature is not 150 // where to chop the conic. If the max curvature is not
135 // found along the curve segment it will return 1 and 151 // found along the curve segment it will return 1 and
136 // dst[0] is the original conic. If it returns 2 the dst[0] 152 // dst[0] is the original conic. If it returns 2 the dst[0]
137 // and dst[1] are the two new conics. 153 // and dst[1] are the two new conics.
138 static int split_conic(const SkPoint src[3], SkConic dst[2], const SkScalar weig ht) { 154 int split_conic(const SkPoint src[3], SkConic dst[2], const SkScalar weight) {
139 SkScalar t = SkFindQuadMaxCurvature(src); 155 SkScalar t = SkFindQuadMaxCurvature(src);
140 if (t == 0) { 156 if (t == 0) {
141 if (dst) { 157 if (dst) {
142 dst[0].set(src, weight); 158 dst[0].set(src, weight);
143 } 159 }
144 return 1; 160 return 1;
145 } else { 161 } else {
146 if (dst) { 162 if (dst) {
147 SkConic conic; 163 SkConic conic;
148 conic.set(src, weight); 164 conic.set(src, weight);
149 conic.chopAt(t, dst); 165 conic.chopAt(t, dst);
150 } 166 }
151 return 2; 167 return 2;
152 } 168 }
153 } 169 }
154 170
155 // Calls split_conic on the entire conic and then once more on each subsection. 171 // Calls split_conic on the entire conic and then once more on each subsection.
156 // Most cases will result in either 1 conic (chop point is not within t range) 172 // Most cases will result in either 1 conic (chop point is not within t range)
157 // or 3 points (split once and then one subsection is split again). 173 // or 3 points (split once and then one subsection is split again).
158 static int chop_conic(const SkPoint src[3], SkConic dst[4], const SkScalar weigh t) { 174 int chop_conic(const SkPoint src[3], SkConic dst[4], const SkScalar weight) {
159 SkConic dstTemp[2]; 175 SkConic dstTemp[2];
160 int conicCnt = split_conic(src, dstTemp, weight); 176 int conicCnt = split_conic(src, dstTemp, weight);
161 if (2 == conicCnt) { 177 if (2 == conicCnt) {
162 int conicCnt2 = split_conic(dstTemp[0].fPts, dst, dstTemp[0].fW); 178 int conicCnt2 = split_conic(dstTemp[0].fPts, dst, dstTemp[0].fW);
163 conicCnt = conicCnt2 + split_conic(dstTemp[1].fPts, &dst[conicCnt2], dst Temp[1].fW); 179 conicCnt = conicCnt2 + split_conic(dstTemp[1].fPts, &dst[conicCnt2], dst Temp[1].fW);
164 } else { 180 } else {
165 dst[0] = dstTemp[0]; 181 dst[0] = dstTemp[0];
166 } 182 }
167 return conicCnt; 183 return conicCnt;
168 } 184 }
169 185
170 // returns 0 if quad/conic is degen or close to it 186 // returns 0 if quad/conic is degen or close to it
171 // in this case approx the path with lines 187 // in this case approx the path with lines
172 // otherwise returns 1 188 // otherwise returns 1
173 static int is_degen_quad_or_conic(const SkPoint p[3], SkScalar* dsqd) { 189 int is_degen_quad_or_conic(const SkPoint p[3], SkScalar* dsqd) {
174 static const SkScalar gDegenerateToLineTol = SK_Scalar1; 190 static const SkScalar gDegenerateToLineTol = SK_Scalar1;
175 static const SkScalar gDegenerateToLineTolSqd = 191 static const SkScalar gDegenerateToLineTolSqd =
176 SkScalarMul(gDegenerateToLineTol, gDegenerateToLineTol); 192 SkScalarMul(gDegenerateToLineTol, gDegenerateToLineTol);
177 193
178 if (p[0].distanceToSqd(p[1]) < gDegenerateToLineTolSqd || 194 if (p[0].distanceToSqd(p[1]) < gDegenerateToLineTolSqd ||
179 p[1].distanceToSqd(p[2]) < gDegenerateToLineTolSqd) { 195 p[1].distanceToSqd(p[2]) < gDegenerateToLineTolSqd) {
180 return 1; 196 return 1;
181 } 197 }
182 198
183 *dsqd = p[1].distanceToLineBetweenSqd(p[0], p[2]); 199 *dsqd = p[1].distanceToLineBetweenSqd(p[0], p[2]);
184 if (*dsqd < gDegenerateToLineTolSqd) { 200 if (*dsqd < gDegenerateToLineTolSqd) {
185 return 1; 201 return 1;
186 } 202 }
187 203
188 if (p[2].distanceToLineBetweenSqd(p[1], p[0]) < gDegenerateToLineTolSqd) { 204 if (p[2].distanceToLineBetweenSqd(p[1], p[0]) < gDegenerateToLineTolSqd) {
189 return 1; 205 return 1;
190 } 206 }
191 return 0; 207 return 0;
192 } 208 }
193 209
194 static int is_degen_quad_or_conic(const SkPoint p[3]) { 210 int is_degen_quad_or_conic(const SkPoint p[3]) {
195 SkScalar dsqd; 211 SkScalar dsqd;
196 return is_degen_quad_or_conic(p, &dsqd); 212 return is_degen_quad_or_conic(p, &dsqd);
197 } 213 }
198 214
199 // we subdivide the quads to avoid huge overfill 215 // we subdivide the quads to avoid huge overfill
200 // if it returns -1 then should be drawn as lines 216 // if it returns -1 then should be drawn as lines
201 static int num_quad_subdivs(const SkPoint p[3]) { 217 int num_quad_subdivs(const SkPoint p[3]) {
202 SkScalar dsqd; 218 SkScalar dsqd;
203 if (is_degen_quad_or_conic(p, &dsqd)) { 219 if (is_degen_quad_or_conic(p, &dsqd)) {
204 return -1; 220 return -1;
205 } 221 }
206 222
207 // tolerance of triangle height in pixels 223 // tolerance of triangle height in pixels
208 // tuned on windows Quadro FX 380 / Z600 224 // tuned on windows Quadro FX 380 / Z600
209 // trade off of fill vs cpu time on verts 225 // trade off of fill vs cpu time on verts
210 // maybe different when do this using gpu (geo or tess shaders) 226 // maybe different when do this using gpu (geo or tess shaders)
211 static const SkScalar gSubdivTol = 175 * SK_Scalar1; 227 static const SkScalar gSubdivTol = 175 * SK_Scalar1;
(...skipping 15 matching lines...) Expand all
227 243
228 /** 244 /**
229 * Generates the lines and quads to be rendered. Lines are always recorded in 245 * Generates the lines and quads to be rendered. Lines are always recorded in
230 * device space. We will do a device space bloat to account for the 1pixel 246 * device space. We will do a device space bloat to account for the 1pixel
231 * thickness. 247 * thickness.
232 * Quads are recorded in device space unless m contains 248 * Quads are recorded in device space unless m contains
233 * perspective, then in they are in src space. We do this because we will 249 * perspective, then in they are in src space. We do this because we will
234 * subdivide large quads to reduce over-fill. This subdivision has to be 250 * subdivide large quads to reduce over-fill. This subdivision has to be
235 * performed before applying the perspective matrix. 251 * performed before applying the perspective matrix.
236 */ 252 */
237 static int gather_lines_and_quads(const SkPath& path, 253 int gather_lines_and_quads(const SkPath& path,
238 const SkMatrix& m, 254 const SkMatrix& m,
239 const SkIRect& devClipBounds, 255 const SkIRect& devClipBounds,
240 GrAAHairLinePathRenderer::PtArray* lines, 256 GrAAHairLinePathRenderer::PtArray* lines,
241 GrAAHairLinePathRenderer::PtArray* quads, 257 GrAAHairLinePathRenderer::PtArray* quads,
242 GrAAHairLinePathRenderer::PtArray* conics, 258 GrAAHairLinePathRenderer::PtArray* conics,
243 GrAAHairLinePathRenderer::IntArray* quadSubdiv Cnts, 259 GrAAHairLinePathRenderer::IntArray* quadSubdivCnts,
244 GrAAHairLinePathRenderer::FloatArray* conicWei ghts) { 260 GrAAHairLinePathRenderer::FloatArray* conicWeights) {
245 SkPath::Iter iter(path, false); 261 SkPath::Iter iter(path, false);
246 262
247 int totalQuadCount = 0; 263 int totalQuadCount = 0;
248 SkRect bounds; 264 SkRect bounds;
249 SkIRect ibounds; 265 SkIRect ibounds;
250 266
251 bool persp = m.hasPerspective(); 267 bool persp = m.hasPerspective();
252 268
253 for (;;) { 269 for (;;) {
254 SkPoint pathPts[4]; 270 SkPoint pathPts[4];
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
418 } fConic; 434 } fConic;
419 SkVector fQuadCoord; 435 SkVector fQuadCoord;
420 struct { 436 struct {
421 SkScalar fBogus[4]; 437 SkScalar fBogus[4];
422 }; 438 };
423 }; 439 };
424 }; 440 };
425 441
426 GR_STATIC_ASSERT(sizeof(BezierVertex) == 3 * sizeof(SkPoint)); 442 GR_STATIC_ASSERT(sizeof(BezierVertex) == 3 * sizeof(SkPoint));
427 443
428 static void intersect_lines(const SkPoint& ptA, const SkVector& normA, 444 void intersect_lines(const SkPoint& ptA, const SkVector& normA,
429 const SkPoint& ptB, const SkVector& normB, 445 const SkPoint& ptB, const SkVector& normB,
430 SkPoint* result) { 446 SkPoint* result) {
431 447
432 SkScalar lineAW = -normA.dot(ptA); 448 SkScalar lineAW = -normA.dot(ptA);
433 SkScalar lineBW = -normB.dot(ptB); 449 SkScalar lineBW = -normB.dot(ptB);
434 450
435 SkScalar wInv = SkScalarMul(normA.fX, normB.fY) - 451 SkScalar wInv = SkScalarMul(normA.fX, normB.fY) -
436 SkScalarMul(normA.fY, normB.fX); 452 SkScalarMul(normA.fY, normB.fX);
437 wInv = SkScalarInvert(wInv); 453 wInv = SkScalarInvert(wInv);
438 454
439 result->fX = SkScalarMul(normA.fY, lineBW) - SkScalarMul(lineAW, normB.fY); 455 result->fX = SkScalarMul(normA.fY, lineBW) - SkScalarMul(lineAW, normB.fY);
440 result->fX = SkScalarMul(result->fX, wInv); 456 result->fX = SkScalarMul(result->fX, wInv);
441 457
442 result->fY = SkScalarMul(lineAW, normB.fX) - SkScalarMul(normA.fX, lineBW); 458 result->fY = SkScalarMul(lineAW, normB.fX) - SkScalarMul(normA.fX, lineBW);
443 result->fY = SkScalarMul(result->fY, wInv); 459 result->fY = SkScalarMul(result->fY, wInv);
444 } 460 }
445 461
446 static void set_uv_quad(const SkPoint qpts[3], BezierVertex verts[kQuadNumVertic es]) { 462 void set_uv_quad(const SkPoint qpts[3], BezierVertex verts[kQuadNumVertices]) {
447 // this should be in the src space, not dev coords, when we have perspective 463 // this should be in the src space, not dev coords, when we have perspective
448 GrPathUtils::QuadUVMatrix DevToUV(qpts); 464 GrPathUtils::QuadUVMatrix DevToUV(qpts);
449 DevToUV.apply<kQuadNumVertices, sizeof(BezierVertex), sizeof(SkPoint)>(verts ); 465 DevToUV.apply<kQuadNumVertices, sizeof(BezierVertex), sizeof(SkPoint)>(verts );
450 } 466 }
451 467
452 static void bloat_quad(const SkPoint qpts[3], const SkMatrix* toDevice, 468 void bloat_quad(const SkPoint qpts[3], const SkMatrix* toDevice,
453 const SkMatrix* toSrc, BezierVertex verts[kQuadNumVertice s]) { 469 const SkMatrix* toSrc, BezierVertex verts[kQuadNumVertices]) {
454 SkASSERT(!toDevice == !toSrc); 470 SkASSERT(!toDevice == !toSrc);
455 // original quad is specified by tri a,b,c 471 // original quad is specified by tri a,b,c
456 SkPoint a = qpts[0]; 472 SkPoint a = qpts[0];
457 SkPoint b = qpts[1]; 473 SkPoint b = qpts[1];
458 SkPoint c = qpts[2]; 474 SkPoint c = qpts[2];
459 475
460 if (toDevice) { 476 if (toDevice) {
461 toDevice->mapPoints(&a, 1); 477 toDevice->mapPoints(&a, 1);
462 toDevice->mapPoints(&b, 1); 478 toDevice->mapPoints(&b, 1);
463 toDevice->mapPoints(&c, 1); 479 toDevice->mapPoints(&c, 1);
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
521 } 537 }
522 } 538 }
523 539
524 // Equations based off of Loop-Blinn Quadratic GPU Rendering 540 // Equations based off of Loop-Blinn Quadratic GPU Rendering
525 // Input Parametric: 541 // Input Parametric:
526 // P(t) = (P0*(1-t)^2 + 2*w*P1*t*(1-t) + P2*t^2) / (1-t)^2 + 2*w*t*(1-t) + t^2) 542 // P(t) = (P0*(1-t)^2 + 2*w*P1*t*(1-t) + P2*t^2) / (1-t)^2 + 2*w*t*(1-t) + t^2)
527 // Output Implicit: 543 // Output Implicit:
528 // f(x, y, w) = f(P) = K^2 - LM 544 // f(x, y, w) = f(P) = K^2 - LM
529 // K = dot(k, P), L = dot(l, P), M = dot(m, P) 545 // K = dot(k, P), L = dot(l, P), M = dot(m, P)
530 // k, l, m are calculated in function GrPathUtils::getConicKLM 546 // k, l, m are calculated in function GrPathUtils::getConicKLM
531 static void set_conic_coeffs(const SkPoint p[3], BezierVertex verts[kQuadNumVert ices], 547 void set_conic_coeffs(const SkPoint p[3], BezierVertex verts[kQuadNumVertices],
532 const SkScalar weight) { 548 const SkScalar weight) {
533 SkScalar klm[9]; 549 SkScalar klm[9];
534 550
535 GrPathUtils::getConicKLM(p, weight, klm); 551 GrPathUtils::getConicKLM(p, weight, klm);
536 552
537 for (int i = 0; i < kQuadNumVertices; ++i) { 553 for (int i = 0; i < kQuadNumVertices; ++i) {
538 const SkPoint pnt = verts[i].fPos; 554 const SkPoint pnt = verts[i].fPos;
539 verts[i].fConic.fK = pnt.fX * klm[0] + pnt.fY * klm[1] + klm[2]; 555 verts[i].fConic.fK = pnt.fX * klm[0] + pnt.fY * klm[1] + klm[2];
540 verts[i].fConic.fL = pnt.fX * klm[3] + pnt.fY * klm[4] + klm[5]; 556 verts[i].fConic.fL = pnt.fX * klm[3] + pnt.fY * klm[4] + klm[5];
541 verts[i].fConic.fM = pnt.fX * klm[6] + pnt.fY * klm[7] + klm[8]; 557 verts[i].fConic.fM = pnt.fX * klm[6] + pnt.fY * klm[7] + klm[8];
542 } 558 }
543 } 559 }
544 560
545 static void add_conics(const SkPoint p[3], 561 void add_conics(const SkPoint p[3],
546 const SkScalar weight, 562 const SkScalar weight,
547 const SkMatrix* toDevice, 563 const SkMatrix* toDevice,
548 const SkMatrix* toSrc, 564 const SkMatrix* toSrc,
549 BezierVertex** vert) { 565 BezierVertex** vert) {
550 bloat_quad(p, toDevice, toSrc, *vert); 566 bloat_quad(p, toDevice, toSrc, *vert);
551 set_conic_coeffs(p, *vert, weight); 567 set_conic_coeffs(p, *vert, weight);
552 *vert += kQuadNumVertices; 568 *vert += kQuadNumVertices;
553 } 569 }
554 570
555 static void add_quads(const SkPoint p[3], 571 void add_quads(const SkPoint p[3],
556 int subdiv, 572 int subdiv,
557 const SkMatrix* toDevice, 573 const SkMatrix* toDevice,
558 const SkMatrix* toSrc, 574 const SkMatrix* toSrc,
559 BezierVertex** vert) { 575 BezierVertex** vert) {
560 SkASSERT(subdiv >= 0); 576 SkASSERT(subdiv >= 0);
561 if (subdiv) { 577 if (subdiv) {
562 SkPoint newP[5]; 578 SkPoint newP[5];
563 SkChopQuadAtHalf(p, newP); 579 SkChopQuadAtHalf(p, newP);
564 add_quads(newP + 0, subdiv-1, toDevice, toSrc, vert); 580 add_quads(newP + 0, subdiv-1, toDevice, toSrc, vert);
565 add_quads(newP + 2, subdiv-1, toDevice, toSrc, vert); 581 add_quads(newP + 2, subdiv-1, toDevice, toSrc, vert);
566 } else { 582 } else {
567 bloat_quad(p, toDevice, toSrc, *vert); 583 bloat_quad(p, toDevice, toSrc, *vert);
568 set_uv_quad(p, *vert); 584 set_uv_quad(p, *vert);
569 *vert += kQuadNumVertices; 585 *vert += kQuadNumVertices;
570 } 586 }
571 } 587 }
572 588
573 static void add_line(const SkPoint p[2], 589 void add_line(const SkPoint p[2],
574 const SkMatrix* toSrc, 590 const SkMatrix* toSrc,
575 uint8_t coverage, 591 uint8_t coverage,
576 LineVertex** vert) { 592 LineVertex** vert) {
577 const SkPoint& a = p[0]; 593 const SkPoint& a = p[0];
578 const SkPoint& b = p[1]; 594 const SkPoint& b = p[1];
579 595
580 SkVector ortho, vec = b; 596 SkVector ortho, vec = b;
581 vec -= a; 597 vec -= a;
582 598
583 if (vec.setLength(SK_ScalarHalf)) { 599 if (vec.setLength(SK_ScalarHalf)) {
584 // Create a vector orthogonal to 'vec' and of unit length 600 // Create a vector orthogonal to 'vec' and of unit length
585 ortho.fX = 2.0f * vec.fY; 601 ortho.fX = 2.0f * vec.fY;
586 ortho.fY = -2.0f * vec.fX; 602 ortho.fY = -2.0f * vec.fX;
(...skipping 21 matching lines...) Expand all
608 } else { 624 } else {
609 // just make it degenerate and likely offscreen 625 // just make it degenerate and likely offscreen
610 for (int i = 0; i < kLineSegNumVertices; ++i) { 626 for (int i = 0; i < kLineSegNumVertices; ++i) {
611 (*vert)[i].fPos.set(SK_ScalarMax, SK_ScalarMax); 627 (*vert)[i].fPos.set(SK_ScalarMax, SK_ScalarMax);
612 } 628 }
613 } 629 }
614 630
615 *vert += kLineSegNumVertices; 631 *vert += kLineSegNumVertices;
616 } 632 }
617 633
634 }
635
618 /////////////////////////////////////////////////////////////////////////////// 636 ///////////////////////////////////////////////////////////////////////////////
619 637
620 bool GrAAHairLinePathRenderer::canDrawPath(const GrDrawTarget* target, 638 bool GrAAHairLinePathRenderer::canDrawPath(const GrDrawTarget* target,
621 const GrPipelineBuilder* pipelineBuil der, 639 const GrPipelineBuilder* pipelineBuil der,
622 const SkMatrix& viewMatrix, 640 const SkMatrix& viewMatrix,
623 const SkPath& path, 641 const SkPath& path,
624 const GrStrokeInfo& stroke, 642 const GrStrokeInfo& stroke,
625 bool antiAlias) const { 643 bool antiAlias) const {
626 if (!antiAlias) { 644 if (!antiAlias) {
627 return false; 645 return false;
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
678 class AAHairlineBatch : public GrBatch { 696 class AAHairlineBatch : public GrBatch {
679 public: 697 public:
680 struct Geometry { 698 struct Geometry {
681 GrColor fColor; 699 GrColor fColor;
682 uint8_t fCoverage; 700 uint8_t fCoverage;
683 SkMatrix fViewMatrix; 701 SkMatrix fViewMatrix;
684 SkPath fPath; 702 SkPath fPath;
685 SkIRect fDevClipBounds; 703 SkIRect fDevClipBounds;
686 }; 704 };
687 705
688 static GrBatch* Create(const Geometry& geometry) { 706 // TODO Batch itself should not hold on to index buffers. Instead, these sh ould live in the
689 return SkNEW_ARGS(AAHairlineBatch, (geometry)); 707 // cache.
708 static GrBatch* Create(const Geometry& geometry, const GrIndexBuffer* linesI ndexBuffer,
709 const GrIndexBuffer* quadsIndexBuffer) {
710 return SkNEW_ARGS(AAHairlineBatch, (geometry, linesIndexBuffer, quadsInd exBuffer));
690 } 711 }
691 712
692 const char* name() const override { return "AAHairlineBatch"; } 713 const char* name() const override { return "AAHairlineBatch"; }
693 714
694 void getInvariantOutputColor(GrInitInvariantOutput* out) const override { 715 void getInvariantOutputColor(GrInitInvariantOutput* out) const override {
695 // When this is called on a batch, there is only one geometry bundle 716 // When this is called on a batch, there is only one geometry bundle
696 out->setKnownFourComponents(fGeoData[0].fColor); 717 out->setKnownFourComponents(fGeoData[0].fColor);
697 } 718 }
698 void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override { 719 void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override {
699 out->setUnknownSingleComponent(); 720 out->setUnknownSingleComponent();
(...skipping 17 matching lines...) Expand all
717 738
718 void generateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline ) override; 739 void generateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline ) override;
719 740
720 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } 741 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
721 742
722 private: 743 private:
723 typedef SkTArray<SkPoint, true> PtArray; 744 typedef SkTArray<SkPoint, true> PtArray;
724 typedef SkTArray<int, true> IntArray; 745 typedef SkTArray<int, true> IntArray;
725 typedef SkTArray<float, true> FloatArray; 746 typedef SkTArray<float, true> FloatArray;
726 747
727 AAHairlineBatch(const Geometry& geometry) { 748 AAHairlineBatch(const Geometry& geometry, const GrIndexBuffer* linesIndexBuf fer,
749 const GrIndexBuffer* quadsIndexBuffer)
750 : fLinesIndexBuffer(linesIndexBuffer)
751 , fQuadsIndexBuffer(quadsIndexBuffer) {
752 SkASSERT(linesIndexBuffer && quadsIndexBuffer);
728 this->initClassID<AAHairlineBatch>(); 753 this->initClassID<AAHairlineBatch>();
729 fGeoData.push_back(geometry); 754 fGeoData.push_back(geometry);
730 755
731 // compute bounds 756 // compute bounds
732 fBounds = geometry.fPath.getBounds(); 757 fBounds = geometry.fPath.getBounds();
733 geometry.fViewMatrix.mapRect(&fBounds); 758 geometry.fViewMatrix.mapRect(&fBounds);
734 } 759 }
735 760
736 bool onCombineIfPossible(GrBatch* t) override { 761 bool onCombineIfPossible(GrBatch* t) override {
737 AAHairlineBatch* that = t->cast<AAHairlineBatch>(); 762 AAHairlineBatch* that = t->cast<AAHairlineBatch>();
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
776 GrColor fColor; 801 GrColor fColor;
777 uint8_t fCoverage; 802 uint8_t fCoverage;
778 SkRect fDevBounds; 803 SkRect fDevBounds;
779 bool fUsesLocalCoords; 804 bool fUsesLocalCoords;
780 bool fColorIgnored; 805 bool fColorIgnored;
781 bool fCoverageIgnored; 806 bool fCoverageIgnored;
782 }; 807 };
783 808
784 BatchTracker fBatch; 809 BatchTracker fBatch;
785 SkSTArray<1, Geometry, true> fGeoData; 810 SkSTArray<1, Geometry, true> fGeoData;
811 const GrIndexBuffer* fLinesIndexBuffer;
812 const GrIndexBuffer* fQuadsIndexBuffer;
786 }; 813 };
787 814
788 void AAHairlineBatch::generateGeometry(GrBatchTarget* batchTarget, const GrPipel ine* pipeline) { 815 void AAHairlineBatch::generateGeometry(GrBatchTarget* batchTarget, const GrPipel ine* pipeline) {
789 // Setup the viewmatrix and localmatrix for the GrGeometryProcessor. 816 // Setup the viewmatrix and localmatrix for the GrGeometryProcessor.
790 SkMatrix invert; 817 SkMatrix invert;
791 if (!this->viewMatrix().invert(&invert)) { 818 if (!this->viewMatrix().invert(&invert)) {
792 return; 819 return;
793 } 820 }
794 821
795 // we will transform to identity space if the viewmatrix does not have persp ective 822 // we will transform to identity space if the viewmatrix does not have persp ective
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
846 const Geometry& args = fGeoData[i]; 873 const Geometry& args = fGeoData[i];
847 quadCount += gather_lines_and_quads(args.fPath, args.fViewMatrix, args.f DevClipBounds, 874 quadCount += gather_lines_and_quads(args.fPath, args.fViewMatrix, args.f DevClipBounds,
848 &lines, &quads, &conics, &qSubdivs, &cWeights); 875 &lines, &quads, &conics, &qSubdivs, &cWeights);
849 } 876 }
850 877
851 int lineCount = lines.count() / 2; 878 int lineCount = lines.count() / 2;
852 int conicCount = conics.count() / 3; 879 int conicCount = conics.count() / 3;
853 880
854 // do lines first 881 // do lines first
855 if (lineCount) { 882 if (lineCount) {
856 SkAutoTUnref<const GrIndexBuffer> linesIndexBuffer(
857 ref_lines_index_buffer(batchTarget->resourceProvider()));
858 batchTarget->initDraw(lineGP, pipeline); 883 batchTarget->initDraw(lineGP, pipeline);
859 884
860 // TODO remove this when batch is everywhere 885 // TODO remove this when batch is everywhere
861 GrPipelineInfo init; 886 GrPipelineInfo init;
862 init.fColorIgnored = fBatch.fColorIgnored; 887 init.fColorIgnored = fBatch.fColorIgnored;
863 init.fOverrideColor = GrColor_ILLEGAL; 888 init.fOverrideColor = GrColor_ILLEGAL;
864 init.fCoverageIgnored = fBatch.fCoverageIgnored; 889 init.fCoverageIgnored = fBatch.fCoverageIgnored;
865 init.fUsesLocalCoords = this->usesLocalCoords(); 890 init.fUsesLocalCoords = this->usesLocalCoords();
866 lineGP->initBatchTracker(batchTarget->currentBatchTracker(), init); 891 lineGP->initBatchTracker(batchTarget->currentBatchTracker(), init);
867 892
868 const GrVertexBuffer* vertexBuffer; 893 const GrVertexBuffer* vertexBuffer;
869 int firstVertex; 894 int firstVertex;
870 895
871 size_t vertexStride = lineGP->getVertexStride(); 896 size_t vertexStride = lineGP->getVertexStride();
872 int vertexCount = kLineSegNumVertices * lineCount; 897 int vertexCount = kLineSegNumVertices * lineCount;
873 void *vertices = batchTarget->vertexPool()->makeSpace(vertexStride, 898 void *vertices = batchTarget->vertexPool()->makeSpace(vertexStride,
874 vertexCount, 899 vertexCount,
875 &vertexBuffer, 900 &vertexBuffer,
876 &firstVertex); 901 &firstVertex);
877 902
878 if (!vertices || !linesIndexBuffer) { 903 if (!vertices) {
879 SkDebugf("Could not allocate vertices\n"); 904 SkDebugf("Could not allocate vertices\n");
880 return; 905 return;
881 } 906 }
882 907
883 SkASSERT(lineGP->getVertexStride() == sizeof(LineVertex)); 908 SkASSERT(lineGP->getVertexStride() == sizeof(LineVertex));
884 909
885 LineVertex* verts = reinterpret_cast<LineVertex*>(vertices); 910 LineVertex* verts = reinterpret_cast<LineVertex*>(vertices);
886 for (int i = 0; i < lineCount; ++i) { 911 for (int i = 0; i < lineCount; ++i) {
887 add_line(&lines[2*i], toSrc, this->coverage(), &verts); 912 add_line(&lines[2*i], toSrc, this->coverage(), &verts);
888 } 913 }
889 914
890 { 915 {
891 GrDrawTarget::DrawInfo info; 916 GrDrawTarget::DrawInfo info;
892 info.setVertexBuffer(vertexBuffer); 917 info.setVertexBuffer(vertexBuffer);
893 info.setIndexBuffer(linesIndexBuffer); 918 info.setIndexBuffer(fLinesIndexBuffer);
894 info.setPrimitiveType(kTriangles_GrPrimitiveType); 919 info.setPrimitiveType(kTriangles_GrPrimitiveType);
895 info.setStartIndex(0); 920 info.setStartIndex(0);
896 921
897 int lines = 0; 922 int lines = 0;
898 while (lines < lineCount) { 923 while (lines < lineCount) {
899 int n = SkTMin(lineCount - lines, kLineSegsNumInIdxBuffer); 924 int n = SkTMin(lineCount - lines, kLineSegsNumInIdxBuffer);
900 925
901 info.setStartVertex(kLineSegNumVertices*lines + firstVertex); 926 info.setStartVertex(kLineSegNumVertices*lines + firstVertex);
902 info.setVertexCount(kLineSegNumVertices*n); 927 info.setVertexCount(kLineSegNumVertices*n);
903 info.setIndexCount(kIdxsPerLineSeg*n); 928 info.setIndexCount(kIdxsPerLineSeg*n);
904 batchTarget->draw(info); 929 batchTarget->draw(info);
905 930
906 lines += n; 931 lines += n;
907 } 932 }
908 } 933 }
909 } 934 }
910 935
911 if (quadCount || conicCount) { 936 if (quadCount || conicCount) {
912 const GrVertexBuffer* vertexBuffer; 937 const GrVertexBuffer* vertexBuffer;
913 int firstVertex; 938 int firstVertex;
914 939
915 SkAutoTUnref<const GrIndexBuffer> quadsIndexBuffer(
916 ref_quads_index_buffer(batchTarget->resourceProvider()));
917
918 size_t vertexStride = sizeof(BezierVertex); 940 size_t vertexStride = sizeof(BezierVertex);
919 int vertexCount = kQuadNumVertices * quadCount + kQuadNumVertices * coni cCount; 941 int vertexCount = kQuadNumVertices * quadCount + kQuadNumVertices * coni cCount;
920 void *vertices = batchTarget->vertexPool()->makeSpace(vertexStride, 942 void *vertices = batchTarget->vertexPool()->makeSpace(vertexStride,
921 vertexCount, 943 vertexCount,
922 &vertexBuffer, 944 &vertexBuffer,
923 &firstVertex); 945 &firstVertex);
924 946
925 if (!vertices || !quadsIndexBuffer) { 947 if (!vertices) {
926 SkDebugf("Could not allocate vertices\n"); 948 SkDebugf("Could not allocate vertices\n");
927 return; 949 return;
928 } 950 }
929 951
930 // Setup vertices 952 // Setup vertices
931 BezierVertex* verts = reinterpret_cast<BezierVertex*>(vertices); 953 BezierVertex* verts = reinterpret_cast<BezierVertex*>(vertices);
932 954
933 int unsubdivQuadCnt = quads.count() / 3; 955 int unsubdivQuadCnt = quads.count() / 3;
934 for (int i = 0; i < unsubdivQuadCnt; ++i) { 956 for (int i = 0; i < unsubdivQuadCnt; ++i) {
935 SkASSERT(qSubdivs[i] >= 0); 957 SkASSERT(qSubdivs[i] >= 0);
(...skipping 12 matching lines...) Expand all
948 GrPipelineInfo init; 970 GrPipelineInfo init;
949 init.fColorIgnored = fBatch.fColorIgnored; 971 init.fColorIgnored = fBatch.fColorIgnored;
950 init.fOverrideColor = GrColor_ILLEGAL; 972 init.fOverrideColor = GrColor_ILLEGAL;
951 init.fCoverageIgnored = fBatch.fCoverageIgnored; 973 init.fCoverageIgnored = fBatch.fCoverageIgnored;
952 init.fUsesLocalCoords = this->usesLocalCoords(); 974 init.fUsesLocalCoords = this->usesLocalCoords();
953 quadGP->initBatchTracker(batchTarget->currentBatchTracker(), init); 975 quadGP->initBatchTracker(batchTarget->currentBatchTracker(), init);
954 976
955 { 977 {
956 GrDrawTarget::DrawInfo info; 978 GrDrawTarget::DrawInfo info;
957 info.setVertexBuffer(vertexBuffer); 979 info.setVertexBuffer(vertexBuffer);
958 info.setIndexBuffer(quadsIndexBuffer); 980 info.setIndexBuffer(fQuadsIndexBuffer);
959 info.setPrimitiveType(kTriangles_GrPrimitiveType); 981 info.setPrimitiveType(kTriangles_GrPrimitiveType);
960 info.setStartIndex(0); 982 info.setStartIndex(0);
961 983
962 int quads = 0; 984 int quads = 0;
963 while (quads < quadCount) { 985 while (quads < quadCount) {
964 int n = SkTMin(quadCount - quads, kQuadsNumInIdxBuffer); 986 int n = SkTMin(quadCount - quads, kQuadsNumInIdxBuffer);
965 987
966 info.setStartVertex(kQuadNumVertices*quads + firstVertex); 988 info.setStartVertex(kQuadNumVertices*quads + firstVertex);
967 info.setVertexCount(kQuadNumVertices*n); 989 info.setVertexCount(kQuadNumVertices*n);
968 info.setIndexCount(kIdxsPerQuad*n); 990 info.setIndexCount(kIdxsPerQuad*n);
(...skipping 11 matching lines...) Expand all
980 GrPipelineInfo init; 1002 GrPipelineInfo init;
981 init.fColorIgnored = fBatch.fColorIgnored; 1003 init.fColorIgnored = fBatch.fColorIgnored;
982 init.fOverrideColor = GrColor_ILLEGAL; 1004 init.fOverrideColor = GrColor_ILLEGAL;
983 init.fCoverageIgnored = fBatch.fCoverageIgnored; 1005 init.fCoverageIgnored = fBatch.fCoverageIgnored;
984 init.fUsesLocalCoords = this->usesLocalCoords(); 1006 init.fUsesLocalCoords = this->usesLocalCoords();
985 conicGP->initBatchTracker(batchTarget->currentBatchTracker(), init); 1007 conicGP->initBatchTracker(batchTarget->currentBatchTracker(), init);
986 1008
987 { 1009 {
988 GrDrawTarget::DrawInfo info; 1010 GrDrawTarget::DrawInfo info;
989 info.setVertexBuffer(vertexBuffer); 1011 info.setVertexBuffer(vertexBuffer);
990 info.setIndexBuffer(quadsIndexBuffer); 1012 info.setIndexBuffer(fQuadsIndexBuffer);
991 info.setPrimitiveType(kTriangles_GrPrimitiveType); 1013 info.setPrimitiveType(kTriangles_GrPrimitiveType);
992 info.setStartIndex(0); 1014 info.setStartIndex(0);
993 1015
994 int conics = 0; 1016 int conics = 0;
995 while (conics < conicCount) { 1017 while (conics < conicCount) {
996 int n = SkTMin(conicCount - conics, kQuadsNumInIdxBuffer); 1018 int n = SkTMin(conicCount - conics, kQuadsNumInIdxBuffer);
997 1019
998 info.setStartVertex(kQuadNumVertices*(quadCount + conics) + firstVertex); 1020 info.setStartVertex(kQuadNumVertices*(quadCount + conics) + firstVertex);
999 info.setVertexCount(kQuadNumVertices*n); 1021 info.setVertexCount(kQuadNumVertices*n);
1000 info.setIndexCount(kIdxsPerQuad*n); 1022 info.setIndexCount(kIdxsPerQuad*n);
1001 batchTarget->draw(info); 1023 batchTarget->draw(info);
1002 1024
1003 conics += n; 1025 conics += n;
1004 } 1026 }
1005 } 1027 }
1006 } 1028 }
1007 } 1029 }
1008 } 1030 }
1009 1031
1010 static GrBatch* create_hairline_batch(GrColor color, 1032 static GrBatch* create_hairline_batch(GrColor color,
1011 const SkMatrix& viewMatrix, 1033 const SkMatrix& viewMatrix,
1012 const SkPath& path, 1034 const SkPath& path,
1013 const GrStrokeInfo& stroke, 1035 const GrStrokeInfo& stroke,
1014 const SkIRect& devClipBounds) { 1036 const SkIRect& devClipBounds,
1037 const GrIndexBuffer* linesIndexBuffer,
1038 const GrIndexBuffer* quadsIndexBuffer) {
1015 SkScalar hairlineCoverage; 1039 SkScalar hairlineCoverage;
1016 uint8_t newCoverage = 0xff; 1040 uint8_t newCoverage = 0xff;
1017 if (GrPathRenderer::IsStrokeHairlineOrEquivalent(stroke, viewMatrix, &hairli neCoverage)) { 1041 if (GrPathRenderer::IsStrokeHairlineOrEquivalent(stroke, viewMatrix, &hairli neCoverage)) {
1018 newCoverage = SkScalarRoundToInt(hairlineCoverage * 0xff); 1042 newCoverage = SkScalarRoundToInt(hairlineCoverage * 0xff);
1019 } 1043 }
1020 1044
1021 AAHairlineBatch::Geometry geometry; 1045 AAHairlineBatch::Geometry geometry;
1022 geometry.fColor = color; 1046 geometry.fColor = color;
1023 geometry.fCoverage = newCoverage; 1047 geometry.fCoverage = newCoverage;
1024 geometry.fViewMatrix = viewMatrix; 1048 geometry.fViewMatrix = viewMatrix;
1025 geometry.fPath = path; 1049 geometry.fPath = path;
1026 geometry.fDevClipBounds = devClipBounds; 1050 geometry.fDevClipBounds = devClipBounds;
1027 1051
1028 return AAHairlineBatch::Create(geometry); 1052 return AAHairlineBatch::Create(geometry, linesIndexBuffer, quadsIndexBuffer) ;
1029 } 1053 }
1030 1054
1031 bool GrAAHairLinePathRenderer::onDrawPath(GrDrawTarget* target, 1055 bool GrAAHairLinePathRenderer::onDrawPath(GrDrawTarget* target,
1032 GrPipelineBuilder* pipelineBuilder, 1056 GrPipelineBuilder* pipelineBuilder,
1033 GrColor color, 1057 GrColor color,
1034 const SkMatrix& viewMatrix, 1058 const SkMatrix& viewMatrix,
1035 const SkPath& path, 1059 const SkPath& path,
1036 const GrStrokeInfo& stroke, 1060 const GrStrokeInfo& stroke,
1037 bool) { 1061 bool) {
1062 if (!fLinesIndexBuffer || !fQuadsIndexBuffer) {
1063 SkDebugf("unable to allocate indices\n");
1064 return false;
1065 }
1066
1038 SkIRect devClipBounds; 1067 SkIRect devClipBounds;
1039 pipelineBuilder->clip().getConservativeBounds(pipelineBuilder->getRenderTarg et(), 1068 pipelineBuilder->clip().getConservativeBounds(pipelineBuilder->getRenderTarg et(),
1040 &devClipBounds); 1069 &devClipBounds);
1041 1070
1042 SkAutoTUnref<GrBatch> batch(create_hairline_batch(color, viewMatrix, path, s troke, 1071 SkAutoTUnref<GrBatch> batch(create_hairline_batch(color, viewMatrix, path, s troke,
1043 devClipBounds)); 1072 devClipBounds, fLinesIndex Buffer,
1073 fQuadsIndexBuffer));
1044 target->drawBatch(pipelineBuilder, batch); 1074 target->drawBatch(pipelineBuilder, batch);
1045 1075
1046 return true; 1076 return true;
1047 } 1077 }
1048 1078
1049 //////////////////////////////////////////////////////////////////////////////// /////////////////// 1079 //////////////////////////////////////////////////////////////////////////////// ///////////////////
1050 1080
1051 #ifdef GR_TEST_UTILS 1081 #ifdef GR_TEST_UTILS
1052 1082
1053 BATCH_TEST_DEFINE(AAHairlineBatch) { 1083 BATCH_TEST_DEFINE(AAHairlineBatch) {
1084 // TODO put these in the cache
1085 static GrIndexBuffer* gQuadIndexBuffer;
1086 static GrIndexBuffer* gLineIndexBuffer;
1087 if (!gQuadIndexBuffer) {
1088 gQuadIndexBuffer = context->getGpu()->createInstancedIndexBuffer(kQuadId xBufPattern,
1089 kIdxsPe rQuad,
1090 kQuadsN umInIdxBuffer,
1091 kQuadNu mVertices);
1092 gLineIndexBuffer = context->getGpu()->createInstancedIndexBuffer(kLineSe gIdxBufPattern,
1093 kIdxsPe rLineSeg,
1094 kLineSe gsNumInIdxBuffer,
1095 kLineSe gNumVertices);
1096 }
1097
1054 GrColor color = GrRandomColor(random); 1098 GrColor color = GrRandomColor(random);
1055 SkMatrix viewMatrix = GrTest::TestMatrix(random); 1099 SkMatrix viewMatrix = GrTest::TestMatrix(random);
1056 GrStrokeInfo stroke(SkStrokeRec::kHairline_InitStyle); 1100 GrStrokeInfo stroke(SkStrokeRec::kHairline_InitStyle);
1057 SkPath path = GrTest::TestPath(random); 1101 SkPath path = GrTest::TestPath(random);
1058 SkIRect devClipBounds; 1102 SkIRect devClipBounds;
1059 devClipBounds.setEmpty(); 1103 devClipBounds.setEmpty();
1060 return create_hairline_batch(color, viewMatrix, path, stroke, devClipBounds) ; 1104 return create_hairline_batch(color, viewMatrix, path, stroke, devClipBounds, gLineIndexBuffer,
1105 gQuadIndexBuffer);
1061 } 1106 }
1062 1107
1063 #endif 1108 #endif
OLDNEW
« no previous file with comments | « src/gpu/GrAAHairLinePathRenderer.h ('k') | src/gpu/GrAARectRenderer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698