Rename MakeResult so that it can be used more broadly.

MakeResult will be needed when migrating `asFragmentProcessor` calls.
However, the typename previously could not be forward-declared because
it was a type buried inside a class. Also, the name `MakeResult` seems
too tightly-coupled to the `Make` functions.

The type has been renamed to `GrFPResult` and moved out of
GrFragmentProcessor to allow `asFragmentProcessor` to use it without
actually #including GrFragmentProcessor.

Change-Id: Ic2c701b943aa64e0f922827b60084e58c67bfb8d
Bug: skia:10217
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/298740
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
This commit is contained in:
John Stiles 2020-06-24 10:42:35 -04:00 committed by Skia Commit-Bot
parent 900630c7cd
commit 72e576492c
13 changed files with 76 additions and 82 deletions

View File

@ -21,6 +21,7 @@ class SkBitmap;
class SkColorMatrix;
class SkColorSpace;
struct SkStageRec;
using GrFPResult = std::tuple<bool, std::unique_ptr<GrFragmentProcessor>>;
namespace skvm {
class Builder;

View File

@ -202,20 +202,6 @@ public:
void visitProxies(const GrOp::VisitProxyFunc& func);
/**
* Some fragment processors' Make() methods have preconditions that might not be satisfied by
* the calling code. Those FPs can return a `MakeResult` from their Make() methods. If creation
* succeeds, the new fragment processor is created and `success` is true. If a precondition is
* not met, `success` is set to false and the input FP is returned unchanged.
*/
using MakeResult = std::tuple<bool /*success*/, std::unique_ptr<GrFragmentProcessor>>;
static MakeResult MakeFailure(std::unique_ptr<GrFragmentProcessor> fp) {
return {false, std::move(fp)};
}
static MakeResult MakeSuccess(std::unique_ptr<GrFragmentProcessor> fp) {
return {true, std::move(fp)};
}
// A pre-order traversal iterator over a hierarchy of FPs. It can also iterate over all the FP
// hierarchies rooted in a GrPaint, GrProcessorSet, or GrPipeline. For these collections it
// iterates the tree rooted at each color FP and then each coverage FP.
@ -705,4 +691,18 @@ private:
Src& fSrc;
};
/**
* Some fragment-processor creation methods have preconditions that might not be satisfied by the
* calling code. Those methods can return a `GrFPResult` from their factory methods. If creation
* succeeds, the new fragment processor is created and `success` is true. If a precondition is not
* met, `success` is set to false and the input FP is returned unchanged.
*/
using GrFPResult = std::tuple<bool /*success*/, std::unique_ptr<GrFragmentProcessor>>;
static inline GrFPResult GrFPFailure(std::unique_ptr<GrFragmentProcessor> fp) {
return {false, std::move(fp)};
}
static inline GrFPResult GrFPSuccess(std::unique_ptr<GrFragmentProcessor> fp) {
return {true, std::move(fp)};
}
#endif

View File

