32#include <unordered_map>
45 , fProgramInfo(programInfo)
46 , fNumFragmentSamplers(0) {}
52 const char* extensionName) {
66 if (!this->emitAndInstallPrimProc(&inputColor, &inputCoverage)) {
69 if (!this->emitAndInstallDstTexture()) {
72 if (!this->emitAndInstallFragProcs(&inputColor, &inputCoverage)) {
75 if (!this->emitAndInstallXferProc(inputColor, inputCoverage)) {
80 return this->checkSamplerCounts();
83bool GrGLSLProgramBuilder::emitAndInstallPrimProc(
SkString* outputColor,
SkString* outputCoverage) {
88 this->nameExpression(outputColor,
"outputColor");
89 this->nameExpression(outputCoverage,
"outputCoverage");
106 texSamplers[i] = this->emitSampler(sampler.backendFormat(),
107 sampler.samplerState(),
110 if (!texSamplers[i].isValid()) {
121 outputColor->
c_str(),
122 outputCoverage->
c_str(),
137 for (
int i = 0; i < fpCount; ++i) {
142 output = this->emitRootFragProc(fp, *
fFPImpls.back(), *inOut, output);
146 *inOut = std::move(output);
157 SkString name = SkStringPrintf(
"TextureSampler_%d", *samplerIndex);
160 GrSamplerState samplerState = te->samplerState();
161 const GrBackendFormat& format = te->view().proxy()->backendFormat();
162 skgpu::Swizzle swizzle = te->view().swizzle();
163 SamplerHandle handle = this->emitSampler(format, samplerState, swizzle, name.c_str());
164 if (!handle.isValid()) {
177 const char* inputColor,
178 const char* destColor,
179 const char* coords)
const {
180 if (fp.isBlendFunction()) {
204 this->nameExpression(&output,
"output");
206 int samplerIndex = 0;
216 this->invokeFP(fp, impl, input.
c_str(),
"half4(1)", fLocalCoordsVar.
c_str()).c_str());
238 ++fSubstageIndices.
back();
245 constexpr const char* kDstColor =
"_dst";
246 const char*
const inputColor = fp.isBlendFunction() ?
"_src" :
"_input";
247 const char* sampleCoords =
"_coords";
258 if (fp.isBlendFunction()) {
263 auto fpCoordsIter = fFPCoordsMap.find(&fp);
264 if (fpCoordsIter == fFPCoordsMap.end()) {
267 if (fp.usesSampleCoords()) {
270 }
else if (fpCoordsIter->second.hasCoordsParam) {
278 GrShaderVar varying = fpCoordsIter->second.coordsVarying;
282 SkASSERT(!fp.usesSampleCoordsDirectly());
298 SkDEBUGFAILF(
"Unexpected varying type for coord: %s %d\n",
309 this->writeChildFPFunctions(fp, impl);
328bool GrGLSLProgramBuilder::emitAndInstallDstTexture() {
332 if (this->
pipeline().usesDstTexture()) {
347 const char* dstTextureCoordsName;
353 &dstTextureCoordsName);
354 fFS.
codeAppend(
"// Read color from copy of the destination\n");
356 fFS.
codeAppendf(
"float2 _dstTexCoord = (sk_FragCoord.xy - %s.xy) * %s.zw;\n",
357 dstTextureCoordsName, dstTextureCoordsName);
363 fFS.
codeAppendf(
"float2 _dstTexCoord = sk_FragCoord.xy - %s.xy;\n",
364 dstTextureCoordsName);
368 fFS.
codeAppendf(
"_dstTexCoord.y = %s.z - _dstTexCoord.y;\n", dstTextureCoordsName);
377 }
else if (this->
pipeline().usesDstInputAttachment()) {
399bool GrGLSLProgramBuilder::emitAndInstallXferProc(
const SkString& colorIn,
410 fFS.enableSecondaryOutput();
414 openBrace.
printf(
"{ // Xfer Processor: %s\n", xp.
name());
424 finalInColor.
c_str(),
425 coverageIn.
size() ? coverageIn.
c_str() :
"float4(1)",
426 fFS.getPrimaryColorOutputName(),
427 fFS.getSecondaryColorOutputName(),
443 ++fNumFragmentSamplers;
453bool GrGLSLProgramBuilder::checkSamplerCounts() {
456 GrCapsDebugf(this->
caps(),
"Program would use too many fragment samplers\n");
464 SkASSERT(!
fFS.fHasReadDstColorThisStage_DebugOnly);
468 SkASSERT(
fp.willReadDstColor() ==
fFS.fHasReadDstColorThisStage_DebugOnly);
476SkString GrGLSLProgramBuilder::getMangleSuffix()
const {
479 suffix.printf(
"_S%d", fStageIndex);
480 for (
auto c : fSubstageIndices) {
481 suffix.appendf(
"_c%d", c);
488 if (
'\0' == prefix) {
491 out.printf(
"%c%s", prefix,
name);
494 SkString suffix = this->getMangleSuffix();
496 const char *underscoreSplitter = out.endsWith(
'_') ?
"x" :
"";
497 out.appendf(
"%s%s", underscoreSplitter, suffix.c_str());
502void GrGLSLProgramBuilder::nameExpression(
SkString* output,
const char* baseName) {
505 if (output->isEmpty()) {
528 auto iter = fFPCoordsMap.find(fp);
529 return (iter != fFPCoordsMap.end()) ? iter->second.hasCoordsParam
530 : fp->usesSampleCoords();
#define GrCapsDebugf(caps,...)
@ kBottomLeft_GrSurfaceOrigin
@ kTopLeft_GrSurfaceOrigin
#define SkDEBUGFAILF(fmt,...)
static bool ok(int result)
SK_API SkString static SkString SkStringPrintf()
const char * functionName() const
void setFunctionName(SkString name)
int numChildProcessors() const
virtual void emitCode(EmitArgs &)=0
ProgramImpl * childProcessor(int index) const
const char * dstColor() override
SkString nameVariable(char prefix, const char *name, bool mangle=true)
virtual GrGLSLUniformHandler * uniformHandler()=0
GrSurfaceOrigin fDstTextureOrigin
bool fragmentProcessorHasCoordsParam(const GrFragmentProcessor *) const
std::vector< std::unique_ptr< GrFragmentProcessor::ProgramImpl > > fFPImpls
virtual const GrCaps * caps() const =0
std::unique_ptr< GrGeometryProcessor::ProgramImpl > fGPImpl
const GrShaderCaps * shaderCaps() const
SamplerHandle fDstTextureSamplerHandle
void addFeature(GrShaderFlags shaders, uint32_t featureBit, const char *extensionName)
const GrGeometryProcessor & geometryProcessor() const
GrGLSLUniformHandler::SamplerHandle SamplerHandle
bool emitTextureSamplersForFPs(const GrFragmentProcessor &fp, GrFragmentProcessor::ProgramImpl &impl, int *samplerIndex)
void appendUniformDecls(GrShaderFlags visibility, SkString *) const
virtual GrGLSLVaryingHandler * varyingHandler()=0
std::string invokeFP(const GrFragmentProcessor &fp, const GrFragmentProcessor::ProgramImpl &impl, const char *inputColor, const char *destColor, const char *coords) const
std::unique_ptr< GrXferProcessor::ProgramImpl > fXPImpl
virtual ~GrGLSLProgramBuilder()
static const int kVarsPerBlock
GrGLSLBuiltinUniformHandles fUniformHandles
GrGLSLFragmentShaderBuilder fFS
void addRTFlipUniform(const char *name)
GrGLSLProgramBuilder(const GrProgramDesc &, const GrProgramInfo &)
bool emitAndInstallProcs()
void writeFPFunction(const GrFragmentProcessor &fp, GrFragmentProcessor::ProgramImpl &impl)
const GrPipeline & pipeline() const
void emitFunction(SkSLType returnType, const char *mangledName, SkSpan< const GrShaderVar > args, const char *body)
this code().appendVAList(format
void definitionAppend(const char *str)
bool addFeature(uint32_t featureBit, const char *extensionName)
void finalize(uint32_t visibility)
void codeAppend(const char *str)
void appendTextureLookup(SkString *out, SamplerHandle, const char *coordName) const
SkString getMangledFunctionName(const char *baseName)
void codeAppendf(const char format[],...) SK_PRINTF_LIKE(2
void appendInputLoad(SamplerHandle)
virtual std::unique_ptr< ProgramImpl > makeProgramImpl(const GrShaderCaps &) const =0
const TextureSampler & textureSampler(int index) const
int numTextureSamplers() const
int numFragmentProcessors() const
bool isColorFragmentProcessor(int idx) const
const GrFragmentProcessor & getFragmentProcessor(int idx) const
const GrSurfaceProxyView & dstProxyView() const
const GrXferProcessor & getXferProcessor() const
virtual const char * name() const =0
const char * c_str() const
const SkString & getName() const
skgpu::Swizzle swizzle() const
GrTextureProxy * asTextureProxy() const
GrSurfaceOrigin origin() const
const GrBackendFormat & backendFormat() const
void setSamplerHandle(GrGLSLShaderBuilder::SamplerHandle handle)
GrTextureType textureType() const
bool hasSecondaryOutput() const
virtual std::unique_ptr< ProgramImpl > makeProgramImpl() const =0
bool willReadDstColor() const
static constexpr const char RTADJUST_NAME[]
void printf(const char format[],...) SK_PRINTF_LIKE(2
const char * c_str() const
const EmbeddedViewParams * params
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
std::string printf(const char *fmt,...) SK_PRINTF_LIKE(1