59 fragBuilder->codeAppendf(
"float2 coord = %s - float2(0.5);",
args.fSampleCoord);
60 fragBuilder->codeAppend(
"half2 f = half2(fract(coord));");
61 fragBuilder->codeAppend(
"coord += 0.5 - f;");
62 fragBuilder->codeAppendf(
"half4 wx = %s * half4(1.0, f.x, f.x * f.x, f.x * f.x * f.x);",
64 fragBuilder->codeAppendf(
"half4 wy = %s * half4(1.0, f.y, f.y * f.y, f.y * f.y * f.y);",
66 fragBuilder->codeAppend(
"half4 rowColors[4];");
67 for (
int y = 0;
y < 4; ++
y) {
68 for (
int x = 0;
x < 4; ++
x) {
71 fragBuilder->codeAppendf(
"rowColors[%d] = %s;",
x, childStr.c_str());
73 fragBuilder->codeAppendf(
74 "half4 s%d = wx.x * rowColors[0] + wx.y * rowColors[1] + wx.z * rowColors[2] + "
75 "wx.w * rowColors[3];",
78 fragBuilder->codeAppend(
79 "half4 bicubicColor = wy.x * s0 + wy.y * s1 + wy.z * s2 + wy.w * s3;");
81 const char*
d = bicubicEffect.fDirection ==
Direction::kX ?
"x" :
"y";
82 fragBuilder->codeAppendf(
"float coord = %s.%s - 0.5;",
args.fSampleCoord,
d);
83 fragBuilder->codeAppend(
"half f = half(fract(coord));");
84 fragBuilder->codeAppend(
"coord += 0.5 - f;");
85 fragBuilder->codeAppend(
"half f2 = f * f;");
86 fragBuilder->codeAppendf(
"half4 w = %s * half4(1.0, f, f2, f2 * f);",
coeffs);
87 fragBuilder->codeAppend(
"half4 c[4];");
88 for (
int i = 0;
i < 4; ++
i) {
96 fragBuilder->codeAppendf(
"c[%d] = %s;",
i, childStr.c_str());
98 fragBuilder->codeAppend(
99 "half4 bicubicColor = c[0] * w.x + c[1] * w.y + c[2] * w.z + c[3] * w.w;");
103 switch (bicubicEffect.fClamp) {
104 case Clamp::kUnpremul:
105 fragBuilder->codeAppend(
"bicubicColor = saturate(bicubicColor);");
108 fragBuilder->codeAppend(
"bicubicColor.a = saturate(bicubicColor.a);");
109 fragBuilder->codeAppend(
110 "bicubicColor.rgb = max(half3(0.0), min(bicubicColor.rgb, bicubicColor.aaa));");
113 fragBuilder->codeAppendf(
"return bicubicColor;");
120 if (fKernel.
B != bicubicEffect.fKernel.B || fKernel.
C != bicubicEffect.fKernel.C) {
121 fKernel = bicubicEffect.fKernel;
146 std::unique_ptr<GrFragmentProcessor>
fp;
164 std::unique_ptr<GrFragmentProcessor>
fp;
166 std::move(view), alphaType,
SkMatrix::I(), sampler, subset, caps);
183 auto lowerBound = [](
float x) {
return std::floor(
x - 1.5f) + 0.5f; };
184 auto upperBound = [](
float x) {
return std::floor(
x + 1.5f) - 0.5f; };
186 lowerBound(domain.
fLeft) ,
187 upperBound(domain.
fRight) ,
188 lowerBound(domain.
fTop) ,
192 std::unique_ptr<GrFragmentProcessor>
fp;
194 std::move(view), alphaType,
SkMatrix::I(), sampler, subset, expandedDomain, caps);
210GrBicubicEffect::GrBicubicEffect(std::unique_ptr<GrFragmentProcessor>
fp,
216 , fDirection(direction)
224 , fKernel(that.fKernel)
225 , fDirection(that.fDirection)
226 , fClamp(that.fClamp) {}
229 uint32_t
key = (
static_cast<uint32_t
>(fDirection) << 0) | (
static_cast<uint32_t
>(fClamp) << 2);
233std::unique_ptr<GrFragmentProcessor::ProgramImpl> GrBicubicEffect::onMakeProgramImpl()
const {
234 return std::make_unique<Impl>();
239 return fDirection == that.fDirection &&
240 fClamp == that.fClamp &&
241 fKernel.
B == that.fKernel.B &&
242 fKernel.
C == that.fKernel.C;
251#if defined(GR_TEST_UTILS)
252std::unique_ptr<GrFragmentProcessor> GrBicubicEffect::TestCreate(GrProcessorTestData*
d) {
254 switch (
d->fRandom->nextULessThan(3)) {
267 auto m = GrTest::TestMatrix(
d->fRandom);
268 switch (
d->fRandom->nextULessThan(3)) {
270 auto [view, ct, at] =
d->randomView();
272 GrTest::TestWrapModes(
d->fRandom, wm);
274 if (
d->fRandom->nextBool()) {
276 subset.
fLeft =
d->fRandom->nextSScalar1() * view.width();
277 subset.
fTop =
d->fRandom->nextSScalar1() * view.height();
278 subset.
fRight =
d->fRandom->nextSScalar1() * view.width();
279 subset.
fBottom =
d->fRandom->nextSScalar1() * view.height();
291 return Make(std::move(view), at,
m, wm[0], wm[1], kernel, direction, *
d->caps());
294 auto [view, ct, at] =
d->randomView();
295 return Make(std::move(view), at,
m, kernel, direction);
#define GR_DEFINE_FRAGMENT_PROCESSOR_TEST(...)
@ kUnknown_SkAlphaType
uninitialized
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
@ kLastEnum_SkAlphaType
last valid value
static unsigned clamp(SkFixed fx, int max)
#define INHERITED(method,...)
void emitCode(EmitArgs &) override
static std::unique_ptr< GrFragmentProcessor > Make(GrSurfaceProxyView view, SkAlphaType, const SkMatrix &, SkCubicResampler, Direction)
static constexpr SkCubicResampler gCatmullRom
static std::unique_ptr< GrFragmentProcessor > MakeSubset(GrSurfaceProxyView view, SkAlphaType, const SkMatrix &, const GrSamplerState::WrapMode wrapX, const GrSamplerState::WrapMode wrapY, const SkRect &subset, SkCubicResampler, Direction, const GrCaps &)
static constexpr SkCubicResampler gMitchell
GrGLSLUniformHandler::UniformHandle UniformHandle
SkString invokeChild(int childIndex, EmitArgs &parentArgs, std::string_view skslCoords={})
static OptimizationFlags ProcessorOptimizationFlags(const GrFragmentProcessor *fp)
GrFragmentProcessor * childProcessor(int index)
void registerChild(std::unique_ptr< GrFragmentProcessor > child, SkSL::SampleUsage sampleUsage=SkSL::SampleUsage::PassThrough())
void setUsesSampleCoordsDirectly()
static SkPMColor4f ConstantOutputForConstantInput(const GrFragmentProcessor *fp, const SkPMColor4f &input)
void setSkM44(UniformHandle, const SkM44 &) const
static std::unique_ptr< GrFragmentProcessor > Make(const SkMatrix &matrix, std::unique_ptr< GrFragmentProcessor > child)
@ kGrBicubicEffect_ClassID
static std::unique_ptr< GrFragmentProcessor > MakeSubset(GrSurfaceProxyView, SkAlphaType, const SkMatrix &, GrSamplerState, const SkRect &subset, const GrCaps &caps, const float border[4]=kDefaultBorder, bool alwaysUseShaderTileMode=false)
static std::unique_ptr< GrFragmentProcessor > Make(GrSurfaceProxyView, SkAlphaType, const SkMatrix &=SkMatrix::I(), GrSamplerState::Filter=GrSamplerState::Filter::kNearest, GrSamplerState::MipmapMode mipmapMode=GrSamplerState::MipmapMode::kNone)
static SkM44 CubicResamplerMatrix(float B, float C)
static const SkMatrix & I()
static SampleUsage Explicit()
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE auto & d
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
GrFPResult MakeChildFP(const SkRuntimeEffect::ChildPtr &child, const GrFPArgs &childArgs)
unsigned useCenter Optional< SkMatrix > matrix
std::string printf(const char *fmt,...) SK_PRINTF_LIKE(1
const myers::Point & get(const myers::Segment &)
SIN Vec< N, float > floor(const Vec< N, float > &x)
SkScalar fBottom
larger y-axis bounds
SkScalar fLeft
smaller x-axis bounds
SkScalar fRight
larger x-axis bounds
SkScalar fTop
smaller y-axis bounds