OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 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 "GrDashingEffect.h" | 8 #include "GrDashingEffect.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 "GrGeometryProcessor.h" | 14 #include "GrGeometryProcessor.h" |
15 #include "GrContext.h" | 15 #include "GrContext.h" |
16 #include "GrCoordTransform.h" | 16 #include "GrCoordTransform.h" |
17 #include "GrDefaultGeoProcFactory.h" | 17 #include "GrDefaultGeoProcFactory.h" |
18 #include "GrDrawTarget.h" | 18 #include "GrDrawTarget.h" |
19 #include "GrDrawTargetCaps.h" | 19 #include "GrDrawTargetCaps.h" |
20 #include "GrInvariantOutput.h" | 20 #include "GrInvariantOutput.h" |
21 #include "GrProcessor.h" | 21 #include "GrProcessor.h" |
22 #include "GrResourceProvider.h" | |
23 #include "GrStrokeInfo.h" | 22 #include "GrStrokeInfo.h" |
24 #include "GrVertexBuffer.h" | 23 #include "GrVertexBuffer.h" |
25 #include "SkGr.h" | 24 #include "SkGr.h" |
26 #include "gl/GrGLGeometryProcessor.h" | 25 #include "gl/GrGLGeometryProcessor.h" |
27 #include "gl/GrGLProcessor.h" | 26 #include "gl/GrGLProcessor.h" |
28 #include "gl/GrGLSL.h" | 27 #include "gl/GrGLSL.h" |
29 #include "gl/builders/GrGLProgramBuilder.h" | 28 #include "gl/builders/GrGLProgramBuilder.h" |
30 | 29 |
31 /////////////////////////////////////////////////////////////////////////////// | 30 /////////////////////////////////////////////////////////////////////////////// |
32 | 31 |
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
341 bool fullDash = this->fullDash(); | 340 bool fullDash = this->fullDash(); |
342 | 341 |
343 // We do two passes over all of the dashes. First we setup the start, e
nd, and bounds, | 342 // We do two passes over all of the dashes. First we setup the start, e
nd, and bounds, |
344 // rectangles. We preserve all of this work in the rects / draws arrays
below. Then we | 343 // rectangles. We preserve all of this work in the rects / draws arrays
below. Then we |
345 // iterate again over these decomposed dashes to generate vertices | 344 // iterate again over these decomposed dashes to generate vertices |
346 SkSTArray<128, SkRect, true> rects; | 345 SkSTArray<128, SkRect, true> rects; |
347 SkSTArray<128, DashDraw, true> draws; | 346 SkSTArray<128, DashDraw, true> draws; |
348 | 347 |
349 int totalRectCount = 0; | 348 int totalRectCount = 0; |
350 int rectOffset = 0; | 349 int rectOffset = 0; |
| 350 rects.push_back_n(3 * instanceCount); |
351 for (int i = 0; i < instanceCount; i++) { | 351 for (int i = 0; i < instanceCount; i++) { |
352 Geometry& args = fGeoData[i]; | 352 Geometry& args = fGeoData[i]; |
353 | 353 |
354 bool hasCap = SkPaint::kButt_Cap != cap && 0 != args.fSrcStrokeWidth
; | 354 bool hasCap = SkPaint::kButt_Cap != cap && 0 != args.fSrcStrokeWidth
; |
355 | 355 |
356 // We always want to at least stroke out half a pixel on each side i
n device space | 356 // We always want to at least stroke out half a pixel on each side i
n device space |
357 // so 0.5f / perpScale gives us this min in src space | 357 // so 0.5f / perpScale gives us this min in src space |
358 SkScalar halfSrcStroke = | 358 SkScalar halfSrcStroke = |
359 SkMaxScalar(args.fSrcStrokeWidth * 0.5f, 0.5f / args.fPerpen
dicularScale); | 359 SkMaxScalar(args.fSrcStrokeWidth * 0.5f, 0.5f / args.fPerpen
dicularScale); |
360 | 360 |
361 SkScalar strokeAdj; | 361 SkScalar strokeAdj; |
362 if (!hasCap) { | 362 if (!hasCap) { |
363 strokeAdj = 0.f; | 363 strokeAdj = 0.f; |
364 } else { | 364 } else { |
365 strokeAdj = halfSrcStroke; | 365 strokeAdj = halfSrcStroke; |
366 } | 366 } |
367 | 367 |
368 SkScalar startAdj = 0; | 368 SkScalar startAdj = 0; |
369 | 369 |
370 bool lineDone = false; | 370 bool lineDone = false; |
371 | 371 |
372 // Too simplify the algorithm, we always push back rects for start a
nd end rect. | 372 // Too simplify the algorithm, we always push back rects for start a
nd end rect. |
373 // Otherwise we'd have to track start / end rects for each individua
l geometry | 373 // Otherwise we'd have to track start / end rects for each individua
l geometry |
374 rects.push_back(); | |
375 rects.push_back(); | |
376 rects.push_back(); | |
377 SkRect& bounds = rects[rectOffset++]; | 374 SkRect& bounds = rects[rectOffset++]; |
378 SkRect& startRect = rects[rectOffset++]; | 375 SkRect& startRect = rects[rectOffset++]; |
379 SkRect& endRect = rects[rectOffset++]; | 376 SkRect& endRect = rects[rectOffset++]; |
380 | 377 |
381 bool hasStartRect = false; | 378 bool hasStartRect = false; |
382 // If we are using AA, check to see if we are drawing a partial dash
at the start. If so | 379 // If we are using AA, check to see if we are drawing a partial dash
at the start. If so |
383 // draw it separately here and adjust our start point accordingly | 380 // draw it separately here and adjust our start point accordingly |
384 if (useAA) { | 381 if (useAA) { |
385 if (args.fPhase > 0 && args.fPhase < args.fIntervals[0]) { | 382 if (args.fPhase > 0 && args.fPhase < args.fIntervals[0]) { |
386 SkPoint startPts[2]; | 383 SkPoint startPts[2]; |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
529 draw.fStartOffset = startOffset; | 526 draw.fStartOffset = startOffset; |
530 draw.fDevBloatX = devBloatX; | 527 draw.fDevBloatX = devBloatX; |
531 draw.fDevBloatY = devBloatY; | 528 draw.fDevBloatY = devBloatY; |
532 draw.fHalfDevStroke = halfDevStroke; | 529 draw.fHalfDevStroke = halfDevStroke; |
533 draw.fStrokeWidth = strokeWidth; | 530 draw.fStrokeWidth = strokeWidth; |
534 draw.fHasStartRect = hasStartRect; | 531 draw.fHasStartRect = hasStartRect; |
535 draw.fLineDone = lineDone; | 532 draw.fLineDone = lineDone; |
536 draw.fHasEndRect = hasEndRect; | 533 draw.fHasEndRect = hasEndRect; |
537 } | 534 } |
538 | 535 |
539 SkAutoTUnref<const GrIndexBuffer> indexBuffer( | 536 if (!totalRectCount) { |
540 batchTarget->resourceProvider()->refQuadIndexBuffer()); | 537 return; |
| 538 } |
541 | 539 |
542 const GrVertexBuffer* vertexBuffer; | 540 QuadHelper helper; |
543 int firstVertex; | 541 void* vertices = helper.init(batchTarget, gp->getVertexStride(), totalRe
ctCount); |
544 size_t vertexStride = gp->getVertexStride(); | 542 if (!vertices) { |
545 void* vertices = batchTarget->vertexPool()->makeSpace(vertexStride, | |
546 totalRectCount * k
VertsPerDash, | |
547 &vertexBuffer, | |
548 &firstVertex); | |
549 if (!vertices || !indexBuffer) { | |
550 SkDebugf("Could not allocate buffers\n"); | |
551 return; | 543 return; |
552 } | 544 } |
553 | 545 |
554 int curVIdx = 0; | 546 int curVIdx = 0; |
555 int rectIndex = 0; | 547 int rectIndex = 0; |
556 for (int i = 0; i < instanceCount; i++) { | 548 for (int i = 0; i < instanceCount; i++) { |
557 Geometry& args = fGeoData[i]; | 549 Geometry& geom = fGeoData[i]; |
558 | 550 |
559 if (!draws[i].fLineDone) { | 551 if (!draws[i].fLineDone) { |
560 if (fullDash) { | 552 if (fullDash) { |
561 setup_dashed_rect(rects[rectIndex], vertices, curVIdx, args.
fSrcRotInv, | 553 setup_dashed_rect(rects[rectIndex], vertices, curVIdx, geom.
fSrcRotInv, |
562 draws[i].fStartOffset, draws[i].fDevBloatX
, | 554 draws[i].fStartOffset, draws[i].fDevBloatX
, |
563 draws[i].fDevBloatY, draws[i].fLineLength, | 555 draws[i].fDevBloatY, draws[i].fLineLength, |
564 draws[i].fHalfDevStroke, args.fIntervals[0
], | 556 draws[i].fHalfDevStroke, geom.fIntervals[0
], |
565 args.fIntervals[1], draws[i].fStrokeWidth, | 557 geom.fIntervals[1], draws[i].fStrokeWidth, |
566 capType, gp->getVertexStride()); | 558 capType, gp->getVertexStride()); |
567 } else { | 559 } else { |
568 SkPoint* verts = reinterpret_cast<SkPoint*>(vertices); | 560 SkPoint* verts = reinterpret_cast<SkPoint*>(vertices); |
569 SkASSERT(gp->getVertexStride() == sizeof(SkPoint)); | 561 SkASSERT(gp->getVertexStride() == sizeof(SkPoint)); |
570 setup_dashed_rect_pos(rects[rectIndex], curVIdx, args.fSrcRo
tInv, verts); | 562 setup_dashed_rect_pos(rects[rectIndex], curVIdx, geom.fSrcRo
tInv, verts); |
571 } | 563 } |
572 curVIdx += 4; | 564 curVIdx += 4; |
573 } | 565 } |
574 rectIndex++; | 566 rectIndex++; |
575 | 567 |
576 if (draws[i].fHasStartRect) { | 568 if (draws[i].fHasStartRect) { |
577 if (fullDash) { | 569 if (fullDash) { |
578 setup_dashed_rect(rects[rectIndex], vertices, curVIdx, args.
fSrcRotInv, | 570 setup_dashed_rect(rects[rectIndex], vertices, curVIdx, geom.
fSrcRotInv, |
579 draws[i].fStartOffset, draws[i].fDevBloatX
, | 571 draws[i].fStartOffset, draws[i].fDevBloatX
, |
580 draws[i].fDevBloatY, args.fIntervals[0], | 572 draws[i].fDevBloatY, geom.fIntervals[0], |
581 draws[i].fHalfDevStroke, args.fIntervals[0
], | 573 draws[i].fHalfDevStroke, geom.fIntervals[0
], |
582 args.fIntervals[1], draws[i].fStrokeWidth,
capType, | 574 geom.fIntervals[1], draws[i].fStrokeWidth,
capType, |
583 gp->getVertexStride()); | 575 gp->getVertexStride()); |
584 } else { | 576 } else { |
585 SkPoint* verts = reinterpret_cast<SkPoint*>(vertices); | 577 SkPoint* verts = reinterpret_cast<SkPoint*>(vertices); |
586 SkASSERT(gp->getVertexStride() == sizeof(SkPoint)); | 578 SkASSERT(gp->getVertexStride() == sizeof(SkPoint)); |
587 setup_dashed_rect_pos(rects[rectIndex], curVIdx, args.fSrcRo
tInv, verts); | 579 setup_dashed_rect_pos(rects[rectIndex], curVIdx, geom.fSrcRo
tInv, verts); |
588 } | 580 } |
589 | |
590 curVIdx += 4; | 581 curVIdx += 4; |
591 } | 582 } |
592 rectIndex++; | 583 rectIndex++; |
593 | 584 |
594 if (draws[i].fHasEndRect) { | 585 if (draws[i].fHasEndRect) { |
595 if (fullDash) { | 586 if (fullDash) { |
596 setup_dashed_rect(rects[rectIndex], vertices, curVIdx, args.
fSrcRotInv, | 587 setup_dashed_rect(rects[rectIndex], vertices, curVIdx, geom.
fSrcRotInv, |
597 draws[i].fStartOffset, draws[i].fDevBloatX
, | 588 draws[i].fStartOffset, draws[i].fDevBloatX
, |
598 draws[i].fDevBloatY, args.fIntervals[0], | 589 draws[i].fDevBloatY, geom.fIntervals[0], |
599 draws[i].fHalfDevStroke, args.fIntervals[0
], | 590 draws[i].fHalfDevStroke, geom.fIntervals[0
], |
600 args.fIntervals[1], draws[i].fStrokeWidth,
capType, | 591 geom.fIntervals[1], draws[i].fStrokeWidth,
capType, |
601 gp->getVertexStride()); | 592 gp->getVertexStride()); |
602 } else { | 593 } else { |
603 SkPoint* verts = reinterpret_cast<SkPoint*>(vertices); | 594 SkPoint* verts = reinterpret_cast<SkPoint*>(vertices); |
604 SkASSERT(gp->getVertexStride() == sizeof(SkPoint)); | 595 SkASSERT(gp->getVertexStride() == sizeof(SkPoint)); |
605 setup_dashed_rect_pos(rects[rectIndex], curVIdx, args.fSrcRo
tInv, verts); | 596 setup_dashed_rect_pos(rects[rectIndex], curVIdx, geom.fSrcRo
tInv, verts); |
606 } | 597 } |
607 curVIdx += 4; | 598 curVIdx += 4; |
608 } | 599 } |
609 rectIndex++; | 600 rectIndex++; |
610 } | 601 } |
611 | 602 SkASSERT(0 == (curVIdx % 4) && (curVIdx / 4) == totalRectCount); |
612 GrDrawTarget::DrawInfo drawInfo; | 603 helper.issueDraws(batchTarget); |
613 drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType); | |
614 drawInfo.setStartVertex(0); | |
615 drawInfo.setStartIndex(0); | |
616 drawInfo.setVerticesPerInstance(kVertsPerDash); | |
617 drawInfo.setIndicesPerInstance(kIndicesPerDash); | |
618 drawInfo.adjustStartVertex(firstVertex); | |
619 drawInfo.setVertexBuffer(vertexBuffer); | |
620 drawInfo.setIndexBuffer(indexBuffer); | |
621 | |
622 int maxInstancesPerDraw = indexBuffer->maxQuads(); | |
623 while (totalRectCount) { | |
624 drawInfo.setInstanceCount(SkTMin(totalRectCount, maxInstancesPerDraw
)); | |
625 drawInfo.setVertexCount(drawInfo.instanceCount() * drawInfo.vertices
PerInstance()); | |
626 drawInfo.setIndexCount(drawInfo.instanceCount() * drawInfo.indicesPe
rInstance()); | |
627 | |
628 batchTarget->draw(drawInfo); | |
629 | |
630 drawInfo.setStartVertex(drawInfo.startVertex() + drawInfo.vertexCoun
t()); | |
631 totalRectCount -= drawInfo.instanceCount(); | |
632 } | |
633 } | 604 } |
634 | 605 |
635 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } | 606 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } |
636 | 607 |
637 private: | 608 private: |
638 DashBatch(const Geometry& geometry, SkPaint::Cap cap, DashAAMode aaMode, boo
l fullDash) { | 609 DashBatch(const Geometry& geometry, SkPaint::Cap cap, DashAAMode aaMode, boo
l fullDash) { |
639 this->initClassID<DashBatch>(); | 610 this->initClassID<DashBatch>(); |
640 fGeoData.push_back(geometry); | 611 fGeoData.push_back(geometry); |
641 | 612 |
642 fBatch.fAAMode = aaMode; | 613 fBatch.fAAMode = aaMode; |
(...skipping 729 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1372 info.fIntervals = intervals; | 1343 info.fIntervals = intervals; |
1373 info.fCount = 2; | 1344 info.fCount = 2; |
1374 info.fPhase = phase; | 1345 info.fPhase = phase; |
1375 SkDEBUGCODE(bool success = ) strokeInfo.setDashInfo(info); | 1346 SkDEBUGCODE(bool success = ) strokeInfo.setDashInfo(info); |
1376 SkASSERT(success); | 1347 SkASSERT(success); |
1377 | 1348 |
1378 return create_batch(color, viewMatrix, pts, useAA, strokeInfo, msaaRT); | 1349 return create_batch(color, viewMatrix, pts, useAA, strokeInfo, msaaRT); |
1379 } | 1350 } |
1380 | 1351 |
1381 #endif | 1352 #endif |
OLD | NEW |