diff --git a/src/gpu/effects/GrSkSLFP.cpp b/src/gpu/effects/GrSkSLFP.cpp index 7055e3fda6..01722eeb63 100644 --- a/src/gpu/effects/GrSkSLFP.cpp +++ b/src/gpu/effects/GrSkSLFP.cpp @@ -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::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(new GrSkSLFP(context->priv().fpFactoryCache(), context->priv().caps()->shaderCaps(), kind, index, name, sksl, SkString(), - inputs, inputSize)); + inputs, inputSize, matrix)); } std::unique_ptr 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(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 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 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 { diff --git a/src/gpu/effects/GrSkSLFP.h b/src/gpu/effects/GrSkSLFP.h index 1764e9dfda..6d3ec157ff 100644 --- a/src/gpu/effects/GrSkSLFP.h +++ b/src/gpu/effects/GrSkSLFP.h @@ -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 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 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 diff --git a/src/shaders/SkRTShader.cpp b/src/shaders/SkRTShader.cpp index 3c5c30cdb8..6d59e55d2a 100644 --- a/src/shaders/SkRTShader.cpp +++ b/src/shaders/SkRTShader.cpp @@ -45,6 +45,11 @@ SkRTShader::SkRTShader(SkString sksl, sk_sp 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(); 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 SkRuntimeShaderMaker(SkString sksl, sk_sp inputs, #if SK_SUPPORT_GPU std::unique_ptr 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 - diff --git a/src/sksl/SkSLCompiler.h b/src/sksl/SkSLCompiler.h index 138bc05ca7..eaaf50c08a 100644 --- a/src/sksl/SkSLCompiler.h +++ b/src/sksl/SkSLCompiler.h @@ -68,6 +68,8 @@ public: enum class Kind { kInput, kOutput, + kCoordX, + kCoordY, kUniform, kChildProcessor }; diff --git a/src/sksl/SkSLPipelineStageCodeGenerator.cpp b/src/sksl/SkSLPipelineStageCodeGenerator.cpp index a258539bbd..428b130001 100644 --- a/src/sksl/SkSLPipelineStageCodeGenerator.cpp +++ b/src/sksl/SkSLPipelineStageCodeGenerator.cpp @@ -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) {