Update GrConvexPolyEffect to support an input FP.
Change-Id: I813a4e4a5b4b0dc4f8ea59056d125386e6049ab4 Bug: skia:10217 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/296516 Reviewed-by: Michael Ludwig <michaelludwig@google.com> Commit-Queue: John Stiles <johnstiles@google.com>
This commit is contained in:
parent
6b2caf7dfc
commit
ec9269be54
@ -126,7 +126,8 @@ protected:
|
||||
path->transform(m, &p);
|
||||
|
||||
GrClipEdgeType edgeType = (GrClipEdgeType) et;
|
||||
std::unique_ptr<GrFragmentProcessor> fp(GrConvexPolyEffect::Make(edgeType, p));
|
||||
std::unique_ptr<GrFragmentProcessor> fp =
|
||||
GrConvexPolyEffect::Make(/*inputFP=*/nullptr, edgeType, p);
|
||||
if (!fp) {
|
||||
continue;
|
||||
}
|
||||
@ -165,7 +166,8 @@ protected:
|
||||
for (int et = 0; et < kGrClipEdgeTypeCnt; ++et) {
|
||||
SkRect rect = iter.get()->makeOffset(x, y);
|
||||
GrClipEdgeType edgeType = (GrClipEdgeType) et;
|
||||
std::unique_ptr<GrFragmentProcessor> fp(GrConvexPolyEffect::Make(edgeType, rect));
|
||||
std::unique_ptr<GrFragmentProcessor> fp =
|
||||
GrConvexPolyEffect::Make(/*inputFP=*/nullptr, edgeType, rect);
|
||||
if (!fp) {
|
||||
continue;
|
||||
}
|
||||
|
@ -23,7 +23,6 @@
|
||||
#include "src/gpu/GrStencilAttachment.h"
|
||||
#include "src/gpu/GrStyle.h"
|
||||
#include "src/gpu/GrTextureProxy.h"
|
||||
#include "src/gpu/effects/GrConvexPolyEffect.h"
|
||||
#include "src/gpu/effects/GrRRectEffect.h"
|
||||
#include "src/gpu/effects/generated/GrDeviceSpaceEffect.h"
|
||||
#include "src/gpu/geometry/GrStyledShape.h"
|
||||
|
@ -687,9 +687,22 @@ GrReducedClip::ClipResult GrReducedClip::addAnalyticFP(const SkPath& deviceSpace
|
||||
return ClipResult::kNotClipped;
|
||||
}
|
||||
|
||||
if (auto fp = GrConvexPolyEffect::Make(GetClipEdgeType(invert, aa), deviceSpacePath)) {
|
||||
fAnalyticFPs.push_back(std::move(fp));
|
||||
return ClipResult::kClipped;
|
||||
if (fAnalyticFPs.empty()) {
|
||||
// Create our first analytic effect in the stack.
|
||||
auto fp = GrConvexPolyEffect::Make(/*inputFP=*/nullptr, GetClipEdgeType(invert, aa),
|
||||
deviceSpacePath);
|
||||
if (fp != nullptr) {
|
||||
fAnalyticFPs.push_back(std::move(fp));
|
||||
return ClipResult::kClipped;
|
||||
}
|
||||
} else {
|
||||
// Combine this analytic effect with the previous effect in the stack.
|
||||
auto fp = GrConvexPolyEffect::Make(&fAnalyticFPs.back(), GetClipEdgeType(invert, aa),
|
||||
deviceSpacePath);
|
||||
if (fp != nullptr) {
|
||||
fAnalyticFPs.back() = std::move(fp);
|
||||
return ClipResult::kClipped;
|
||||
}
|
||||
}
|
||||
|
||||
if (fCCPRClipPaths.count() < fMaxCCPRClipPaths && GrAA::kYes == aa) {
|
||||
|
@ -66,7 +66,12 @@ void GrGLConvexPolyEffect::emitCode(EmitArgs& args) {
|
||||
if (GrProcessorEdgeTypeIsInverseFill(cpe.getEdgeType())) {
|
||||
fragBuilder->codeAppend("\talpha = 1.0 - alpha;\n");
|
||||
}
|
||||
fragBuilder->codeAppendf("\t%s = %s * alpha;\n", args.fOutputColor, args.fInputColor);
|
||||
|
||||
SkString inputSample = cpe.hasInputFP()
|
||||
? this->invokeChild(/*childIndex=*/0, args.fInputColor, args)
|
||||
: SkString(args.fInputColor);
|
||||
|
||||
fragBuilder->codeAppendf("\t%s = %s * alpha;\n", args.fOutputColor, inputSample.c_str());
|
||||
}
|
||||
|
||||
void GrGLConvexPolyEffect::onSetData(const GrGLSLProgramDataManager& pdman,
|
||||
@ -89,8 +94,9 @@ void GrGLConvexPolyEffect::GenKey(const GrProcessor& processor, const GrShaderCa
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::unique_ptr<GrFragmentProcessor> GrConvexPolyEffect::Make(GrClipEdgeType type,
|
||||
const SkPath& path) {
|
||||
std::unique_ptr<GrFragmentProcessor> GrConvexPolyEffect::Make(
|
||||
std::unique_ptr<GrFragmentProcessor>* inputFP,
|
||||
GrClipEdgeType type, const SkPath& path) {
|
||||
if (GrClipEdgeType::kHairlineAA == type) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -105,14 +111,16 @@ std::unique_ptr<GrFragmentProcessor> GrConvexPolyEffect::Make(GrClipEdgeType typ
|
||||
// skip the draw or omit the clip element.
|
||||
if (!SkPathPriv::CheapComputeFirstDirection(path, &dir)) {
|
||||
if (GrProcessorEdgeTypeIsInverseFill(type)) {
|
||||
return GrConstColorProcessor::Make(/*inputFP=*/nullptr, SK_PMColor4fWHITE,
|
||||
return GrConstColorProcessor::Make(inputFP ? std::move(*inputFP) : nullptr,
|
||||
SK_PMColor4fWHITE,
|
||||
GrConstColorProcessor::InputMode::kModulateRGBA);
|
||||
}
|
||||
// This could use kIgnore instead of kModulateRGBA but it would trigger a debug print
|
||||
// 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 GrConstColorProcessor::Make(/*inputFP=*/nullptr, SK_PMColor4fTRANSPARENT,
|
||||
return GrConstColorProcessor::Make(inputFP ? std::move(*inputFP) : nullptr,
|
||||
SK_PMColor4fTRANSPARENT,
|
||||
GrConstColorProcessor::InputMode::kModulateRGBA);
|
||||
}
|
||||
|
||||
@ -160,15 +168,16 @@ std::unique_ptr<GrFragmentProcessor> GrConvexPolyEffect::Make(GrClipEdgeType typ
|
||||
if (path.isInverseFillType()) {
|
||||
type = GrInvertProcessorEdgeType(type);
|
||||
}
|
||||
return Make(type, n, edges);
|
||||
return Make(inputFP, type, n, edges);
|
||||
}
|
||||
|
||||
std::unique_ptr<GrFragmentProcessor> GrConvexPolyEffect::Make(GrClipEdgeType edgeType,
|
||||
const SkRect& rect) {
|
||||
std::unique_ptr<GrFragmentProcessor> GrConvexPolyEffect::Make(
|
||||
std::unique_ptr<GrFragmentProcessor>* inputFP,
|
||||
GrClipEdgeType edgeType, const SkRect& rect) {
|
||||
if (GrClipEdgeType::kHairlineAA == edgeType){
|
||||
return nullptr;
|
||||
}
|
||||
return GrAARectEffect::Make(/*inputFP=*/nullptr, edgeType, rect);
|
||||
return GrAARectEffect::Make(inputFP ? std::move(*inputFP) : nullptr, edgeType, rect);
|
||||
}
|
||||
|
||||
GrConvexPolyEffect::~GrConvexPolyEffect() {}
|
||||
@ -182,7 +191,8 @@ GrGLSLFragmentProcessor* GrConvexPolyEffect::onCreateGLSLInstance() const {
|
||||
return new GrGLConvexPolyEffect;
|
||||
}
|
||||
|
||||
GrConvexPolyEffect::GrConvexPolyEffect(GrClipEdgeType edgeType, int n, const SkScalar edges[])
|
||||
GrConvexPolyEffect::GrConvexPolyEffect(std::unique_ptr<GrFragmentProcessor> inputFP,
|
||||
GrClipEdgeType edgeType, int n, const SkScalar edges[])
|
||||
: INHERITED(kGrConvexPolyEffect_ClassID, kCompatibleWithCoverageAsAlpha_OptimizationFlag)
|
||||
, fEdgeType(edgeType)
|
||||
, fEdgeCount(n) {
|
||||
@ -194,12 +204,17 @@ GrConvexPolyEffect::GrConvexPolyEffect(GrClipEdgeType edgeType, int n, const SkS
|
||||
for (int i = 0; i < n; ++i) {
|
||||
fEdges[3 * i + 2] += SK_ScalarHalf;
|
||||
}
|
||||
|
||||
if (inputFP != nullptr) {
|
||||
this->registerChildProcessor(std::move(inputFP));
|
||||
}
|
||||
}
|
||||
|
||||
GrConvexPolyEffect::GrConvexPolyEffect(const GrConvexPolyEffect& that)
|
||||
: INHERITED(kGrConvexPolyEffect_ClassID, kCompatibleWithCoverageAsAlpha_OptimizationFlag)
|
||||
, fEdgeType(that.fEdgeType)
|
||||
, fEdgeCount(that.fEdgeCount) {
|
||||
this->cloneAndRegisterAllChildProcessors(that);
|
||||
memcpy(fEdges, that.fEdges, 3 * that.fEdgeCount * sizeof(SkScalar));
|
||||
}
|
||||
|
||||
@ -230,7 +245,7 @@ std::unique_ptr<GrFragmentProcessor> GrConvexPolyEffect::TestCreate(GrProcessorT
|
||||
do {
|
||||
GrClipEdgeType edgeType = static_cast<GrClipEdgeType>(
|
||||
d->fRandom->nextULessThan(kGrClipEdgeTypeCnt));
|
||||
fp = GrConvexPolyEffect::Make(edgeType, count, edges);
|
||||
fp = GrConvexPolyEffect::Make(/*inputFP=*/nullptr, edgeType, count, edges);
|
||||
} while (nullptr == fp);
|
||||
return fp;
|
||||
}
|
||||
|
@ -23,9 +23,7 @@ class SkPath;
|
||||
*/
|
||||
class GrConvexPolyEffect : public GrFragmentProcessor {
|
||||
public:
|
||||
enum {
|
||||
kMaxEdges = 8,
|
||||
};
|
||||
static constexpr int kMaxEdges = 8;
|
||||
|
||||
/**
|
||||
* edges is a set of n edge equations where n is limited to kMaxEdges. It contains 3*n values.
|
||||
@ -37,25 +35,32 @@ public:
|
||||
* them in src space. There are a number of ways this could be accomplished but we'd probably
|
||||
* 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).
|
||||
*
|
||||
* The input fragment processor is passed as a pointer because it is only absorbed if creation
|
||||
* of the convex-poly effect is successful. If Make returns nullptr, the inputFP is left as-is.
|
||||
*/
|
||||
static std::unique_ptr<GrFragmentProcessor> Make(GrClipEdgeType edgeType, int n,
|
||||
const SkScalar edges[]) {
|
||||
static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor>* inputFP,
|
||||
GrClipEdgeType edgeType,
|
||||
int n, const SkScalar edges[]) {
|
||||
if (n <= 0 || n > kMaxEdges || GrClipEdgeType::kHairlineAA == edgeType) {
|
||||
return nullptr;
|
||||
}
|
||||
return std::unique_ptr<GrFragmentProcessor>(new GrConvexPolyEffect(edgeType, n, edges));
|
||||
return std::unique_ptr<GrFragmentProcessor>(
|
||||
new GrConvexPolyEffect(inputFP ? std::move(*inputFP) : nullptr, edgeType, n, edges));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an effect that clips against the path. If the path is not a convex polygon, is
|
||||
* inverse filled, or has too many edges, this will return nullptr.
|
||||
*/
|
||||
static std::unique_ptr<GrFragmentProcessor> Make(GrClipEdgeType, const SkPath&);
|
||||
static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor>*,
|
||||
GrClipEdgeType, const SkPath&);
|
||||
|
||||
/**
|
||||
* Creates an effect that fills inside the rect with AA edges..
|
||||
*/
|
||||
static std::unique_ptr<GrFragmentProcessor> Make(GrClipEdgeType, const SkRect&);
|
||||
static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor>*,
|
||||
GrClipEdgeType, const SkRect&);
|
||||
|
||||
~GrConvexPolyEffect() override;
|
||||
|
||||
@ -69,8 +74,12 @@ public:
|
||||
|
||||
const SkScalar* getEdges() const { return fEdges; }
|
||||
|
||||
bool hasInputFP() const { return numChildProcessors() > 0; }
|
||||
|
||||
private:
|
||||
GrConvexPolyEffect(GrClipEdgeType edgeType, int n, const SkScalar edges[]);
|
||||
GrConvexPolyEffect(std::unique_ptr<GrFragmentProcessor> inputFP,
|
||||
GrClipEdgeType edgeType,
|
||||
int n, const SkScalar edges[]);
|
||||
GrConvexPolyEffect(const GrConvexPolyEffect&);
|
||||
|
||||
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
|
||||
|
@ -726,7 +726,7 @@ std::unique_ptr<GrFragmentProcessor> GrRRectEffect::Make(GrClipEdgeType edgeType
|
||||
const SkRRect& rrect,
|
||||
const GrShaderCaps& caps) {
|
||||
if (rrect.isRect()) {
|
||||
return GrConvexPolyEffect::Make(edgeType, rrect.getBounds());
|
||||
return GrConvexPolyEffect::Make(/*inputFP=*/nullptr, edgeType, rrect.getBounds());
|
||||
}
|
||||
|
||||
if (rrect.isOval()) {
|
||||
@ -738,7 +738,7 @@ 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.
|
||||
return GrConvexPolyEffect::Make(edgeType, rrect.getBounds());
|
||||
return GrConvexPolyEffect::Make(/*inputFP=*/nullptr, edgeType, rrect.getBounds());
|
||||
}
|
||||
if (SkRRectPriv::GetSimpleRadii(rrect).fX == SkRRectPriv::GetSimpleRadii(rrect).fY) {
|
||||
return CircularRRectEffect::Make(/*inputFP=*/nullptr, edgeType,
|
||||
@ -804,7 +804,7 @@ std::unique_ptr<GrFragmentProcessor> GrRRectEffect::Make(GrClipEdgeType edgeType
|
||||
return CircularRRectEffect::Make(/*inputFP=*/nullptr, edgeType, cornerFlags, *rr);
|
||||
}
|
||||
case CircularRRectEffect::kNone_CornerFlags:
|
||||
return GrConvexPolyEffect::Make(edgeType, rrect.getBounds());
|
||||
return GrConvexPolyEffect::Make(/*inputFP=*/nullptr, edgeType, rrect.getBounds());
|
||||
default: {
|
||||
if (squashedRadii) {
|
||||
// If we got here then we squashed some but not all the radii to zero. (If all
|
||||
|
Loading…
Reference in New Issue
Block a user