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

View File

@ -74,7 +74,8 @@ public:
const char* sksl, const char* sksl,
const void* inputs, const void* inputs,
size_t inputSize, 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( static std::unique_ptr<GrSkSLFP> Make(
GrContext_Base* context, GrContext_Base* context,
@ -83,7 +84,8 @@ public:
SkString sksl, SkString sksl,
const void* inputs, const void* inputs,
size_t inputSize, 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; const char* name() const override;
@ -94,7 +96,7 @@ public:
private: private:
GrSkSLFP(sk_sp<GrSkSLFPFactoryCache> factoryCache, const GrShaderCaps* shaderCaps, GrSkSLFP(sk_sp<GrSkSLFPFactoryCache> factoryCache, const GrShaderCaps* shaderCaps,
SkSL::Program::Kind kind, int fIndex, const char* name, const char* sksl, 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); GrSkSLFP(const GrSkSLFP& other);
@ -132,6 +134,8 @@ private:
size_t fInputSize; size_t fInputSize;
GrCoordTransform fCoordTransform;
mutable SkSL::String fKey; mutable SkSL::String fKey;
GR_DECLARE_FRAGMENT_PROCESSOR_TEST 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 { 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>(); auto ctx = rec.fAlloc->make<SkRasterPipeline_InterpreterCtx>();
ctx->paintColor = rec.fPaint.getColor4f(); ctx->paintColor = rec.fPaint.getColor4f();
ctx->inputs = fInputs->data(); ctx->inputs = fInputs->data();
@ -75,6 +80,7 @@ bool SkRTShader::onAppendStages(const SkStageRec& rec) const {
ctx->fn = ctx->byteCode->getFunction("main"); ctx->fn = ctx->byteCode->getFunction("main");
rec.fPipeline->append(SkRasterPipeline::seed_shader); rec.fPipeline->append(SkRasterPipeline::seed_shader);
rec.fPipeline->append_matrix(rec.fAlloc, inverse);
rec.fPipeline->append(SkRasterPipeline::interpreter, ctx); rec.fPipeline->append(SkRasterPipeline::interpreter, ctx);
return true; return true;
} }
@ -130,8 +136,12 @@ sk_sp<SkShader> SkRuntimeShaderMaker(SkString sksl, sk_sp<SkData> inputs,
#if SK_SUPPORT_GPU #if SK_SUPPORT_GPU
std::unique_ptr<GrFragmentProcessor> SkRTShader::asFragmentProcessor(const GrFPArgs& args) const { 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, return GrSkSLFP::Make(args.fContext, fUniqueID, "runtime-shader", fSkSL,
fInputs->data(), fInputs->size()); fInputs->data(), fInputs->size(), SkSL::Program::kPipelineStage_Kind,
&matrix);
} }
#endif #endif

View File

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

View File

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