1 /* 2 * Copyright 2014 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef GrGLFullProgramBuilder_DEFINED 9 #define GrGLFullProgramBuilder_DEFINED 10 11 #include "GrGLProgramBuilder.h" 12 #include "../GrGLGeometryProcessor.h" 13 14 class GrGLVertexProgramEffects; 15 16 class GrGLFullProgramBuilder : public GrGLProgramBuilder { 17 public: 18 GrGLFullProgramBuilder(GrGpuGL*, const GrGLProgramDesc&); 19 20 /** Add a varying variable to the current program to pass values between vertex and fragment 21 shaders. If the last two parameters are non-NULL, they are filled in with the name 22 generated. */ 23 void addVarying(GrSLType type, 24 const char* name, 25 const char** vsOutName = NULL, 26 const char** fsInName = NULL, 27 GrGLShaderVar::Precision fsPrecision=GrGLShaderVar::kDefault_Precision); 28 29 /** Add a separable varying input variable to the current program. 30 * A separable varying (fragment shader input) is a varying that can be used also when vertex 31 * shaders are not used. With a vertex shader, the operation is same as with other 32 * varyings. Without a vertex shader, such as with NV_path_rendering, GL APIs are used to 33 * populate the variable. The APIs can refer to the variable through the returned handle. 34 */ 35 VaryingHandle addSeparableVarying(GrSLType type, 36 const char* name, 37 const char** vsOutName, 38 const char** fsInName); 39 40 GrGLVertexShaderBuilder* getVertexShaderBuilder() { return &fVS; } 41 42 /* 43 * This non-virtual call will hide the parent call to prevent GPs from accessing fragment shader 44 * functionality they shouldn't be using 45 */ 46 GrGLProcessorFragmentShaderBuilder* getFragmentShaderBuilder() { return &fFS; } 47 48 private: 49 virtual void createAndEmitEffects(const GrGeometryStage* geometryProcessor, 50 const GrFragmentStage* colorStages[], 51 const GrFragmentStage* coverageStages[], 52 GrGLSLExpr4* inputColor, 53 GrGLSLExpr4* inputCoverage) SK_OVERRIDE; 54 55 GrGLProgramEffects* onCreateAndEmitEffects(const GrFragmentStage* effectStages[], 56 int effectCnt, 57 const GrGLProgramDesc::EffectKeyProvider&, 58 GrGLSLExpr4* inOutFSColor); 59 60 class GrGLGeometryProcessorEmitter : public GrGLProgramBuilder::GrGLProcessorEmitterInterface { 61 public: 62 GrGLGeometryProcessorEmitter(GrGLFullProgramBuilder* builder) 63 : fBuilder(builder) 64 , fGeometryProcessor(NULL) 65 , fGLGeometryProcessor(NULL) {} 66 virtual ~GrGLGeometryProcessorEmitter() {} 67 void set(const GrGeometryProcessor* gp) { 68 SkASSERT(NULL == fGeometryProcessor); 69 fGeometryProcessor = gp; 70 } 71 virtual GrGLProcessor* createGLInstance() { 72 SkASSERT(fGeometryProcessor); 73 SkASSERT(NULL == fGLGeometryProcessor); 74 fGLGeometryProcessor = 75 fGeometryProcessor->getFactory().createGLInstance(*fGeometryProcessor); 76 return fGLGeometryProcessor; 77 } 78 virtual void emit(const GrProcessorKey& key, 79 const char* outColor, 80 const char* inColor, 81 const GrGLProcessor::TransformedCoordsArray& coords, 82 const GrGLProcessor::TextureSamplerArray& samplers) { 83 SkASSERT(fGeometryProcessor); 84 SkASSERT(fGLGeometryProcessor); 85 fGLGeometryProcessor->emitCode(fBuilder, *fGeometryProcessor, key, outColor, 86 inColor, coords, samplers); 87 // this will not leak because it has already been used by createGLInstance 88 fGLGeometryProcessor = NULL; 89 fGeometryProcessor = NULL; 90 } 91 private: 92 GrGLFullProgramBuilder* fBuilder; 93 const GrGeometryProcessor* fGeometryProcessor; 94 GrGLGeometryProcessor* fGLGeometryProcessor; 95 }; 96 97 virtual void emitEffect(const GrProcessorStage& stage, 98 const GrProcessorKey& key, 99 const char* outColor, 100 const char* inColor, 101 int stageIndex) SK_OVERRIDE; 102 103 /** 104 * Helper for emitEffect(). Emits code to implement an effect's coord transforms in the VS. 105 * Varyings are added as an outputs of the VS and inputs to the FS. The varyings may be either a 106 * vec2f or vec3f depending upon whether perspective interpolation is required or not. The names 107 * of the varyings in the VS and FS as well their types are appended to the 108 * TransformedCoordsArray* object, which is in turn passed to the effect's emitCode() function. 109 */ 110 void emitTransforms(const GrProcessorStage& effectStage, 111 GrGLProcessor::TransformedCoordsArray* outCoords); 112 113 virtual bool compileAndAttachShaders(GrGLuint programId, 114 SkTDArray<GrGLuint>* shaderIds) const SK_OVERRIDE; 115 116 virtual void bindProgramLocations(GrGLuint programId) SK_OVERRIDE; 117 118 virtual GrGLProgramEffects* getProgramEffects() SK_OVERRIDE { return fProgramEffects.get(); } 119 120 typedef GrGLProgramDesc::EffectKeyProvider EffectKeyProvider; 121 122 GrGLGeometryProcessorEmitter fGLGeometryProcessorEmitter; 123 GrGLGeometryShaderBuilder fGS; 124 GrGLVertexShaderBuilder fVS; 125 SkAutoTDelete<GrGLVertexProgramEffects> fProgramEffects; 126 127 typedef GrGLProgramBuilder INHERITED; 128 }; 129 130 #endif 131