Update ConstColor FP to support an input FP.
In the "ignore input" mode, the input FP contributes nothing and is never sampled. In the "modulate input" cases, the input FP is sampled as one would expect. Change-Id: I96717d63d8e3d7ef6aa4eaaf88154c6e5ce47e55 Bug: skia:10217 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/296299 Reviewed-by: Brian Osman <brianosman@google.com> Commit-Queue: John Stiles <johnstiles@google.com>
This commit is contained in:
parent
a4a132c2be
commit
e3a39f7053
@ -119,7 +119,7 @@ protected:
|
|||||||
|
|
||||||
GrConstColorProcessor::InputMode mode = (GrConstColorProcessor::InputMode) m;
|
GrConstColorProcessor::InputMode mode = (GrConstColorProcessor::InputMode) m;
|
||||||
SkPMColor4f color = SkPMColor4f::FromBytes_RGBA(kColors[procColor]);
|
SkPMColor4f color = SkPMColor4f::FromBytes_RGBA(kColors[procColor]);
|
||||||
auto fp = GrConstColorProcessor::Make(color, mode);
|
auto fp = GrConstColorProcessor::Make(/*inputFP=*/nullptr, color, mode);
|
||||||
|
|
||||||
grPaint.addColorFragmentProcessor(std::move(fp));
|
grPaint.addColorFragmentProcessor(std::move(fp));
|
||||||
renderTargetContext->priv().testingOnly_addDrawOp(
|
renderTargetContext->priv().testingOnly_addDrawOp(
|
||||||
|
@ -94,7 +94,8 @@ std::unique_ptr<GrFragmentProcessor> SkModeColorFilter::asFragmentProcessor(
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto constFP = GrConstColorProcessor::Make(SkColorToPMColor4f(fColor, dstColorInfo),
|
auto constFP = GrConstColorProcessor::Make(/*inputFP=*/nullptr,
|
||||||
|
SkColorToPMColor4f(fColor, dstColorInfo),
|
||||||
GrConstColorProcessor::InputMode::kIgnore);
|
GrConstColorProcessor::InputMode::kIgnore);
|
||||||
auto fp = GrXfermodeFragmentProcessor::MakeFromSrcProcessor(std::move(constFP), fMode);
|
auto fp = GrXfermodeFragmentProcessor::MakeFromSrcProcessor(std::move(constFP), fMode);
|
||||||
if (!fp) {
|
if (!fp) {
|
||||||
|
@ -362,7 +362,7 @@ sk_sp<SkSpecialImage> ArithmeticImageFilterImpl::filterImageGPU(
|
|||||||
background->alphaType(),
|
background->alphaType(),
|
||||||
ctx.colorSpace());
|
ctx.colorSpace());
|
||||||
} else {
|
} else {
|
||||||
bgFP = GrConstColorProcessor::Make(SK_PMColor4fTRANSPARENT,
|
bgFP = GrConstColorProcessor::Make(/*inputFP=*/nullptr, SK_PMColor4fTRANSPARENT,
|
||||||
GrConstColorProcessor::InputMode::kIgnore);
|
GrConstColorProcessor::InputMode::kIgnore);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,7 +272,7 @@ sk_sp<SkSpecialImage> SkXfermodeImageFilterImpl::filterImageGPU(
|
|||||||
background->alphaType(),
|
background->alphaType(),
|
||||||
ctx.colorSpace());
|
ctx.colorSpace());
|
||||||
} else {
|
} else {
|
||||||
bgFP = GrConstColorProcessor::Make(SK_PMColor4fTRANSPARENT,
|
bgFP = GrConstColorProcessor::Make(/*inputFP=*/nullptr, SK_PMColor4fTRANSPARENT,
|
||||||
GrConstColorProcessor::InputMode::kIgnore);
|
GrConstColorProcessor::InputMode::kIgnore);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -420,8 +420,8 @@ std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::RunInSeries(
|
|||||||
SkPMColor4f knownColor;
|
SkPMColor4f knownColor;
|
||||||
int leadingFPsToEliminate = info.initialProcessorsToEliminate(&knownColor);
|
int leadingFPsToEliminate = info.initialProcessorsToEliminate(&knownColor);
|
||||||
if (leadingFPsToEliminate) {
|
if (leadingFPsToEliminate) {
|
||||||
std::unique_ptr<GrFragmentProcessor> colorFP(
|
std::unique_ptr<GrFragmentProcessor> colorFP = GrConstColorProcessor::Make(
|
||||||
GrConstColorProcessor::Make(knownColor, GrConstColorProcessor::InputMode::kIgnore));
|
/*inputFP=*/nullptr, knownColor, GrConstColorProcessor::InputMode::kIgnore);
|
||||||
if (leadingFPsToEliminate == cnt) {
|
if (leadingFPsToEliminate == cnt) {
|
||||||
return colorFP;
|
return colorFP;
|
||||||
}
|
}
|
||||||
|
@ -293,19 +293,19 @@ static inline bool skpaint_to_grpaint_impl(GrRecordingContext* context,
|
|||||||
shaderFP = GrXfermodeFragmentProcessor::MakeFromSrcProcessor(std::move(shaderFP),
|
shaderFP = GrXfermodeFragmentProcessor::MakeFromSrcProcessor(std::move(shaderFP),
|
||||||
*primColorMode);
|
*primColorMode);
|
||||||
|
|
||||||
// The above may return null if compose results in a pass through of the prim color.
|
|
||||||
if (shaderFP) {
|
|
||||||
grPaint->addColorFragmentProcessor(std::move(shaderFP));
|
|
||||||
}
|
|
||||||
|
|
||||||
// We can ignore origColor here - alpha is unchanged by gamma
|
// We can ignore origColor here - alpha is unchanged by gamma
|
||||||
float paintAlpha = skPaint.getColor4f().fA;
|
float paintAlpha = skPaint.getColor4f().fA;
|
||||||
if (1.0f != paintAlpha) {
|
if (1.0f != paintAlpha) {
|
||||||
// No gamut conversion - paintAlpha is a (linear) alpha value, splatted to all
|
// No gamut conversion - paintAlpha is a (linear) alpha value, splatted to all
|
||||||
// color channels. It's value should be treated as the same in ANY color space.
|
// color channels. It's value should be treated as the same in ANY color space.
|
||||||
grPaint->addColorFragmentProcessor(GrConstColorProcessor::Make(
|
shaderFP = GrConstColorProcessor::Make(
|
||||||
{ paintAlpha, paintAlpha, paintAlpha, paintAlpha },
|
std::move(shaderFP), { paintAlpha, paintAlpha, paintAlpha, paintAlpha },
|
||||||
GrConstColorProcessor::InputMode::kModulateRGBA));
|
GrConstColorProcessor::InputMode::kModulateRGBA);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The above may return null if compose results in a pass through of the prim color.
|
||||||
|
if (shaderFP) {
|
||||||
|
grPaint->addColorFragmentProcessor(std::move(shaderFP));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// The shader's FP sees the paint *unpremul* color
|
// The shader's FP sees the paint *unpremul* color
|
||||||
@ -318,14 +318,10 @@ static inline bool skpaint_to_grpaint_impl(GrRecordingContext* context,
|
|||||||
// There is a blend between the primitive color and the paint color. The blend considers
|
// There is a blend between the primitive color and the paint color. The blend considers
|
||||||
// the opaque paint color. The paint's alpha is applied to the post-blended color.
|
// the opaque paint color. The paint's alpha is applied to the post-blended color.
|
||||||
SkPMColor4f opaqueColor = origColor.makeOpaque().premul();
|
SkPMColor4f opaqueColor = origColor.makeOpaque().premul();
|
||||||
auto processor = GrConstColorProcessor::Make(opaqueColor,
|
auto processor = GrConstColorProcessor::Make(/*inputFP=*/nullptr, opaqueColor,
|
||||||
GrConstColorProcessor::InputMode::kIgnore);
|
GrConstColorProcessor::InputMode::kIgnore);
|
||||||
processor = GrXfermodeFragmentProcessor::MakeFromSrcProcessor(std::move(processor),
|
processor = GrXfermodeFragmentProcessor::MakeFromSrcProcessor(std::move(processor),
|
||||||
*primColorMode);
|
*primColorMode);
|
||||||
if (processor) {
|
|
||||||
grPaint->addColorFragmentProcessor(std::move(processor));
|
|
||||||
}
|
|
||||||
|
|
||||||
grPaint->setColor4f(opaqueColor);
|
grPaint->setColor4f(opaqueColor);
|
||||||
|
|
||||||
// We can ignore origColor here - alpha is unchanged by gamma
|
// We can ignore origColor here - alpha is unchanged by gamma
|
||||||
@ -333,9 +329,13 @@ static inline bool skpaint_to_grpaint_impl(GrRecordingContext* context,
|
|||||||
if (1.0f != paintAlpha) {
|
if (1.0f != paintAlpha) {
|
||||||
// No gamut conversion - paintAlpha is a (linear) alpha value, splatted to all
|
// No gamut conversion - paintAlpha is a (linear) alpha value, splatted to all
|
||||||
// color channels. It's value should be treated as the same in ANY color space.
|
// color channels. It's value should be treated as the same in ANY color space.
|
||||||
grPaint->addColorFragmentProcessor(GrConstColorProcessor::Make(
|
processor = GrConstColorProcessor::Make(
|
||||||
{ paintAlpha, paintAlpha, paintAlpha, paintAlpha },
|
std::move(processor), { paintAlpha, paintAlpha, paintAlpha, paintAlpha },
|
||||||
GrConstColorProcessor::InputMode::kModulateRGBA));
|
GrConstColorProcessor::InputMode::kModulateRGBA);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (processor) {
|
||||||
|
grPaint->addColorFragmentProcessor(std::move(processor));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// No shader, no primitive color.
|
// No shader, no primitive color.
|
||||||
|
@ -13,51 +13,60 @@ enum class InputMode {
|
|||||||
kLast = kModulateA
|
kLast = kModulateA
|
||||||
};
|
};
|
||||||
|
|
||||||
|
in fragmentProcessor? inputFP;
|
||||||
layout(ctype=SkPMColor4f, tracked) in uniform half4 color;
|
layout(ctype=SkPMColor4f, tracked) in uniform half4 color;
|
||||||
layout(key) in InputMode mode;
|
layout(key) in InputMode mode;
|
||||||
|
|
||||||
@optimizationFlags {
|
@optimizationFlags {
|
||||||
OptFlags(color, mode)
|
(inputFP ? ProcessorOptimizationFlags(inputFP.get()) : kAll_OptimizationFlags) &
|
||||||
|
(kConstantOutputForConstantInput_OptimizationFlag |
|
||||||
|
((mode != InputMode::kIgnore) ? kCompatibleWithCoverageAsAlpha_OptimizationFlag
|
||||||
|
: kNone_OptimizationFlags) |
|
||||||
|
((color.isOpaque()) ? kPreservesOpaqueInput_OptimizationFlag
|
||||||
|
: kNone_OptimizationFlags))
|
||||||
}
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
@switch (mode) {
|
@switch (mode) {
|
||||||
case InputMode::kIgnore:
|
case InputMode::kIgnore: {
|
||||||
sk_OutColor = color;
|
sk_OutColor = color;
|
||||||
break;
|
break;
|
||||||
case InputMode::kModulateRGBA:
|
}
|
||||||
sk_OutColor = sk_InColor * color;
|
case InputMode::kModulateRGBA: {
|
||||||
|
half4 inputColor = sample(inputFP, sk_InColor);
|
||||||
|
sk_OutColor = inputColor * color;
|
||||||
break;
|
break;
|
||||||
case InputMode::kModulateA:
|
}
|
||||||
sk_OutColor = sk_InColor.a * color;
|
case InputMode::kModulateA: {
|
||||||
|
half inputAlpha = sample(inputFP, sk_InColor).a;
|
||||||
|
sk_OutColor = inputAlpha * color;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@class {
|
@class {
|
||||||
static const int kInputModeCnt = (int) InputMode::kLast + 1;
|
static const int kInputModeCnt = (int) InputMode::kLast + 1;
|
||||||
|
|
||||||
static OptimizationFlags OptFlags(const SkPMColor4f& color, InputMode mode) {
|
SkPMColor4f constantOutputForConstantInput(const SkPMColor4f& inColor) const override {
|
||||||
OptimizationFlags flags = kConstantOutputForConstantInput_OptimizationFlag;
|
|
||||||
if (mode != InputMode::kIgnore) {
|
|
||||||
flags |= kCompatibleWithCoverageAsAlpha_OptimizationFlag;
|
|
||||||
}
|
|
||||||
if (color.isOpaque()) {
|
|
||||||
flags |= kPreservesOpaqueInput_OptimizationFlag;
|
|
||||||
}
|
|
||||||
return flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
SkPMColor4f constantOutputForConstantInput(const SkPMColor4f& input) const override {
|
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case InputMode::kIgnore:
|
case InputMode::kIgnore: {
|
||||||
return color;
|
return color;
|
||||||
case InputMode::kModulateA:
|
}
|
||||||
|
case InputMode::kModulateA: {
|
||||||
|
SkPMColor4f input = this->numChildProcessors()
|
||||||
|
? ConstantOutputForConstantInput(this->childProcessor(inputFP_index), inColor)
|
||||||
|
: inColor;
|
||||||
return color * input.fA;
|
return color * input.fA;
|
||||||
case InputMode::kModulateRGBA:
|
}
|
||||||
|
case InputMode::kModulateRGBA: {
|
||||||
|
SkPMColor4f input = this->numChildProcessors()
|
||||||
|
? ConstantOutputForConstantInput(this->childProcessor(inputFP_index), inColor)
|
||||||
|
: inColor;
|
||||||
return color * input;
|
return color * input;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
SK_ABORT("Unexpected mode");
|
SkUNREACHABLE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,5 +91,5 @@ void main() {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
InputMode mode = static_cast<InputMode>(d->fRandom->nextULessThan(kInputModeCnt));
|
InputMode mode = static_cast<InputMode>(d->fRandom->nextULessThan(kInputModeCnt));
|
||||||
return GrConstColorProcessor::Make(color, mode);
|
return GrConstColorProcessor::Make(/*inputFP=*/nullptr, color, mode);
|
||||||
}
|
}
|
||||||
|
@ -105,14 +105,14 @@ std::unique_ptr<GrFragmentProcessor> GrConvexPolyEffect::Make(GrClipEdgeType typ
|
|||||||
// skip the draw or omit the clip element.
|
// skip the draw or omit the clip element.
|
||||||
if (!SkPathPriv::CheapComputeFirstDirection(path, &dir)) {
|
if (!SkPathPriv::CheapComputeFirstDirection(path, &dir)) {
|
||||||
if (GrProcessorEdgeTypeIsInverseFill(type)) {
|
if (GrProcessorEdgeTypeIsInverseFill(type)) {
|
||||||
return GrConstColorProcessor::Make(SK_PMColor4fWHITE,
|
return GrConstColorProcessor::Make(/*inputFP=*/nullptr, SK_PMColor4fWHITE,
|
||||||
GrConstColorProcessor::InputMode::kModulateRGBA);
|
GrConstColorProcessor::InputMode::kModulateRGBA);
|
||||||
}
|
}
|
||||||
// This could use kIgnore instead of kModulateRGBA but it would trigger a debug print
|
// 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.
|
// 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
|
// We don't really care about this unlikely case so we just use kModulateRGBA to suppress
|
||||||
// the print.
|
// the print.
|
||||||
return GrConstColorProcessor::Make(SK_PMColor4fTRANSPARENT,
|
return GrConstColorProcessor::Make(/*inputFP=*/nullptr, SK_PMColor4fTRANSPARENT,
|
||||||
GrConstColorProcessor::InputMode::kModulateRGBA);
|
GrConstColorProcessor::InputMode::kModulateRGBA);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -284,7 +284,7 @@ std::unique_ptr<GrFragmentProcessor> GrSkSLFP::TestCreate(GrProcessorTestData* d
|
|||||||
auto result = GrSkSLFP::Make(d->context(), effect, "Arithmetic",
|
auto result = GrSkSLFP::Make(d->context(), effect, "Arithmetic",
|
||||||
SkData::MakeWithCopy(&inputs, sizeof(inputs)));
|
SkData::MakeWithCopy(&inputs, sizeof(inputs)));
|
||||||
result->addChild(GrConstColorProcessor::Make(
|
result->addChild(GrConstColorProcessor::Make(
|
||||||
SK_PMColor4fWHITE, GrConstColorProcessor::InputMode::kIgnore));
|
/*inputFP=*/nullptr, SK_PMColor4fWHITE, GrConstColorProcessor::InputMode::kIgnore));
|
||||||
return std::unique_ptr<GrFragmentProcessor>(result.release());
|
return std::unique_ptr<GrFragmentProcessor>(result.release());
|
||||||
}
|
}
|
||||||
case 2: {
|
case 2: {
|
||||||
|
@ -245,7 +245,7 @@ std::unique_ptr<GrFragmentProcessor> GrXfermodeFragmentProcessor::MakeFromTwoPro
|
|||||||
SkBlendMode mode) {
|
SkBlendMode mode) {
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case SkBlendMode::kClear:
|
case SkBlendMode::kClear:
|
||||||
return GrConstColorProcessor::Make(SK_PMColor4fTRANSPARENT,
|
return GrConstColorProcessor::Make(/*inputFP=*/nullptr, SK_PMColor4fTRANSPARENT,
|
||||||
GrConstColorProcessor::InputMode::kIgnore);
|
GrConstColorProcessor::InputMode::kIgnore);
|
||||||
case SkBlendMode::kSrc:
|
case SkBlendMode::kSrc:
|
||||||
return src;
|
return src;
|
||||||
@ -496,7 +496,7 @@ std::unique_ptr<GrFragmentProcessor> GrXfermodeFragmentProcessor::MakeFromDstPro
|
|||||||
std::unique_ptr<GrFragmentProcessor> dst, SkBlendMode mode) {
|
std::unique_ptr<GrFragmentProcessor> dst, SkBlendMode mode) {
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case SkBlendMode::kClear:
|
case SkBlendMode::kClear:
|
||||||
return GrConstColorProcessor::Make(SK_PMColor4fTRANSPARENT,
|
return GrConstColorProcessor::Make(/*inputFP=*/nullptr, SK_PMColor4fTRANSPARENT,
|
||||||
GrConstColorProcessor::InputMode::kIgnore);
|
GrConstColorProcessor::InputMode::kIgnore);
|
||||||
case SkBlendMode::kSrc:
|
case SkBlendMode::kSrc:
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -510,7 +510,7 @@ std::unique_ptr<GrFragmentProcessor> GrXfermodeFragmentProcessor::MakeFromSrcPro
|
|||||||
std::unique_ptr<GrFragmentProcessor> src, SkBlendMode mode) {
|
std::unique_ptr<GrFragmentProcessor> src, SkBlendMode mode) {
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case SkBlendMode::kClear:
|
case SkBlendMode::kClear:
|
||||||
return GrConstColorProcessor::Make(SK_PMColor4fTRANSPARENT,
|
return GrConstColorProcessor::Make(/*inputFP=*/nullptr, SK_PMColor4fTRANSPARENT,
|
||||||
GrConstColorProcessor::InputMode::kIgnore);
|
GrConstColorProcessor::InputMode::kIgnore);
|
||||||
case SkBlendMode::kDst:
|
case SkBlendMode::kDst:
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -30,12 +30,33 @@ public:
|
|||||||
colorVar = args.fUniformHandler->addUniform(&_outer, kFragment_GrShaderFlag,
|
colorVar = args.fUniformHandler->addUniform(&_outer, kFragment_GrShaderFlag,
|
||||||
kHalf4_GrSLType, "color");
|
kHalf4_GrSLType, "color");
|
||||||
fragBuilder->codeAppendf(
|
fragBuilder->codeAppendf(
|
||||||
"@switch (%d) {\n case 0:\n %s = %s;\n break;\n case 1:\n "
|
"@switch (%d) {\n case 0:\n {\n %s = %s;\n "
|
||||||
" %s = %s * %s;\n break;\n case 2:\n %s = %s.w * %s;\n "
|
"break;\n }\n case 1:\n {",
|
||||||
"break;\n}\n",
|
(int)_outer.mode, args.fOutputColor,
|
||||||
(int)_outer.mode, args.fOutputColor, args.fUniformHandler->getUniformCStr(colorVar),
|
args.fUniformHandler->getUniformCStr(colorVar));
|
||||||
args.fOutputColor, args.fInputColor, args.fUniformHandler->getUniformCStr(colorVar),
|
SkString _input1009 = SkStringPrintf("%s", args.fInputColor);
|
||||||
args.fOutputColor, args.fInputColor,
|
SkString _sample1009;
|
||||||
|
if (_outer.inputFP_index >= 0) {
|
||||||
|
_sample1009 = this->invokeChild(_outer.inputFP_index, _input1009.c_str(), args);
|
||||||
|
} else {
|
||||||
|
_sample1009 = _input1009;
|
||||||
|
}
|
||||||
|
fragBuilder->codeAppendf(
|
||||||
|
"\n half4 inputColor = %s;\n %s = inputColor * %s;\n "
|
||||||
|
" break;\n }\n case 2:\n {",
|
||||||
|
_sample1009.c_str(), args.fOutputColor,
|
||||||
|
args.fUniformHandler->getUniformCStr(colorVar));
|
||||||
|
SkString _input1181 = SkStringPrintf("%s", args.fInputColor);
|
||||||
|
SkString _sample1181;
|
||||||
|
if (_outer.inputFP_index >= 0) {
|
||||||
|
_sample1181 = this->invokeChild(_outer.inputFP_index, _input1181.c_str(), args);
|
||||||
|
} else {
|
||||||
|
_sample1181 = _input1181;
|
||||||
|
}
|
||||||
|
fragBuilder->codeAppendf(
|
||||||
|
"\n half inputAlpha = %s.w;\n %s = inputAlpha * %s;\n "
|
||||||
|
" break;\n }\n}\n",
|
||||||
|
_sample1181.c_str(), args.fOutputColor,
|
||||||
args.fUniformHandler->getUniformCStr(colorVar));
|
args.fUniformHandler->getUniformCStr(colorVar));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,7 +92,11 @@ bool GrConstColorProcessor::onIsEqual(const GrFragmentProcessor& other) const {
|
|||||||
GrConstColorProcessor::GrConstColorProcessor(const GrConstColorProcessor& src)
|
GrConstColorProcessor::GrConstColorProcessor(const GrConstColorProcessor& src)
|
||||||
: INHERITED(kGrConstColorProcessor_ClassID, src.optimizationFlags())
|
: INHERITED(kGrConstColorProcessor_ClassID, src.optimizationFlags())
|
||||||
, color(src.color)
|
, color(src.color)
|
||||||
, mode(src.mode) {}
|
, mode(src.mode) {
|
||||||
|
if (src.inputFP_index >= 0) {
|
||||||
|
inputFP_index = this->cloneAndRegisterChildProcessor(src.childProcessor(src.inputFP_index));
|
||||||
|
}
|
||||||
|
}
|
||||||
std::unique_ptr<GrFragmentProcessor> GrConstColorProcessor::clone() const {
|
std::unique_ptr<GrFragmentProcessor> GrConstColorProcessor::clone() const {
|
||||||
return std::unique_ptr<GrFragmentProcessor>(new GrConstColorProcessor(*this));
|
return std::unique_ptr<GrFragmentProcessor>(new GrConstColorProcessor(*this));
|
||||||
}
|
}
|
||||||
@ -98,6 +123,6 @@ std::unique_ptr<GrFragmentProcessor> GrConstColorProcessor::TestCreate(GrProcess
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
InputMode mode = static_cast<InputMode>(d->fRandom->nextULessThan(kInputModeCnt));
|
InputMode mode = static_cast<InputMode>(d->fRandom->nextULessThan(kInputModeCnt));
|
||||||
return GrConstColorProcessor::Make(color, mode);
|
return GrConstColorProcessor::Make(/*inputFP=*/nullptr, color, mode);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -23,42 +23,60 @@ public:
|
|||||||
|
|
||||||
static const int kInputModeCnt = (int)InputMode::kLast + 1;
|
static const int kInputModeCnt = (int)InputMode::kLast + 1;
|
||||||
|
|
||||||
static OptimizationFlags OptFlags(const SkPMColor4f& color, InputMode mode) {
|
SkPMColor4f constantOutputForConstantInput(const SkPMColor4f& inColor) const override {
|
||||||
OptimizationFlags flags = kConstantOutputForConstantInput_OptimizationFlag;
|
|
||||||
if (mode != InputMode::kIgnore) {
|
|
||||||
flags |= kCompatibleWithCoverageAsAlpha_OptimizationFlag;
|
|
||||||
}
|
|
||||||
if (color.isOpaque()) {
|
|
||||||
flags |= kPreservesOpaqueInput_OptimizationFlag;
|
|
||||||
}
|
|
||||||
return flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
SkPMColor4f constantOutputForConstantInput(const SkPMColor4f& input) const override {
|
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case InputMode::kIgnore:
|
case InputMode::kIgnore: {
|
||||||
return color;
|
return color;
|
||||||
case InputMode::kModulateA:
|
}
|
||||||
|
case InputMode::kModulateA: {
|
||||||
|
SkPMColor4f input = this->numChildProcessors()
|
||||||
|
? ConstantOutputForConstantInput(
|
||||||
|
this->childProcessor(inputFP_index), inColor)
|
||||||
|
: inColor;
|
||||||
return color * input.fA;
|
return color * input.fA;
|
||||||
case InputMode::kModulateRGBA:
|
}
|
||||||
|
case InputMode::kModulateRGBA: {
|
||||||
|
SkPMColor4f input = this->numChildProcessors()
|
||||||
|
? ConstantOutputForConstantInput(
|
||||||
|
this->childProcessor(inputFP_index), inColor)
|
||||||
|
: inColor;
|
||||||
return color * input;
|
return color * input;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
SK_ABORT("Unexpected mode");
|
SkUNREACHABLE;
|
||||||
}
|
}
|
||||||
static std::unique_ptr<GrFragmentProcessor> Make(SkPMColor4f color, InputMode mode) {
|
static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> inputFP,
|
||||||
return std::unique_ptr<GrFragmentProcessor>(new GrConstColorProcessor(color, mode));
|
SkPMColor4f color,
|
||||||
|
InputMode mode) {
|
||||||
|
return std::unique_ptr<GrFragmentProcessor>(
|
||||||
|
new GrConstColorProcessor(std::move(inputFP), color, mode));
|
||||||
}
|
}
|
||||||
GrConstColorProcessor(const GrConstColorProcessor& src);
|
GrConstColorProcessor(const GrConstColorProcessor& src);
|
||||||
std::unique_ptr<GrFragmentProcessor> clone() const override;
|
std::unique_ptr<GrFragmentProcessor> clone() const override;
|
||||||
const char* name() const override { return "ConstColorProcessor"; }
|
const char* name() const override { return "ConstColorProcessor"; }
|
||||||
|
int inputFP_index = -1;
|
||||||
SkPMColor4f color;
|
SkPMColor4f color;
|
||||||
InputMode mode;
|
InputMode mode;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
GrConstColorProcessor(SkPMColor4f color, InputMode mode)
|
GrConstColorProcessor(std::unique_ptr<GrFragmentProcessor> inputFP,
|
||||||
: INHERITED(kGrConstColorProcessor_ClassID, (OptimizationFlags)OptFlags(color, mode))
|
SkPMColor4f color,
|
||||||
|
InputMode mode)
|
||||||
|
: INHERITED(kGrConstColorProcessor_ClassID,
|
||||||
|
(OptimizationFlags)(inputFP ? ProcessorOptimizationFlags(inputFP.get())
|
||||||
|
: kAll_OptimizationFlags) &
|
||||||
|
(kConstantOutputForConstantInput_OptimizationFlag |
|
||||||
|
((mode != InputMode::kIgnore)
|
||||||
|
? kCompatibleWithCoverageAsAlpha_OptimizationFlag
|
||||||
|
: kNone_OptimizationFlags) |
|
||||||
|
((color.isOpaque()) ? kPreservesOpaqueInput_OptimizationFlag
|
||||||
|
: kNone_OptimizationFlags)))
|
||||||
, color(color)
|
, color(color)
|
||||||
, mode(mode) {}
|
, mode(mode) {
|
||||||
|
if (inputFP) {
|
||||||
|
inputFP_index = this->registerChildProcessor(std::move(inputFP));
|
||||||
|
}
|
||||||
|
}
|
||||||
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
|
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
|
||||||
void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
|
void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
|
||||||
bool onIsEqual(const GrFragmentProcessor&) const override;
|
bool onIsEqual(const GrFragmentProcessor&) const override;
|
||||||
|
@ -118,7 +118,8 @@ skvm::Color SkColor4Shader::onProgram(skvm::Builder* p,
|
|||||||
std::unique_ptr<GrFragmentProcessor> SkColorShader::asFragmentProcessor(
|
std::unique_ptr<GrFragmentProcessor> SkColorShader::asFragmentProcessor(
|
||||||
const GrFPArgs& args) const {
|
const GrFPArgs& args) const {
|
||||||
SkPMColor4f color = SkColorToPMColor4f(fColor, *args.fDstColorInfo);
|
SkPMColor4f color = SkColorToPMColor4f(fColor, *args.fDstColorInfo);
|
||||||
return GrConstColorProcessor::Make(color, GrConstColorProcessor::InputMode::kModulateA);
|
return GrConstColorProcessor::Make(/*inputFP=*/nullptr, color,
|
||||||
|
GrConstColorProcessor::InputMode::kModulateA);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<GrFragmentProcessor> SkColor4Shader::asFragmentProcessor(
|
std::unique_ptr<GrFragmentProcessor> SkColor4Shader::asFragmentProcessor(
|
||||||
@ -127,7 +128,7 @@ std::unique_ptr<GrFragmentProcessor> SkColor4Shader::asFragmentProcessor(
|
|||||||
args.fDstColorInfo->colorSpace(), kUnpremul_SkAlphaType };
|
args.fDstColorInfo->colorSpace(), kUnpremul_SkAlphaType };
|
||||||
SkColor4f color = fColor;
|
SkColor4f color = fColor;
|
||||||
steps.apply(color.vec());
|
steps.apply(color.vec());
|
||||||
return GrConstColorProcessor::Make(color.premul(),
|
return GrConstColorProcessor::Make(/*inputFP=*/nullptr, color.premul(),
|
||||||
GrConstColorProcessor::InputMode::kModulateA);
|
GrConstColorProcessor::InputMode::kModulateA);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1443,13 +1443,13 @@ std::unique_ptr<GrFragmentProcessor> SkPerlinNoiseShaderImpl::asFragmentProcesso
|
|||||||
// TODO: Either treat the output of this shader as sRGB or allow client to specify a
|
// TODO: Either treat the output of this shader as sRGB or allow client to specify a
|
||||||
// color space of the noise. Either way, this case (and the GLSL) need to convert to
|
// color space of the noise. Either way, this case (and the GLSL) need to convert to
|
||||||
// the destination.
|
// the destination.
|
||||||
auto inner =
|
auto inner = GrConstColorProcessor::Make(
|
||||||
GrConstColorProcessor::Make(SkPMColor4f::FromBytes_RGBA(0x80404040),
|
/*inputFP=*/nullptr, SkPMColor4f::FromBytes_RGBA(0x80404040),
|
||||||
GrConstColorProcessor::InputMode::kModulateRGBA);
|
GrConstColorProcessor::InputMode::kModulateRGBA);
|
||||||
return GrFragmentProcessor::MulChildByInputAlpha(std::move(inner));
|
return GrFragmentProcessor::MulChildByInputAlpha(std::move(inner));
|
||||||
}
|
}
|
||||||
// Emit zero.
|
// Emit zero.
|
||||||
return GrConstColorProcessor::Make(SK_PMColor4fTRANSPARENT,
|
return GrConstColorProcessor::Make(/*inputFP=*/nullptr, SK_PMColor4fTRANSPARENT,
|
||||||
GrConstColorProcessor::InputMode::kIgnore);
|
GrConstColorProcessor::InputMode::kIgnore);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,7 +92,8 @@ static void run_test(GrContext* ctx, skiatest::Reporter* reporter) {
|
|||||||
GrPaint paint;
|
GrPaint paint;
|
||||||
|
|
||||||
const SkPMColor4f color = { 1.0f, 0.0f, 0.0f, 1.0f };
|
const SkPMColor4f color = { 1.0f, 0.0f, 0.0f, 1.0f };
|
||||||
auto fp = GrConstColorProcessor::Make(color, GrConstColorProcessor::InputMode::kIgnore);
|
auto fp = GrConstColorProcessor::Make(/*inputFP=*/nullptr, color,
|
||||||
|
GrConstColorProcessor::InputMode::kIgnore);
|
||||||
paint.addColorFragmentProcessor(std::move(fp));
|
paint.addColorFragmentProcessor(std::move(fp));
|
||||||
|
|
||||||
rtc->drawPath(nullptr, std::move(paint), GrAA::kNo,
|
rtc->drawPath(nullptr, std::move(paint), GrAA::kNo,
|
||||||
@ -110,7 +111,8 @@ static void run_test(GrContext* ctx, skiatest::Reporter* reporter) {
|
|||||||
GrPaint paint;
|
GrPaint paint;
|
||||||
|
|
||||||
const SkPMColor4f color = { 0.0f, 1.0f, 0.0f, 1.0f };
|
const SkPMColor4f color = { 0.0f, 1.0f, 0.0f, 1.0f };
|
||||||
auto fp = GrConstColorProcessor::Make(color, GrConstColorProcessor::InputMode::kIgnore);
|
auto fp = GrConstColorProcessor::Make(/*inputFP=*/nullptr, color,
|
||||||
|
GrConstColorProcessor::InputMode::kIgnore);
|
||||||
paint.addColorFragmentProcessor(std::move(fp));
|
paint.addColorFragmentProcessor(std::move(fp));
|
||||||
|
|
||||||
rtc->drawPath(nullptr, std::move(paint), GrAA::kNo,
|
rtc->drawPath(nullptr, std::move(paint), GrAA::kNo,
|
||||||
@ -126,7 +128,6 @@ static void run_test(GrContext* ctx, skiatest::Reporter* reporter) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DEF_GPUTEST_FOR_CONTEXTS(GrDefaultPathRendererTest,
|
DEF_GPUTEST_FOR_CONTEXTS(GrDefaultPathRendererTest,
|
||||||
|
Loading…
Reference in New Issue
Block a user