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:
parent
7d592cda58
commit
5d34303748
@ -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,
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user