Replace RGB <-> HSL FPs with runtime FPs

Awkwardly, there is still two copies of (some of) this SkSL. We have
helper functions in SkRuntimeEffectPriv.h that implement these
transformations, and those are used by the high contrast color filter.

However: The RGB to HSL code is fairly different, and produces results
that are visibly different. For this CL, I didn't want to impact either
use case, so this is just a migration of the existing .fp code (only
used by HSLA color matrices). We can/should look at merging the
implementation in the future.

Change-Id: I8a9aa6a2d8563ab4333af79a528e406c08b0e1ba
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/419497
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: John Stiles <johnstiles@google.com>
This commit is contained in:
Brian Osman 2021-06-17 16:39:08 -04:00 committed by Skia Commit-Bot
parent 311010405e
commit 71bf78604b
10 changed files with 76 additions and 396 deletions

View File

@ -324,12 +324,8 @@ skia_gpu_sources = [
"$_src/gpu/effects/generated/GrDitherEffect.h",
"$_src/gpu/effects/generated/GrEllipseEffect.cpp",
"$_src/gpu/effects/generated/GrEllipseEffect.h",
"$_src/gpu/effects/generated/GrHSLToRGBFilterEffect.cpp",
"$_src/gpu/effects/generated/GrHSLToRGBFilterEffect.h",
"$_src/gpu/effects/generated/GrOverrideInputFragmentProcessor.cpp",
"$_src/gpu/effects/generated/GrOverrideInputFragmentProcessor.h",
"$_src/gpu/effects/generated/GrRGBToHSLFilterEffect.cpp",
"$_src/gpu/effects/generated/GrRGBToHSLFilterEffect.h",
"$_src/gpu/effects/generated/GrRRectBlurEffect.cpp",
"$_src/gpu/effects/generated/GrRRectBlurEffect.h",
"$_src/gpu/effects/generated/GrRectBlurEffect.cpp",

View File

@ -215,9 +215,7 @@ skia_gpu_processor_sources = [
"$_src/gpu/effects/GrDeviceSpaceEffect.fp",
"$_src/gpu/effects/GrDitherEffect.fp",
"$_src/gpu/effects/GrEllipseEffect.fp",
"$_src/gpu/effects/GrHSLToRGBFilterEffect.fp",
"$_src/gpu/effects/GrOverrideInputFragmentProcessor.fp",
"$_src/gpu/effects/GrRGBToHSLFilterEffect.fp",
"$_src/gpu/effects/GrRRectBlurEffect.fp",
"$_src/gpu/effects/GrRectBlurEffect.fp",
"$_src/gpu/gradients/GrClampedGradientEffect.fp",

View File

@ -120,8 +120,80 @@ skvm::Color SkColorFilter_Matrix::onProgram(skvm::Builder* p, skvm::Color c,
}
#if SK_SUPPORT_GPU
#include "src/gpu/effects/generated/GrHSLToRGBFilterEffect.h"
#include "src/gpu/effects/generated/GrRGBToHSLFilterEffect.h"
#include "src/gpu/effects/GrSkSLFP.h"
// Convert RGBA -> HSLA (including unpremul).
//
// Based on work by Sam Hocevar, Emil Persson, and Ian Taylor [1][2][3]. High-level ideas:
//
// - minimize the number of branches by sorting and computing the hue phase in parallel (vec4s)
//
// - trade the third sorting branch for a potentially faster std::min and leaving 2nd/3rd
// channels unsorted (based on the observation that swapping both the channels and the bias sign
// has no effect under abs)
//
// - use epsilon offsets for denominators, to avoid explicit zero-checks
//
// An additional trick we employ is deferring premul->unpremul conversion until the very end: the
// alpha factor gets naturally simplified for H and S, and only L requires a dedicated unpremul
// division (so we trade three divs for one).
//
// [1] http://lolengine.net/blog/2013/01/13/fast-rgb-to-hsv
// [2] http://lolengine.net/blog/2013/07/27/rgb-to-hsv-in-glsl
// [3] http://www.chilliant.com/rgb2hsv.html
static std::unique_ptr<GrFragmentProcessor> rgb_to_hsl(std::unique_ptr<GrFragmentProcessor> child) {
static auto effect = SkMakeRuntimeEffect(SkRuntimeEffect::MakeForColorFilter, R"(
half4 main(half4 c) {
half4 p = (c.g < c.b) ? half4(c.bg, -1, 2/3.0)
: half4(c.gb, 0, -1/3.0);
half4 q = (c.r < p.x) ? half4(p.x, c.r, p.yw)
: half4(c.r, p.x, p.yz);
// q.x -> max channel value
// q.yz -> 2nd/3rd channel values (unsorted)
// q.w -> bias value dependent on max channel selection
half eps = 0.0001;
half pmV = q.x;
half pmC = pmV - min(q.y, q.z);
half pmL = pmV - pmC * 0.5;
half H = abs(q.w + (q.y - q.z) / (pmC * 6 + eps));
half S = pmC / (c.a + eps - abs(pmL * 2 - c.a));
half L = pmL / (c.a + eps);
return half4(H, S, L, c.a);
}
)");
return GrSkSLFP::Make(
effect, "RgbToHsl", std::move(child), GrSkSLFP::OptFlags::kPreservesOpaqueInput);
}
// Convert HSLA -> RGBA (including clamp and premul).
//
// Based on work by Sam Hocevar, Emil Persson, and Ian Taylor [1][2][3].
//
// [1] http://lolengine.net/blog/2013/01/13/fast-rgb-to-hsv
// [2] http://lolengine.net/blog/2013/07/27/rgb-to-hsv-in-glsl
// [3] http://www.chilliant.com/rgb2hsv.html
static std::unique_ptr<GrFragmentProcessor> hsl_to_rgb(std::unique_ptr<GrFragmentProcessor> child) {
static auto effect = SkMakeRuntimeEffect(SkRuntimeEffect::MakeForColorFilter, R"(
half4 main(half4 color) {
half3 hsl = color.rgb;
half C = (1 - abs(2 * hsl.z - 1)) * hsl.y;
half3 p = hsl.xxx + half3(0, 2/3.0, 1/3.0);
half3 q = saturate(abs(fract(p) * 6 - 3) - 1);
half3 rgb = (q - 0.5) * C + hsl.z;
color = saturate(half4(rgb, color.a));
color.rgb *= color.a;
return color;
}
)");
return GrSkSLFP::Make(
effect, "HslToRgb", std::move(child), GrSkSLFP::OptFlags::kPreservesOpaqueInput);
}
GrFPResult SkColorFilter_Matrix::asFragmentProcessor(std::unique_ptr<GrFragmentProcessor> fp,
GrRecordingContext*,
const GrColorInfo&) const {
@ -134,12 +206,12 @@ GrFPResult SkColorFilter_Matrix::asFragmentProcessor(std::unique_ptr<GrFragmentP
break;
case Domain::kHSLA:
fp = GrRGBToHSLFilterEffect::Make(std::move(fp));
fp = rgb_to_hsl(std::move(fp));
fp = GrFragmentProcessor::ColorMatrix(std::move(fp), fMatrix,
/* unpremulInput = */ false,
/* clampRGBOutput = */ false,
/* premulOutput = */ false);
fp = GrHSLToRGBFilterEffect::Make(std::move(fp));
fp = hsl_to_rgb(std::move(fp));
break;
}

View File

@ -86,7 +86,6 @@ public:
kGrFillRRectOp_Processor_ClassID,
kGrGaussianConvolutionFragmentProcessor_ClassID,
kGrHighContrastFilterEffect_ClassID,
kGrHSLToRGBFilterEffect_ClassID,
kGrImprovedPerlinNoiseEffect_ClassID,
kGrLinearGradientLayout_ClassID,
kGrLumaColorFilterEffect_ClassID,
@ -101,7 +100,6 @@ public:
kGrQuadEffect_ClassID,
kGrRadialGradientLayout_ClassID,
kGrRectBlurEffect_ClassID,
kGrRGBToHSLFilterEffect_ClassID,
kGrRRectBlurEffect_ClassID,
kGrRRectShadowGeoProc_ClassID,
kGrSingleIntervalGradientColorizer_ClassID,

View File

@ -1,55 +0,0 @@
/*
* Copyright 2019 Google LLC
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
// Convert HSLA -> RGBA (including clamp and premul).
//
// Based on work by Sam Hocevar, Emil Persson, and Ian Taylor [1][2][3].
//
// [1] http://lolengine.net/blog/2013/01/13/fast-rgb-to-hsv
// [2] http://lolengine.net/blog/2013/07/27/rgb-to-hsv-in-glsl
// [3] http://www.chilliant.com/rgb2hsv.html
in fragmentProcessor inputFP;
half4 main() {
half4 color = sample(inputFP);
half3 hsl = color.rgb;
half C = (1 - abs(2 * hsl.z - 1)) * hsl.y;
half3 p = hsl.xxx + half3(0, 2/3.0, 1/3.0);
half3 q = saturate(abs(fract(p) * 6 - 3) - 1);
half3 rgb = (q - 0.5) * C + hsl.z;
color = saturate(half4(rgb, color.a));
color.rgb *= color.a;
return color;
}
@optimizationFlags {
ProcessorOptimizationFlags(inputFP.get()) & (kConstantOutputForConstantInput_OptimizationFlag |
kPreservesOpaqueInput_OptimizationFlag)
}
@class {
#include "include/private/SkColorData.h"
#include "include/private/SkNx.h"
SkPMColor4f constantOutputForConstantInput(const SkPMColor4f& inColor) const override {
SkPMColor4f c = ConstantOutputForConstantInput(this->childProcessor(0), inColor);
const auto H = c[0],
S = c[1],
L = c[2],
C = (1 - std::abs(2 * L - 1)) * S;
const auto p = H + Sk4f(0, 2/3.f, 1/3.f, 0),
q = Sk4f::Min(Sk4f::Max(((p - p.floor()) * 6 - 3).abs() - 1, 0), 1),
rgb = (q - 0.5f) * C + L,
rgba = Sk4f::Min(Sk4f::Max(Sk4f(rgb[0], rgb[1], rgb[2], c.fA), 0), 1);
return SkColor4f{rgba[0], rgba[1], rgba[2], rgba[3]}.premul();
}
}

View File

@ -1,77 +0,0 @@
/*
* Copyright 2019 Google LLC
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
// Convert RGBA -> HSLA (including unpremul).
//
// Based on work by Sam Hocevar, Emil Persson, and Ian Taylor [1][2][3]. High-level ideas:
//
// - minimize the number of branches by sorting and computing the hue phase in parallel (vec4s)
//
// - trade the third sorting branch for a potentially faster std::min and leaving 2nd/3rd
// channels unsorted (based on the observation that swapping both the channels and the bias sign
// has no effect under abs)
//
// - use epsilon offsets for denominators, to avoid explicit zero-checks
//
// An additional trick we employ is deferring premul->unpremul conversion until the very end: the
// alpha factor gets naturally simplified for H and S, and only L requires a dedicated unpremul
// division (so we trade three divs for one).
//
// [1] http://lolengine.net/blog/2013/01/13/fast-rgb-to-hsv
// [2] http://lolengine.net/blog/2013/07/27/rgb-to-hsv-in-glsl
// [3] http://www.chilliant.com/rgb2hsv.html
in fragmentProcessor inputFP;
half4 main() {
half4 c = sample(inputFP);
half4 p = (c.g < c.b) ? half4(c.bg, -1, 2/3.0)
: half4(c.gb, 0, -1/3.0);
half4 q = (c.r < p.x) ? half4(p.x, c.r, p.yw)
: half4(c.r, p.x, p.yz);
// q.x -> max channel value
// q.yz -> 2nd/3rd channel values (unsorted)
// q.w -> bias value dependent on max channel selection
half eps = 0.0001;
half pmV = q.x;
half pmC = pmV - min(q.y, q.z);
half pmL = pmV - pmC * 0.5;
half H = abs(q.w + (q.y - q.z) / (pmC * 6 + eps));
half S = pmC / (c.a + eps - abs(pmL * 2 - c.a));
half L = pmL / (c.a + eps);
return half4(H, S, L, c.a);
}
@optimizationFlags {
ProcessorOptimizationFlags(inputFP.get()) & (kConstantOutputForConstantInput_OptimizationFlag |
kPreservesOpaqueInput_OptimizationFlag)
}
@class {
#include "include/private/SkColorData.h"
SkPMColor4f constantOutputForConstantInput(const SkPMColor4f& inColor) const override {
SkPMColor4f c = ConstantOutputForConstantInput(this->childProcessor(0), inColor);
const auto p = (c.fG < c.fB) ? SkPMColor4f{ c.fB, c.fG, -1, 2/3.f }
: SkPMColor4f{ c.fG, c.fB, 0, -1/3.f },
q = (c.fR < p[0]) ? SkPMColor4f{ p[0], c.fR, p[1], p[3] }
: SkPMColor4f{ c.fR, p[0], p[1], p[2] };
const auto eps = 0.0001f, // matching SkSL/ColorMatrix half4 epsilon
pmV = q[0],
pmC = pmV - std::min(q[1], q[2]),
pmL = pmV - pmC * 0.5f,
H = std::abs(q[3] + (q[1] - q[2]) / (pmC * 6 + eps)),
S = pmC / (c.fA + eps - std::abs(pmL * 2 - c.fA)),
L = pmL / (c.fA + eps);
return { H, S, L, c.fA };
}
}

View File

@ -1,65 +0,0 @@
/*
* Copyright 2019 Google LLC
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
/**************************************************************************************************
*** This file was autogenerated from GrHSLToRGBFilterEffect.fp; do not modify.
**************************************************************************************************/
#include "GrHSLToRGBFilterEffect.h"
#include "src/core/SkUtils.h"
#include "src/gpu/GrTexture.h"
#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
#include "src/gpu/glsl/GrGLSLProgramBuilder.h"
#include "src/sksl/SkSLCPP.h"
#include "src/sksl/SkSLUtil.h"
class GrGLSLHSLToRGBFilterEffect : public GrGLSLFragmentProcessor {
public:
GrGLSLHSLToRGBFilterEffect() {}
void emitCode(EmitArgs& args) override {
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
const GrHSLToRGBFilterEffect& _outer = args.fFp.cast<GrHSLToRGBFilterEffect>();
(void)_outer;
SkString _sample0 = this->invokeChild(0, args);
fragBuilder->codeAppendf(
R"SkSL(half4 color = %s;
half3 hsl = color.xyz;
half C = (1.0 - abs(2.0 * hsl.z - 1.0)) * hsl.y;
half3 p = hsl.xxx + half3(0.0, 0.66666668653488159, 0.3333333432674408);
half3 q = clamp(abs(fract(p) * 6.0 - 3.0) - 1.0, 0.0, 1.0);
half3 rgb = (q - 0.5) * C + hsl.z;
color = clamp(half4(rgb, color.w), 0.0, 1.0);
color.xyz *= color.w;
return color;
)SkSL",
_sample0.c_str());
}
private:
void onSetData(const GrGLSLProgramDataManager& pdman,
const GrFragmentProcessor& _proc) override {}
};
std::unique_ptr<GrGLSLFragmentProcessor> GrHSLToRGBFilterEffect::onMakeProgramImpl() const {
return std::make_unique<GrGLSLHSLToRGBFilterEffect>();
}
void GrHSLToRGBFilterEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps,
GrProcessorKeyBuilder* b) const {}
bool GrHSLToRGBFilterEffect::onIsEqual(const GrFragmentProcessor& other) const {
const GrHSLToRGBFilterEffect& that = other.cast<GrHSLToRGBFilterEffect>();
(void)that;
return true;
}
GrHSLToRGBFilterEffect::GrHSLToRGBFilterEffect(const GrHSLToRGBFilterEffect& src)
: INHERITED(kGrHSLToRGBFilterEffect_ClassID, src.optimizationFlags()) {
this->cloneAndRegisterAllChildProcessors(src);
}
std::unique_ptr<GrFragmentProcessor> GrHSLToRGBFilterEffect::clone() const {
return std::make_unique<GrHSLToRGBFilterEffect>(*this);
}
#if GR_TEST_UTILS
SkString GrHSLToRGBFilterEffect::onDumpInfo() const { return SkString(); }
#endif

View File

@ -1,59 +0,0 @@
/*
* Copyright 2019 Google LLC
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
/**************************************************************************************************
*** This file was autogenerated from GrHSLToRGBFilterEffect.fp; do not modify.
**************************************************************************************************/
#ifndef GrHSLToRGBFilterEffect_DEFINED
#define GrHSLToRGBFilterEffect_DEFINED
#include "include/core/SkM44.h"
#include "include/core/SkTypes.h"
#include "src/gpu/GrFragmentProcessor.h"
class GrHSLToRGBFilterEffect : public GrFragmentProcessor {
public:
#include "include/private/SkColorData.h"
#include "include/private/SkNx.h"
SkPMColor4f constantOutputForConstantInput(const SkPMColor4f& inColor) const override {
SkPMColor4f c = ConstantOutputForConstantInput(this->childProcessor(0), inColor);
const auto H = c[0], S = c[1], L = c[2], C = (1 - std::abs(2 * L - 1)) * S;
const auto p = H + Sk4f(0, 2 / 3.f, 1 / 3.f, 0),
q = Sk4f::Min(Sk4f::Max(((p - p.floor()) * 6 - 3).abs() - 1, 0), 1),
rgb = (q - 0.5f) * C + L,
rgba = Sk4f::Min(Sk4f::Max(Sk4f(rgb[0], rgb[1], rgb[2], c.fA), 0), 1);
return SkColor4f{rgba[0], rgba[1], rgba[2], rgba[3]}.premul();
}
static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> inputFP) {
return std::unique_ptr<GrFragmentProcessor>(new GrHSLToRGBFilterEffect(std::move(inputFP)));
}
GrHSLToRGBFilterEffect(const GrHSLToRGBFilterEffect& src);
std::unique_ptr<GrFragmentProcessor> clone() const override;
const char* name() const override { return "HSLToRGBFilterEffect"; }
private:
GrHSLToRGBFilterEffect(std::unique_ptr<GrFragmentProcessor> inputFP)
: INHERITED(kGrHSLToRGBFilterEffect_ClassID,
(OptimizationFlags)ProcessorOptimizationFlags(inputFP.get()) &
(kConstantOutputForConstantInput_OptimizationFlag |
kPreservesOpaqueInput_OptimizationFlag)) {
this->registerChild(std::move(inputFP), SkSL::SampleUsage::PassThrough());
}
std::unique_ptr<GrGLSLFragmentProcessor> onMakeProgramImpl() const override;
void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
bool onIsEqual(const GrFragmentProcessor&) const override;
#if GR_TEST_UTILS
SkString onDumpInfo() const override;
#endif
GR_DECLARE_FRAGMENT_PROCESSOR_TEST
using INHERITED = GrFragmentProcessor;
};
#endif

