Update GrRRectEffect to take an input FP and return a MakeResult.

Change-Id: If5abcd2347871c62e03c8708705ec1041572465a
Bug: skia:10217
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/296838
Commit-Queue: John Stiles <johnstiles@google.com>
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
This commit is contained in:
John Stiles 2020-06-17 13:53:37 -04:00 committed by Skia Commit-Bot
parent 8605d84f6d
commit 851b90e102
6 changed files with 74 additions and 62 deletions

View File

@ -91,9 +91,11 @@ protected:
SkRRect rrect = fRRect;
rrect.offset(SkIntToScalar(x + kGap), SkIntToScalar(y + kGap));
const auto& caps = *renderTargetContext->caps()->shaderCaps();
auto fp = GrRRectEffect::Make(edgeType, rrect, caps);
SkASSERT(fp);
if (fp) {
auto [success, fp] = GrRRectEffect::Make(/*inputFP=*/nullptr, edgeType, rrect,
caps);
SkASSERT(success);
if (success) {
SkASSERT(fp);
GrPaint grPaint;
grPaint.setColor4f({ 0, 0, 0, 1.f });
grPaint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc));

View File

@ -120,8 +120,9 @@ protected:
rrect.offset(SkIntToScalar(x), SkIntToScalar(y));
GrClipEdgeType edgeType = (GrClipEdgeType) et;
const auto& caps = *renderTargetContext->caps()->shaderCaps();
auto fp = GrRRectEffect::Make(edgeType, rrect, caps);
if (fp) {
auto [success, fp] = GrRRectEffect::Make(/*inputFP=*/nullptr,
edgeType, rrect, caps);
if (success) {
GrPaint grPaint;
grPaint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc));
grPaint.addCoverageFragmentProcessor(std::move(fp));

View File

