skia2/fuzz/oss_fuzz/FuzzSKSL2Pipeline.cpp
Brian Osman adadb95a9f Better first-class shader & color filter support in runtime effects
This does a few things, because they're all intertwined:

1) SkRuntimeEffect's API now includes details about children (which Skia
   stage was declared, not just the name). The factories verify that the
   declared types in the SkSL match up with the C++ types being passed.
   Today, we still only support adding children of the same type, so the
   checks are simple. Once we allow mixing types, we'll be testing the
   declared type against the actual C++ type supplied for each slot.
2) Adds sample variants that supply the input color to the child. This
   is now the only way to invoke a colorFilter child. Internally, we
   support passing a color when invoking a child shader, but I'm not
   exposing that. It's not clearly part of the semantics of the Skia
   pipeline, and is almost never useful. It also exposes users to
   several inconsistencies (skbug.com/11942).
3) Because of #2, it's possible that we can't compute a reusable program
   to filter individual colors. In that case, we don't set the constant
   output for constant input optimization, and filterColor4f falls back
   to the slower base-class implementation.

Bug: skia:11813 skia:11942
Change-Id: I06c41e1b35056e486f3163a72acf6b9535d7fed4
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/401917
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Mike Klein <mtklein@google.com>
2021-05-04 01:29:57 +00:00

68 lines
2.2 KiB
C++

/*
* Copyright 2019 Google, LLC
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "src/gpu/GrShaderCaps.h"
#include "src/sksl/SkSLCompiler.h"
#include "src/sksl/codegen/SkSLPipelineStageCodeGenerator.h"
#include "src/sksl/ir/SkSLVarDeclarations.h"
#include "src/sksl/ir/SkSLVariable.h"
#include "fuzz/Fuzz.h"
bool FuzzSKSL2Pipeline(sk_sp<SkData> bytes) {
sk_sp<GrShaderCaps> caps = SkSL::ShaderCapsFactory::Default();
SkSL::Compiler compiler(caps.get());
SkSL::Program::Settings settings;
std::unique_ptr<SkSL::Program> program = compiler.convertProgram(
SkSL::ProgramKind::kRuntimeShader,
SkSL::String((const char*) bytes->data(),
bytes->size()),
settings);
if (!program) {
return false;
}
class Callbacks : public SkSL::PipelineStage::Callbacks {
using String = SkSL::String;
String declareUniform(const SkSL::VarDeclaration* decl) override {
return decl->var().name();
}
void defineFunction(const char* /*decl*/, const char* /*body*/, bool /*isMain*/) override {}
void defineStruct(const char* /*definition*/) override {}
void declareGlobal(const char* /*declaration*/) override {}
String sampleChild(int index, String coords, String color) override {
String result = "sample(" + SkSL::to_string(index);
if (!coords.empty()) {
result += ", " + coords;
}
if (!color.empty()) {
result += ", " + color;
}
result += ")";
return result;
}
};
Callbacks callbacks;
SkSL::PipelineStage::ConvertProgram(*program, "coords", "inColor", &callbacks);
return true;
}
#if defined(SK_BUILD_FOR_LIBFUZZER)
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
if (size > 3000) {
return 0;
}
auto bytes = SkData::MakeWithoutCopy(data, size);
FuzzSKSL2Pipeline(bytes);
return 0;
}
#endif