Draw ovals with GrAAFillRRectOp

GrAAFillRRectOp has special geometry and a fragment-shader branch to
conditionally evaluate the arc equation. This same special geometry
and fragment branch also turn out to be a substantial optimization for
drawing ovals (namely, by not evaluating the arc equation inside the
oval's inner diamond). Given these optimizations, it's a clear win to
draw ovals the exact same way we do round rects.

However, we still don't draw true circles as round rects, because it
can cause perf regressions on some platforms as compared to the
dedicated circle Op.

Bug: skia:
Change-Id: Ifdfc4f593a8ab01b6f73a9e15dde732254213455
Reviewed-on: https://skia-review.googlesource.com/c/173277
Reviewed-by: Jim Van Verth <jvanverth@google.com>
Commit-Queue: Chris Dalton <csmartdalton@google.com>
This commit is contained in:
Chris Dalton 2018-11-28 16:58:09 -07:00 committed by Skia Commit-Bot
parent e801210a11
commit ebc38c998c

View File

@ -1383,9 +1383,24 @@ void GrRenderTargetContext::drawOval(const GrClip& clip,
GrAAType aaType = this->chooseAAType(aa, GrAllowMixedSamples::kNo);
if (GrAAType::kCoverage == aaType) {
const GrShaderCaps* shaderCaps = this->caps()->shaderCaps();
if (auto op = GrOvalOpFactory::MakeOvalOp(fContext, std::move(paint), viewMatrix, oval,
style, shaderCaps)) {
std::unique_ptr<GrDrawOp> op;
// GrAAFillRRectOp has special geometry and a fragment-shader branch to conditionally
// evaluate the arc equation. This same special geometry and fragment branch also turn out
// to be a substantial optimization for drawing ovals (namely, by not evaluating the arc
// equation inside the oval's inner diamond). Given these optimizations, it's a clear win to
// draw ovals the exact same way we do round rects.
//
// However, we still don't draw true circles as round rects, because it can cause perf
// regressions on some platforms as compared to the dedicated circle Op.
if (style.isSimpleFill() && oval.height() != oval.width()) {
op = GrAAFillRRectOp::Make(fContext, viewMatrix, SkRRect::MakeOval(oval), *this->caps(),
std::move(paint));
}
if (!op) {
op = GrOvalOpFactory::MakeOvalOp(fContext, std::move(paint), viewMatrix, oval, style,
this->caps()->shaderCaps());
}
if (op) {
this->addDrawOp(clip, std::move(op));
return;
}