OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2012 Google Inc. | 3 * Copyright 2012 Google Inc. |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 #include "GrAAConvexPathRenderer.h" | 9 #include "GrAAConvexPathRenderer.h" |
10 | 10 |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
121 if (dir == SkPath::kCCW_Direction) { | 121 if (dir == SkPath::kCCW_Direction) { |
122 normSide = GrPoint::kRight_Side; | 122 normSide = GrPoint::kRight_Side; |
123 } else { | 123 } else { |
124 normSide = GrPoint::kLeft_Side; | 124 normSide = GrPoint::kLeft_Side; |
125 } | 125 } |
126 | 126 |
127 *vCount = 0; | 127 *vCount = 0; |
128 *iCount = 0; | 128 *iCount = 0; |
129 // compute normals at all points | 129 // compute normals at all points |
130 for (int a = 0; a < count; ++a) { | 130 for (int a = 0; a < count; ++a) { |
131 const Segment& sega = (*segments)[a]; | 131 Segment& sega = (*segments)[a]; |
132 int b = (a + 1) % count; | 132 int b = (a + 1) % count; |
133 Segment& segb = (*segments)[b]; | 133 Segment& segb = (*segments)[b]; |
134 | 134 |
135 const GrPoint* prevPt = &sega.endPt(); | 135 const GrPoint* prevPt = &sega.endPt(); |
136 int n = segb.countPoints(); | 136 int n = segb.countPoints(); |
137 for (int p = 0; p < n; ++p) { | 137 for (int p = 0; p < n; ++p) { |
138 segb.fNorms[p] = segb.fPts[p] - *prevPt; | 138 segb.fNorms[p] = segb.fPts[p] - *prevPt; |
139 segb.fNorms[p].normalize(); | 139 segb.fNorms[p].normalize(); |
140 segb.fNorms[p].setOrthog(segb.fNorms[p], normSide); | 140 segb.fNorms[p].setOrthog(segb.fNorms[p], normSide); |
141 prevPt = &segb.fPts[p]; | 141 prevPt = &segb.fPts[p]; |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
297 } | 297 } |
298 } | 298 } |
299 | 299 |
300 struct QuadVertex { | 300 struct QuadVertex { |
301 GrPoint fPos; | 301 GrPoint fPos; |
302 GrPoint fUV; | 302 GrPoint fUV; |
303 SkScalar fD0; | 303 SkScalar fD0; |
304 SkScalar fD1; | 304 SkScalar fD1; |
305 }; | 305 }; |
306 | 306 |
| 307 struct Draw { |
| 308 Draw() : fVertexCnt(0), fIndexCnt(0) {} |
| 309 int fVertexCnt; |
| 310 int fIndexCnt; |
| 311 }; |
| 312 |
| 313 typedef SkTArray<Draw, true> DrawArray; |
| 314 |
307 void create_vertices(const SegmentArray& segments, | 315 void create_vertices(const SegmentArray& segments, |
308 const SkPoint& fanPt, | 316 const SkPoint& fanPt, |
| 317 DrawArray* draws, |
309 QuadVertex* verts, | 318 QuadVertex* verts, |
310 uint16_t* idxs) { | 319 uint16_t* idxs) { |
311 int v = 0; | 320 Draw* draw = &draws->push_back(); |
312 int i = 0; | 321 // alias just to make vert/index assignments easier to read. |
| 322 int* v = &draw->fVertexCnt; |
| 323 int* i = &draw->fIndexCnt; |
313 | 324 |
314 int count = segments.count(); | 325 int count = segments.count(); |
315 for (int a = 0; a < count; ++a) { | 326 for (int a = 0; a < count; ++a) { |
316 const Segment& sega = segments[a]; | 327 const Segment& sega = segments[a]; |
317 int b = (a + 1) % count; | 328 int b = (a + 1) % count; |
318 const Segment& segb = segments[b]; | 329 const Segment& segb = segments[b]; |
319 | 330 |
| 331 // Check whether adding the verts for this segment to the current draw w
ould cause index |
| 332 // values to overflow. |
| 333 int vCount = 4; |
| 334 if (Segment::kLine == segb.fType) { |
| 335 vCount += 5; |
| 336 } else { |
| 337 vCount += 6; |
| 338 } |
| 339 if (draw->fVertexCnt + vCount > (1 << 16)) { |
| 340 verts += *v; |
| 341 idxs += *i; |
| 342 draw = &draws->push_back(); |
| 343 v = &draw->fVertexCnt; |
| 344 i = &draw->fIndexCnt; |
| 345 } |
| 346 |
320 // FIXME: These tris are inset in the 1 unit arc around the corner | 347 // FIXME: These tris are inset in the 1 unit arc around the corner |
321 verts[v + 0].fPos = sega.endPt(); | 348 verts[*v + 0].fPos = sega.endPt(); |
322 verts[v + 1].fPos = verts[v + 0].fPos + sega.endNorm(); | 349 verts[*v + 1].fPos = verts[*v + 0].fPos + sega.endNorm(); |
323 verts[v + 2].fPos = verts[v + 0].fPos + segb.fMid; | 350 verts[*v + 2].fPos = verts[*v + 0].fPos + segb.fMid; |
324 verts[v + 3].fPos = verts[v + 0].fPos + segb.fNorms[0]; | 351 verts[*v + 3].fPos = verts[*v + 0].fPos + segb.fNorms[0]; |
325 verts[v + 0].fUV.set(0,0); | 352 verts[*v + 0].fUV.set(0,0); |
326 verts[v + 1].fUV.set(0,-SK_Scalar1); | 353 verts[*v + 1].fUV.set(0,-SK_Scalar1); |
327 verts[v + 2].fUV.set(0,-SK_Scalar1); | 354 verts[*v + 2].fUV.set(0,-SK_Scalar1); |
328 verts[v + 3].fUV.set(0,-SK_Scalar1); | 355 verts[*v + 3].fUV.set(0,-SK_Scalar1); |
329 verts[v + 0].fD0 = verts[v + 0].fD1 = -SK_Scalar1; | 356 verts[*v + 0].fD0 = verts[*v + 0].fD1 = -SK_Scalar1; |
330 verts[v + 1].fD0 = verts[v + 1].fD1 = -SK_Scalar1; | 357 verts[*v + 1].fD0 = verts[*v + 1].fD1 = -SK_Scalar1; |
331 verts[v + 2].fD0 = verts[v + 2].fD1 = -SK_Scalar1; | 358 verts[*v + 2].fD0 = verts[*v + 2].fD1 = -SK_Scalar1; |
332 verts[v + 3].fD0 = verts[v + 3].fD1 = -SK_Scalar1; | 359 verts[*v + 3].fD0 = verts[*v + 3].fD1 = -SK_Scalar1; |
333 | 360 |
334 idxs[i + 0] = v + 0; | 361 idxs[*i + 0] = *v + 0; |
335 idxs[i + 1] = v + 2; | 362 idxs[*i + 1] = *v + 2; |
336 idxs[i + 2] = v + 1; | 363 idxs[*i + 2] = *v + 1; |
337 idxs[i + 3] = v + 0; | 364 idxs[*i + 3] = *v + 0; |
338 idxs[i + 4] = v + 3; | 365 idxs[*i + 4] = *v + 3; |
339 idxs[i + 5] = v + 2; | 366 idxs[*i + 5] = *v + 2; |
340 | 367 |
341 v += 4; | 368 *v += 4; |
342 i += 6; | 369 *i += 6; |
343 | 370 |
344 if (Segment::kLine == segb.fType) { | 371 if (Segment::kLine == segb.fType) { |
345 verts[v + 0].fPos = fanPt; | 372 verts[*v + 0].fPos = fanPt; |
346 verts[v + 1].fPos = sega.endPt(); | 373 verts[*v + 1].fPos = sega.endPt(); |
347 verts[v + 2].fPos = segb.fPts[0]; | 374 verts[*v + 2].fPos = segb.fPts[0]; |
348 | 375 |
349 verts[v + 3].fPos = verts[v + 1].fPos + segb.fNorms[0]; | 376 verts[*v + 3].fPos = verts[*v + 1].fPos + segb.fNorms[0]; |
350 verts[v + 4].fPos = verts[v + 2].fPos + segb.fNorms[0]; | 377 verts[*v + 4].fPos = verts[*v + 2].fPos + segb.fNorms[0]; |
351 | 378 |
352 // we draw the line edge as a degenerate quad (u is 0, v is the | 379 // we draw the line edge as a degenerate quad (u is 0, v is the |
353 // signed distance to the edge) | 380 // signed distance to the edge) |
354 SkScalar dist = fanPt.distanceToLineBetween(verts[v + 1].fPos, | 381 SkScalar dist = fanPt.distanceToLineBetween(verts[*v + 1].fPos, |
355 verts[v + 2].fPos); | 382 verts[*v + 2].fPos); |
356 verts[v + 0].fUV.set(0, dist); | 383 verts[*v + 0].fUV.set(0, dist); |
357 verts[v + 1].fUV.set(0, 0); | 384 verts[*v + 1].fUV.set(0, 0); |
358 verts[v + 2].fUV.set(0, 0); | 385 verts[*v + 2].fUV.set(0, 0); |
359 verts[v + 3].fUV.set(0, -SK_Scalar1); | 386 verts[*v + 3].fUV.set(0, -SK_Scalar1); |
360 verts[v + 4].fUV.set(0, -SK_Scalar1); | 387 verts[*v + 4].fUV.set(0, -SK_Scalar1); |
361 | 388 |
362 verts[v + 0].fD0 = verts[v + 0].fD1 = -SK_Scalar1; | 389 verts[*v + 0].fD0 = verts[*v + 0].fD1 = -SK_Scalar1; |
363 verts[v + 1].fD0 = verts[v + 1].fD1 = -SK_Scalar1; | 390 verts[*v + 1].fD0 = verts[*v + 1].fD1 = -SK_Scalar1; |
364 verts[v + 2].fD0 = verts[v + 2].fD1 = -SK_Scalar1; | 391 verts[*v + 2].fD0 = verts[*v + 2].fD1 = -SK_Scalar1; |
365 verts[v + 3].fD0 = verts[v + 3].fD1 = -SK_Scalar1; | 392 verts[*v + 3].fD0 = verts[*v + 3].fD1 = -SK_Scalar1; |
366 verts[v + 4].fD0 = verts[v + 4].fD1 = -SK_Scalar1; | 393 verts[*v + 4].fD0 = verts[*v + 4].fD1 = -SK_Scalar1; |
367 | 394 |
368 idxs[i + 0] = v + 0; | 395 idxs[*i + 0] = *v + 0; |
369 idxs[i + 1] = v + 2; | 396 idxs[*i + 1] = *v + 2; |
370 idxs[i + 2] = v + 1; | 397 idxs[*i + 2] = *v + 1; |
371 | 398 |
372 idxs[i + 3] = v + 3; | 399 idxs[*i + 3] = *v + 3; |
373 idxs[i + 4] = v + 1; | 400 idxs[*i + 4] = *v + 1; |
374 idxs[i + 5] = v + 2; | 401 idxs[*i + 5] = *v + 2; |
375 | 402 |
376 idxs[i + 6] = v + 4; | 403 idxs[*i + 6] = *v + 4; |
377 idxs[i + 7] = v + 3; | 404 idxs[*i + 7] = *v + 3; |
378 idxs[i + 8] = v + 2; | 405 idxs[*i + 8] = *v + 2; |
379 | 406 |
380 v += 5; | 407 *v += 5; |
381 i += 9; | 408 *i += 9; |
382 } else { | 409 } else { |
383 GrPoint qpts[] = {sega.endPt(), segb.fPts[0], segb.fPts[1]}; | 410 GrPoint qpts[] = {sega.endPt(), segb.fPts[0], segb.fPts[1]}; |
384 | 411 |
385 GrVec midVec = segb.fNorms[0] + segb.fNorms[1]; | 412 GrVec midVec = segb.fNorms[0] + segb.fNorms[1]; |
386 midVec.normalize(); | 413 midVec.normalize(); |
387 | 414 |
388 verts[v + 0].fPos = fanPt; | 415 verts[*v + 0].fPos = fanPt; |
389 verts[v + 1].fPos = qpts[0]; | 416 verts[*v + 1].fPos = qpts[0]; |
390 verts[v + 2].fPos = qpts[2]; | 417 verts[*v + 2].fPos = qpts[2]; |
391 verts[v + 3].fPos = qpts[0] + segb.fNorms[0]; | 418 verts[*v + 3].fPos = qpts[0] + segb.fNorms[0]; |
392 verts[v + 4].fPos = qpts[2] + segb.fNorms[1]; | 419 verts[*v + 4].fPos = qpts[2] + segb.fNorms[1]; |
393 verts[v + 5].fPos = qpts[1] + midVec; | 420 verts[*v + 5].fPos = qpts[1] + midVec; |
394 | 421 |
395 SkScalar c = segb.fNorms[0].dot(qpts[0]); | 422 SkScalar c = segb.fNorms[0].dot(qpts[0]); |
396 verts[v + 0].fD0 = -segb.fNorms[0].dot(fanPt) + c; | 423 verts[*v + 0].fD0 = -segb.fNorms[0].dot(fanPt) + c; |
397 verts[v + 1].fD0 = 0.f; | 424 verts[*v + 1].fD0 = 0.f; |
398 verts[v + 2].fD0 = -segb.fNorms[0].dot(qpts[2]) + c; | 425 verts[*v + 2].fD0 = -segb.fNorms[0].dot(qpts[2]) + c; |
399 verts[v + 3].fD0 = -SK_ScalarMax/100; | 426 verts[*v + 3].fD0 = -SK_ScalarMax/100; |
400 verts[v + 4].fD0 = -SK_ScalarMax/100; | 427 verts[*v + 4].fD0 = -SK_ScalarMax/100; |
401 verts[v + 5].fD0 = -SK_ScalarMax/100; | 428 verts[*v + 5].fD0 = -SK_ScalarMax/100; |
402 | 429 |
403 c = segb.fNorms[1].dot(qpts[2]); | 430 c = segb.fNorms[1].dot(qpts[2]); |
404 verts[v + 0].fD1 = -segb.fNorms[1].dot(fanPt) + c; | 431 verts[*v + 0].fD1 = -segb.fNorms[1].dot(fanPt) + c; |
405 verts[v + 1].fD1 = -segb.fNorms[1].dot(qpts[0]) + c; | 432 verts[*v + 1].fD1 = -segb.fNorms[1].dot(qpts[0]) + c; |
406 verts[v + 2].fD1 = 0.f; | 433 verts[*v + 2].fD1 = 0.f; |
407 verts[v + 3].fD1 = -SK_ScalarMax/100; | 434 verts[*v + 3].fD1 = -SK_ScalarMax/100; |
408 verts[v + 4].fD1 = -SK_ScalarMax/100; | 435 verts[*v + 4].fD1 = -SK_ScalarMax/100; |
409 verts[v + 5].fD1 = -SK_ScalarMax/100; | 436 verts[*v + 5].fD1 = -SK_ScalarMax/100; |
410 | 437 |
411 GrPathUtils::QuadUVMatrix toUV(qpts); | 438 GrPathUtils::QuadUVMatrix toUV(qpts); |
412 toUV.apply<6, sizeof(QuadVertex), sizeof(GrPoint)>(verts + v); | 439 toUV.apply<6, sizeof(QuadVertex), sizeof(GrPoint)>(verts + *v); |
413 | 440 |
414 idxs[i + 0] = v + 3; | 441 idxs[*i + 0] = *v + 3; |
415 idxs[i + 1] = v + 1; | 442 idxs[*i + 1] = *v + 1; |
416 idxs[i + 2] = v + 2; | 443 idxs[*i + 2] = *v + 2; |
417 idxs[i + 3] = v + 4; | 444 idxs[*i + 3] = *v + 4; |
418 idxs[i + 4] = v + 3; | 445 idxs[*i + 4] = *v + 3; |
419 idxs[i + 5] = v + 2; | 446 idxs[*i + 5] = *v + 2; |
420 | 447 |
421 idxs[i + 6] = v + 5; | 448 idxs[*i + 6] = *v + 5; |
422 idxs[i + 7] = v + 3; | 449 idxs[*i + 7] = *v + 3; |
423 idxs[i + 8] = v + 4; | 450 idxs[*i + 8] = *v + 4; |
424 | 451 |
425 idxs[i + 9] = v + 0; | 452 idxs[*i + 9] = *v + 0; |
426 idxs[i + 10] = v + 2; | 453 idxs[*i + 10] = *v + 2; |
427 idxs[i + 11] = v + 1; | 454 idxs[*i + 11] = *v + 1; |
428 | 455 |
429 v += 6; | 456 *v += 6; |
430 i += 12; | 457 *i += 12; |
431 } | 458 } |
432 } | 459 } |
433 } | 460 } |
434 | 461 |
435 } | 462 } |
436 | 463 |
437 /////////////////////////////////////////////////////////////////////////////// | 464 /////////////////////////////////////////////////////////////////////////////// |
438 | 465 |
439 /* | 466 /* |
440 * Quadratic specified by 0=u^2-v canonical coords. u and v are the first | 467 * Quadratic specified by 0=u^2-v canonical coords. u and v are the first |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
594 vm = &SkMatrix::I(); | 621 vm = &SkMatrix::I(); |
595 } | 622 } |
596 | 623 |
597 QuadVertex *verts; | 624 QuadVertex *verts; |
598 uint16_t* idxs; | 625 uint16_t* idxs; |
599 | 626 |
600 int vCount; | 627 int vCount; |
601 int iCount; | 628 int iCount; |
602 enum { | 629 enum { |
603 kPreallocSegmentCnt = 512 / sizeof(Segment), | 630 kPreallocSegmentCnt = 512 / sizeof(Segment), |
| 631 kPreallocDrawCnt = 4, |
604 }; | 632 }; |
605 SkSTArray<kPreallocSegmentCnt, Segment, true> segments; | 633 SkSTArray<kPreallocSegmentCnt, Segment, true> segments; |
606 SkPoint fanPt; | 634 SkPoint fanPt; |
607 | 635 |
608 if (!get_segments(*path, *vm, &segments, &fanPt, &vCount, &iCount)) { | 636 if (!get_segments(*path, *vm, &segments, &fanPt, &vCount, &iCount)) { |
609 return false; | 637 return false; |
610 } | 638 } |
611 | 639 |
612 drawState->setVertexAttribs<gPathAttribs>(SK_ARRAY_COUNT(gPathAttribs)); | 640 drawState->setVertexAttribs<gPathAttribs>(SK_ARRAY_COUNT(gPathAttribs)); |
613 | 641 |
614 enum { | 642 enum { |
615 // the edge effects share this stage with glyph rendering | 643 // the edge effects share this stage with glyph rendering |
616 // (kGlyphMaskStage in GrTextContext) && SW path rendering | 644 // (kGlyphMaskStage in GrTextContext) && SW path rendering |
617 // (kPathMaskStage in GrSWMaskHelper) | 645 // (kPathMaskStage in GrSWMaskHelper) |
618 kEdgeEffectStage = GrPaint::kTotalStages, | 646 kEdgeEffectStage = GrPaint::kTotalStages, |
619 }; | 647 }; |
620 static const int kEdgeAttrIndex = 1; | 648 static const int kEdgeAttrIndex = 1; |
621 GrEffectRef* quadEffect = QuadEdgeEffect::Create(); | 649 GrEffectRef* quadEffect = QuadEdgeEffect::Create(); |
622 drawState->setEffect(kEdgeEffectStage, quadEffect, kEdgeAttrIndex)->unref(); | 650 drawState->setEffect(kEdgeEffectStage, quadEffect, kEdgeAttrIndex)->unref(); |
623 | 651 |
624 GrDrawTarget::AutoReleaseGeometry arg(target, vCount, iCount); | 652 GrDrawTarget::AutoReleaseGeometry arg(target, vCount, iCount); |
625 if (!arg.succeeded()) { | 653 if (!arg.succeeded()) { |
626 return false; | 654 return false; |
627 } | 655 } |
628 GrAssert(sizeof(QuadVertex) == drawState->getVertexSize()); | 656 GrAssert(sizeof(QuadVertex) == drawState->getVertexSize()); |
629 verts = reinterpret_cast<QuadVertex*>(arg.vertices()); | 657 verts = reinterpret_cast<QuadVertex*>(arg.vertices()); |
630 idxs = reinterpret_cast<uint16_t*>(arg.indices()); | 658 idxs = reinterpret_cast<uint16_t*>(arg.indices()); |
631 | 659 |
632 create_vertices(segments, fanPt, verts, idxs); | 660 SkSTArray<kPreallocDrawCnt, Draw, true> draws; |
| 661 create_vertices(segments, fanPt, &draws, verts, idxs); |
633 | 662 |
634 target->drawIndexed(kTriangles_GrPrimitiveType, | 663 int vOffset = 0; |
635 0, // start vertex | 664 for (int i = 0; i < draws.count(); ++i) { |
636 0, // start index | 665 const Draw& draw = draws[i]; |
637 vCount, | 666 target->drawIndexed(kTriangles_GrPrimitiveType, |
638 iCount); | 667 vOffset, // start vertex |
| 668 0, // start index |
| 669 draw.fVertexCnt, |
| 670 draw.fIndexCnt); |
| 671 vOffset += draw.fVertexCnt; |
| 672 } |
639 | 673 |
640 return true; | 674 return true; |
641 } | 675 } |
OLD | NEW |