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

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

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