60 const char* inputColor,
62 const uint8_t* uniformData,
66 , fInputColor(inputColor)
68 , fUniformData(uniformData)
69 , fSpecialized(specialized) {}
77 return std::string(var->
name());
81 size_t sizeInBytes =
type->slotCount() *
sizeof(
float);
82 const float* floatData =
reinterpret_cast<const float*
>(fUniformData);
83 const int* intData =
reinterpret_cast<const int*
>(fUniformData);
84 fUniformData += sizeInBytes;
87 if (
type->isArray()) {
96 SkASSERTF(!isArray,
"specializing array uniforms is not allowed");
101 size_t slots =
type->slotCount();
102 for (
size_t i = 0;
i < slots; ++
i) {
111 const char* uniformName =
nullptr;
113 fArgs.fUniformHandler->addUniformArray(&fArgs.fFp.cast<
GrSkSLFP>(),
119 fSelf->fUniformHandles.push_back(handle);
120 return std::string(uniformName);
123 std::string getMangledName(
const char*
name)
override {
124 return std::string(fArgs.fFragBuilder->getMangledFunctionName(
name).c_str());
127 void defineFunction(
const char* decl,
const char* body,
bool isMain)
override {
129 fArgs.fFragBuilder->codeAppend(body);
131 fArgs.fFragBuilder->emitFunction(decl, body);
135 void declareFunction(
const char* decl)
override {
136 fArgs.fFragBuilder->emitFunctionPrototype(decl);
139 void defineStruct(
const char* definition)
override {
140 fArgs.fFragBuilder->definitionAppend(definition);
143 void declareGlobal(
const char* declaration)
override {
144 fArgs.fFragBuilder->definitionAppend(declaration);
147 std::string sampleShader(
int index, std::string coords)
override {
164 return child ? std::string(fSelf->invokeChild(index, fInputColor, fArgs, coords)
166 : std::string(
"half4(0)");
169 std::string sampleColorFilter(
int index, std::string
color)
override {
170 return std::string(fSelf->invokeChild(index,
176 std::string sampleBlender(
int index, std::string
src, std::string
dst)
override {
177 if (!fSelf->childProcessor(index)) {
181 fSelf->invokeChild(index,
src.c_str(),
dst.c_str(), fArgs).c_str());
186 std::string toLinearSrgb(std::string
color)
override {
188 if (
fp.fToLinearSrgbChildIndex < 0) {
192 SkString xformedColor = fSelf->invokeChild(
193 fp.fToLinearSrgbChildIndex,
color.c_str(), fArgs);
197 std::string fromLinearSrgb(std::string
color)
override {
199 if (
fp.fFromLinearSrgbChildIndex < 0) {
203 SkString xformedColor = fSelf->invokeChild(
204 fp.fFromLinearSrgbChildIndex,
color.c_str(), fArgs);
210 const char* fInputColor;
212 const uint8_t* fUniformData;
214 int fUniformIndex = 0;
219 if (
fp.fInputChildIndex >= 0) {
220 args.fFragBuilder->codeAppendf(
"%s = %s;\n",
222 this->invokeChild(
fp.fInputChildIndex,
args).c_str());
225 if (
fp.fEffect->allowBlender()) {
228 if (
fp.fDestColorChildIndex >= 0) {
229 args.fFragBuilder->codeAppendf(
232 this->invokeChild(
fp.fDestColorChildIndex,
args.fDestColor,
args).c_str());
244 if (
fp.fEffect->samplesOutsideMain()) {
245 GrShaderVar inputColorCopy(
args.fFragBuilder->getMangledFunctionName(
"inColor"),
247 args.fFragBuilder->declareGlobal(inputColorCopy);
248 inputColorName = inputColorCopy.
getName();
249 args.fFragBuilder->codeAppendf(
"%s = %s;\n", inputColorName.
c_str(),
args.fInputColor);
251 inputColorName =
args.fFragBuilder->newTmpVarName(
"inColor");
252 args.fFragBuilder->codeAppendf(
253 "half4 %s = %s;\n", inputColorName.
c_str(),
args.fInputColor);
258 const char* coords =
"float2(0)";
260 if (
fp.usesSampleCoordsDirectly()) {
261 coordsVarName =
args.fFragBuilder->newTmpVarName(
"coords");
262 coords = coordsVarName.
c_str();
263 args.fFragBuilder->codeAppendf(
"float2 %s = %s;\n", coords,
args.fSampleCoord);
266 FPCallbacks callbacks(
this,
268 inputColorName.
c_str(),
273 program, coords,
args.fInputColor,
args.fDestColor, &callbacks);
282 SkSpan(outer.specialized(), outer.uniformCount()),
283 outer.uniformData());
286 std::vector<UniformHandle> fUniformHandles;
293 std::unique_ptr<GrFragmentProcessor> inputFP,
294 std::unique_ptr<GrFragmentProcessor> destColorFP,
296 SkSpan<std::unique_ptr<GrFragmentProcessor>> childFPs) {
300 size_t uniformSize = uniforms->
size();
302 std::unique_ptr<GrSkSLFP>
fp(
new (uniformSize + specializedSize)
305 for (
auto& childFP : childFPs) {
306 fp->addChild(std::move(childFP),
true);
309 fp->setInput(std::move(inputFP));
312 fp->setDestColorFP(std::move(destColorFP));
314 if (
fp->fEffect->usesColorTransform() && dstColorSpace) {
315 fp->addColorTransformChildren(dstColorSpace.
get());
330 :
INHERITED(kGrSkSLFP_ClassID, DetermineOptimizationFlags(optFlags, effect.
get()))
331 , fEffect(
std::move(effect))
333 , fUniformSize(
SkToU32(fEffect->uniformSize())) {
335 if (fEffect->usesSampleCoords()) {
343GrSkSLFP::GrSkSLFP(
const GrSkSLFP& other)
345 , fEffect(other.fEffect)
347 , fUniformSize(other.fUniformSize)
348 , fInputChildIndex(other.fInputChildIndex)
349 , fDestColorChildIndex(other.fDestColorChildIndex)
350 , fToLinearSrgbChildIndex(other.fToLinearSrgbChildIndex)
351 , fFromLinearSrgbChildIndex(other.fFromLinearSrgbChildIndex) {
352 std::copy_n(other.specialized(), this->uniformCount(), this->specialized());
356void GrSkSLFP::addChild(std::unique_ptr<GrFragmentProcessor> child,
bool mergeOptFlags) {
357 SkASSERTF(fInputChildIndex == -1,
"all addChild calls must happen before setInput");
358 SkASSERTF(fDestColorChildIndex == -1,
"all addChild calls must happen before setDestColorFP");
360 SkASSERT((
size_t)childIndex < fEffect->fSampleUsages.size());
365 this->
registerChild(std::move(child), fEffect->fSampleUsages[childIndex]);
368void GrSkSLFP::setInput(std::unique_ptr<GrFragmentProcessor> input) {
369 SkASSERTF(fInputChildIndex == -1,
"setInput should not be called more than once");
371 SkASSERT((
size_t)fInputChildIndex >= fEffect->fSampleUsages.size());
376void GrSkSLFP::setDestColorFP(std::unique_ptr<GrFragmentProcessor> destColorFP) {
378 SkASSERTF(fDestColorChildIndex == -1,
"setDestColorFP should not be called more than once");
380 SkASSERT((
size_t)fDestColorChildIndex >= fEffect->fSampleUsages.size());
385void GrSkSLFP::addColorTransformChildren(
SkColorSpace* dstColorSpace) {
386 SkASSERTF(fToLinearSrgbChildIndex == -1 && fFromLinearSrgbChildIndex == -1,
387 "addColorTransformChildren should not be called more than once");
404 SkASSERT((
size_t)fToLinearSrgbChildIndex >= fEffect->fSampleUsages.size());
408 SkASSERT((
size_t)fFromLinearSrgbChildIndex >= fEffect->fSampleUsages.size());
412std::unique_ptr<GrFragmentProcessor::ProgramImpl> GrSkSLFP::onMakeProgramImpl()
const {
413 return std::make_unique<Impl>();
420 b->add32(fEffect->hash());
421 b->add32(fUniformSize);
423 const Specialized* specialized = this->specialized();
424 const uint8_t* uniformData = this->uniformData();
425 size_t uniformCount = this->uniformCount();
426 auto iter = fEffect->
uniforms().begin();
428 for (
size_t i = 0;
i < uniformCount; ++
i, ++iter) {
430 b->addBool(specialize,
"specialize");
432 b->addBytes(iter->sizeInBytes(), uniformData + iter->offset, iter->name);
439 const size_t specializedSize = this->uniformCount() *
sizeof(Specialized);
440 return fEffect->hash() == sk.fEffect->hash() &&
441 this->uniformCount() == sk.uniformCount() &&
442 fUniformSize == sk.fUniformSize &&
445 fUniformSize + specializedSize);
449 return std::unique_ptr<GrFragmentProcessor>(
new (UniformPayloadSize(fEffect.
get()))
460 bool appendShader(
int index)
override {
461 SkDEBUGFAIL(
"constant-output-for-constant-input unsupported when child shaders present");
464 bool appendColorFilter(
int index)
override {
465 SkDEBUGFAIL(
"constant-output-for-constant-input unsupported when child shaders present");
468 bool appendBlender(
int index)
override {
469 SkDEBUGFAIL(
"constant-output-for-constant-input unsupported when child shaders present");
472 void toLinearSrgb(
const void*
color)
override { }
473 void fromLinearSrgb(
const void*
color)
override { }
479 fUniformSize /
sizeof(
float)};
482 pipeline.appendConstantColor(&alloc,
color.vec());
483 ConstantOutputForConstantInput_SkRPCallbacks callbacks;
484 if (program->appendStages(&pipeline, &alloc, &callbacks, uniforms)) {
487 pipeline.append(SkRasterPipelineOp::store_f32, &outputCtx);
488 pipeline.run(0, 0, 1, 1);
501#if defined(GR_TEST_UTILS)
503std::unique_ptr<GrFragmentProcessor> GrSkSLFP::TestCreate(GrProcessorTestData*
d) {
506 c =
d->fRandom->nextU();
511 d->context(), filter.get(),
nullptr,
GrColorInfo{}, props);
513 return std::move(
fp);
SkAssertResult(font.textToGlyphs("Hello", 5, SkTextEncoding::kUTF8, glyphs, std::size(glyphs))==count)
#define GR_DEFINE_FRAGMENT_PROCESSOR_TEST(...)
#define SkDEBUGFAIL(message)
#define SkASSERTF(cond, fmt,...)
SkColorSpace * sk_srgb_linear_singleton()
static void * sk_careful_memcpy(void *dst, const void *src, size_t len)
static int sk_careful_memcmp(const void *a, const void *b, size_t len)
#define INHERITED(method,...)
const char * SkSLTypeString(SkSLType t)
static constexpr bool SkSLTypeIsFloatType(SkSLType type)
SkSpan(Container &&) -> SkSpan< std::remove_pointer_t< decltype(std::data(std::declval< Container >()))> >
constexpr uint32_t SkToU32(S x)
void clearConstantOutputForConstantInputFlag()
static OptimizationFlags ProcessorOptimizationFlags(const GrFragmentProcessor *fp)
int numChildProcessors() const
void mergeOptimizationFlags(OptimizationFlags flags)
GrFragmentProcessor * childProcessor(int index)
void registerChild(std::unique_ptr< GrFragmentProcessor > child, SkSL::SampleUsage sampleUsage=SkSL::SampleUsage::PassThrough())
void setIsBlendFunction()
const SkSL::SampleUsage & sampleUsage() const
void setUsesSampleCoordsDirectly()
@ kConstantOutputForConstantInput_OptimizationFlag
static SkPMColor4f ConstantOutputForConstantInput(const GrFragmentProcessor *fp, const SkPMColor4f &input)
void setRuntimeEffectUniforms(SkSpan< const SkRuntimeEffect::Uniform >, SkSpan< const UniformHandle >, SkSpan< const Specialized >, const void *src) const
const SkString & getName() const
void emitCode(EmitArgs &args) override
std::unique_ptr< GrFragmentProcessor > clone() const override
static std::unique_ptr< GrSkSLFP > MakeWithData(sk_sp< SkRuntimeEffect > effect, const char *name, sk_sp< SkColorSpace > dstColorSpace, std::unique_ptr< GrFragmentProcessor > inputFP, std::unique_ptr< GrFragmentProcessor > destColorFP, const sk_sp< const SkData > &uniforms, SkSpan< std::unique_ptr< GrFragmentProcessor > > childFPs)
const char * name() const override
const void * data() const
static sk_sp< SkColorFilter > MakeWithSkColors(const SkColor[kNumColors])
static constexpr int kNumColors
static bool SupportsConstantOutputForConstantInput(const SkRuntimeEffect *effect)
size_t uniformSize() const
bool allowBlender() const
SkSpan< const Uniform > uniforms() const
bool isPassThrough() const
static SampleUsage PassThrough()
std::string_view name() const
const Type & type() const
bool isEffectChild() const
virtual int columns() const
const char * c_str() const
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE auto & d
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
std::unique_ptr< GrFragmentProcessor > Make(const SkMaskFilter *maskfilter, const GrFPArgs &args, const SkMatrix &ctm)
PODArray< SkColor > colors
void ConvertProgram(const Program &program, const char *sampleCoords, const char *inputColor, const char *destColor, Callbacks *callbacks)
std::string printf(const char *fmt,...) SK_PRINTF_LIKE(1
bool type_to_sksltype(const Context &context, const Type &type, SkSLType *outType)
DEF_SWITCHES_START aot vmservice shared library name
const myers::Point & get(const myers::Segment &)
std::string to_string(float value)
static SkString to_string(int n)