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

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

Issue 23712005: Add bevel-stroke support in GrAARectRenderer (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: Created 7 years, 3 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 | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright 2012 Google Inc. 2 * Copyright 2012 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 "GrAARectRenderer.h" 8 #include "GrAARectRenderer.h"
9 #include "GrGpu.h" 9 #include "GrGpu.h"
10 #include "gl/GrGLEffect.h" 10 #include "gl/GrGLEffect.h"
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after
339 SkDELETE_ARRAY(data); 339 SkDELETE_ARRAY(data);
340 } else { 340 } else {
341 fAAFillRectIndexBuffer->unlock(); 341 fAAFillRectIndexBuffer->unlock();
342 } 342 }
343 } 343 }
344 } 344 }
345 345
346 return fAAFillRectIndexBuffer; 346 return fAAFillRectIndexBuffer;
347 } 347 }
348 348
349 static const uint16_t gStrokeAARectIdx[] = { 349 static const uint16_t gMiterStrokeAARectIdx[] = {
350 0 + 0, 1 + 0, 5 + 0, 5 + 0, 4 + 0, 0 + 0, 350 0 + 0, 1 + 0, 5 + 0, 5 + 0, 4 + 0, 0 + 0,
351 1 + 0, 2 + 0, 6 + 0, 6 + 0, 5 + 0, 1 + 0, 351 1 + 0, 2 + 0, 6 + 0, 6 + 0, 5 + 0, 1 + 0,
352 2 + 0, 3 + 0, 7 + 0, 7 + 0, 6 + 0, 2 + 0, 352 2 + 0, 3 + 0, 7 + 0, 7 + 0, 6 + 0, 2 + 0,
353 3 + 0, 0 + 0, 4 + 0, 4 + 0, 7 + 0, 3 + 0, 353 3 + 0, 0 + 0, 4 + 0, 4 + 0, 7 + 0, 3 + 0,
354 354
355 0 + 4, 1 + 4, 5 + 4, 5 + 4, 4 + 4, 0 + 4, 355 0 + 4, 1 + 4, 5 + 4, 5 + 4, 4 + 4, 0 + 4,
356 1 + 4, 2 + 4, 6 + 4, 6 + 4, 5 + 4, 1 + 4, 356 1 + 4, 2 + 4, 6 + 4, 6 + 4, 5 + 4, 1 + 4,
357 2 + 4, 3 + 4, 7 + 4, 7 + 4, 6 + 4, 2 + 4, 357 2 + 4, 3 + 4, 7 + 4, 7 + 4, 6 + 4, 2 + 4,
358 3 + 4, 0 + 4, 4 + 4, 4 + 4, 7 + 4, 3 + 4, 358 3 + 4, 0 + 4, 4 + 4, 4 + 4, 7 + 4, 3 + 4,
359 359
360 0 + 8, 1 + 8, 5 + 8, 5 + 8, 4 + 8, 0 + 8, 360 0 + 8, 1 + 8, 5 + 8, 5 + 8, 4 + 8, 0 + 8,
361 1 + 8, 2 + 8, 6 + 8, 6 + 8, 5 + 8, 1 + 8, 361 1 + 8, 2 + 8, 6 + 8, 6 + 8, 5 + 8, 1 + 8,
362 2 + 8, 3 + 8, 7 + 8, 7 + 8, 6 + 8, 2 + 8, 362 2 + 8, 3 + 8, 7 + 8, 7 + 8, 6 + 8, 2 + 8,
363 3 + 8, 0 + 8, 4 + 8, 4 + 8, 7 + 8, 3 + 8, 363 3 + 8, 0 + 8, 4 + 8, 4 + 8, 7 + 8, 3 + 8,
364 }; 364 };
365 365
366 int GrAARectRenderer::aaStrokeRectIndexCount() { 366 static const uint16_t gBevelStrokeAARectIdx[] = {
367 return GR_ARRAY_COUNT(gStrokeAARectIdx); 367 0 + 0, 1 + 0, 9 + 0, 9 + 0, 8 + 0, 0 + 0,
368 1 + 0, 5 + 0, 13 + 0, 13 + 0, 9 + 0, 1 + 0,
369 5 + 0, 6 + 0, 14 + 0, 14 + 0, 13 + 0, 5 + 0,
370 6 + 0, 2 + 0, 10 + 0, 10 + 0, 14 + 0, 6 + 0,
371 2 + 0, 3 + 0, 11 + 0, 11 + 0, 10 + 0, 2 + 0,
372 3 + 0, 7 + 0, 15 + 0, 15 + 0, 11 + 0, 3 + 0,
373 7 + 0, 4 + 0, 12 + 0, 12 + 0, 15 + 0, 7 + 0,
374 4 + 0, 0 + 0, 8 + 0, 8 + 0, 12 + 0, 4 + 0,
375
376 0 + 8, 1 + 8, 9 + 8, 9 + 8, 8 + 8, 0 + 8,
377 1 + 8, 5 + 8, 9 + 8,
378 5 + 8, 6 + 8, 10 + 8, 10 + 8, 9 + 8, 5 + 8,
379 6 + 8, 2 + 8, 10 + 8,
380 2 + 8, 3 + 8, 11 + 8, 11 + 8, 10 + 8, 2 + 8,
381 3 + 8, 7 + 8, 11 + 8,
382 7 + 8, 4 + 8, 8 + 8, 8 + 8, 11 + 8, 7 + 8,
383 4 + 8, 0 + 8, 8 + 8,
384
385 0 + 16, 1 + 16, 5 + 16, 5 + 16, 4 + 16, 0 + 16,
386 1 + 16, 2 + 16, 6 + 16, 6 + 16, 5 + 16, 1 + 16,
387 2 + 16, 3 + 16, 7 + 16, 7 + 16, 6 + 16, 2 + 16,
388 3 + 16, 0 + 16, 4 + 16, 4 + 16, 7 + 16, 3 + 16,
389 };
390
391 int GrAARectRenderer::aaStrokeRectIndexCount(bool miterStroke) {
392 return miterStroke ? GR_ARRAY_COUNT(gMiterStrokeAARectIdx) :
393 GR_ARRAY_COUNT(gBevelStrokeAARectIdx);
368 } 394 }
369 395
370 GrIndexBuffer* GrAARectRenderer::aaStrokeRectIndexBuffer(GrGpu* gpu) { 396 GrIndexBuffer* GrAARectRenderer::aaStrokeRectIndexBuffer(GrGpu* gpu,
397 bool miterStroke) {
371 if (NULL == fAAStrokeRectIndexBuffer) { 398 if (NULL == fAAStrokeRectIndexBuffer) {
372 fAAStrokeRectIndexBuffer = 399 fAAStrokeRectIndexBuffer =
373 gpu->createIndexBuffer(sizeof(gStrokeAARectIdx), false); 400 gpu->createIndexBuffer(miterStroke ?
bsalomon 2013/09/17 15:03:47 I don't think this is right. This index buffer is
yunchao 2013/09/22 08:36:37 Yeah, good suggestion.
401 sizeof(gMiterStrokeAARectIdx) :
402 sizeof(gBevelStrokeAARectIdx),
403 false);
374 if (NULL != fAAStrokeRectIndexBuffer) { 404 if (NULL != fAAStrokeRectIndexBuffer) {
375 #ifdef SK_DEBUG 405 #ifdef SK_DEBUG
376 bool updated = 406 bool updated =
377 #endif 407 #endif
378 fAAStrokeRectIndexBuffer->updateData(gStrokeAARectIdx, 408 fAAStrokeRectIndexBuffer->updateData(miterStroke ?
379 sizeof(gStrokeAARectIdx)); 409 gMiterStrokeAARectIdx :
410 gBevelStrokeAARectIdx,
411 miterStroke ?
412 sizeof(gMiterStrokeAARectIdx) :
413 sizeof(gBevelStrokeAARectIdx));
380 GR_DEBUGASSERT(updated); 414 GR_DEBUGASSERT(updated);
381 } 415 }
382 } 416 }
383 return fAAStrokeRectIndexBuffer; 417 return fAAStrokeRectIndexBuffer;
384 } 418 }
385 419
386 void GrAARectRenderer::geometryFillAARect(GrGpu* gpu, 420 void GrAARectRenderer::geometryFillAARect(GrGpu* gpu,
387 GrDrawTarget* target, 421 GrDrawTarget* target,
388 const SkRect& rect, 422 const SkRect& rect,
389 const SkMatrix& combinedMatrix, 423 const SkMatrix& combinedMatrix,
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
653 target->drawIndexedInstances(kTriangles_GrPrimitiveType, 1, 4, 6); 687 target->drawIndexedInstances(kTriangles_GrPrimitiveType, 1, 4, 6);
654 target->resetIndexSource(); 688 target->resetIndexSource();
655 } 689 }
656 690
657 void GrAARectRenderer::strokeAARect(GrGpu* gpu, 691 void GrAARectRenderer::strokeAARect(GrGpu* gpu,
658 GrDrawTarget* target, 692 GrDrawTarget* target,
659 const SkRect& rect, 693 const SkRect& rect,
660 const SkMatrix& combinedMatrix, 694 const SkMatrix& combinedMatrix,
661 const SkRect& devRect, 695 const SkRect& devRect,
662 SkScalar width, 696 SkScalar width,
663 bool useVertexCoverage) { 697 bool useVertexCoverage,
698 bool miterStroke) {
664 GrVec devStrokeSize; 699 GrVec devStrokeSize;
665 if (width > 0) { 700 if (width > 0) {
666 devStrokeSize.set(width, width); 701 devStrokeSize.set(width, width);
667 combinedMatrix.mapVectors(&devStrokeSize, 1); 702 combinedMatrix.mapVectors(&devStrokeSize, 1);
668 devStrokeSize.setAbs(devStrokeSize); 703 devStrokeSize.setAbs(devStrokeSize);
669 } else { 704 } else {
670 devStrokeSize.set(SK_Scalar1, SK_Scalar1); 705 devStrokeSize.set(SK_Scalar1, SK_Scalar1);
671 } 706 }
672 707
673 const SkScalar dx = devStrokeSize.fX; 708 const SkScalar dx = devStrokeSize.fX;
(...skipping 21 matching lines...) Expand all
695 730
696 if (spare <= 0) { 731 if (spare <= 0) {
697 this->fillAARect(gpu, target, devOutside, SkMatrix::I(), 732 this->fillAARect(gpu, target, devOutside, SkMatrix::I(),
698 devOutside, useVertexCoverage); 733 devOutside, useVertexCoverage);
699 return; 734 return;
700 } 735 }
701 736
702 SkRect devInside(devRect); 737 SkRect devInside(devRect);
703 devInside.inset(rx, ry); 738 devInside.inset(rx, ry);
704 739
705 this->geometryStrokeAARect(gpu, target, devOutside, devInside, useVertexCove rage); 740 SkRect devOutsideAssist(devRect);
741
742 if (!miterStroke) {
743 devOutside.outset(0, -ry);
744 devOutsideAssist.outset(0, ry);
745 }
746 this->geometryStrokeAARect(gpu, target, devOutside, devOutsideAssist,
747 devInside, useVertexCoverage, miterStroke);
706 } 748 }
707 749
708 void GrAARectRenderer::geometryStrokeAARect(GrGpu* gpu, 750 void GrAARectRenderer::geometryStrokeAARect(GrGpu* gpu,
709 GrDrawTarget* target, 751 GrDrawTarget* target,
710 const SkRect& devOutside, 752 const SkRect& devOutside,
753 const SkRect& devOutsideAssist,
711 const SkRect& devInside, 754 const SkRect& devInside,
712 bool useVertexCoverage) { 755 bool useVertexCoverage,
756 bool miterStroke) {
713 GrDrawState* drawState = target->drawState(); 757 GrDrawState* drawState = target->drawState();
714 758
715 set_aa_rect_vertex_attributes(drawState, useVertexCoverage); 759 set_aa_rect_vertex_attributes(drawState, useVertexCoverage);
716 760
717 GrDrawTarget::AutoReleaseGeometry geo(target, 16, 0); 761 int outerVertexNum4Miter = 4, outerVertexNum4Bevel = 8;
762 int outerVertexNum, innerVertexNum = 4;
763 int totalVertexNum;
764 if (miterStroke) {
765 totalVertexNum = outerVertexNum4Miter * 2 + innerVertexNum * 2;
766 outerVertexNum = outerVertexNum4Miter;
767 } else {
768 totalVertexNum = outerVertexNum4Bevel * 2 + innerVertexNum * 2;
769 outerVertexNum = outerVertexNum4Bevel;
770 }
771
772 GrDrawTarget::AutoReleaseGeometry geo(target, totalVertexNum, 0);
718 if (!geo.succeeded()) { 773 if (!geo.succeeded()) {
719 GrPrintf("Failed to get space for vertices!\n"); 774 GrPrintf("Failed to get space for vertices!\n");
720 return; 775 return;
721 } 776 }
722 GrIndexBuffer* indexBuffer = this->aaStrokeRectIndexBuffer(gpu); 777 GrIndexBuffer* indexBuffer = this->aaStrokeRectIndexBuffer(gpu, miterStroke) ;
723 if (NULL == indexBuffer) { 778 if (NULL == indexBuffer) {
724 GrPrintf("Failed to create index buffer!\n"); 779 GrPrintf("Failed to create index buffer!\n");
725 return; 780 return;
726 } 781 }
727 782
728 intptr_t verts = reinterpret_cast<intptr_t>(geo.vertices()); 783 intptr_t verts = reinterpret_cast<intptr_t>(geo.vertices());
729 size_t vsize = drawState->getVertexSize(); 784 size_t vsize = drawState->getVertexSize();
730 SkASSERT(sizeof(GrPoint) + sizeof(GrColor) == vsize); 785 SkASSERT(sizeof(GrPoint) + sizeof(GrColor) == vsize);
731 786
732 // We create vertices for four nested rectangles. There are two ramps from 0 to full 787 // We create vertices for four nested rectangles. There are two ramps from 0 to full
733 // coverage, one on the exterior of the stroke and the other on the interior . 788 // coverage, one on the exterior of the stroke and the other on the interior .
734 // The following pointers refer to the four rects, from outermost to innermo st. 789 // The following pointers refer to the four rects, from outermost to innermo st.
735 GrPoint* fan0Pos = reinterpret_cast<GrPoint*>(verts); 790 GrPoint* fan0Pos = reinterpret_cast<GrPoint*>(verts);
736 GrPoint* fan1Pos = reinterpret_cast<GrPoint*>(verts + 4 * vsize); 791 GrPoint* fan1Pos = reinterpret_cast<GrPoint*>(verts + outerVertexNum * vsize );
737 GrPoint* fan2Pos = reinterpret_cast<GrPoint*>(verts + 8 * vsize); 792 GrPoint* fan2Pos = reinterpret_cast<GrPoint*>(verts + 2 * outerVertexNum * v size);
738 GrPoint* fan3Pos = reinterpret_cast<GrPoint*>(verts + 12 * vsize); 793 GrPoint* fan3Pos = reinterpret_cast<GrPoint*>(verts + (2 * outerVertexNum + innerVertexNum) * vsize);
739 794
740 #ifndef SK_IGNORE_THIN_STROKED_RECT_FIX 795 #ifndef SK_IGNORE_THIN_STROKED_RECT_FIX
741 // TODO: this only really works if the X & Y margins are the same all around 796 // TODO: this only really works if the X & Y margins are the same all around
742 // the rect 797 // the rect
743 SkScalar inset = SkMinScalar(SK_Scalar1, devOutside.fRight - devInside.fRigh t); 798 SkScalar inset = SkMinScalar(SK_Scalar1, devOutside.fRight - devInside.fRigh t);
744 inset = SkMinScalar(inset, devInside.fLeft - devOutside.fLeft); 799 inset = SkMinScalar(inset, devInside.fLeft - devOutside.fLeft);
745 inset = SkMinScalar(inset, devInside.fTop - devOutside.fTop); 800 inset = SkMinScalar(inset, devInside.fTop - devOutside.fTop);
746 inset = SK_ScalarHalf * SkMinScalar(inset, devOutside.fBottom - devInside.fB ottom); 801 if (miterStroke) {
802 inset = SK_ScalarHalf * SkMinScalar(inset, devOutside.fBottom - devInsid e.fBottom);
803 } else {
804 inset = SK_ScalarHalf * SkMinScalar(inset, devOutsideAssist.fBottom - de vInside.fBottom);
805 }
747 SkASSERT(inset >= 0); 806 SkASSERT(inset >= 0);
748 #else 807 #else
749 SkScalar inset = SK_ScalarHalf; 808 SkScalar inset = SK_ScalarHalf;
750 #endif 809 #endif
751 810
752 // outermost 811 if (miterStroke) {
753 set_inset_fan(fan0Pos, vsize, devOutside, -SK_ScalarHalf, -SK_ScalarHalf); 812 // outermost
754 // inner two 813 set_inset_fan(fan0Pos, vsize, devOutside, -SK_ScalarHalf, -SK_ScalarHalf );
755 set_inset_fan(fan1Pos, vsize, devOutside, inset, inset); 814 // inner two
756 set_inset_fan(fan2Pos, vsize, devInside, -inset, -inset); 815 set_inset_fan(fan1Pos, vsize, devOutside, inset, inset);
757 // innermost 816 set_inset_fan(fan2Pos, vsize, devInside, -inset, -inset);
758 set_inset_fan(fan3Pos, vsize, devInside, SK_ScalarHalf, SK_ScalarHalf); 817 // innermost
818 set_inset_fan(fan3Pos, vsize, devInside, SK_ScalarHalf, SK_ScalarHalf );
819 } else {
820 GrPoint* fan0AssistPos = reinterpret_cast<GrPoint*>(verts + 4 * vsize);
821 GrPoint* fan1AssistPos = reinterpret_cast<GrPoint*>(verts + (outerVertex Num + 4) * vsize);
822 // outermost
823 set_inset_fan(fan0Pos, vsize, devOutside, -SK_ScalarHalf, -SK_ScalarHalf );
824 set_inset_fan(fan0AssistPos, vsize, devOutsideAssist, -SK_ScalarHalf, -S K_ScalarHalf);
825 // outer one of the inner two
826 set_inset_fan(fan1Pos, vsize, devOutside, inset, inset);
827 set_inset_fan(fan1AssistPos, vsize, devOutsideAssist, inset, inset);
828 // inner one of the inner two
829 set_inset_fan(fan2Pos, vsize, devInside, -inset, -inset);
830 // innermost
831 set_inset_fan(fan3Pos, vsize, devInside, SK_ScalarHalf, SK_ScalarHalf );
832 }
759 833
760 // The outermost rect has 0 coverage 834 // The outermost rect has 0 coverage
761 verts += sizeof(GrPoint); 835 verts += sizeof(GrPoint);
762 for (int i = 0; i < 4; ++i) { 836 for (int i = 0; i < outerVertexNum; ++i) {
763 *reinterpret_cast<GrColor*>(verts + i * vsize) = 0; 837 *reinterpret_cast<GrColor*>(verts + i * vsize) = 0;
764 } 838 }
765 839
766 int scale; 840 int scale;
767 if (inset < SK_ScalarHalf) { 841 if (inset < SK_ScalarHalf) {
768 scale = SkScalarFloorToInt(512.0f * inset / (inset + SK_ScalarHalf)); 842 scale = SkScalarFloorToInt(512.0f * inset / (inset + SK_ScalarHalf));
769 SkASSERT(scale >= 0 && scale <= 255); 843 SkASSERT(scale >= 0 && scale <= 255);
770 } else { 844 } else {
771 scale = 0xff; 845 scale = 0xff;
772 } 846 }
773 847
774 // The inner two rects have full coverage 848 // The inner two rects have full coverage
775 GrColor innerColor; 849 GrColor innerColor;
776 if (useVertexCoverage) { 850 if (useVertexCoverage) {
777 innerColor = GrColorPackRGBA(scale, scale, scale, scale); 851 innerColor = GrColorPackRGBA(scale, scale, scale, scale);
778 } else { 852 } else {
779 if (0xff == scale) { 853 if (0xff == scale) {
780 innerColor = target->getDrawState().getColor(); 854 innerColor = target->getDrawState().getColor();
781 } else { 855 } else {
782 innerColor = SkAlphaMulQ(target->getDrawState().getColor(), scale); 856 innerColor = SkAlphaMulQ(target->getDrawState().getColor(), scale);
783 } 857 }
784 } 858 }
785 859
786 verts += 4 * vsize; 860 verts += outerVertexNum * vsize;
787 for (int i = 0; i < 8; ++i) { 861 for (int i = 0; i < outerVertexNum + innerVertexNum; ++i) {
788 *reinterpret_cast<GrColor*>(verts + i * vsize) = innerColor; 862 *reinterpret_cast<GrColor*>(verts + i * vsize) = innerColor;
789 } 863 }
790 864
791 // The innermost rect has 0 coverage 865 // The innermost rect has 0 coverage
792 verts += 8 * vsize; 866 verts += (2 * outerVertexNum + innerVertexNum) * vsize;
793 for (int i = 0; i < 4; ++i) { 867 for (int i = 0; i < innerVertexNum; ++i) {
794 *reinterpret_cast<GrColor*>(verts + i * vsize) = 0; 868 *reinterpret_cast<GrColor*>(verts + i * vsize) = 0;
795 } 869 }
796 870
797 target->setIndexSourceToBuffer(indexBuffer); 871 target->setIndexSourceToBuffer(indexBuffer);
798 target->drawIndexed(kTriangles_GrPrimitiveType, 872 target->drawIndexed(kTriangles_GrPrimitiveType, 0, 0,
799 0, 0, 16, aaStrokeRectIndexCount()); 873 totalVertexNum, aaStrokeRectIndexCount(miterStroke));
800 } 874 }
801 875
802 void GrAARectRenderer::fillAANestedRects(GrGpu* gpu, 876 void GrAARectRenderer::fillAANestedRects(GrGpu* gpu,
803 GrDrawTarget* target, 877 GrDrawTarget* target,
804 const SkRect rects[2], 878 const SkRect rects[2],
805 const SkMatrix& combinedMatrix, 879 const SkMatrix& combinedMatrix,
806 bool useVertexCoverage) { 880 bool useVertexCoverage) {
807 SkASSERT(combinedMatrix.rectStaysRect()); 881 SkASSERT(combinedMatrix.rectStaysRect());
808 SkASSERT(!rects[1].isEmpty()); 882 SkASSERT(!rects[1].isEmpty());
809 883
810 SkRect devOutside, devInside; 884 SkRect devOutside, devOutsideAssist, devInside;
811 combinedMatrix.mapRect(&devOutside, rects[0]); 885 combinedMatrix.mapRect(&devOutside, rects[0]);
812 // can't call mapRect for devInside since it calls sort 886 // can't call mapRect for devInside since it calls sort
813 combinedMatrix.mapPoints((SkPoint*)&devInside, (const SkPoint*)&rects[1], 2) ; 887 combinedMatrix.mapPoints((SkPoint*)&devInside, (const SkPoint*)&rects[1], 2) ;
814 888
815 if (devInside.isEmpty()) { 889 if (devInside.isEmpty()) {
816 this->fillAARect(gpu, target, devOutside, SkMatrix::I(), devOutside, use VertexCoverage); 890 this->fillAARect(gpu, target, devOutside, SkMatrix::I(), devOutside, use VertexCoverage);
817 return; 891 return;
818 } 892 }
819 893
820 this->geometryStrokeAARect(gpu, target, devOutside, devInside, useVertexCove rage); 894 this->geometryStrokeAARect(gpu, target, devOutside, devOutsideAssist,
895 devInside, useVertexCoverage, true);
821 } 896 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698