Add coord transform to GrSKSLFP, support CTM/local matrix in runtime shaders

Change-Id: Ib44f08f4e958782cd5eb8461ef18305c14b1cde7
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/233983
Reviewed-by: Mike Klein <mtklein@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
This commit is contained in:
Brian Osman 2019-08-12 15:12:14 -04:00 committed by Skia Commit-Bot
parent 2e1142cc32
commit 3b1e4c268a
5 changed files with 49 additions and 12 deletions

View File

@ -166,6 +166,9 @@ public:
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
int substringStartIndex = 0;
int formatArgIndex = 0;
SkString coords = args.fTransformedCoords.count()
? fragBuilder->ensureCoords2D(args.fTransformedCoords[0])
: SkString("sk_FragCoord");
for (size_t i = 0; i < fGLSL.length(); ++i) {
char c = fGLSL[i];
if (c == '%') {
@ -183,6 +186,12 @@ public:
case SkSL::Compiler::FormatArg::Kind::kOutput:
fragBuilder->codeAppend(args.fOutputColor);
break;
case SkSL::Compiler::FormatArg::Kind::kCoordX:
fragBuilder->codeAppendf("%s.x", coords.c_str());
break;
case SkSL::Compiler::FormatArg::Kind::kCoordY:
fragBuilder->codeAppendf("%s.y", coords.c_str());
break;
case SkSL::Compiler::FormatArg::Kind::kUniform:
fragBuilder->codeAppend(args.fUniformHandler->getUniformCStr(
fUniformHandles[arg.fIndex]));
@ -273,25 +282,27 @@ public:
std::unique_ptr<GrSkSLFP> GrSkSLFP::Make(GrContext_Base* context, int index, const char* name,
const char* sksl, const void* inputs,
size_t inputSize, SkSL::Program::Kind kind) {
size_t inputSize, SkSL::Program::Kind kind,
const SkMatrix* matrix) {
return std::unique_ptr<GrSkSLFP>(new GrSkSLFP(context->priv().fpFactoryCache(),
context->priv().caps()->shaderCaps(),
kind, index, name, sksl, SkString(),
inputs, inputSize));
inputs, inputSize, matrix));
}
std::unique_ptr<GrSkSLFP> GrSkSLFP::Make(GrContext_Base* context, int index, const char* name,
SkString sksl, const void* inputs, size_t inputSize,
SkSL::Program::Kind kind) {
SkSL::Program::Kind kind, const SkMatrix* matrix) {
return std::unique_ptr<GrSkSLFP>(new GrSkSLFP(context->priv().fpFactoryCache(),
context->priv().caps()->shaderCaps(),
kind, index, name, nullptr, std::move(sksl),
inputs, inputSize));
inputs, inputSize, matrix));
}
GrSkSLFP::GrSkSLFP(sk_sp<GrSkSLFPFactoryCache> factoryCache, const GrShaderCaps* shaderCaps,
SkSL::Program::Kind kind, int index, const char* name, const char* sksl,
SkString skslString, const void* inputs, size_t inputSize)
SkString skslString, const void* inputs, size_t inputSize,
const SkMatrix* matrix)
: INHERITED(kGrSkSLFP_ClassID, kNone_OptimizationFlags)
, fFactoryCache(factoryCache)
, fShaderCaps(sk_ref_sp(shaderCaps))
@ -305,6 +316,10 @@ GrSkSLFP::GrSkSLFP(sk_sp<GrSkSLFPFactoryCache> factoryCache, const GrShaderCaps*
if (fInputSize) {
memcpy(fInputs.get(), inputs, inputSize);
}
if (matrix) {
fCoordTransform = GrCoordTransform(*matrix);
this->addCoordTransform(&fCoordTransform);
}
}
GrSkSLFP::GrSkSLFP(const GrSkSLFP& other)
@ -322,6 +337,10 @@ GrSkSLFP::GrSkSLFP(const GrSkSLFP& other)
if (fInputSize) {
memcpy(fInputs.get(), other.fInputs.get(), fInputSize);
}
if (other.numCoordTransforms()) {
fCoordTransform = other.fCoordTransform;
this->addCoordTransform(&fCoordTransform);
}
}
const char* GrSkSLFP::name() const {

View File

@ -74,7 +74,8 @@ public:
const char* sksl,
const void* inputs,
size_t inputSize,
SkSL::Program::Kind kind = SkSL::Program::kPipelineStage_Kind);
SkSL::Program::Kind kind = SkSL::Program::kPipelineStage_Kind,
const SkMatrix* matrix = nullptr);
static std::unique_ptr<GrSkSLFP> Make(
GrContext_Base* context,
@ -83,7 +84,8 @@ public:
SkString sksl,
const void* inputs,
size_t inputSize,
SkSL::Program::Kind kind = SkSL::Program::kPipelineStage_Kind);
SkSL::Program::Kind kind = SkSL::Program::kPipelineStage_Kind,
const SkMatrix* matrix = nullptr);
const char* name() const override;
@ -94,7 +96,7 @@ public:
private:
GrSkSLFP(sk_sp<GrSkSLFPFactoryCache> factoryCache, const GrShaderCaps* shaderCaps,
SkSL::Program::Kind kind, int fIndex, const char* name, const char* sksl,
SkString skslString, const void* inputs, size_t inputSize);
SkString skslString, const void* inputs, size_t inputSize, const SkMatrix* matrix);
GrSkSLFP(const GrSkSLFP& other);
@ -132,6 +134,8 @@ private:
size_t fInputSize;
GrCoordTransform fCoordTransform;
mutable SkSL::String fKey;
GR_DECLARE_FRAGMENT_PROCESSOR_TEST

