diff options
-rw-r--r-- | src/gpu/GrDrawContext.cpp | 7 | ||||
-rw-r--r-- | src/gpu/batches/GrAAStrokeRectBatch.cpp | 96 | ||||
-rw-r--r-- | src/gpu/batches/GrAAStrokeRectBatch.h | 13 | ||||
-rw-r--r-- | src/gpu/batches/GrRectBatchFactory.cpp | 64 | ||||
-rw-r--r-- | src/gpu/batches/GrRectBatchFactory.h | 12 |
5 files changed, 107 insertions, 85 deletions
diff --git a/src/gpu/GrDrawContext.cpp b/src/gpu/GrDrawContext.cpp index 94fcee0313..1969bd03be 100644 --- a/src/gpu/GrDrawContext.cpp +++ b/src/gpu/GrDrawContext.cpp @@ -273,13 +273,12 @@ void GrDrawContext::drawRect(GrRenderTarget* rt, if (needAA && canApplyAA) { SkASSERT(!viewMatrix.hasPerspective()); - SkRect devBoundRect; - viewMatrix.mapRect(&devBoundRect, rect); SkAutoTUnref<GrDrawBatch> batch; if (width >= 0) { - batch.reset(GrRectBatchFactory::CreateAAStroke(color, viewMatrix, rect, devBoundRect, - *strokeInfo)); + batch.reset(GrRectBatchFactory::CreateAAStroke(color, viewMatrix, rect, *strokeInfo)); } else { + SkRect devBoundRect; + viewMatrix.mapRect(&devBoundRect, rect); batch.reset(GrRectBatchFactory::CreateAAFill(color, viewMatrix, rect, devBoundRect)); } fDrawTarget->drawBatch(pipelineBuilder, batch); diff --git a/src/gpu/batches/GrAAStrokeRectBatch.cpp b/src/gpu/batches/GrAAStrokeRectBatch.cpp index ea8bc2e46e..9addc2fa41 100644 --- a/src/gpu/batches/GrAAStrokeRectBatch.cpp +++ b/src/gpu/batches/GrAAStrokeRectBatch.cpp @@ -520,6 +520,68 @@ void AAStrokeRectBatch::generateAAStrokeRectGeometry(void* vertices, } } +inline static bool is_miter(const SkStrokeRec& stroke) { + // For hairlines, make bevel and round joins appear the same as mitered ones. + // small miter limit means right angles show bevel... + if ((stroke.getWidth() > 0) && (stroke.getJoin() != SkPaint::kMiter_Join || + stroke.getMiter() < SK_ScalarSqrt2)) { + return false; + } + return true; +} + +static void compute_rects(SkRect* devOutside, SkRect* devOutsideAssist, SkRect* devInside, + bool* isDegenerate, const SkMatrix& viewMatrix, const SkRect& rect, + SkScalar strokeWidth, bool miterStroke) { + SkRect devRect; + viewMatrix.mapRect(&devRect, rect); + + SkVector devStrokeSize; + if (strokeWidth > 0) { + devStrokeSize.set(strokeWidth, strokeWidth); + viewMatrix.mapVectors(&devStrokeSize, 1); + devStrokeSize.setAbs(devStrokeSize); + } else { + devStrokeSize.set(SK_Scalar1, SK_Scalar1); + } + + const SkScalar dx = devStrokeSize.fX; + const SkScalar dy = devStrokeSize.fY; + const SkScalar rx = SkScalarMul(dx, SK_ScalarHalf); + const SkScalar ry = SkScalarMul(dy, SK_ScalarHalf); + + *devOutside = devRect; + *devOutsideAssist = devRect; + *devInside = devRect; + + devOutside->outset(rx, ry); + devInside->inset(rx, ry); + + // If we have a degenerate stroking rect(ie the stroke is larger than inner rect) then we + // make a degenerate inside rect to avoid double hitting. We will also jam all of the points + // together when we render these rects. + SkScalar spare; + { + SkScalar w = devRect.width() - dx; + SkScalar h = devRect.height() - dy; + spare = SkTMin(w, h); + } + + *isDegenerate = spare <= 0; + if (*isDegenerate) { + devInside->fLeft = devInside->fRight = devRect.centerX(); + devInside->fTop = devInside->fBottom = devRect.centerY(); + } + + // For bevel-stroke, use 2 SkRect instances(devOutside and devOutsideAssist) + // to draw the outside of the octagon. Because there are 8 vertices on the outer + // edge, while vertex number of inner edge is 4, the same as miter-stroke. + if (!miterStroke) { + devOutside->inset(0, ry); + devOutsideAssist->outset(0, ry); + } +} + namespace GrAAStrokeRectBatch { GrDrawBatch* Create(GrColor color, @@ -535,22 +597,42 @@ GrDrawBatch* Create(GrColor color, return batch; } +GrDrawBatch* Create(GrColor color, + const SkMatrix& viewMatrix, + const SkRect& rect, + const SkStrokeRec& stroke) { + bool isMiterStroke = is_miter(stroke); + AAStrokeRectBatch* batch = AAStrokeRectBatch::Create(viewMatrix, isMiterStroke); + + SkRect devOutside, devOutsideAssist, devInside; + bool isDegenerate; + compute_rects(&devOutside, &devOutsideAssist, &devInside, &isDegenerate, viewMatrix, + rect, stroke.getWidth(), isMiterStroke); + + batch->append(color, devOutside, devOutsideAssist, devInside, isDegenerate); + batch->init(); + return batch; +} + bool Append(GrBatch* origBatch, GrColor color, const SkMatrix& viewMatrix, - const SkRect& devOutside, - const SkRect& devOutsideAssist, - const SkRect& devInside, - bool miterStroke, - bool degenerate) { + const SkRect& rect, + const SkStrokeRec& stroke) { AAStrokeRectBatch* batch = origBatch->cast<AAStrokeRectBatch>(); // we can't batch across vm changes - if (!batch->canAppend(viewMatrix, miterStroke)) { + bool isMiterStroke = is_miter(stroke); + if (!batch->canAppend(viewMatrix, isMiterStroke)) { return false; } - batch->appendAndUpdateBounds(color, devOutside, devOutsideAssist, devInside, degenerate); + SkRect devOutside, devOutsideAssist, devInside; + bool isDegenerate; + compute_rects(&devOutside, &devOutsideAssist, &devInside, &isDegenerate, viewMatrix, + rect, stroke.getWidth(), isMiterStroke); + + batch->appendAndUpdateBounds(color, devOutside, devOutsideAssist, devInside, isDegenerate); return true; } diff --git a/src/gpu/batches/GrAAStrokeRectBatch.h b/src/gpu/batches/GrAAStrokeRectBatch.h index 242597b66a..4959232bab 100644 --- a/src/gpu/batches/GrAAStrokeRectBatch.h +++ b/src/gpu/batches/GrAAStrokeRectBatch.h @@ -15,6 +15,7 @@ class GrDrawBatch; class GrResourceProvider; class SkMatrix; struct SkRect; +class SkStrokeRec; namespace GrAAStrokeRectBatch { @@ -26,14 +27,16 @@ GrDrawBatch* Create(GrColor color, bool miterStroke, bool degenerate); +GrDrawBatch* Create(GrColor color, + const SkMatrix& viewMatrix, + const SkRect& rect, + const SkStrokeRec& stroke); + bool Append(GrBatch*, GrColor color, const SkMatrix& viewMatrix, - const SkRect& devOutside, - const SkRect& devOutsideAssist, - const SkRect& devInside, - bool miterStroke, - bool degenerate); + const SkRect& rect, + const SkStrokeRec& stroke); }; diff --git a/src/gpu/batches/GrRectBatchFactory.cpp b/src/gpu/batches/GrRectBatchFactory.cpp index f34a8c058a..f144d1b532 100644 --- a/src/gpu/batches/GrRectBatchFactory.cpp +++ b/src/gpu/batches/GrRectBatchFactory.cpp @@ -13,70 +13,6 @@ namespace GrRectBatchFactory { -GrDrawBatch* CreateAAStroke(GrColor color, - const SkMatrix& viewMatrix, - const SkRect& rect, - const SkRect& devRect, - const SkStrokeRec& stroke) { - SkVector devStrokeSize; - SkScalar width = stroke.getWidth(); - if (width > 0) { - devStrokeSize.set(width, width); - viewMatrix.mapVectors(&devStrokeSize, 1); - devStrokeSize.setAbs(devStrokeSize); - } else { - devStrokeSize.set(SK_Scalar1, SK_Scalar1); - } - - const SkScalar dx = devStrokeSize.fX; - const SkScalar dy = devStrokeSize.fY; - const SkScalar rx = SkScalarMul(dx, SK_ScalarHalf); - const SkScalar ry = SkScalarMul(dy, SK_ScalarHalf); - - SkRect devOutside(devRect); - devOutside.outset(rx, ry); - - bool miterStroke = true; - // For hairlines, make bevel and round joins appear the same as mitered ones. - // small miter limit means right angles show bevel... - if ((width > 0) && (stroke.getJoin() != SkPaint::kMiter_Join || - stroke.getMiter() < SK_ScalarSqrt2)) { - miterStroke = false; - } - - SkRect devInside(devRect); - devInside.inset(rx, ry); - - // If we have a degenerate stroking rect(ie the stroke is larger than inner rect) then we - // make a degenerate inside rect to avoid double hitting. We will also jam all of the points - // together when we render these rects. - SkScalar spare; - { - SkScalar w = devRect.width() - dx; - SkScalar h = devRect.height() - dy; - spare = SkTMin(w, h); - } - - bool degenerate = spare <= 0; - if (degenerate) { - devInside.fLeft = devInside.fRight = devRect.centerX(); - devInside.fTop = devInside.fBottom = devRect.centerY(); - } - - SkRect devOutsideAssist(devRect); - - // For bevel-stroke, use 2 SkRect instances(devOutside and devOutsideAssist) - // to draw the outer of the rect. Because there are 8 vertices on the outer - // edge, while vertex number of inner edge is 4, the same as miter-stroke. - if (!miterStroke) { - devOutside.inset(0, ry); - devOutsideAssist.outset(0, ry); - } - - return GrAAStrokeRectBatch::Create(color, viewMatrix, devOutside, devOutsideAssist, devInside, - miterStroke, degenerate); -} - GrDrawBatch* CreateAAFillNestedRects(GrColor color, const SkMatrix& viewMatrix, const SkRect rects[2]) { diff --git a/src/gpu/batches/GrRectBatchFactory.h b/src/gpu/batches/GrRectBatchFactory.h index fbbc66acbc..16eeaee02c 100644 --- a/src/gpu/batches/GrRectBatchFactory.h +++ b/src/gpu/batches/GrRectBatchFactory.h @@ -9,6 +9,7 @@ #define GrRectBatchFactory_DEFINED #include "GrAAFillRectBatch.h" +#include "GrAAStrokeRectBatch.h" #include "GrColor.h" #include "GrNonAAFillRectBatch.h" #include "GrNonAAStrokeRectBatch.h" @@ -59,11 +60,12 @@ inline GrDrawBatch* CreateNonAAStroke(GrColor color, return GrNonAAStrokeRectBatch::Create(color, viewMatrix, rect, strokeWidth, snapToPixelCenters); } -GrDrawBatch* CreateAAStroke(GrColor, - const SkMatrix& viewMatrix, - const SkRect& rect, - const SkRect& devRect, - const SkStrokeRec& stroke); +inline GrDrawBatch* CreateAAStroke(GrColor color, + const SkMatrix& viewMatrix, + const SkRect& rect, + const SkStrokeRec& stroke) { + return GrAAStrokeRectBatch::Create(color, viewMatrix, rect, stroke); +} // First rect is outer; second rect is inner GrDrawBatch* CreateAAFillNestedRects(GrColor, |