Delete GrSurfaceDrawContext::drawDRRect

Instead, we just push the inner rrect to the clip stack and draw the
outer. It's faster to use GrFillRRectOp for the outer rect anyway, and
now that we use analytic clipping even when MSAA is enabled, there is
no added value in a specialized drawDRRect implementation.

Bug: skia:7826
Bug: skia:11396
Change-Id: I07b3143f2a5f9c75c7dfeda54e777b105bde9992
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/383396
Commit-Queue: Chris Dalton <csmartdalton@google.com>
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
This commit is contained in:
Chris Dalton 2021-03-12 09:08:07 -07:00 committed by Skia Commit-Bot
parent 7d592cda58
commit 5d34303748
3 changed files with 27 additions and 152 deletions

View File

@ -1201,126 +1201,6 @@ bool GrSurfaceDrawContext::drawFastShadow(const GrClip* clip,
///////////////////////////////////////////////////////////////////////////////
bool GrSurfaceDrawContext::drawFilledDRRect(const GrClip* clip,
GrPaint&& paint,
GrAA aa,
const SkMatrix& viewMatrix,
const SkRRect& origOuter,
const SkRRect& origInner) {
SkASSERT(!origInner.isEmpty());
SkASSERT(!origOuter.isEmpty());
SkTCopyOnFirstWrite<SkRRect> inner(origInner), outer(origOuter);
GrAAType aaType = this->chooseAAType(aa);
if (GrAAType::kMSAA == aaType) {
return false;
}
if (GrAAType::kCoverage == aaType && SkRRectPriv::IsCircle(*inner)
&& SkRRectPriv::IsCircle(*outer)) {
auto outerR = outer->width() / 2.f;
auto innerR = inner->width() / 2.f;
auto cx = outer->getBounds().fLeft + outerR;
auto cy = outer->getBounds().fTop + outerR;
if (SkScalarNearlyEqual(cx, inner->getBounds().fLeft + innerR) &&
SkScalarNearlyEqual(cy, inner->getBounds().fTop + innerR)) {
auto avgR = (innerR + outerR) / 2.f;
auto circleBounds = SkRect::MakeLTRB(cx - avgR, cy - avgR, cx + avgR, cy + avgR);
SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle);
stroke.setStrokeStyle(outerR - innerR);
auto op = GrOvalOpFactory::MakeOvalOp(fContext, std::move(paint), viewMatrix,
circleBounds, GrStyle(stroke, nullptr),
this->caps()->shaderCaps());
if (op) {
this->addDrawOp(clip, std::move(op));
return true;
}
assert_alive(paint);
}
}
GrClipEdgeType innerEdgeType, outerEdgeType;
if (GrAAType::kCoverage == aaType) {
innerEdgeType = GrClipEdgeType::kInverseFillAA;
outerEdgeType = GrClipEdgeType::kFillAA;
} else {
innerEdgeType = GrClipEdgeType::kInverseFillBW;
outerEdgeType = GrClipEdgeType::kFillBW;
}
SkMatrix inverseVM;
if (!viewMatrix.isIdentity()) {
if (!origInner.transform(viewMatrix, inner.writable())) {
return false;
}
if (!origOuter.transform(viewMatrix, outer.writable())) {
return false;
}
if (!viewMatrix.invert(&inverseVM)) {
return false;
}
} else {
inverseVM.reset();
}
const auto& caps = *this->caps()->shaderCaps();
// TODO these need to be a geometry processors
auto [success, fp] = GrRRectEffect::Make(/*inputFP=*/nullptr, innerEdgeType, *inner, caps);
if (!success) {
return false;
}
std::tie(success, fp) = GrRRectEffect::Make(std::move(fp), outerEdgeType, *outer, caps);
if (!success) {
return false;
}
paint.setCoverageFragmentProcessor(std::move(fp));
SkRect bounds = outer->getBounds();
if (GrAAType::kCoverage == aaType) {
bounds.outset(SK_ScalarHalf, SK_ScalarHalf);
}
this->fillRectWithLocalMatrix(clip, std::move(paint), GrAA::kNo, SkMatrix::I(), bounds,
inverseVM);
return true;
}
void GrSurfaceDrawContext::drawDRRect(const GrClip* clip,
GrPaint&& paint,
GrAA aa,
const SkMatrix& viewMatrix,
const SkRRect& outer,
const SkRRect& inner) {
ASSERT_SINGLE_OWNER
RETURN_IF_ABANDONED
SkDEBUGCODE(this->validate();)
GR_CREATE_TRACE_MARKER_CONTEXT("GrSurfaceDrawContext", "drawDRRect", fContext);
SkASSERT(!outer.isEmpty());
SkASSERT(!inner.isEmpty());
AutoCheckFlush acf(this->drawingManager());
if (this->drawFilledDRRect(clip, std::move(paint), aa, viewMatrix, outer, inner)) {
return;
}
assert_alive(paint);
SkPath path;
path.setIsVolatile(true);
path.addRRect(inner);
path.addRRect(outer);
path.setFillType(SkPathFillType::kEvenOdd);
this->drawShapeUsingPathRenderer(clip, std::move(paint), aa, viewMatrix,
GrStyledShape(path, DoSimplify::kNo));
}
///////////////////////////////////////////////////////////////////////////////
void GrSurfaceDrawContext::drawRegion(const GrClip* clip,
GrPaint&& paint,
GrAA aa,

View File

@ -368,23 +368,6 @@ public:
const SkPath& path,
const SkDrawShadowRec& rec);
/**
* Shortcut for filling a SkPath consisting of nested rrects using a paint. The result is
* undefined if outer does not contain inner.
*
* @param paint describes how to color pixels.
* @param GrAA Controls whether rrects edges are antialiased
* @param viewMatrix transformation matrix
* @param outer the outer roundrect
* @param inner the inner roundrect
*/
void drawDRRect(const GrClip*,
GrPaint&&,
GrAA,
const SkMatrix& viewMatrix,
const SkRRect& outer,
const SkRRect& inner);
/**
* Draws a path.
*
@ -668,14 +651,6 @@ private:
void internalStencilClear(const SkIRect* scissor, bool insideStencilMask);
// Only consumes the GrPaint if successful.
bool drawFilledDRRect(const GrClip* clip,
GrPaint&& paint,
GrAA,
const SkMatrix& viewMatrix,
const SkRRect& origOuter,
const SkRRect& origInner);
// If the drawn quad's paint is a const blended color, provide it as a non-null pointer to
// 'constColor', which enables the draw-as-clear optimization. Otherwise it is assumed the paint
// requires some form of shading that invalidates using a clear op.

View File

@ -41,6 +41,7 @@
#include "src/gpu/GrTextureAdjuster.h"
#include "src/gpu/GrTracing.h"
#include "src/gpu/SkGr.h"
#include "src/gpu/effects/GrRRectEffect.h"
#include "src/gpu/geometry/GrStyledShape.h"
#include "src/image/SkImage_Base.h"
#include "src/image/SkReadPixelsRec.h"
@ -499,6 +500,18 @@ void SkGpuDevice::drawRRect(const SkRRect& rrect, const SkPaint& paint) {
this->localToDevice(), rrect, style);
}
static std::unique_ptr<GrFragmentProcessor> make_inverse_rrect_fp(const SkMatrix& viewMatrix,
const SkRRect& rrect, bool aa,
const GrShaderCaps& shaderCaps) {
SkTCopyOnFirstWrite<SkRRect> devRRect(rrect);
if (viewMatrix.isIdentity() || rrect.transform(viewMatrix, devRRect.writable())) {
auto edgeType = (aa) ? GrClipEdgeType::kInverseFillAA : GrClipEdgeType::kInverseFillBW;
auto [success, fp] = GrRRectEffect::Make(/*inputFP=*/nullptr, edgeType, *devRRect,
shaderCaps);
return (success) ? std::move(fp) : nullptr;
}
return nullptr;
}
void SkGpuDevice::drawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint) {
ASSERT_SINGLE_OWNER
@ -514,15 +527,22 @@ void SkGpuDevice::drawDRRect(const SkRRect& outer, const SkRRect& inner, const S
SkStrokeRec stroke(paint);
if (stroke.isFillStyle() && !paint.getMaskFilter() && !paint.getPathEffect()) {
GrPaint grPaint;
if (!SkPaintToGrPaint(this->recordingContext(), fSurfaceDrawContext->colorInfo(), paint,
this->asMatrixProvider(), &grPaint)) {
// For axis-aligned filled DRRects, just draw a regular rrect with inner clipped out using a
// coverage FP instead of using path rendering.
if (auto fp = make_inverse_rrect_fp(this->localToDevice(), inner, paint.isAntiAlias(),
*fSurfaceDrawContext->caps()->shaderCaps())) {
GrPaint grPaint;
if (!SkPaintToGrPaint(this->recordingContext(), fSurfaceDrawContext->colorInfo(), paint,
this->asMatrixProvider(), &grPaint)) {
return;
}
SkASSERT(!grPaint.hasCoverageFragmentProcessor());
grPaint.setCoverageFragmentProcessor(std::move(fp));
fSurfaceDrawContext->drawRRect(this->clip(), std::move(grPaint),
GrAA(paint.isAntiAlias()), this->localToDevice(), outer,
GrStyle());
return;
}
fSurfaceDrawContext->drawDRRect(this->clip(), std::move(grPaint), GrAA(paint.isAntiAlias()),
this->localToDevice(), outer, inner);
return;
}
SkPath path;