@ -669,10 +669,23 @@ GrReducedClip::ClipResult GrReducedClip::addAnalyticFP(const SkRRect& deviceSpac
return ClipResult::kNotClipped;
}
if (auto fp = GrRRectEffect::Make(GetClipEdgeType(invert, aa), deviceSpaceRRect,
*fCaps->shaderCaps())) {
fAnalyticFPs.push_back(std::move(fp));
return ClipResult::kClipped;
if (fAnalyticFPs.empty()) {
// Create our first analytic effect in the stack.
auto [success, fp] = GrRRectEffect::Make(/*inputFP=*/nullptr, GetClipEdgeType(invert, aa),
deviceSpaceRRect, *fCaps->shaderCaps());
if (success) {
fAnalyticFPs.push_back(std::move(fp));
return ClipResult::kClipped;
}
} else {
// Combine this analytic effect with the previous effect in the stack.
auto [success, fp] = GrRRectEffect::Make(std::move(fAnalyticFPs.back()),
GetClipEdgeType(invert, aa), deviceSpaceRRect,
*fCaps->shaderCaps());
fAnalyticFPs.back() = std::move(fp);
if (success) {
return ClipResult::kClipped;
}
}
SkPath deviceSpacePath;

View File

@ -1498,18 +1498,17 @@ bool GrRenderTargetContext::drawFilledDRRect(const GrClip* clip,
const auto& caps = *this->caps()->shaderCaps();
// TODO these need to be a geometry processors
auto innerEffect = GrRRectEffect::Make(innerEdgeType, *inner, caps);
if (!innerEffect) {
auto [success, fp] = GrRRectEffect::Make(/*inputFP=*/nullptr, innerEdgeType, *inner, caps);
if (!success) {
return false;
}
auto outerEffect = GrRRectEffect::Make(outerEdgeType, *outer, caps);
if (!outerEffect) {
std::tie(success, fp) = GrRRectEffect::Make(std::move(fp), outerEdgeType, *outer, caps);
if (!success) {
return false;
}
paint.addCoverageFragmentProcessor(std::move(innerEffect));
paint.addCoverageFragmentProcessor(std::move(outerEffect));
paint.addCoverageFragmentProcessor(std::move(fp));
SkRect bounds = outer->getBounds();
if (GrAAType::kCoverage == aaType) {

View File

@ -45,9 +45,8 @@ public:
// The flags are used to indicate which corners are circluar (unflagged corners are assumed to
// be square).
static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> inputFP,
GrClipEdgeType,
uint32_t circularCornerFlags, const SkRRect&);
static MakeResult Make(std::unique_ptr<GrFragmentProcessor>, GrClipEdgeType,
uint32_t circularCornerFlags, const SkRRect&);
~CircularRRectEffect() override {}
@ -85,14 +84,15 @@ private:
typedef GrFragmentProcessor INHERITED;
};
std::unique_ptr<GrFragmentProcessor> CircularRRectEffect::Make(
std::unique_ptr<GrFragmentProcessor> inputFP, GrClipEdgeType edgeType,
uint32_t circularCornerFlags, const SkRRect& rrect) {
GrFragmentProcessor::MakeResult CircularRRectEffect::Make(
std::unique_ptr<GrFragmentProcessor> inputFP,
GrClipEdgeType edgeType,
uint32_t circularCornerFlags, const SkRRect& rrect) {
if (GrClipEdgeType::kFillAA != edgeType && GrClipEdgeType::kInverseFillAA != edgeType) {
return nullptr;
return MakeFailure(std::move(inputFP));
}
return std::unique_ptr<GrFragmentProcessor>(
new CircularRRectEffect(std::move(inputFP), edgeType, circularCornerFlags, rrect));
return MakeSuccess(std::unique_ptr<GrFragmentProcessor>(
new CircularRRectEffect(std::move(inputFP), edgeType, circularCornerFlags, rrect)));
}
CircularRRectEffect::CircularRRectEffect(std::unique_ptr<GrFragmentProcessor> inputFP,
@ -140,11 +140,13 @@ std::unique_ptr<GrFragmentProcessor> CircularRRectEffect::TestCreate(GrProcessor
SkRRect rrect;
rrect.setRectXY(SkRect::MakeWH(w, h), r, r);
std::unique_ptr<GrFragmentProcessor> fp;
bool success;
do {
GrClipEdgeType et =
(GrClipEdgeType)d->fRandom->nextULessThan(kGrClipEdgeTypeCnt);
fp = GrRRectEffect::Make(et, rrect, *d->caps()->shaderCaps());
} while (nullptr == fp);
std::tie(success, fp) = GrRRectEffect::Make(/*inputFP=*/nullptr, et, rrect,
*d->caps()->shaderCaps());
} while (!success);
return fp;
}
#endif
@ -410,8 +412,7 @@ GrGLSLFragmentProcessor* CircularRRectEffect::onCreateGLSLInstance() const {
class EllipticalRRectEffect : public GrFragmentProcessor {
public:
static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor>,
GrClipEdgeType, const SkRRect&);
static MakeResult Make(std::unique_ptr<GrFragmentProcessor>, GrClipEdgeType, const SkRRect&);
~EllipticalRRectEffect() override {}
@ -445,14 +446,14 @@ private:
typedef GrFragmentProcessor INHERITED;
};
std::unique_ptr<GrFragmentProcessor> EllipticalRRectEffect::Make(
std::unique_ptr<GrFragmentProcessor> inputFP,
GrClipEdgeType edgeType, const SkRRect& rrect) {
GrFragmentProcessor::MakeResult EllipticalRRectEffect::Make(
std::unique_ptr<GrFragmentProcessor> inputFP,
GrClipEdgeType edgeType, const SkRRect& rrect) {
if (GrClipEdgeType::kFillAA != edgeType && GrClipEdgeType::kInverseFillAA != edgeType) {
return nullptr;
return MakeFailure(std::move(inputFP));
}
return std::unique_ptr<GrFragmentProcessor>(new EllipticalRRectEffect(
std::move(inputFP), edgeType, rrect));
return MakeSuccess(std::unique_ptr<GrFragmentProcessor>(
new EllipticalRRectEffect(std::move(inputFP), edgeType, rrect)));
}
EllipticalRRectEffect::EllipticalRRectEffect(std::unique_ptr<GrFragmentProcessor> inputFP,
@ -517,10 +518,12 @@ std::unique_ptr<GrFragmentProcessor> EllipticalRRectEffect::TestCreate(GrProcess
r[SkRRect::kUpperLeft_Corner].fY);
}
std::unique_ptr<GrFragmentProcessor> fp;
bool success;
do {
GrClipEdgeType et = (GrClipEdgeType)d->fRandom->nextULessThan(kGrClipEdgeTypeCnt);
fp = GrRRectEffect::Make(et, rrect, *d->caps()->shaderCaps());
} while (nullptr == fp);
std::tie(success, fp) = GrRRectEffect::Make(/*inputFP=*/nullptr, et, rrect,
*d->caps()->shaderCaps());
} while (!success);
return fp;
}
#endif
@ -722,19 +725,16 @@ GrGLSLFragmentProcessor* EllipticalRRectEffect::onCreateGLSLInstance() const {
//////////////////////////////////////////////////////////////////////////////
std::unique_ptr<GrFragmentProcessor> GrRRectEffect::Make(GrClipEdgeType edgeType,
const SkRRect& rrect,
const GrShaderCaps& caps) {
GrFragmentProcessor::MakeResult GrRRectEffect::Make(std::unique_ptr<GrFragmentProcessor> inputFP,
GrClipEdgeType edgeType,
const SkRRect& rrect,
const GrShaderCaps& caps) {
if (rrect.isRect()) {
auto [success, fp] = GrConvexPolyEffect::Make(/*inputFP=*/nullptr,
edgeType, rrect.getBounds());
return std::move(fp);
return GrConvexPolyEffect::Make(std::move(inputFP), edgeType, rrect.getBounds());
}
if (rrect.isOval()) {
auto [success, fp] = GrOvalEffect::Make(/*inputFP=*/nullptr, edgeType, rrect.getBounds(),
caps);
return std::move(fp);
return GrOvalEffect::Make(std::move(inputFP), edgeType, rrect.getBounds(), caps);
}
if (rrect.isSimple()) {
@ -742,15 +742,13 @@ std::unique_ptr<GrFragmentProcessor> GrRRectEffect::Make(GrClipEdgeType edgeType
SkRRectPriv::GetSimpleRadii(rrect).fY < kRadiusMin) {
// In this case the corners are extremely close to rectangular and we collapse the
// clip to a rectangular clip.
auto [success, fp] = GrConvexPolyEffect::Make(/*inputFP=*/nullptr,
edgeType, rrect.getBounds());
return std::move(fp);
return GrConvexPolyEffect::Make(std::move(inputFP), edgeType, rrect.getBounds());
}
if (SkRRectPriv::GetSimpleRadii(rrect).fX == SkRRectPriv::GetSimpleRadii(rrect).fY) {
return CircularRRectEffect::Make(/*inputFP=*/nullptr, edgeType,
return CircularRRectEffect::Make(std::move(inputFP), edgeType,
CircularRRectEffect::kAll_CornerFlags, rrect);
} else {
return EllipticalRRectEffect::Make(/*inputFP=*/nullptr, edgeType, rrect);
return EllipticalRRectEffect::Make(std::move(inputFP), edgeType, rrect);
}
}
@ -807,27 +805,24 @@ std::unique_ptr<GrFragmentProcessor> GrRRectEffect::Make(GrClipEdgeType edgeType
if (squashedRadii) {
rr.writable()->setRectRadii(rrect.getBounds(), radii);
}
return CircularRRectEffect::Make(/*inputFP=*/nullptr, edgeType, cornerFlags, *rr);
return CircularRRectEffect::Make(std::move(inputFP), edgeType, cornerFlags, *rr);
}
case CircularRRectEffect::kNone_CornerFlags: {
auto [success, fp] = GrConvexPolyEffect::Make(/*inputFP=*/nullptr,
edgeType, rrect.getBounds());
return std::move(fp);
return GrConvexPolyEffect::Make(std::move(inputFP), edgeType, rrect.getBounds());
}
default: {
if (squashedRadii) {
// If we got here then we squashed some but not all the radii to zero. (If all
// had been squashed cornerFlags would be 0.) The elliptical effect doesn't
// support some rounded and some square corners.
return nullptr;
return GrFragmentProcessor::MakeFailure(std::move(inputFP));
}
if (rrect.isNinePatch()) {
return EllipticalRRectEffect::Make(/*inputFP=*/nullptr, edgeType, rrect);
return EllipticalRRectEffect::Make(std::move(inputFP), edgeType, rrect);
}
return nullptr;
return GrFragmentProcessor::MakeFailure(std::move(inputFP));
}
}
}
return nullptr;
return GrFragmentProcessor::MakeFailure(std::move(inputFP));
}

View File

@ -11,8 +11,8 @@
#include "include/core/SkRefCnt.h"
#include "include/gpu/GrTypes.h"
#include "include/private/GrTypesPriv.h"
#include "src/gpu/GrFragmentProcessor.h"
class GrFragmentProcessor;
class GrShaderCaps;
class GrProcessor;
class SkRRect;
@ -21,9 +21,11 @@ namespace GrRRectEffect {
/**
* Creates an effect that performs anti-aliased clipping against a SkRRect. It doesn't support
* all varieties of SkRRect so the caller must check for a nullptr return.
* all varieties of SkRRect, so the caller must check `success` in the MakeResult.
*/
std::unique_ptr<GrFragmentProcessor> Make(GrClipEdgeType, const SkRRect&, const GrShaderCaps&);
GrFragmentProcessor::MakeResult Make(std::unique_ptr<GrFragmentProcessor>, GrClipEdgeType,
const SkRRect&, const GrShaderCaps&);
};
#endif