Index: src/gpu/SkGpuDevice.cpp |
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp |
index 10bcecf2ba350c3b08e002f22815835d166288bd..774f5646c049e616d1fedb085db80e91f318a35b 100644 |
--- a/src/gpu/SkGpuDevice.cpp |
+++ b/src/gpu/SkGpuDevice.cpp |
@@ -692,12 +692,76 @@ void SkGpuDevice::drawOval(const SkDraw& draw, const SkRect& oval, const SkPaint |
#include "SkMaskFilter.h" |
/////////////////////////////////////////////////////////////////////////////// |
+void SkGpuDevice::drawStrokedLine(const SkPoint points[2], |
+ const SkDraw& draw, |
+ const SkPaint& origPaint) { |
+ ASSERT_SINGLE_OWNER |
+ GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawStrokedLine", fContext); |
+ CHECK_SHOULD_DRAW(draw); |
+ |
+ SkASSERT(SkPaint::kStroke_Style == origPaint.getStyle()); |
+ SkASSERT(!origPaint.getPathEffect()); |
+ SkASSERT(!origPaint.getMaskFilter()); |
+ |
+ const SkScalar halfWidth = origPaint.getStrokeWidth()/2.0f; |
reed1
2016/05/31 12:54:48
Does this version devolve into multiply-by-0.5 ?
robertphillips
2016/05/31 19:06:54
Done.
|
+ SkASSERT(halfWidth > 0); |
reed1
2016/05/31 12:54:48
Do you not try to trigger your hairline code for t
robertphillips
2016/05/31 19:06:54
To the best of my knowledge we only kick into hair
|
+ |
+ SkVector v = points[1] - points[0]; |
+ |
+ SkScalar length = SkPoint::Normalize(&v); |
+ |
+ SkPaint newPaint(origPaint); |
+ newPaint.setStyle(SkPaint::kFill_Style); |
+ |
+ SkScalar xtraLength = 0.0f; |
+ if (SkPaint::kButt_Cap != origPaint.getStrokeCap()) { |
+ xtraLength = halfWidth; |
+ } |
+ |
+ SkPoint mid = points[0] + points[1]; |
+ mid.scale(0.5f); |
+ |
+ SkRect rect = SkRect::MakeLTRB(mid.fX-halfWidth, mid.fY - 0.5f*length - xtraLength, |
+ mid.fX+halfWidth, mid.fY + 0.5f*length + xtraLength); |
+ SkMatrix m; |
+ m.setSinCos(v.fX, -v.fY, mid.fX, mid.fY); |
reed1
2016/05/31 12:54:48
Is this really faster than just drawing a quad? I
robertphillips
2016/05/31 19:06:54
Doing it this way allows greater batching. A more
|
+ |
+ SkMatrix local = m; |
+ |
+ m.postConcat(*draw.fMatrix); |
+ |
+ GrPaint grPaint; |
+ if (!SkPaintToGrPaint(this->context(), newPaint, m, |
+ this->surfaceProps().isGammaCorrect(), &grPaint)) { |
+ return; |
+ } |
+ |
+ if (SkPaint::kRound_Cap != origPaint.getStrokeCap()) { |
+ fDrawContext->fillRectWithLocalMatrix(fClip, grPaint, m, rect, local); |
+ } else { |
+ // TODO: add a GrDrawContext::fillRRectWithLocalMatrix entry point |
+ SkASSERT(0); |
+ const SkRRect rrect = SkRRect::MakeRectXY(rect, halfWidth, halfWidth); |
+ |
+ GrStyle style(newPaint); |
+ fDrawContext->drawRRect(fClip, grPaint, m, rrect, style); |
+ } |
+} |
void SkGpuDevice::drawPath(const SkDraw& draw, const SkPath& origSrcPath, |
const SkPaint& paint, const SkMatrix* prePathMatrix, |
bool pathIsMutable) { |
ASSERT_SINGLE_OWNER |
if (!origSrcPath.isInverseFillType() && !paint.getPathEffect() && !prePathMatrix) { |
+ SkPoint points[2]; |
+ if (SkPaint::kStroke_Style == paint.getStyle() && paint.getStrokeWidth() > 0 && |
+ !paint.getMaskFilter() && SkPaint::kRound_Cap != paint.getStrokeCap() && |
+ draw.fMatrix->preservesRightAngles() && origSrcPath.isLine(points)) { |
reed1
2016/05/31 12:54:48
May not come up much, but if we just create quads,
robertphillips
2016/05/31 19:06:54
Right. The skew and perspective cases don't seem t
|
+ // TODO: to support round capped stroked lines we need RRect batches |
bsalomon
2016/05/31 16:47:27
Re to TODO. Unless we really have to, I strongly p
robertphillips
2016/05/31 19:06:54
Done. Switched the TODO over to an informational c
|
+ // that take a localMatrix |
+ this->drawStrokedLine(points, draw, paint); |
+ return; |
+ } |
bool isClosed; |
SkRect rect; |
if (origSrcPath.isRect(&rect, &isClosed) && isClosed) { |