View File

@ -45,6 +45,11 @@ SkRTShader::SkRTShader(SkString sksl, sk_sp<SkData> inputs, const SkMatrix* loca
{}
bool SkRTShader::onAppendStages(const SkStageRec& rec) const {
SkMatrix inverse;
if (!this->computeTotalInverse(rec.fCTM, rec.fLocalM, &inverse)) {
return false;
}
auto ctx = rec.fAlloc->make<SkRasterPipeline_InterpreterCtx>();
ctx->paintColor = rec.fPaint.getColor4f();
ctx->inputs = fInputs->data();
@ -75,6 +80,7 @@ bool SkRTShader::onAppendStages(const SkStageRec& rec) const {
ctx->fn = ctx->byteCode->getFunction("main");
rec.fPipeline->append(SkRasterPipeline::seed_shader);
rec.fPipeline->append_matrix(rec.fAlloc, inverse);
rec.fPipeline->append(SkRasterPipeline::interpreter, ctx);
return true;
}
@ -130,8 +136,12 @@ sk_sp<SkShader> SkRuntimeShaderMaker(SkString sksl, sk_sp<SkData> inputs,
#if SK_SUPPORT_GPU
std::unique_ptr<GrFragmentProcessor> SkRTShader::asFragmentProcessor(const GrFPArgs& args) const {
SkMatrix matrix;
if (!this->totalLocalMatrix(args.fPreLocalMatrix, args.fPostLocalMatrix)->invert(&matrix)) {
return nullptr;
}
return GrSkSLFP::Make(args.fContext, fUniqueID, "runtime-shader", fSkSL,
fInputs->data(), fInputs->size());
fInputs->data(), fInputs->size(), SkSL::Program::kPipelineStage_Kind,
&matrix);
}
#endif

View File

@ -68,6 +68,8 @@ public:
enum class Kind {
kInput,
kOutput,
kCoordX,
kCoordY,
kUniform,
kChildProcessor
};

View File

@ -128,10 +128,12 @@ void PipelineStageCodeGenerator::writeVariableReference(const VariableReference&
fFormatArgs->push_back(Compiler::FormatArg(Compiler::FormatArg::Kind::kOutput));
break;
case SK_MAIN_X_BUILTIN:
this->write("sk_FragCoord.x");
this->write("%s");
fFormatArgs->push_back(Compiler::FormatArg(Compiler::FormatArg::Kind::kCoordX));
break;
case SK_MAIN_Y_BUILTIN:
this->write("sk_FragCoord.y");
this->write("%s");
fFormatArgs->push_back(Compiler::FormatArg(Compiler::FormatArg::Kind::kCoordY));
break;
default:
if (ref.fVariable.fModifiers.fFlags & Modifiers::kUniform_Flag) {