1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2014 Google Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "src/gpu/effects/GrBicubicEffect.h" 9cb93a386Sopenharmony_ci 10cb93a386Sopenharmony_ci#include "src/core/SkMatrixPriv.h" 11cb93a386Sopenharmony_ci#include "src/gpu/GrTexture.h" 12cb93a386Sopenharmony_ci#include "src/gpu/effects/GrMatrixEffect.h" 13cb93a386Sopenharmony_ci#include "src/gpu/effects/GrTextureEffect.h" 14cb93a386Sopenharmony_ci#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h" 15cb93a386Sopenharmony_ci#include "src/gpu/glsl/GrGLSLProgramDataManager.h" 16cb93a386Sopenharmony_ci#include "src/gpu/glsl/GrGLSLUniformHandler.h" 17cb93a386Sopenharmony_ci#include <cmath> 18cb93a386Sopenharmony_ci 19cb93a386Sopenharmony_ciclass GrBicubicEffect::Impl : public ProgramImpl { 20cb93a386Sopenharmony_cipublic: 21cb93a386Sopenharmony_ci void emitCode(EmitArgs&) override; 22cb93a386Sopenharmony_ci 23cb93a386Sopenharmony_ciprivate: 24cb93a386Sopenharmony_ci void onSetData(const GrGLSLProgramDataManager&, const GrFragmentProcessor&) override; 25cb93a386Sopenharmony_ci 26cb93a386Sopenharmony_ci SkImage::CubicResampler fKernel = {-1, -1}; 27cb93a386Sopenharmony_ci UniformHandle fCoefficientUni; 28cb93a386Sopenharmony_ci}; 29cb93a386Sopenharmony_ci 30cb93a386Sopenharmony_civoid GrBicubicEffect::Impl::emitCode(EmitArgs& args) { 31cb93a386Sopenharmony_ci const GrBicubicEffect& bicubicEffect = args.fFp.cast<GrBicubicEffect>(); 32cb93a386Sopenharmony_ci 33cb93a386Sopenharmony_ci GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; 34cb93a386Sopenharmony_ci 35cb93a386Sopenharmony_ci const char* coeffs; 36cb93a386Sopenharmony_ci fCoefficientUni = args.fUniformHandler->addUniform(&args.fFp, kFragment_GrShaderFlag, 37cb93a386Sopenharmony_ci kHalf4x4_GrSLType, "coefficients", &coeffs); 38cb93a386Sopenharmony_ci // We determine our fractional offset (f) within the texel. We then snap coord to a texel 39cb93a386Sopenharmony_ci // center. The snap prevents cases where the starting coords are near a texel boundary and 40cb93a386Sopenharmony_ci // offsets with imperfect precision would cause us to skip/double hit a texel. 41cb93a386Sopenharmony_ci // The use of "texel" above is somewhat abstract as we're sampling a child processor. It is 42cb93a386Sopenharmony_ci // assumed the child processor represents something akin to a nearest neighbor sampled texture. 43cb93a386Sopenharmony_ci if (bicubicEffect.fDirection == GrBicubicEffect::Direction::kXY) { 44cb93a386Sopenharmony_ci fragBuilder->codeAppendf("float2 coord = %s - float2(0.5);", args.fSampleCoord); 45cb93a386Sopenharmony_ci fragBuilder->codeAppend("half2 f = half2(fract(coord));"); 46cb93a386Sopenharmony_ci fragBuilder->codeAppend("coord += 0.5 - f;"); 47cb93a386Sopenharmony_ci fragBuilder->codeAppendf("half4 wx = %s * half4(1.0, f.x, f.x * f.x, f.x * f.x * f.x);", 48cb93a386Sopenharmony_ci coeffs); 49cb93a386Sopenharmony_ci fragBuilder->codeAppendf("half4 wy = %s * half4(1.0, f.y, f.y * f.y, f.y * f.y * f.y);", 50cb93a386Sopenharmony_ci coeffs); 51cb93a386Sopenharmony_ci fragBuilder->codeAppend("half4 rowColors[4];"); 52cb93a386Sopenharmony_ci for (int y = 0; y < 4; ++y) { 53cb93a386Sopenharmony_ci for (int x = 0; x < 4; ++x) { 54cb93a386Sopenharmony_ci SkString coord; 55cb93a386Sopenharmony_ci coord.printf("coord + float2(%d, %d)", x - 1, y - 1); 56cb93a386Sopenharmony_ci auto childStr = 57cb93a386Sopenharmony_ci this->invokeChild(0, args, SkSL::String(coord.c_str(), coord.size())); 58cb93a386Sopenharmony_ci fragBuilder->codeAppendf("rowColors[%d] = %s;", x, childStr.c_str()); 59cb93a386Sopenharmony_ci } 60cb93a386Sopenharmony_ci fragBuilder->codeAppendf( 61cb93a386Sopenharmony_ci "half4 s%d = wx.x * rowColors[0] + wx.y * rowColors[1] + wx.z * rowColors[2] + " 62cb93a386Sopenharmony_ci "wx.w * rowColors[3];", 63cb93a386Sopenharmony_ci y); 64cb93a386Sopenharmony_ci } 65cb93a386Sopenharmony_ci fragBuilder->codeAppend( 66cb93a386Sopenharmony_ci "half4 bicubicColor = wy.x * s0 + wy.y * s1 + wy.z * s2 + wy.w * s3;"); 67cb93a386Sopenharmony_ci } else { 68cb93a386Sopenharmony_ci const char* d = bicubicEffect.fDirection == Direction::kX ? "x" : "y"; 69cb93a386Sopenharmony_ci fragBuilder->codeAppendf("float coord = %s.%s - 0.5;", args.fSampleCoord, d); 70cb93a386Sopenharmony_ci fragBuilder->codeAppend("half f = half(fract(coord));"); 71cb93a386Sopenharmony_ci fragBuilder->codeAppend("coord += 0.5 - f;"); 72cb93a386Sopenharmony_ci fragBuilder->codeAppend("half f2 = f * f;"); 73cb93a386Sopenharmony_ci fragBuilder->codeAppendf("half4 w = %s * half4(1.0, f, f2, f2 * f);", coeffs); 74cb93a386Sopenharmony_ci fragBuilder->codeAppend("half4 c[4];"); 75cb93a386Sopenharmony_ci for (int i = 0; i < 4; ++i) { 76cb93a386Sopenharmony_ci SkString coord; 77cb93a386Sopenharmony_ci if (bicubicEffect.fDirection == Direction::kX) { 78cb93a386Sopenharmony_ci coord.printf("float2(coord + %d, %s.y)", i - 1, args.fSampleCoord); 79cb93a386Sopenharmony_ci } else { 80cb93a386Sopenharmony_ci coord.printf("float2(%s.x, coord + %d)", args.fSampleCoord, i - 1); 81cb93a386Sopenharmony_ci } 82cb93a386Sopenharmony_ci auto childStr = this->invokeChild(0, args, SkSL::String(coord.c_str(), coord.size())); 83cb93a386Sopenharmony_ci fragBuilder->codeAppendf("c[%d] = %s;", i, childStr.c_str()); 84cb93a386Sopenharmony_ci } 85cb93a386Sopenharmony_ci fragBuilder->codeAppend( 86cb93a386Sopenharmony_ci "half4 bicubicColor = c[0] * w.x + c[1] * w.y + c[2] * w.z + c[3] * w.w;"); 87cb93a386Sopenharmony_ci } 88cb93a386Sopenharmony_ci // Bicubic can send colors out of range, so clamp to get them back in (source) gamut. 89cb93a386Sopenharmony_ci // The kind of clamp we have to do depends on the alpha type. 90cb93a386Sopenharmony_ci switch (bicubicEffect.fClamp) { 91cb93a386Sopenharmony_ci case Clamp::kUnpremul: 92cb93a386Sopenharmony_ci fragBuilder->codeAppend("bicubicColor = saturate(bicubicColor);"); 93cb93a386Sopenharmony_ci break; 94cb93a386Sopenharmony_ci case Clamp::kPremul: 95cb93a386Sopenharmony_ci fragBuilder->codeAppend( 96cb93a386Sopenharmony_ci "bicubicColor.rgb = max(half3(0.0), min(bicubicColor.rgb, bicubicColor.aaa));"); 97cb93a386Sopenharmony_ci break; 98cb93a386Sopenharmony_ci } 99cb93a386Sopenharmony_ci fragBuilder->codeAppendf("return bicubicColor;"); 100cb93a386Sopenharmony_ci} 101cb93a386Sopenharmony_ci 102cb93a386Sopenharmony_ci#include "src/shaders/SkImageShader.h" 103cb93a386Sopenharmony_ci 104cb93a386Sopenharmony_civoid GrBicubicEffect::Impl::onSetData(const GrGLSLProgramDataManager& pdm, 105cb93a386Sopenharmony_ci const GrFragmentProcessor& fp) { 106cb93a386Sopenharmony_ci auto& bicubicEffect = fp.cast<GrBicubicEffect>(); 107cb93a386Sopenharmony_ci 108cb93a386Sopenharmony_ci if (fKernel.B != bicubicEffect.fKernel.B || fKernel.C != bicubicEffect.fKernel.C) { 109cb93a386Sopenharmony_ci fKernel = bicubicEffect.fKernel; 110cb93a386Sopenharmony_ci pdm.setSkM44(fCoefficientUni, SkImageShader::CubicResamplerMatrix(fKernel.B, fKernel.C)); 111cb93a386Sopenharmony_ci } 112cb93a386Sopenharmony_ci} 113cb93a386Sopenharmony_ci 114cb93a386Sopenharmony_cistd::unique_ptr<GrFragmentProcessor> GrBicubicEffect::Make(GrSurfaceProxyView view, 115cb93a386Sopenharmony_ci SkAlphaType alphaType, 116cb93a386Sopenharmony_ci const SkMatrix& matrix, 117cb93a386Sopenharmony_ci SkImage::CubicResampler kernel, 118cb93a386Sopenharmony_ci Direction direction) { 119cb93a386Sopenharmony_ci auto fp = GrTextureEffect::Make(std::move(view), alphaType, SkMatrix::I()); 120cb93a386Sopenharmony_ci auto clamp = kPremul_SkAlphaType == alphaType ? Clamp::kPremul : Clamp::kUnpremul; 121cb93a386Sopenharmony_ci return GrMatrixEffect::Make(matrix, std::unique_ptr<GrFragmentProcessor>( 122cb93a386Sopenharmony_ci new GrBicubicEffect(std::move(fp), kernel, direction, clamp))); 123cb93a386Sopenharmony_ci} 124cb93a386Sopenharmony_ci 125cb93a386Sopenharmony_cistd::unique_ptr<GrFragmentProcessor> GrBicubicEffect::Make(GrSurfaceProxyView view, 126cb93a386Sopenharmony_ci SkAlphaType alphaType, 127cb93a386Sopenharmony_ci const SkMatrix& matrix, 128cb93a386Sopenharmony_ci const GrSamplerState::WrapMode wrapX, 129cb93a386Sopenharmony_ci const GrSamplerState::WrapMode wrapY, 130cb93a386Sopenharmony_ci SkImage::CubicResampler kernel, 131cb93a386Sopenharmony_ci Direction direction, 132cb93a386Sopenharmony_ci const GrCaps& caps) { 133cb93a386Sopenharmony_ci GrSamplerState sampler(wrapX, wrapY, GrSamplerState::Filter::kNearest); 134cb93a386Sopenharmony_ci std::unique_ptr<GrFragmentProcessor> fp; 135cb93a386Sopenharmony_ci fp = GrTextureEffect::Make(std::move(view), alphaType, SkMatrix::I(), sampler, caps); 136cb93a386Sopenharmony_ci auto clamp = kPremul_SkAlphaType == alphaType ? Clamp::kPremul : Clamp::kUnpremul; 137cb93a386Sopenharmony_ci return GrMatrixEffect::Make(matrix, std::unique_ptr<GrFragmentProcessor>( 138cb93a386Sopenharmony_ci new GrBicubicEffect(std::move(fp), kernel, direction, clamp))); 139cb93a386Sopenharmony_ci} 140cb93a386Sopenharmony_ci 141cb93a386Sopenharmony_cistd::unique_ptr<GrFragmentProcessor> GrBicubicEffect::MakeSubset( 142cb93a386Sopenharmony_ci GrSurfaceProxyView view, 143cb93a386Sopenharmony_ci SkAlphaType alphaType, 144cb93a386Sopenharmony_ci const SkMatrix& matrix, 145cb93a386Sopenharmony_ci const GrSamplerState::WrapMode wrapX, 146cb93a386Sopenharmony_ci const GrSamplerState::WrapMode wrapY, 147cb93a386Sopenharmony_ci const SkRect& subset, 148cb93a386Sopenharmony_ci SkImage::CubicResampler kernel, 149cb93a386Sopenharmony_ci Direction direction, 150cb93a386Sopenharmony_ci const GrCaps& caps) { 151cb93a386Sopenharmony_ci GrSamplerState sampler(wrapX, wrapY, GrSamplerState::Filter::kNearest); 152cb93a386Sopenharmony_ci std::unique_ptr<GrFragmentProcessor> fp; 153cb93a386Sopenharmony_ci fp = GrTextureEffect::MakeSubset( 154cb93a386Sopenharmony_ci std::move(view), alphaType, SkMatrix::I(), sampler, subset, caps); 155cb93a386Sopenharmony_ci auto clamp = kPremul_SkAlphaType == alphaType ? Clamp::kPremul : Clamp::kUnpremul; 156cb93a386Sopenharmony_ci return GrMatrixEffect::Make(matrix, std::unique_ptr<GrFragmentProcessor>( 157cb93a386Sopenharmony_ci new GrBicubicEffect(std::move(fp), kernel, direction, clamp))); 158cb93a386Sopenharmony_ci} 159cb93a386Sopenharmony_ci 160cb93a386Sopenharmony_cistd::unique_ptr<GrFragmentProcessor> GrBicubicEffect::MakeSubset( 161cb93a386Sopenharmony_ci GrSurfaceProxyView view, 162cb93a386Sopenharmony_ci SkAlphaType alphaType, 163cb93a386Sopenharmony_ci const SkMatrix& matrix, 164cb93a386Sopenharmony_ci const GrSamplerState::WrapMode wrapX, 165cb93a386Sopenharmony_ci const GrSamplerState::WrapMode wrapY, 166cb93a386Sopenharmony_ci const SkRect& subset, 167cb93a386Sopenharmony_ci const SkRect& domain, 168cb93a386Sopenharmony_ci SkImage::CubicResampler kernel, 169cb93a386Sopenharmony_ci Direction direction, 170cb93a386Sopenharmony_ci const GrCaps& caps) { 171cb93a386Sopenharmony_ci auto lowerBound = [](float x) { return std::floor(x - 1.5f) + 0.5f; }; 172cb93a386Sopenharmony_ci auto upperBound = [](float x) { return std::floor(x + 1.5f) - 0.5f; }; 173cb93a386Sopenharmony_ci SkRect expandedDomain { 174cb93a386Sopenharmony_ci lowerBound(domain.fLeft) , 175cb93a386Sopenharmony_ci upperBound(domain.fRight) , 176cb93a386Sopenharmony_ci lowerBound(domain.fTop) , 177cb93a386Sopenharmony_ci upperBound(domain.fBottom) 178cb93a386Sopenharmony_ci }; 179cb93a386Sopenharmony_ci GrSamplerState sampler(wrapX, wrapY, GrSamplerState::Filter::kNearest); 180cb93a386Sopenharmony_ci std::unique_ptr<GrFragmentProcessor> fp; 181cb93a386Sopenharmony_ci fp = GrTextureEffect::MakeSubset( 182cb93a386Sopenharmony_ci std::move(view), alphaType, SkMatrix::I(), sampler, subset, expandedDomain, caps); 183cb93a386Sopenharmony_ci auto clamp = kPremul_SkAlphaType == alphaType ? Clamp::kPremul : Clamp::kUnpremul; 184cb93a386Sopenharmony_ci return GrMatrixEffect::Make(matrix, std::unique_ptr<GrFragmentProcessor>( 185cb93a386Sopenharmony_ci new GrBicubicEffect(std::move(fp), kernel, direction, clamp))); 186cb93a386Sopenharmony_ci} 187cb93a386Sopenharmony_ci 188cb93a386Sopenharmony_cistd::unique_ptr<GrFragmentProcessor> GrBicubicEffect::Make(std::unique_ptr<GrFragmentProcessor> fp, 189cb93a386Sopenharmony_ci SkAlphaType alphaType, 190cb93a386Sopenharmony_ci const SkMatrix& matrix, 191cb93a386Sopenharmony_ci SkImage::CubicResampler kernel, 192cb93a386Sopenharmony_ci Direction direction) { 193cb93a386Sopenharmony_ci auto clamp = kPremul_SkAlphaType == alphaType ? Clamp::kPremul : Clamp::kUnpremul; 194cb93a386Sopenharmony_ci return GrMatrixEffect::Make(matrix, std::unique_ptr<GrFragmentProcessor>( 195cb93a386Sopenharmony_ci new GrBicubicEffect(std::move(fp), kernel, direction, clamp))); 196cb93a386Sopenharmony_ci} 197cb93a386Sopenharmony_ci 198cb93a386Sopenharmony_ciGrBicubicEffect::GrBicubicEffect(std::unique_ptr<GrFragmentProcessor> fp, 199cb93a386Sopenharmony_ci SkImage::CubicResampler kernel, 200cb93a386Sopenharmony_ci Direction direction, 201cb93a386Sopenharmony_ci Clamp clamp) 202cb93a386Sopenharmony_ci : INHERITED(kGrBicubicEffect_ClassID, ProcessorOptimizationFlags(fp.get())) 203cb93a386Sopenharmony_ci , fKernel(kernel) 204cb93a386Sopenharmony_ci , fDirection(direction) 205cb93a386Sopenharmony_ci , fClamp(clamp) { 206cb93a386Sopenharmony_ci this->setUsesSampleCoordsDirectly(); 207cb93a386Sopenharmony_ci this->registerChild(std::move(fp), SkSL::SampleUsage::Explicit()); 208cb93a386Sopenharmony_ci} 209cb93a386Sopenharmony_ci 210cb93a386Sopenharmony_ciGrBicubicEffect::GrBicubicEffect(const GrBicubicEffect& that) 211cb93a386Sopenharmony_ci : INHERITED(that) 212cb93a386Sopenharmony_ci , fKernel(that.fKernel) 213cb93a386Sopenharmony_ci , fDirection(that.fDirection) 214cb93a386Sopenharmony_ci , fClamp(that.fClamp) {} 215cb93a386Sopenharmony_ci 216cb93a386Sopenharmony_ciSkString GrBicubicEffect::getShaderDfxInfo() const 217cb93a386Sopenharmony_ci{ 218cb93a386Sopenharmony_ci SkString format; 219cb93a386Sopenharmony_ci format.printf("ShaderDfx_GrBicubicEffect_%d_%d", fDirection, fClamp); 220cb93a386Sopenharmony_ci return format; 221cb93a386Sopenharmony_ci} 222cb93a386Sopenharmony_ci 223cb93a386Sopenharmony_civoid GrBicubicEffect::onAddToKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const { 224cb93a386Sopenharmony_ci uint32_t key = (static_cast<uint32_t>(fDirection) << 0) | (static_cast<uint32_t>(fClamp) << 2); 225cb93a386Sopenharmony_ci b->add32(key); 226cb93a386Sopenharmony_ci} 227cb93a386Sopenharmony_ci 228cb93a386Sopenharmony_cistd::unique_ptr<GrFragmentProcessor::ProgramImpl> GrBicubicEffect::onMakeProgramImpl() const { 229cb93a386Sopenharmony_ci return std::make_unique<Impl>(); 230cb93a386Sopenharmony_ci} 231cb93a386Sopenharmony_ci 232cb93a386Sopenharmony_cibool GrBicubicEffect::onIsEqual(const GrFragmentProcessor& other) const { 233cb93a386Sopenharmony_ci const auto& that = other.cast<GrBicubicEffect>(); 234cb93a386Sopenharmony_ci return fDirection == that.fDirection && 235cb93a386Sopenharmony_ci fClamp == that.fClamp && 236cb93a386Sopenharmony_ci fKernel.B == that.fKernel.B && 237cb93a386Sopenharmony_ci fKernel.C == that.fKernel.C; 238cb93a386Sopenharmony_ci} 239cb93a386Sopenharmony_ci 240cb93a386Sopenharmony_ciSkPMColor4f GrBicubicEffect::constantOutputForConstantInput(const SkPMColor4f& input) const { 241cb93a386Sopenharmony_ci return GrFragmentProcessor::ConstantOutputForConstantInput(this->childProcessor(0), input); 242cb93a386Sopenharmony_ci} 243cb93a386Sopenharmony_ci 244cb93a386Sopenharmony_ciGR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrBicubicEffect); 245cb93a386Sopenharmony_ci 246cb93a386Sopenharmony_ci#if GR_TEST_UTILS 247cb93a386Sopenharmony_cistd::unique_ptr<GrFragmentProcessor> GrBicubicEffect::TestCreate(GrProcessorTestData* d) { 248cb93a386Sopenharmony_ci Direction direction = Direction::kX; 249cb93a386Sopenharmony_ci switch (d->fRandom->nextULessThan(3)) { 250cb93a386Sopenharmony_ci case 0: 251cb93a386Sopenharmony_ci direction = Direction::kX; 252cb93a386Sopenharmony_ci break; 253cb93a386Sopenharmony_ci case 1: 254cb93a386Sopenharmony_ci direction = Direction::kY; 255cb93a386Sopenharmony_ci break; 256cb93a386Sopenharmony_ci case 2: 257cb93a386Sopenharmony_ci direction = Direction::kXY; 258cb93a386Sopenharmony_ci break; 259cb93a386Sopenharmony_ci } 260cb93a386Sopenharmony_ci auto kernel = d->fRandom->nextBool() ? GrBicubicEffect::gMitchell 261cb93a386Sopenharmony_ci : GrBicubicEffect::gCatmullRom; 262cb93a386Sopenharmony_ci auto m = GrTest::TestMatrix(d->fRandom); 263cb93a386Sopenharmony_ci switch (d->fRandom->nextULessThan(3)) { 264cb93a386Sopenharmony_ci case 0: { 265cb93a386Sopenharmony_ci auto [view, ct, at] = d->randomView(); 266cb93a386Sopenharmony_ci GrSamplerState::WrapMode wm[2]; 267cb93a386Sopenharmony_ci GrTest::TestWrapModes(d->fRandom, wm); 268cb93a386Sopenharmony_ci 269cb93a386Sopenharmony_ci if (d->fRandom->nextBool()) { 270cb93a386Sopenharmony_ci SkRect subset; 271cb93a386Sopenharmony_ci subset.fLeft = d->fRandom->nextSScalar1() * view.width(); 272cb93a386Sopenharmony_ci subset.fTop = d->fRandom->nextSScalar1() * view.height(); 273cb93a386Sopenharmony_ci subset.fRight = d->fRandom->nextSScalar1() * view.width(); 274cb93a386Sopenharmony_ci subset.fBottom = d->fRandom->nextSScalar1() * view.height(); 275cb93a386Sopenharmony_ci subset.sort(); 276cb93a386Sopenharmony_ci return MakeSubset(std::move(view), 277cb93a386Sopenharmony_ci at, 278cb93a386Sopenharmony_ci m, 279cb93a386Sopenharmony_ci wm[0], 280cb93a386Sopenharmony_ci wm[1], 281cb93a386Sopenharmony_ci subset, 282cb93a386Sopenharmony_ci kernel, 283cb93a386Sopenharmony_ci direction, 284cb93a386Sopenharmony_ci *d->caps()); 285cb93a386Sopenharmony_ci } 286cb93a386Sopenharmony_ci return Make(std::move(view), at, m, wm[0], wm[1], kernel, direction, *d->caps()); 287cb93a386Sopenharmony_ci } 288cb93a386Sopenharmony_ci case 1: { 289cb93a386Sopenharmony_ci auto [view, ct, at] = d->randomView(); 290cb93a386Sopenharmony_ci return Make(std::move(view), at, m, kernel, direction); 291cb93a386Sopenharmony_ci } 292cb93a386Sopenharmony_ci default: { 293cb93a386Sopenharmony_ci SkAlphaType at; 294cb93a386Sopenharmony_ci do { 295cb93a386Sopenharmony_ci at = static_cast<SkAlphaType>(d->fRandom->nextULessThan(kLastEnum_SkAlphaType + 1)); 296cb93a386Sopenharmony_ci } while (at == kUnknown_SkAlphaType); 297cb93a386Sopenharmony_ci return Make(GrProcessorUnitTest::MakeChildFP(d), at, m, kernel, direction); 298cb93a386Sopenharmony_ci } 299cb93a386Sopenharmony_ci } 300cb93a386Sopenharmony_ci} 301cb93a386Sopenharmony_ci#endif 302