Add a drawSimpleShape method to GrSurfaceDrawContext
Bug: chromium:1172543
Change-Id: I8c5f48cd7744755d5c207c53088912f0aa893369
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/366146
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
Commit-Queue: Chris Dalton <csmartdalton@google.com>
diff --git a/src/gpu/GrSurfaceDrawContext.cpp b/src/gpu/GrSurfaceDrawContext.cpp
index cf1f20a..857c26f 100644
--- a/src/gpu/GrSurfaceDrawContext.cpp
+++ b/src/gpu/GrSurfaceDrawContext.cpp
@@ -1587,61 +1587,13 @@
// claim strokes before trying to simplify them.
shape.simplifyStroke();
- if (!shape.style().hasPathEffect()) {
- GrAAType aaType = this->chooseAAType(aa);
- SkPoint linePts[2];
- SkRRect rrect;
- // We can ignore the starting point and direction since there is no path effect.
- bool inverted;
- if (shape.asLine(linePts, &inverted) && !inverted &&
- shape.style().strokeRec().getStyle() == SkStrokeRec::kStroke_Style &&
- shape.style().strokeRec().getCap() != SkPaint::kRound_Cap) {
- // The stroked line is an oriented rectangle, which looks the same or better (if
- // perspective) compared to path rendering. The exception is subpixel/hairline lines
- // that are non-AA or MSAA, in which case the default path renderer achieves higher
- // quality.
- // FIXME(michaelludwig): If the fill rect op could take an external coverage, or checks
- // for and outsets thin non-aa rects to 1px, the path renderer could be skipped.
- SkScalar coverage;
- if (aaType == GrAAType::kCoverage ||
- !SkDrawTreatAAStrokeAsHairline(shape.style().strokeRec().getWidth(), viewMatrix,
- &coverage)) {
- this->drawStrokedLine(clip, std::move(paint), aa, viewMatrix, linePts,
- shape.style().strokeRec());
- return;
- }
- } else if (shape.asRRect(&rrect, nullptr, nullptr, &inverted) && !inverted) {
- if (rrect.isRect()) {
- this->drawRect(clip, std::move(paint), aa, viewMatrix, rrect.rect(),
- &shape.style());
- return;
- } else if (rrect.isOval()) {
- this->drawOval(clip, std::move(paint), aa, viewMatrix, rrect.rect(), shape.style());
- return;
- }
- this->drawRRect(clip, std::move(paint), aa, viewMatrix, rrect, shape.style());
- return;
- } else if (GrAAType::kCoverage == aaType && shape.style().isSimpleFill() &&
- viewMatrix.rectStaysRect()) {
- // TODO: the rectStaysRect restriction could be lifted if we were willing to apply
- // the matrix to all the points individually rather than just to the rect
- SkRect rects[2];
- if (shape.asNestedRects(rects)) {
- // Concave AA paths are expensive - try to avoid them for special cases
- GrOp::Owner op = GrStrokeRectOp::MakeNested(
- fContext, std::move(paint), viewMatrix, rects);
- if (op) {
- this->addDrawOp(clip, std::move(op));
- }
- // Returning here indicates that there is nothing to draw in this case.
- return;
- }
- }
+ if (this->drawSimpleShape(clip, &paint, aa, viewMatrix, shape)) {
+ return;
}
// If we get here in drawShape(), we definitely need to use path rendering
this->drawShapeUsingPathRenderer(clip, std::move(paint), aa, viewMatrix, std::move(shape),
- /* attempt fallback */ false);
+ /* attemptDrawSimple */ false);
}
static SkIRect get_clip_bounds(const GrSurfaceDrawContext* rtc, const GrClip* clip) {
@@ -1772,12 +1724,69 @@
this->fillQuadWithEdgeAA(clip, std::move(paint), aa, edgeAA, viewMatrix, corners, nullptr);
}
+bool GrSurfaceDrawContext::drawSimpleShape(const GrClip* clip, GrPaint* paint, GrAA aa,
+ const SkMatrix& viewMatrix, const GrStyledShape& shape) {
+ if (!shape.style().hasPathEffect()) {
+ GrAAType aaType = this->chooseAAType(aa);
+ SkPoint linePts[2];
+ SkRRect rrect;
+ // We can ignore the starting point and direction since there is no path effect.
+ bool inverted;
+ if (shape.asLine(linePts, &inverted) && !inverted &&
+ shape.style().strokeRec().getStyle() == SkStrokeRec::kStroke_Style &&
+ shape.style().strokeRec().getCap() != SkPaint::kRound_Cap) {
+ // The stroked line is an oriented rectangle, which looks the same or better (if
+ // perspective) compared to path rendering. The exception is subpixel/hairline lines
+ // that are non-AA or MSAA, in which case the default path renderer achieves higher
+ // quality.
+ // FIXME(michaelludwig): If the fill rect op could take an external coverage, or checks
+ // for and outsets thin non-aa rects to 1px, the path renderer could be skipped.
+ SkScalar coverage;
+ if (aaType == GrAAType::kCoverage ||
+ !SkDrawTreatAAStrokeAsHairline(shape.style().strokeRec().getWidth(), viewMatrix,
+ &coverage)) {
+ this->drawStrokedLine(clip, std::move(*paint), aa, viewMatrix, linePts,
+ shape.style().strokeRec());
+ return true;
+ }
+ } else if (shape.asRRect(&rrect, nullptr, nullptr, &inverted) && !inverted) {
+ if (rrect.isRect()) {
+ this->drawRect(clip, std::move(*paint), aa, viewMatrix, rrect.rect(),
+ &shape.style());
+ return true;
+ } else if (rrect.isOval()) {
+ this->drawOval(clip, std::move(*paint), aa, viewMatrix, rrect.rect(),
+ shape.style());
+ return true;
+ }
+ this->drawRRect(clip, std::move(*paint), aa, viewMatrix, rrect, shape.style());
+ return true;
+ } else if (GrAAType::kCoverage == aaType && shape.style().isSimpleFill() &&
+ viewMatrix.rectStaysRect()) {
+ // TODO: the rectStaysRect restriction could be lifted if we were willing to apply the
+ // matrix to all the points individually rather than just to the rect
+ SkRect rects[2];
+ if (shape.asNestedRects(rects)) {
+ // Concave AA paths are expensive - try to avoid them for special cases
+ GrOp::Owner op = GrStrokeRectOp::MakeNested(
+ fContext, std::move(*paint), viewMatrix, rects);
+ if (op) {
+ this->addDrawOp(clip, std::move(op));
+ }
+ // Returning here indicates that there is nothing to draw in this case.
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
void GrSurfaceDrawContext::drawShapeUsingPathRenderer(const GrClip* clip,
GrPaint&& paint,
GrAA aa,
const SkMatrix& viewMatrix,
GrStyledShape&& shape,
- bool attemptShapeFallback) {
+ bool attemptDrawSimple) {
ASSERT_SINGLE_OWNER
RETURN_IF_ABANDONED
GR_CREATE_TRACE_MARKER_CONTEXT("GrSurfaceDrawContext", "internalDrawPath", fContext);
@@ -1790,12 +1799,13 @@
// claim strokes before trying to simplify them.
shape.simplifyStroke();
- if (attemptShapeFallback && shape.simplified()) {
+ if (attemptDrawSimple && shape.simplified()) {
// Usually we enter drawShapeUsingPathRenderer() because the shape+style was too
// complex for dedicated draw ops. However, if GrStyledShape was able to reduce something
// we ought to try again instead of going right to path rendering.
- this->drawShape(clip, std::move(paint), aa, viewMatrix, std::move(shape));
- return;
+ if (this->drawSimpleShape(clip, &paint, aa, viewMatrix, shape)) {
+ return;
+ }
}
SkIRect clipConservativeBounds = get_clip_bounds(this, clip);
diff --git a/src/gpu/GrSurfaceDrawContext.h b/src/gpu/GrSurfaceDrawContext.h
index d88225e..a5c12a3 100644
--- a/src/gpu/GrSurfaceDrawContext.h
+++ b/src/gpu/GrSurfaceDrawContext.h
@@ -709,10 +709,15 @@
void drawStrokedLine(const GrClip*, GrPaint&&, GrAA, const SkMatrix&, const SkPoint[2],
const SkStrokeRec&);
- // If 'attemptShapeFallback' is true, and the original shape had been simplfied, this
- // will re-route through drawShape() to see if we can avoid path rendering one more time.
+ // Tries to detect if the given shape is a simple, and draws it without path rendering if
+ // we know how.
+ bool drawSimpleShape(const GrClip*, GrPaint*, GrAA, const SkMatrix&, const GrStyledShape&);
+
+ // If 'attemptDrawSimple' is true, and the original shape had been simplfied, this
+ // will attempt to re-route through drawSimpleShape() to see if we can avoid path rendering one
+ // more time.
void drawShapeUsingPathRenderer(const GrClip*, GrPaint&&, GrAA, const SkMatrix&,
- GrStyledShape&&, bool attemptShapeFallback = true);
+ GrStyledShape&&, bool attemptDrawSimple = true);
// Makes a copy of the proxy if it is necessary for the draw and places the texture that should
// be used by GrXferProcessor to access the destination color in 'result'. If the return