View File

@ -1,67 +0,0 @@
/*
* Copyright 2019 Google LLC
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
/**************************************************************************************************
*** This file was autogenerated from GrRGBToHSLFilterEffect.fp; do not modify.
**************************************************************************************************/
#include "GrRGBToHSLFilterEffect.h"
#include "src/core/SkUtils.h"
#include "src/gpu/GrTexture.h"
#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
#include "src/gpu/glsl/GrGLSLProgramBuilder.h"
#include "src/sksl/SkSLCPP.h"
#include "src/sksl/SkSLUtil.h"
class GrGLSLRGBToHSLFilterEffect : public GrGLSLFragmentProcessor {
public:
GrGLSLRGBToHSLFilterEffect() {}
void emitCode(EmitArgs& args) override {
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
const GrRGBToHSLFilterEffect& _outer = args.fFp.cast<GrRGBToHSLFilterEffect>();
(void)_outer;
SkString _sample0 = this->invokeChild(0, args);
fragBuilder->codeAppendf(
R"SkSL(half4 c = %s;
half4 p = c.y < c.z ? half4(c.zy, -1.0, 0.66666668653488159) : half4(c.yz, 0.0, -0.3333333432674408);
half4 q = c.x < p.x ? half4(p.x, c.x, p.yw) : half4(c.x, p.x, p.yz);
half eps = 9.9999997473787516e-05;
half pmV = q.x;
half pmC = pmV - min(q.y, q.z);
half pmL = pmV - pmC * 0.5;
half H = abs(q.w + (q.y - q.z) / (pmC * 6.0 + eps));
half S = pmC / ((c.w + eps) - abs(pmL * 2.0 - c.w));
half L = pmL / (c.w + eps);
return half4(H, S, L, c.w);
)SkSL",
_sample0.c_str());
}
private:
void onSetData(const GrGLSLProgramDataManager& pdman,
const GrFragmentProcessor& _proc) override {}
};
std::unique_ptr<GrGLSLFragmentProcessor> GrRGBToHSLFilterEffect::onMakeProgramImpl() const {
return std::make_unique<GrGLSLRGBToHSLFilterEffect>();
}
void GrRGBToHSLFilterEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps,
GrProcessorKeyBuilder* b) const {}
bool GrRGBToHSLFilterEffect::onIsEqual(const GrFragmentProcessor& other) const {
const GrRGBToHSLFilterEffect& that = other.cast<GrRGBToHSLFilterEffect>();
(void)that;
return true;
}
GrRGBToHSLFilterEffect::GrRGBToHSLFilterEffect(const GrRGBToHSLFilterEffect& src)
: INHERITED(kGrRGBToHSLFilterEffect_ClassID, src.optimizationFlags()) {
this->cloneAndRegisterAllChildProcessors(src);
}
std::unique_ptr<GrFragmentProcessor> GrRGBToHSLFilterEffect::clone() const {
return std::make_unique<GrRGBToHSLFilterEffect>(*this);
}
#if GR_TEST_UTILS
SkString GrRGBToHSLFilterEffect::onDumpInfo() const { return SkString(); }
#endif

