1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2015 Google Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#ifndef GrGLSLProgramBuilder_DEFINED 9cb93a386Sopenharmony_ci#define GrGLSLProgramBuilder_DEFINED 10cb93a386Sopenharmony_ci 11cb93a386Sopenharmony_ci#include "src/gpu/GrCaps.h" 12cb93a386Sopenharmony_ci#include "src/gpu/GrFragmentProcessor.h" 13cb93a386Sopenharmony_ci#include "src/gpu/GrGeometryProcessor.h" 14cb93a386Sopenharmony_ci#include "src/gpu/GrProgramInfo.h" 15cb93a386Sopenharmony_ci#include "src/gpu/GrXferProcessor.h" 16cb93a386Sopenharmony_ci#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h" 17cb93a386Sopenharmony_ci#include "src/gpu/glsl/GrGLSLProgramDataManager.h" 18cb93a386Sopenharmony_ci#include "src/gpu/glsl/GrGLSLUniformHandler.h" 19cb93a386Sopenharmony_ci#include "src/gpu/glsl/GrGLSLVertexGeoBuilder.h" 20cb93a386Sopenharmony_ci#include "src/sksl/SkSLCompiler.h" 21cb93a386Sopenharmony_ci 22cb93a386Sopenharmony_ci#include <vector> 23cb93a386Sopenharmony_ci 24cb93a386Sopenharmony_ciclass GrProgramDesc; 25cb93a386Sopenharmony_ciclass GrRenderTarget; 26cb93a386Sopenharmony_ciclass GrShaderVar; 27cb93a386Sopenharmony_ciclass GrGLSLVaryingHandler; 28cb93a386Sopenharmony_ciclass SkString; 29cb93a386Sopenharmony_ciclass GrShaderCaps; 30cb93a386Sopenharmony_ci 31cb93a386Sopenharmony_ciclass GrGLSLProgramBuilder { 32cb93a386Sopenharmony_cipublic: 33cb93a386Sopenharmony_ci using UniformHandle = GrGLSLUniformHandler::UniformHandle; 34cb93a386Sopenharmony_ci using SamplerHandle = GrGLSLUniformHandler::SamplerHandle; 35cb93a386Sopenharmony_ci 36cb93a386Sopenharmony_ci virtual ~GrGLSLProgramBuilder(); 37cb93a386Sopenharmony_ci 38cb93a386Sopenharmony_ci virtual const GrCaps* caps() const = 0; 39cb93a386Sopenharmony_ci const GrShaderCaps* shaderCaps() const { return this->caps()->shaderCaps(); } 40cb93a386Sopenharmony_ci 41cb93a386Sopenharmony_ci GrSurfaceOrigin origin() const { return fProgramInfo.origin(); } 42cb93a386Sopenharmony_ci const GrPipeline& pipeline() const { return fProgramInfo.pipeline(); } 43cb93a386Sopenharmony_ci const GrGeometryProcessor& geometryProcessor() const { return fProgramInfo.geomProc(); } 44cb93a386Sopenharmony_ci bool snapVerticesToPixelCenters() const { 45cb93a386Sopenharmony_ci return fProgramInfo.pipeline().snapVerticesToPixelCenters(); 46cb93a386Sopenharmony_ci } 47cb93a386Sopenharmony_ci bool hasPointSize() const { return fProgramInfo.primitiveType() == GrPrimitiveType::kPoints; } 48cb93a386Sopenharmony_ci virtual SkSL::Compiler* shaderCompiler() const = 0; 49cb93a386Sopenharmony_ci 50cb93a386Sopenharmony_ci const GrProgramDesc& desc() const { return fDesc; } 51cb93a386Sopenharmony_ci 52cb93a386Sopenharmony_ci void appendUniformDecls(GrShaderFlags visibility, SkString*) const; 53cb93a386Sopenharmony_ci 54cb93a386Sopenharmony_ci const char* samplerVariable(SamplerHandle handle) const { 55cb93a386Sopenharmony_ci return this->uniformHandler()->samplerVariable(handle); 56cb93a386Sopenharmony_ci } 57cb93a386Sopenharmony_ci 58cb93a386Sopenharmony_ci GrSwizzle samplerSwizzle(SamplerHandle handle) const { 59cb93a386Sopenharmony_ci return this->uniformHandler()->samplerSwizzle(handle); 60cb93a386Sopenharmony_ci } 61cb93a386Sopenharmony_ci 62cb93a386Sopenharmony_ci const char* inputSamplerVariable(SamplerHandle handle) const { 63cb93a386Sopenharmony_ci return this->uniformHandler()->inputSamplerVariable(handle); 64cb93a386Sopenharmony_ci } 65cb93a386Sopenharmony_ci 66cb93a386Sopenharmony_ci GrSwizzle inputSamplerSwizzle(SamplerHandle handle) const { 67cb93a386Sopenharmony_ci return this->uniformHandler()->inputSamplerSwizzle(handle); 68cb93a386Sopenharmony_ci } 69cb93a386Sopenharmony_ci 70cb93a386Sopenharmony_ci // Used to add a uniform for render target flip (used for dFdy, sk_Clockwise, and sk_FragCoord) 71cb93a386Sopenharmony_ci // without mangling the name of the uniform inside of a stage. 72cb93a386Sopenharmony_ci void addRTFlipUniform(const char* name); 73cb93a386Sopenharmony_ci 74cb93a386Sopenharmony_ci // Generates a name for a variable. The generated string will be name prefixed by the prefix 75cb93a386Sopenharmony_ci // char (unless the prefix is '\0'). It also will mangle the name to be stage-specific unless 76cb93a386Sopenharmony_ci // explicitly asked not to. `nameVariable` can also be used to generate names for functions or 77cb93a386Sopenharmony_ci // other types of symbols where unique names are important. 78cb93a386Sopenharmony_ci SkString nameVariable(char prefix, const char* name, bool mangle = true); 79cb93a386Sopenharmony_ci 80cb93a386Sopenharmony_ci /** 81cb93a386Sopenharmony_ci * If the FP's coords are unused or all uses have been lifted to interpolated varyings then 82cb93a386Sopenharmony_ci * don't put coords in the FP's function signature or call sites. 83cb93a386Sopenharmony_ci */ 84cb93a386Sopenharmony_ci bool fragmentProcessorHasCoordsParam(const GrFragmentProcessor*); 85cb93a386Sopenharmony_ci 86cb93a386Sopenharmony_ci virtual GrGLSLUniformHandler* uniformHandler() = 0; 87cb93a386Sopenharmony_ci virtual const GrGLSLUniformHandler* uniformHandler() const = 0; 88cb93a386Sopenharmony_ci virtual GrGLSLVaryingHandler* varyingHandler() = 0; 89cb93a386Sopenharmony_ci 90cb93a386Sopenharmony_ci // Used for backend customization of the output color and secondary color variables from the 91cb93a386Sopenharmony_ci // fragment processor. Only used if the outputs are explicitly declared in the shaders 92cb93a386Sopenharmony_ci virtual void finalizeFragmentOutputColor(GrShaderVar& outputColor) {} 93cb93a386Sopenharmony_ci virtual void finalizeFragmentSecondaryColor(GrShaderVar& outputColor) {} 94cb93a386Sopenharmony_ci 95cb93a386Sopenharmony_ci // number of each input/output type in a single allocation block, used by many builders 96cb93a386Sopenharmony_ci static const int kVarsPerBlock; 97cb93a386Sopenharmony_ci 98cb93a386Sopenharmony_ci GrGLSLVertexBuilder fVS; 99cb93a386Sopenharmony_ci GrGLSLFragmentShaderBuilder fFS; 100cb93a386Sopenharmony_ci 101cb93a386Sopenharmony_ci const GrProgramDesc& fDesc; 102cb93a386Sopenharmony_ci const GrProgramInfo& fProgramInfo; 103cb93a386Sopenharmony_ci 104cb93a386Sopenharmony_ci GrGLSLBuiltinUniformHandles fUniformHandles; 105cb93a386Sopenharmony_ci 106cb93a386Sopenharmony_ci std::unique_ptr<GrGeometryProcessor::ProgramImpl> fGPImpl; 107cb93a386Sopenharmony_ci std::unique_ptr<GrXferProcessor::ProgramImpl> fXPImpl; 108cb93a386Sopenharmony_ci std::vector<std::unique_ptr<GrFragmentProcessor::ProgramImpl>> fFPImpls; 109cb93a386Sopenharmony_ci 110cb93a386Sopenharmony_ci SamplerHandle fDstTextureSamplerHandle; 111cb93a386Sopenharmony_ci GrSurfaceOrigin fDstTextureOrigin; 112cb93a386Sopenharmony_ci 113cb93a386Sopenharmony_ciprotected: 114cb93a386Sopenharmony_ci explicit GrGLSLProgramBuilder(const GrProgramDesc&, const GrProgramInfo&); 115cb93a386Sopenharmony_ci 116cb93a386Sopenharmony_ci void addFeature(GrShaderFlags shaders, uint32_t featureBit, const char* extensionName); 117cb93a386Sopenharmony_ci 118cb93a386Sopenharmony_ci bool emitAndInstallProcs(); 119cb93a386Sopenharmony_ci 120cb93a386Sopenharmony_ci void finalizeShaders(); 121cb93a386Sopenharmony_ci 122cb93a386Sopenharmony_ci bool fragColorIsInOut() const { return fFS.primaryColorOutputIsInOut(); } 123cb93a386Sopenharmony_ci 124cb93a386Sopenharmony_ciprivate: 125cb93a386Sopenharmony_ci // advanceStage is called by program creator between each processor's emit code. It increments 126cb93a386Sopenharmony_ci // the stage index for variable name mangling, and also ensures verification variables in the 127cb93a386Sopenharmony_ci // fragment shader are cleared. 128cb93a386Sopenharmony_ci void advanceStage() { 129cb93a386Sopenharmony_ci fStageIndex++; 130cb93a386Sopenharmony_ci SkDEBUGCODE(fFS.debugOnly_resetPerStageVerification();) 131cb93a386Sopenharmony_ci fFS.nextStage(); 132cb93a386Sopenharmony_ci } 133cb93a386Sopenharmony_ci 134cb93a386Sopenharmony_ci SkString getMangleSuffix() const; 135cb93a386Sopenharmony_ci 136cb93a386Sopenharmony_ci // Generates a possibly mangled name for a stage variable and writes it to the fragment shader. 137cb93a386Sopenharmony_ci void nameExpression(SkString*, const char* baseName); 138cb93a386Sopenharmony_ci 139cb93a386Sopenharmony_ci bool emitAndInstallPrimProc(SkString* outputColor, SkString* outputCoverage); 140cb93a386Sopenharmony_ci bool emitAndInstallDstTexture(); 141cb93a386Sopenharmony_ci /** Adds the root FPs */ 142cb93a386Sopenharmony_ci bool emitAndInstallFragProcs(SkString* colorInOut, SkString* coverageInOut); 143cb93a386Sopenharmony_ci /** Adds a single root FP tree. */ 144cb93a386Sopenharmony_ci SkString emitFragProc(const GrFragmentProcessor&, 145cb93a386Sopenharmony_ci GrFragmentProcessor::ProgramImpl&, 146cb93a386Sopenharmony_ci const SkString& input, 147cb93a386Sopenharmony_ci SkString output); 148cb93a386Sopenharmony_ci /** Recursive step to write out children FPs' functions before parent's. */ 149cb93a386Sopenharmony_ci void writeChildFPFunctions(const GrFragmentProcessor& fp, 150cb93a386Sopenharmony_ci GrFragmentProcessor::ProgramImpl& impl); 151cb93a386Sopenharmony_ci /** Adds the SkSL function that implements an FP assuming its children are already written. */ 152cb93a386Sopenharmony_ci void writeFPFunction(const GrFragmentProcessor& fp, GrFragmentProcessor::ProgramImpl& impl); 153cb93a386Sopenharmony_ci bool emitAndInstallXferProc(const SkString& colorIn, const SkString& coverageIn); 154cb93a386Sopenharmony_ci SamplerHandle emitSampler(const GrBackendFormat&, GrSamplerState, const GrSwizzle&, 155cb93a386Sopenharmony_ci const char* name); 156cb93a386Sopenharmony_ci SamplerHandle emitInputSampler(const GrSwizzle& swizzle, const char* name); 157cb93a386Sopenharmony_ci bool checkSamplerCounts(); 158cb93a386Sopenharmony_ci 159cb93a386Sopenharmony_ci#ifdef SK_DEBUG 160cb93a386Sopenharmony_ci void verify(const GrGeometryProcessor&); 161cb93a386Sopenharmony_ci void verify(const GrFragmentProcessor&); 162cb93a386Sopenharmony_ci void verify(const GrXferProcessor&); 163cb93a386Sopenharmony_ci#endif 164cb93a386Sopenharmony_ci 165cb93a386Sopenharmony_ci // This is used to check that we don't excede the allowable number of resources in a shader. 166cb93a386Sopenharmony_ci int fNumFragmentSamplers; 167cb93a386Sopenharmony_ci 168cb93a386Sopenharmony_ci GrGeometryProcessor::ProgramImpl::FPCoordsMap fFPCoordsMap; 169cb93a386Sopenharmony_ci 170cb93a386Sopenharmony_ci /** 171cb93a386Sopenharmony_ci * Each root processor has an stage index. The GP is stage 0. The first root FP is stage 1, 172cb93a386Sopenharmony_ci * the second root FP is stage 2, etc. The XP's stage index is last and its value depends on 173cb93a386Sopenharmony_ci * how many root FPs there are. Names are mangled by appending _S<stage-index>. 174cb93a386Sopenharmony_ci */ 175cb93a386Sopenharmony_ci int fStageIndex = -1; 176cb93a386Sopenharmony_ci 177cb93a386Sopenharmony_ci /** 178cb93a386Sopenharmony_ci * When emitting FP stages we track the children FPs as "substages" and do additional name 179cb93a386Sopenharmony_ci * mangling based on where in the FP hierarchy we are. The first FP is stage index 1. It's first 180cb93a386Sopenharmony_ci * child would be substage 0 of stage 1. If that FP also has three children then its third child 181cb93a386Sopenharmony_ci * would be substage 2 of stubstage 0 of stage 1 and would be mangled as "_S1_c0_c2". 182cb93a386Sopenharmony_ci */ 183cb93a386Sopenharmony_ci SkTArray<int> fSubstageIndices; 184cb93a386Sopenharmony_ci}; 185cb93a386Sopenharmony_ci 186cb93a386Sopenharmony_ci#endif 187