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

Unified 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, 2 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 side-by-side diff with in-line comments
Download patch
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);
}
« no previous file with comments | « src/gpu/GrAARectRenderer.h ('k') | src/gpu/GrContext.cpp » ('j') | src/gpu/SkGpuDevice.cpp » ('J')

Powered by Google App Engine
This is Rietveld 408576698