Index: src/gpu/GrContext.cpp |
=================================================================== |
--- src/gpu/GrContext.cpp (revision 9163) |
+++ src/gpu/GrContext.cpp (working copy) |
@@ -792,17 +792,9 @@ |
return; |
} |
if (width >= 0) { |
- GrVec strokeSize; |
- if (width > 0) { |
- strokeSize.set(width, width); |
- combinedMatrix.mapVectors(&strokeSize, 1); |
- strokeSize.setAbs(strokeSize); |
- } else { |
- strokeSize.set(SK_Scalar1, SK_Scalar1); |
- } |
fAARectRenderer->strokeAARect(this->getGpu(), target, |
rect, combinedMatrix, devRect, |
- strokeSize, useVertexCoverage); |
+ width, useVertexCoverage); |
} else { |
// filled AA rect |
fAARectRenderer->fillAARect(this->getGpu(), target, |
@@ -1004,6 +996,52 @@ |
} |
} |
+namespace { |
+ |
+// Can 'path' be drawn as a pair of filled nested rectangles? |
+static bool is_nested_rects(GrDrawTarget* target, |
+ const SkPath& path, |
+ const SkStrokeRec& stroke, |
+ SkRect rects[2], |
+ bool* useVertexCoverage) { |
+ SkASSERT(stroke.isFillStyle()); |
+ |
+ if (path.isInverseFillType()) { |
+ return false; |
+ } |
+ |
+ const GrDrawState& drawState = target->getDrawState(); |
+ |
+ // TODO: this restriction could be lifted if we were willing to apply |
+ // the matrix to all the points individually rather than just to the rect |
+ if (!drawState.getViewMatrix().preservesAxisAlignment()) { |
+ return false; |
+ } |
+ |
+ *useVertexCoverage = false; |
+ if (!target->getDrawState().canTweakAlphaForCoverage()) { |
+ if (disable_coverage_aa_for_blend(target)) { |
+ return false; |
+ } else { |
+ *useVertexCoverage = true; |
+ } |
+ } |
+ |
+ SkPath::Direction dirs[2]; |
+ if (!path.isNestedRects(rects, dirs)) { |
+ return false; |
+ } |
+ |
+ if (SkPath::kWinding_FillType == path.getFillType()) { |
+ // The two rects need to be wound opposite to each other |
+ return dirs[0] != dirs[1]; |
+ } else { |
+ return true; |
+ } |
+} |
+ |
+}; |
+ |
void GrContext::drawPath(const GrPaint& paint, const SkPath& path, const SkStrokeRec& stroke) { |
if (path.isEmpty()) { |
@@ -1021,9 +1059,28 @@ |
GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW); |
GrDrawState::AutoStageDisable atr(fDrawState); |
+ bool useAA = paint.isAntiAlias() && !this->getRenderTarget()->isMultisampled(); |
+ if (useAA && stroke.getWidth() < 0 && !path.isConvex()) { |
+ // Concave AA paths are expensive - try to avoid them for special cases |
+ bool useVertexCoverage; |
+ SkRect rects[2]; |
+ |
+ if (is_nested_rects(target, path, stroke, rects, &useVertexCoverage)) { |
+ GrDrawState::AutoDeviceCoordDraw adcd(target->drawState()); |
+ if (!adcd.succeeded()) { |
+ return; |
+ } |
+ |
+ fAARectRenderer->fillAANestedRects(this->getGpu(), target, |
+ rects, |
+ adcd.getOriginalMatrix(), |
+ useVertexCoverage); |
+ return; |
+ } |
+ } |
+ |
SkRect ovalRect; |
bool isOval = path.isOval(&ovalRect); |
- bool useAA = paint.isAntiAlias() && !this->getRenderTarget()->isMultisampled(); |
if (!isOval || path.isInverseFillType() |
|| !fOvalRenderer->drawOval(target, this, useAA, ovalRect, stroke)) { |