@ -17,16 +17,15 @@ float prevRadius = -1;
uniform float4 circle;
@make {
static MakeResult Make(std::unique_ptr<GrFragmentProcessor> inputFP,
static GrFPResult Make(std::unique_ptr<GrFragmentProcessor> inputFP,
GrClipEdgeType edgeType, SkPoint center, float radius) {
// A radius below half causes the implicit insetting done by this processor to become
// inverted. We could handle this case by making the processor code more complicated.
if (radius < .5f && GrProcessorEdgeTypeIsInverseFill(edgeType)) {
return MakeFailure(std::move(inputFP));
return GrFPFailure(std::move(inputFP));
}
return MakeSuccess(
std::unique_ptr<GrFragmentProcessor>(new GrCircleEffect(std::move(inputFP),
edgeType, center, radius)));
return GrFPSuccess(std::unique_ptr<GrFragmentProcessor>(
new GrCircleEffect(std::move(inputFP), edgeType, center, radius)));
}
}

View File

@ -94,11 +94,10 @@ void GrGLConvexPolyEffect::GenKey(const GrProcessor& processor, const GrShaderCa
//////////////////////////////////////////////////////////////////////////////
GrFragmentProcessor::MakeResult GrConvexPolyEffect::Make(
std::unique_ptr<GrFragmentProcessor> inputFP,
GrClipEdgeType type, const SkPath& path) {
GrFPResult GrConvexPolyEffect::Make(std::unique_ptr<GrFragmentProcessor> inputFP,
GrClipEdgeType type, const SkPath& path) {
if (path.getSegmentMasks() != SkPath::kLine_SegmentMask || !path.isConvex()) {
return MakeFailure(std::move(inputFP));
return GrFPFailure(std::move(inputFP));
}
SkPathPriv::FirstDirection dir;
@ -107,7 +106,7 @@ GrFragmentProcessor::MakeResult GrConvexPolyEffect::Make(
// skip the draw or omit the clip element.
if (!SkPathPriv::CheapComputeFirstDirection(path, &dir)) {
if (GrProcessorEdgeTypeIsInverseFill(type)) {
return MakeSuccess(
return GrFPSuccess(
GrConstColorProcessor::Make(std::move(inputFP), SK_PMColor4fWHITE,
GrConstColorProcessor::InputMode::kModulateRGBA));
}
@ -115,7 +114,7 @@ GrFragmentProcessor::MakeResult GrConvexPolyEffect::Make(
// about a coverage processor not being compatible with the alpha-as-coverage optimization.
// We don't really care about this unlikely case so we just use kModulateRGBA to suppress
// the print.
return MakeSuccess(
return GrFPSuccess(
GrConstColorProcessor::Make(std::move(inputFP), SK_PMColor4fTRANSPARENT,
GrConstColorProcessor::InputMode::kModulateRGBA));
}
@ -139,7 +138,7 @@ GrFragmentProcessor::MakeResult GrConvexPolyEffect::Make(
break;
case SkPath::kLine_Verb: {
if (n >= kMaxEdges) {
return MakeFailure(std::move(inputFP));
return GrFPFailure(std::move(inputFP));
}
if (pts[0] != pts[1]) {
SkVector v = pts[1] - pts[0];
@ -157,7 +156,7 @@ GrFragmentProcessor::MakeResult GrConvexPolyEffect::Make(
break;
}
default:
return MakeFailure(std::move(inputFP));
return GrFPFailure(std::move(inputFP));
}
}
@ -167,11 +166,10 @@ GrFragmentProcessor::MakeResult GrConvexPolyEffect::Make(
return GrConvexPolyEffect::Make(std::move(inputFP), type, n, edges);
}
GrFragmentProcessor::MakeResult GrConvexPolyEffect::Make(
std::unique_ptr<GrFragmentProcessor> inputFP,
GrClipEdgeType edgeType, const SkRect& rect) {
GrFPResult GrConvexPolyEffect::Make(std::unique_ptr<GrFragmentProcessor> inputFP,
GrClipEdgeType edgeType, const SkRect& rect) {
// TODO: Replace calls to this method with calling GrAARectEffect::Make directly
return MakeSuccess(GrAARectEffect::Make(std::move(inputFP), edgeType, rect));
return GrFPSuccess(GrAARectEffect::Make(std::move(inputFP), edgeType, rect));
}
GrConvexPolyEffect::~GrConvexPolyEffect() {}

View File

@ -36,13 +36,13 @@ public:
* have to modify the effect/shaderbuilder interface to make it possible (e.g. give access
* to the view matrix or untransformed positions in the fragment shader).
*/
static MakeResult Make(std::unique_ptr<GrFragmentProcessor> inputFP,
static GrFPResult Make(std::unique_ptr<GrFragmentProcessor> inputFP,
GrClipEdgeType edgeType, int n, const SkScalar edges[]) {
if (n <= 0 || n > kMaxEdges) {
return MakeFailure(std::move(inputFP));
return GrFPFailure(std::move(inputFP));
}
return MakeSuccess(std::unique_ptr<GrFragmentProcessor>(
return GrFPSuccess(std::unique_ptr<GrFragmentProcessor>(
new GrConvexPolyEffect(std::move(inputFP), edgeType, n, edges)));
}
@ -50,12 +50,12 @@ public:
* Creates an effect that clips against the path. If the path is not a convex polygon, is
* inverse filled, or has too many edges, creation will fail.
*/
static MakeResult Make(std::unique_ptr<GrFragmentProcessor>, GrClipEdgeType, const SkPath&);
static GrFPResult Make(std::unique_ptr<GrFragmentProcessor>, GrClipEdgeType, const SkPath&);
/**
* Creates an effect that fills inside the rect with AA edges..
*/
static MakeResult Make(std::unique_ptr<GrFragmentProcessor>, GrClipEdgeType, const SkRect&);
static GrFPResult Make(std::unique_ptr<GrFragmentProcessor>, GrClipEdgeType, const SkRect&);
~GrConvexPolyEffect() override;

View File

@ -24,21 +24,21 @@ bool medPrecision = !sk_Caps.floatIs32Bits;
layout(when=medPrecision) uniform float2 scale;
@make {
static MakeResult Make(std::unique_ptr<GrFragmentProcessor> inputFP, GrClipEdgeType edgeType,
static GrFPResult Make(std::unique_ptr<GrFragmentProcessor> inputFP, GrClipEdgeType edgeType,
SkPoint center, SkPoint radii, const GrShaderCaps& caps) {
// Small radii produce bad results on devices without full float.
if (!caps.floatIs32Bits() && (radii.fX < 0.5f || radii.fY < 0.5f)) {
return MakeFailure(std::move(inputFP));
return GrFPFailure(std::move(inputFP));
}
// Very narrow ellipses produce bad results on devices without full float
if (!caps.floatIs32Bits() && (radii.fX > 255*radii.fY || radii.fY > 255*radii.fX)) {
return MakeFailure(std::move(inputFP));
return GrFPFailure(std::move(inputFP));
}
// Very large ellipses produce bad results on devices without full float
if (!caps.floatIs32Bits() && (radii.fX > 16384 || radii.fY > 16384)) {
return MakeFailure(std::move(inputFP));
return GrFPFailure(std::move(inputFP));
}
return MakeSuccess(std::unique_ptr<GrFragmentProcessor>(
return GrFPSuccess(std::unique_ptr<GrFragmentProcessor>(
new GrEllipseEffect(std::move(inputFP), edgeType, center, radii)));
}
}

View File

@ -11,9 +11,8 @@
#include "src/gpu/effects/generated/GrCircleEffect.h"
#include "src/gpu/effects/generated/GrEllipseEffect.h"
GrFragmentProcessor::MakeResult GrOvalEffect::Make(std::unique_ptr<GrFragmentProcessor> inputFP,
GrClipEdgeType edgeType, const SkRect& oval,
const GrShaderCaps& caps) {
GrFPResult GrOvalEffect::Make(std::unique_ptr<GrFragmentProcessor> inputFP, GrClipEdgeType edgeType,
const SkRect& oval, const GrShaderCaps& caps) {
SkScalar w = oval.width();
SkScalar h = oval.height();
if (SkScalarNearlyEqual(w, h)) {

View File

@ -21,8 +21,8 @@ namespace GrOvalEffect {
/**
* Creates an effect that performs clipping against an oval.
*/
GrFragmentProcessor::MakeResult Make(std::unique_ptr<GrFragmentProcessor>, GrClipEdgeType,
const SkRect&, const GrShaderCaps&);
GrFPResult Make(std::unique_ptr<GrFragmentProcessor>, GrClipEdgeType, const SkRect&,
const GrShaderCaps&);
};
#endif

View File

@ -45,7 +45,7 @@ public:
// The flags are used to indicate which corners are circluar (unflagged corners are assumed to
// be square).
static MakeResult Make(std::unique_ptr<GrFragmentProcessor>, GrClipEdgeType,
static GrFPResult Make(std::unique_ptr<GrFragmentProcessor>, GrClipEdgeType,
uint32_t circularCornerFlags, const SkRRect&);
~CircularRRectEffect() override {}
@ -84,14 +84,13 @@ private:
typedef GrFragmentProcessor INHERITED;
};
GrFragmentProcessor::MakeResult CircularRRectEffect::Make(
std::unique_ptr<GrFragmentProcessor> inputFP,
GrClipEdgeType edgeType,
uint32_t circularCornerFlags, const SkRRect& rrect) {
GrFPResult CircularRRectEffect::Make(std::unique_ptr<GrFragmentProcessor> inputFP,
GrClipEdgeType edgeType,
uint32_t circularCornerFlags, const SkRRect& rrect) {
if (GrClipEdgeType::kFillAA != edgeType && GrClipEdgeType::kInverseFillAA != edgeType) {
return MakeFailure(std::move(inputFP));
return GrFPFailure(std::move(inputFP));
}
return MakeSuccess(std::unique_ptr<GrFragmentProcessor>(
return GrFPSuccess(std::unique_ptr<GrFragmentProcessor>(
new CircularRRectEffect(std::move(inputFP), edgeType, circularCornerFlags, rrect)));
}
@ -412,7 +411,7 @@ GrGLSLFragmentProcessor* CircularRRectEffect::onCreateGLSLInstance() const {
class EllipticalRRectEffect : public GrFragmentProcessor {
public:
static MakeResult Make(std::unique_ptr<GrFragmentProcessor>, GrClipEdgeType, const SkRRect&);
static GrFPResult Make(std::unique_ptr<GrFragmentProcessor>, GrClipEdgeType, const SkRRect&);
~EllipticalRRectEffect() override {}
@ -446,13 +445,12 @@ private:
typedef GrFragmentProcessor INHERITED;
};
GrFragmentProcessor::MakeResult EllipticalRRectEffect::Make(
std::unique_ptr<GrFragmentProcessor> inputFP,
GrClipEdgeType edgeType, const SkRRect& rrect) {
GrFPResult EllipticalRRectEffect::Make(std::unique_ptr<GrFragmentProcessor> inputFP,
GrClipEdgeType edgeType, const SkRRect& rrect) {
if (GrClipEdgeType::kFillAA != edgeType && GrClipEdgeType::kInverseFillAA != edgeType) {
return MakeFailure(std::move(inputFP));
return GrFPFailure(std::move(inputFP));
}
return MakeSuccess(std::unique_ptr<GrFragmentProcessor>(
return GrFPSuccess(std::unique_ptr<GrFragmentProcessor>(
new EllipticalRRectEffect(std::move(inputFP), edgeType, rrect)));
}
@ -725,10 +723,9 @@ GrGLSLFragmentProcessor* EllipticalRRectEffect::onCreateGLSLInstance() const {
//////////////////////////////////////////////////////////////////////////////
GrFragmentProcessor::MakeResult GrRRectEffect::Make(std::unique_ptr<GrFragmentProcessor> inputFP,
GrClipEdgeType edgeType,
const SkRRect& rrect,
const GrShaderCaps& caps) {
GrFPResult GrRRectEffect::Make(std::unique_ptr<GrFragmentProcessor> inputFP,
GrClipEdgeType edgeType, const SkRRect& rrect,
const GrShaderCaps& caps) {
if (rrect.isRect()) {
return GrConvexPolyEffect::Make(std::move(inputFP), edgeType, rrect.getBounds());
}
@ -815,14 +812,14 @@ GrFragmentProcessor::MakeResult GrRRectEffect::Make(std::unique_ptr<GrFragmentPr
// 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 GrFragmentProcessor::MakeFailure(std::move(inputFP));
return GrFPFailure(std::move(inputFP));
}
if (rrect.isNinePatch()) {
return EllipticalRRectEffect::Make(std::move(inputFP), edgeType, rrect);
}
return GrFragmentProcessor::MakeFailure(std::move(inputFP));
return GrFPFailure(std::move(inputFP));
}
}
}
return GrFragmentProcessor::MakeFailure(std::move(inputFP));
return GrFPFailure(std::move(inputFP));
}

View File

@ -21,10 +21,10 @@ 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 `success` in the MakeResult.
* all varieties of SkRRect, so the caller must check `success` in the GrFPResult.
*/
GrFragmentProcessor::MakeResult Make(std::unique_ptr<GrFragmentProcessor>, GrClipEdgeType,
const SkRRect&, const GrShaderCaps&);
GrFPResult Make(std::unique_ptr<GrFragmentProcessor>, GrClipEdgeType, const SkRRect&,
const GrShaderCaps&);
};

View File

@ -48,12 +48,12 @@ half d;
args.fUniformHandler->getUniformCStr(circleVar),
args.fUniformHandler->getUniformCStr(circleVar),
args.fUniformHandler->getUniformCStr(circleVar));
SkString _input2566(args.fInputColor);
SkString _sample2566;
SkString _input2509(args.fInputColor);
SkString _sample2509;
if (_outer.inputFP_index >= 0) {
_sample2566 = this->invokeChild(_outer.inputFP_index, _input2566.c_str(), args);
_sample2509 = this->invokeChild(_outer.inputFP_index, _input2509.c_str(), args);
} else {
_sample2566.swap(_input2566);
_sample2509.swap(_input2509);
}
fragBuilder->codeAppendf(
R"SkSL(
@ -64,7 +64,7 @@ half4 inputColor = %s;
%s = d > 0.5 ? inputColor : half4(0.0);
}
)SkSL",
_sample2566.c_str(), (int)_outer.edgeType, (int)_outer.edgeType, args.fOutputColor,
_sample2509.c_str(), (int)_outer.edgeType, (int)_outer.edgeType, args.fOutputColor,
args.fOutputColor);
}

View File

@ -19,16 +19,16 @@
class GrCircleEffect : public GrFragmentProcessor {
public:
static MakeResult Make(std::unique_ptr<GrFragmentProcessor> inputFP,
static GrFPResult Make(std::unique_ptr<GrFragmentProcessor> inputFP,
GrClipEdgeType edgeType,
SkPoint center,
float radius) {
// A radius below half causes the implicit insetting done by this processor to become
// inverted. We could handle this case by making the processor code more complicated.
if (radius < .5f && GrProcessorEdgeTypeIsInverseFill(edgeType)) {
return MakeFailure(std::move(inputFP));
return GrFPFailure(std::move(inputFP));
}
return MakeSuccess(std::unique_ptr<GrFragmentProcessor>(
return GrFPSuccess(std::unique_ptr<GrFragmentProcessor>(
new GrCircleEffect(std::move(inputFP), edgeType, center, radius)));
}
GrCircleEffect(const GrCircleEffect& src);

View File

@ -21,24 +21,24 @@
class GrEllipseEffect : public GrFragmentProcessor {
public:
static MakeResult Make(std::unique_ptr<GrFragmentProcessor> inputFP,
static GrFPResult Make(std::unique_ptr<GrFragmentProcessor> inputFP,
GrClipEdgeType edgeType,
SkPoint center,
SkPoint radii,
const GrShaderCaps& caps) {
// Small radii produce bad results on devices without full float.
if (!caps.floatIs32Bits() && (radii.fX < 0.5f || radii.fY < 0.5f)) {
return MakeFailure(std::move(inputFP));
return GrFPFailure(std::move(inputFP));
}
// Very narrow ellipses produce bad results on devices without full float
if (!caps.floatIs32Bits() && (radii.fX > 255 * radii.fY || radii.fY > 255 * radii.fX)) {
return MakeFailure(std::move(inputFP));
return GrFPFailure(std::move(inputFP));
}
// Very large ellipses produce bad results on devices without full float
if (!caps.floatIs32Bits() && (radii.fX > 16384 || radii.fY > 16384)) {
return MakeFailure(std::move(inputFP));
return GrFPFailure(std::move(inputFP));
}
return MakeSuccess(std::unique_ptr<GrFragmentProcessor>(
return GrFPSuccess(std::unique_ptr<GrFragmentProcessor>(
new GrEllipseEffect(std::move(inputFP), edgeType, center, radii)));
}
GrEllipseEffect(const GrEllipseEffect& src);