View File

@ -1,61 +0,0 @@
/*
* Copyright 2019 Google LLC
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
/**************************************************************************************************
*** This file was autogenerated from GrRGBToHSLFilterEffect.fp; do not modify.
**************************************************************************************************/
#ifndef GrRGBToHSLFilterEffect_DEFINED
#define GrRGBToHSLFilterEffect_DEFINED
#include "include/core/SkM44.h"
#include "include/core/SkTypes.h"
#include "src/gpu/GrFragmentProcessor.h"
class GrRGBToHSLFilterEffect : public GrFragmentProcessor {
public:
#include "include/private/SkColorData.h"
SkPMColor4f constantOutputForConstantInput(const SkPMColor4f& inColor) const override {
SkPMColor4f c = ConstantOutputForConstantInput(this->childProcessor(0), inColor);
const auto p = (c.fG < c.fB) ? SkPMColor4f{c.fB, c.fG, -1, 2 / 3.f}
: SkPMColor4f{c.fG, c.fB, 0, -1 / 3.f},
q = (c.fR < p[0]) ? SkPMColor4f{p[0], c.fR, p[1], p[3]}
: SkPMColor4f{c.fR, p[0], p[1], p[2]};
const auto eps = 0.0001f, // matching SkSL/ColorMatrix half4 epsilon
pmV = q[0], pmC = pmV - std::min(q[1], q[2]), pmL = pmV - pmC * 0.5f,
H = std::abs(q[3] + (q[1] - q[2]) / (pmC * 6 + eps)),
S = pmC / (c.fA + eps - std::abs(pmL * 2 - c.fA)), L = pmL / (c.fA + eps);
return {H, S, L, c.fA};
}
static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> inputFP) {
return std::unique_ptr<GrFragmentProcessor>(new GrRGBToHSLFilterEffect(std::move(inputFP)));
}
GrRGBToHSLFilterEffect(const GrRGBToHSLFilterEffect& src);
std::unique_ptr<GrFragmentProcessor> clone() const override;
const char* name() const override { return "RGBToHSLFilterEffect"; }
private:
GrRGBToHSLFilterEffect(std::unique_ptr<GrFragmentProcessor> inputFP)
: INHERITED(kGrRGBToHSLFilterEffect_ClassID,
(OptimizationFlags)ProcessorOptimizationFlags(inputFP.get()) &
(kConstantOutputForConstantInput_OptimizationFlag |
kPreservesOpaqueInput_OptimizationFlag)) {
this->registerChild(std::move(inputFP), SkSL::SampleUsage::PassThrough());
}
std::unique_ptr<GrGLSLFragmentProcessor> onMakeProgramImpl() const override;
void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
bool onIsEqual(const GrFragmentProcessor&) const override;
#if GR_TEST_UTILS
SkString onDumpInfo() const override;
#endif
GR_DECLARE_FRAGMENT_PROCESSOR_TEST
using INHERITED = GrFragmentProcessor;
};
#endif