Index: src/gpu/GrAARectRenderer.cpp |
=================================================================== |
--- src/gpu/GrAARectRenderer.cpp (revision 11903) |
+++ src/gpu/GrAARectRenderer.cpp (working copy) |
@@ -289,7 +289,8 @@ |
void GrAARectRenderer::reset() { |
SkSafeSetNull(fAAFillRectIndexBuffer); |
- SkSafeSetNull(fAAStrokeRectIndexBuffer); |
+ SkSafeSetNull(fAAMiterStrokeRectIndexBuffer); |
+ SkSafeSetNull(fAABevelStrokeRectIndexBuffer); |
} |
static const uint16_t gFillAARectIdx[] = { |
@@ -340,7 +341,7 @@ |
return fAAFillRectIndexBuffer; |
} |
-static const uint16_t gStrokeAARectIdx[] = { |
+static const uint16_t gMiterStrokeAARectIdx[] = { |
0 + 0, 1 + 0, 5 + 0, 5 + 0, 4 + 0, 0 + 0, |
1 + 0, 2 + 0, 6 + 0, 6 + 0, 5 + 0, 1 + 0, |
2 + 0, 3 + 0, 7 + 0, 7 + 0, 6 + 0, 2 + 0, |
@@ -357,24 +358,67 @@ |
3 + 8, 0 + 8, 4 + 8, 4 + 8, 7 + 8, 3 + 8, |
}; |
robertphillips
2013/10/30 14:36:08
Could you add a comment here (and maybe some ASCII
yunchao
2013/10/31 07:47:23
Agree with you. I added a comment about the indice
|
-int GrAARectRenderer::aaStrokeRectIndexCount() { |
- return GR_ARRAY_COUNT(gStrokeAARectIdx); |
+static const uint16_t gBevelStrokeAARectIdx[] = { |
+ 0 + 0, 1 + 0, 9 + 0, 9 + 0, 8 + 0, 0 + 0, |
+ 1 + 0, 5 + 0, 13 + 0, 13 + 0, 9 + 0, 1 + 0, |
+ 5 + 0, 6 + 0, 14 + 0, 14 + 0, 13 + 0, 5 + 0, |
+ 6 + 0, 2 + 0, 10 + 0, 10 + 0, 14 + 0, 6 + 0, |
+ 2 + 0, 3 + 0, 11 + 0, 11 + 0, 10 + 0, 2 + 0, |
+ 3 + 0, 7 + 0, 15 + 0, 15 + 0, 11 + 0, 3 + 0, |
+ 7 + 0, 4 + 0, 12 + 0, 12 + 0, 15 + 0, 7 + 0, |
+ 4 + 0, 0 + 0, 8 + 0, 8 + 0, 12 + 0, 4 + 0, |
+ |
+ 0 + 8, 1 + 8, 9 + 8, 9 + 8, 8 + 8, 0 + 8, |
+ 1 + 8, 5 + 8, 9 + 8, |
+ 5 + 8, 6 + 8, 10 + 8, 10 + 8, 9 + 8, 5 + 8, |
+ 6 + 8, 2 + 8, 10 + 8, |
+ 2 + 8, 3 + 8, 11 + 8, 11 + 8, 10 + 8, 2 + 8, |
+ 3 + 8, 7 + 8, 11 + 8, |
+ 7 + 8, 4 + 8, 8 + 8, 8 + 8, 11 + 8, 7 + 8, |
+ 4 + 8, 0 + 8, 8 + 8, |
+ |
+ 0 + 16, 1 + 16, 5 + 16, 5 + 16, 4 + 16, 0 + 16, |
+ 1 + 16, 2 + 16, 6 + 16, 6 + 16, 5 + 16, 1 + 16, |
+ 2 + 16, 3 + 16, 7 + 16, 7 + 16, 6 + 16, 2 + 16, |
+ 3 + 16, 0 + 16, 4 + 16, 4 + 16, 7 + 16, 3 + 16, |
+}; |
+ |
+int GrAARectRenderer::aaStrokeRectIndexCount(bool miterStroke) { |
+ return miterStroke ? GR_ARRAY_COUNT(gMiterStrokeAARectIdx) : |
+ GR_ARRAY_COUNT(gBevelStrokeAARectIdx); |
} |
-GrIndexBuffer* GrAARectRenderer::aaStrokeRectIndexBuffer(GrGpu* gpu) { |
- if (NULL == fAAStrokeRectIndexBuffer) { |
- fAAStrokeRectIndexBuffer = |
- gpu->createIndexBuffer(sizeof(gStrokeAARectIdx), false); |
- if (NULL != fAAStrokeRectIndexBuffer) { |
+GrIndexBuffer* GrAARectRenderer::aaStrokeRectIndexBuffer(GrGpu* gpu, |
bsalomon
2013/10/30 14:13:02
this can stay as one line (we wrap at 100col)
|
+ bool miterStroke) { |
+ if (miterStroke) { |
+ if (NULL == fAAMiterStrokeRectIndexBuffer) { |
+ fAAMiterStrokeRectIndexBuffer = |
+ gpu->createIndexBuffer(sizeof(gMiterStrokeAARectIdx), false); |
+ if (NULL != fAAMiterStrokeRectIndexBuffer) { |
#ifdef SK_DEBUG |
- bool updated = |
+ bool updated = |
#endif |
- fAAStrokeRectIndexBuffer->updateData(gStrokeAARectIdx, |
- sizeof(gStrokeAARectIdx)); |
- GR_DEBUGASSERT(updated); |
+ fAAMiterStrokeRectIndexBuffer->updateData(gMiterStrokeAARectIdx, |
robertphillips
2013/10/30 14:36:08
Please align the "sizeof" line with the above "(".
|
+ sizeof(gMiterStrokeAARectIdx)); |
+ GR_DEBUGASSERT(updated); |
+ } |
} |
+ return fAAMiterStrokeRectIndexBuffer; |
+ } else { |
+ if (NULL == fAABevelStrokeRectIndexBuffer) { |
+ fAABevelStrokeRectIndexBuffer = |
+ gpu->createIndexBuffer(sizeof(gBevelStrokeAARectIdx), false); |
+ if (NULL != fAABevelStrokeRectIndexBuffer) { |
+#ifdef SK_DEBUG |
+ bool updated = |
+#endif |
+ fAABevelStrokeRectIndexBuffer->updateData(gBevelStrokeAARectIdx, |
robertphillips
2013/10/30 14:36:08
Here too please.
|
+ sizeof(gBevelStrokeAARectIdx)); |
+ GR_DEBUGASSERT(updated); |
+ } |
+ } |
+ return fAABevelStrokeRectIndexBuffer; |
} |
- return fAAStrokeRectIndexBuffer; |
} |
void GrAARectRenderer::geometryFillAARect(GrGpu* gpu, |
@@ -653,9 +697,12 @@ |
const SkRect& rect, |
const SkMatrix& combinedMatrix, |
const SkRect& devRect, |
- SkScalar width, |
- bool useVertexCoverage) { |
+ //SkScalar width, |
bsalomon
2013/10/30 14:13:02
Please remove rather than commenting out.
|
+ const SkStrokeRec* stroke, |
+ bool useVertexCoverage/*, |
+ bool miterStroke*/) { |
bsalomon
2013/10/30 14:13:02
and here
|
GrVec devStrokeSize; |
+ SkScalar width = stroke->getWidth(); |
if (width > 0) { |
devStrokeSize.set(width, width); |
combinedMatrix.mapVectors(&devStrokeSize, 1); |
@@ -696,24 +743,51 @@ |
SkRect devInside(devRect); |
devInside.inset(rx, ry); |
- this->geometryStrokeAARect(gpu, target, devOutside, devInside, useVertexCoverage); |
+ SkRect devOutsideAssist(devRect); |
+ |
robertphillips
2013/10/30 14:36:08
I think the entire computation of "miterStroke" ca
|
+ bool miterStroke = true; |
+ // small miter limit means right angles show bevel... |
+ if (stroke->getJoin() != SkPaint::kMiter_Join || |
+ stroke->getMiter() < SK_ScalarSqrt2) { |
+ miterStroke = false; |
+ } |
+ |
+ if (!miterStroke) { |
robertphillips
2013/10/30 14:36:08
inset(0, ry) rather than outset(0, -ry)?
yunchao
2013/10/31 07:47:23
I checked my local code, it is a typo, it should b
|
+ devOutside.outset(0, -ry); |
+ devOutsideAssist.outset(0, ry); |
+ } |
+ this->geometryStrokeAARect(gpu, target, devOutside, devOutsideAssist, |
+ devInside, useVertexCoverage, miterStroke); |
} |
void GrAARectRenderer::geometryStrokeAARect(GrGpu* gpu, |
GrDrawTarget* target, |
const SkRect& devOutside, |
robertphillips
2013/10/30 14:36:08
Is there a comment somewhere (maybe the header) as
|
+ const SkRect& devOutsideAssist, |
const SkRect& devInside, |
- bool useVertexCoverage) { |
+ bool useVertexCoverage, |
+ bool miterStroke) { |
GrDrawState* drawState = target->drawState(); |
set_aa_rect_vertex_attributes(drawState, useVertexCoverage); |
robertphillips
2013/10/30 14:36:08
Make these two with static const (and prefix with
yunchao
2013/10/31 07:47:23
Yeah, a good suggestion, I will keep this style.
|
- GrDrawTarget::AutoReleaseGeometry geo(target, 16, 0); |
+ int outerVertexNum4Miter = 4, outerVertexNum4Bevel = 8; |
+ int outerVertexNum, innerVertexNum = 4; |
+ int totalVertexNum; |
+ if (miterStroke) { |
+ totalVertexNum = outerVertexNum4Miter * 2 + innerVertexNum * 2; |
+ outerVertexNum = outerVertexNum4Miter; |
+ } else { |
+ totalVertexNum = outerVertexNum4Bevel * 2 + innerVertexNum * 2; |
+ outerVertexNum = outerVertexNum4Bevel; |
+ } |
+ |
+ GrDrawTarget::AutoReleaseGeometry geo(target, totalVertexNum, 0); |
if (!geo.succeeded()) { |
GrPrintf("Failed to get space for vertices!\n"); |
return; |
} |
- GrIndexBuffer* indexBuffer = this->aaStrokeRectIndexBuffer(gpu); |
+ GrIndexBuffer* indexBuffer = this->aaStrokeRectIndexBuffer(gpu, miterStroke); |
if (NULL == indexBuffer) { |
GrPrintf("Failed to create index buffer!\n"); |
return; |
@@ -727,9 +801,9 @@ |
// coverage, one on the exterior of the stroke and the other on the interior. |
// The following pointers refer to the four rects, from outermost to innermost. |
GrPoint* fan0Pos = reinterpret_cast<GrPoint*>(verts); |
- GrPoint* fan1Pos = reinterpret_cast<GrPoint*>(verts + 4 * vsize); |
- GrPoint* fan2Pos = reinterpret_cast<GrPoint*>(verts + 8 * vsize); |
- GrPoint* fan3Pos = reinterpret_cast<GrPoint*>(verts + 12 * vsize); |
+ GrPoint* fan1Pos = reinterpret_cast<GrPoint*>(verts + outerVertexNum * vsize); |
+ GrPoint* fan2Pos = reinterpret_cast<GrPoint*>(verts + 2 * outerVertexNum * vsize); |
+ GrPoint* fan3Pos = reinterpret_cast<GrPoint*>(verts + (2 * outerVertexNum + innerVertexNum) * vsize); |
#ifndef SK_IGNORE_THIN_STROKED_RECT_FIX |
// TODO: this only really works if the X & Y margins are the same all around |
@@ -737,23 +811,42 @@ |
SkScalar inset = SkMinScalar(SK_Scalar1, devOutside.fRight - devInside.fRight); |
inset = SkMinScalar(inset, devInside.fLeft - devOutside.fLeft); |
inset = SkMinScalar(inset, devInside.fTop - devOutside.fTop); |
- inset = SK_ScalarHalf * SkMinScalar(inset, devOutside.fBottom - devInside.fBottom); |
+ if (miterStroke) { |
+ inset = SK_ScalarHalf * SkMinScalar(inset, devOutside.fBottom - devInside.fBottom); |
+ } else { |
+ inset = SK_ScalarHalf * SkMinScalar(inset, devOutsideAssist.fBottom - devInside.fBottom); |
+ } |
SkASSERT(inset >= 0); |
#else |
SkScalar inset = SK_ScalarHalf; |
#endif |
- // outermost |
- set_inset_fan(fan0Pos, vsize, devOutside, -SK_ScalarHalf, -SK_ScalarHalf); |
- // inner two |
- set_inset_fan(fan1Pos, vsize, devOutside, inset, inset); |
- set_inset_fan(fan2Pos, vsize, devInside, -inset, -inset); |
- // innermost |
- set_inset_fan(fan3Pos, vsize, devInside, SK_ScalarHalf, SK_ScalarHalf); |
+ if (miterStroke) { |
+ // outermost |
+ set_inset_fan(fan0Pos, vsize, devOutside, -SK_ScalarHalf, -SK_ScalarHalf); |
+ // inner two |
+ set_inset_fan(fan1Pos, vsize, devOutside, inset, inset); |
+ set_inset_fan(fan2Pos, vsize, devInside, -inset, -inset); |
+ // innermost |
+ set_inset_fan(fan3Pos, vsize, devInside, SK_ScalarHalf, SK_ScalarHalf); |
+ } else { |
+ GrPoint* fan0AssistPos = reinterpret_cast<GrPoint*>(verts + 4 * vsize); |
+ GrPoint* fan1AssistPos = reinterpret_cast<GrPoint*>(verts + (outerVertexNum + 4) * vsize); |
+ // outermost |
+ set_inset_fan(fan0Pos, vsize, devOutside, -SK_ScalarHalf, -SK_ScalarHalf); |
+ set_inset_fan(fan0AssistPos, vsize, devOutsideAssist, -SK_ScalarHalf, -SK_ScalarHalf); |
+ // outer one of the inner two |
+ set_inset_fan(fan1Pos, vsize, devOutside, inset, inset); |
+ set_inset_fan(fan1AssistPos, vsize, devOutsideAssist, inset, inset); |
+ // inner one of the inner two |
+ set_inset_fan(fan2Pos, vsize, devInside, -inset, -inset); |
+ // innermost |
+ set_inset_fan(fan3Pos, vsize, devInside, SK_ScalarHalf, SK_ScalarHalf); |
+ } |
// The outermost rect has 0 coverage |
verts += sizeof(GrPoint); |
- for (int i = 0; i < 4; ++i) { |
+ for (int i = 0; i < outerVertexNum; ++i) { |
*reinterpret_cast<GrColor*>(verts + i * vsize) = 0; |
} |
@@ -777,20 +870,20 @@ |
} |
} |
- verts += 4 * vsize; |
- for (int i = 0; i < 8; ++i) { |
+ verts += outerVertexNum * vsize; |
+ for (int i = 0; i < outerVertexNum + innerVertexNum; ++i) { |
*reinterpret_cast<GrColor*>(verts + i * vsize) = innerColor; |
} |
// The innermost rect has 0 coverage |
- verts += 8 * vsize; |
- for (int i = 0; i < 4; ++i) { |
+ verts += (2 * outerVertexNum + innerVertexNum) * vsize; |
+ for (int i = 0; i < innerVertexNum; ++i) { |
*reinterpret_cast<GrColor*>(verts + i * vsize) = 0; |
} |
target->setIndexSourceToBuffer(indexBuffer); |
- target->drawIndexed(kTriangles_GrPrimitiveType, |
- 0, 0, 16, aaStrokeRectIndexCount()); |
+ target->drawIndexed(kTriangles_GrPrimitiveType, 0, 0, |
+ totalVertexNum, aaStrokeRectIndexCount(miterStroke)); |
} |
void GrAARectRenderer::fillAANestedRects(GrGpu* gpu, |
@@ -801,7 +894,7 @@ |
SkASSERT(combinedMatrix.rectStaysRect()); |
SkASSERT(!rects[1].isEmpty()); |
- SkRect devOutside, devInside; |
+ SkRect devOutside, devOutsideAssist, devInside; |
combinedMatrix.mapRect(&devOutside, rects[0]); |
// can't call mapRect for devInside since it calls sort |
combinedMatrix.mapPoints((SkPoint*)&devInside, (const SkPoint*)&rects[1], 2); |
@@ -811,5 +904,6 @@ |
return; |
} |
- this->geometryStrokeAARect(gpu, target, devOutside, devInside, useVertexCoverage); |
+ this->geometryStrokeAARect(gpu, target, devOutside, devOutsideAssist, |
+ devInside, useVertexCoverage, true); |
} |