1 /* 2 * Copyright 2013 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 GrGLProgramEffects_DEFINED 9 #define GrGLProgramEffects_DEFINED 10 11 #include "GrBackendEffectFactory.h" 12 #include "GrTexture.h" 13 #include "GrTextureAccess.h" 14 #include "GrGLUniformManager.h" 15 16 class GrEffectStage; 17 class GrGLVertexProgramEffectsBuilder; 18 class GrGLShaderBuilder; 19 class GrGLFullShaderBuilder; 20 class GrGLFragmentOnlyShaderBuilder; 21 22 /** 23 * This class encapsulates an array of GrGLEffects and their supporting data (coord transforms 24 * and textures). It is built with GrGLProgramEffectsBuilder, then used to manage the necessary GL 25 * state and shader uniforms. 26 */ 27 class GrGLProgramEffects : public SkRefCnt { 28 public: 29 typedef GrBackendEffectFactory::EffectKey EffectKey; 30 typedef GrGLUniformManager::UniformHandle UniformHandle; 31 32 /** 33 * These methods generate different portions of an effect's final key. 34 */ 35 static EffectKey GenAttribKey(const GrDrawEffect&); 36 static EffectKey GenTransformKey(const GrDrawEffect&); 37 static EffectKey GenTextureKey(const GrDrawEffect&, const GrGLCaps&); 38 39 virtual ~GrGLProgramEffects(); 40 41 /** 42 * Assigns a texture unit to each sampler. It starts on *texUnitIdx and writes the next 43 * available unit to *texUnitIdx when it returns. 44 */ 45 void initSamplers(const GrGLUniformManager&, int* texUnitIdx); 46 47 /** 48 * Calls setData() on each effect, and sets their transformation matrices and texture bindings. 49 */ 50 virtual void setData(GrGpuGL*, 51 const GrGLUniformManager&, 52 const GrEffectStage* effectStages[]) = 0; 53 54 /** 55 * Passed to GrGLEffects so they can add transformed coordinates to their shader code. 56 */ 57 class TransformedCoords { 58 public: 59 TransformedCoords(const SkString& name, GrSLType type) 60 : fName(name), fType(type) { 61 } 62 63 const char* c_str() const { return fName.c_str(); } 64 GrSLType type() const { return fType; } 65 const SkString& getName() const { return fName; } 66 67 private: 68 SkString fName; 69 GrSLType fType; 70 }; 71 72 typedef SkTArray<TransformedCoords> TransformedCoordsArray; 73 74 /** 75 * Passed to GrGLEffects so they can add texture reads to their shader code. 76 */ 77 class TextureSampler { 78 public: 79 TextureSampler(UniformHandle uniform, const GrTextureAccess& access) 80 : fSamplerUniform(uniform) 81 , fConfigComponentMask(GrPixelConfigComponentMask(access.getTexture()->config())) { 82 SkASSERT(0 != fConfigComponentMask); 83 memcpy(fSwizzle, access.getSwizzle(), 5); 84 } 85 86 UniformHandle samplerUniform() const { return fSamplerUniform; } 87 // bitfield of GrColorComponentFlags present in the texture's config. 88 uint32_t configComponentMask() const { return fConfigComponentMask; } 89 const char* swizzle() const { return fSwizzle; } 90 91 private: 92 UniformHandle fSamplerUniform; 93 uint32_t fConfigComponentMask; 94 char fSwizzle[5]; 95 }; 96 97 typedef SkTArray<TextureSampler> TextureSamplerArray; 98 99 protected: 100 GrGLProgramEffects(int reserveCount) 101 : fGLEffects(reserveCount) 102 , fSamplers(reserveCount) { 103 } 104 105 /** 106 * Helper for emitEffect() in a subclasses. Emits uniforms for an effect's texture accesses and 107 * appends the necessary data to the TextureSamplerArray* object so effects can add texture 108 * lookups to their code. This method is only meant to be called during the construction phase. 109 */ 110 void emitSamplers(GrGLShaderBuilder*, const GrEffectRef&, TextureSamplerArray*); 111 112 /** 113 * Helper for setData(). Binds all the textures for an effect. 114 */ 115 void bindTextures(GrGpuGL*, const GrEffectRef&, int effectIdx); 116 117 struct Sampler { 118 SkDEBUGCODE(Sampler() : fTextureUnit(-1) {}) 119 UniformHandle fUniform; 120 int fTextureUnit; 121 }; 122 123 SkTArray<GrGLEffect*> fGLEffects; 124 SkTArray<SkSTArray<4, Sampler, true> > fSamplers; 125 126 private: 127 typedef SkRefCnt INHERITED; 128 }; 129 130 /** 131 * This is an abstract base class for constructing different types of GrGLProgramEffects objects. 132 */ 133 class GrGLProgramEffectsBuilder { 134 public: 135 virtual ~GrGLProgramEffectsBuilder() { } 136 137 /** 138 * Emits the effect's shader code, and stores the necessary uniforms internally. 139 */ 140 virtual void emitEffect(const GrEffectStage&, 141 GrGLProgramEffects::EffectKey, 142 const char* outColor, 143 const char* inColor, 144 int stageIndex) = 0; 145 }; 146 147 //////////////////////////////////////////////////////////////////////////////// 148 149 /** 150 * This is a GrGLProgramEffects implementation that does coord transforms with the vertex shader. 151 */ 152 class GrGLVertexProgramEffects : public GrGLProgramEffects { 153 public: 154 virtual void setData(GrGpuGL*, 155 const GrGLUniformManager&, 156 const GrEffectStage* effectStages[]) SK_OVERRIDE; 157 158 private: 159 friend class GrGLVertexProgramEffectsBuilder; 160 161 GrGLVertexProgramEffects(int reserveCount, bool explicitLocalCoords) 162 : INHERITED(reserveCount) 163 , fTransforms(reserveCount) 164 , fHasExplicitLocalCoords(explicitLocalCoords) { 165 } 166 167 /** 168 * Helper for GrGLProgramEffectsBuilder::emitEfffect(). This method is meant to only be called 169 * during the construction phase. 170 */ 171 void emitEffect(GrGLFullShaderBuilder*, 172 const GrEffectStage&, 173 GrGLProgramEffects::EffectKey, 174 const char* outColor, 175 const char* inColor, 176 int stageIndex); 177 178 /** 179 * Helper for emitEffect(). Emits any attributes an effect may have. 180 */ 181 void emitAttributes(GrGLFullShaderBuilder*, const GrEffectStage&); 182 183 /** 184 * Helper for emitEffect(). Emits code to implement an effect's coord transforms in the VS. 185 * Varyings are added as an outputs of the VS and inputs to the FS. The varyings may be either a 186 * vec2f or vec3f depending upon whether perspective interpolation is required or not. The names 187 * of the varyings in the VS and FS as well their types are appended to the 188 * TransformedCoordsArray* object, which is in turn passed to the effect's emitCode() function. 189 */ 190 void emitTransforms(GrGLFullShaderBuilder*, 191 const GrEffectRef&, 192 EffectKey, 193 TransformedCoordsArray*); 194 195 /** 196 * Helper for setData(). Sets all the transform matrices for an effect. 197 */ 198 void setTransformData(const GrGLUniformManager&, const GrDrawEffect&, int effectIdx); 199 200 struct Transform { 201 Transform() { fCurrentValue = SkMatrix::InvalidMatrix(); } 202 UniformHandle fHandle; 203 GrSLType fType; 204 SkMatrix fCurrentValue; 205 }; 206 207 SkTArray<SkSTArray<2, Transform, true> > fTransforms; 208 bool fHasExplicitLocalCoords; 209 210 typedef GrGLProgramEffects INHERITED; 211 }; 212 213 /** 214 * This class is used to construct a GrGLVertexProgramEffects* object. 215 */ 216 class GrGLVertexProgramEffectsBuilder : public GrGLProgramEffectsBuilder { 217 public: 218 GrGLVertexProgramEffectsBuilder(GrGLFullShaderBuilder*, int reserveCount); 219 virtual ~GrGLVertexProgramEffectsBuilder() { } 220 221 virtual void emitEffect(const GrEffectStage&, 222 GrGLProgramEffects::EffectKey, 223 const char* outColor, 224 const char* inColor, 225 int stageIndex) SK_OVERRIDE; 226 227 /** 228 * Finalizes the building process and returns the effect array. After this call, the builder 229 * becomes invalid. 230 */ 231 GrGLProgramEffects* finish() { return fProgramEffects.detach(); } 232 233 private: 234 GrGLFullShaderBuilder* fBuilder; 235 SkAutoTDelete<GrGLVertexProgramEffects> fProgramEffects; 236 237 typedef GrGLProgramEffectsBuilder INHERITED; 238 }; 239 240 //////////////////////////////////////////////////////////////////////////////// 241 242 /** 243 * This is a GrGLProgramEffects implementation that does coord transforms with 244 * the the NV_path_rendering PathTexGen functionality. 245 */ 246 class GrGLPathTexGenProgramEffects : public GrGLProgramEffects { 247 public: 248 virtual void setData(GrGpuGL*, 249 const GrGLUniformManager&, 250 const GrEffectStage* effectStages[]) SK_OVERRIDE; 251 252 private: 253 friend class GrGLPathTexGenProgramEffectsBuilder; 254 255 GrGLPathTexGenProgramEffects(int reserveCount) 256 : INHERITED(reserveCount) 257 , fTransforms(reserveCount) { 258 } 259 260 /** 261 * Helper for GrGLProgramEffectsBuilder::emitEfffect(). This method is meant to only be called 262 * during the construction phase. 263 */ 264 void emitEffect(GrGLFragmentOnlyShaderBuilder*, 265 const GrEffectStage&, 266 GrGLProgramEffects::EffectKey, 267 const char* outColor, 268 const char* inColor, 269 int stageIndex); 270 271 /** 272 * Helper for emitEffect(). Allocates texture units from the builder for each transform in an 273 * effect. The transforms all use adjacent texture units. They either use two or three of the 274 * coordinates at a given texture unit, depending on if they need perspective interpolation. 275 * The expressions to access the transformed coords (i.e. 'vec2(gl_TexCoord[0])') as well as the 276 * types are appended to the TransformedCoordsArray* object, which is in turn passed to the 277 * effect's emitCode() function. 278 */ 279 void setupPathTexGen(GrGLFragmentOnlyShaderBuilder*, 280 const GrEffectRef&, 281 EffectKey, 282 TransformedCoordsArray*); 283 284 /** 285 * Helper for setData(). Sets the PathTexGen state for each transform in an effect. 286 */ 287 void setPathTexGenState(GrGpuGL*, const GrDrawEffect&, int effectIdx); 288 289 struct Transforms { 290 Transforms(EffectKey transformKey, int texCoordIndex) 291 : fTransformKey(transformKey), fTexCoordIndex(texCoordIndex) {} 292 EffectKey fTransformKey; 293 int fTexCoordIndex; 294 }; 295 296 SkTArray<Transforms> fTransforms; 297 298 typedef GrGLProgramEffects INHERITED; 299 }; 300 301 /** 302 * This class is used to construct a GrGLPathTexGenProgramEffects* object. 303 */ 304 class GrGLPathTexGenProgramEffectsBuilder : public GrGLProgramEffectsBuilder { 305 public: 306 GrGLPathTexGenProgramEffectsBuilder(GrGLFragmentOnlyShaderBuilder*, int reserveCount); 307 virtual ~GrGLPathTexGenProgramEffectsBuilder() { } 308 309 virtual void emitEffect(const GrEffectStage&, 310 GrGLProgramEffects::EffectKey, 311 const char* outColor, 312 const char* inColor, 313 int stageIndex) SK_OVERRIDE; 314 315 /** 316 * Finalizes the building process and returns the effect array. After this call, the builder 317 * becomes invalid. 318 */ 319 GrGLProgramEffects* finish() { return fProgramEffects.detach(); } 320 321 private: 322 GrGLFragmentOnlyShaderBuilder* fBuilder; 323 SkAutoTDelete<GrGLPathTexGenProgramEffects> fProgramEffects; 324 325 typedef GrGLProgramEffectsBuilder INHERITED; 326 }; 327 328 #endif 329