blob: 48d01c8ad7c34a0a3ada6e149bda80d7b8d665fc [file] [log] [blame]
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +00001/*
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
16class GrEffectStage;
commit-bot@chromium.org261dc562013-10-04 15:42:56 +000017class GrGLVertexProgramEffectsBuilder;
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +000018class GrGLShaderBuilder;
commit-bot@chromium.org261dc562013-10-04 15:42:56 +000019class GrGLFullShaderBuilder;
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +000020class GrGLFragmentOnlyShaderBuilder;
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +000021
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 */
commit-bot@chromium.orga05fa062014-05-30 18:55:03 +000027class GrGLProgramEffects : public SkRefCnt {
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +000028public:
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
commit-bot@chromium.org261dc562013-10-04 15:42:56 +000039 virtual ~GrGLProgramEffects();
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +000040
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 */
commit-bot@chromium.org261dc562013-10-04 15:42:56 +000050 virtual void setData(GrGpuGL*,
51 const GrGLUniformManager&,
52 const GrEffectStage* effectStages[]) = 0;
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +000053
54 /**
55 * Passed to GrGLEffects so they can add transformed coordinates to their shader code.
56 */
57 class TransformedCoords {
58 public:
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +000059 TransformedCoords(const SkString& name, GrSLType type)
commit-bot@chromium.org5fd7d5c2013-10-04 01:20:09 +000060 : fName(name), fType(type) {
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +000061 }
62
63 const char* c_str() const { return fName.c_str(); }
64 GrSLType type() const { return fType; }
65 const SkString& getName() const { return fName; }
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +000066
67 private:
68 SkString fName;
69 GrSLType fType;
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +000070 };
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
commit-bot@chromium.org261dc562013-10-04 15:42:56 +000099protected:
commit-bot@chromium.org261dc562013-10-04 15:42:56 +0000100 GrGLProgramEffects(int reserveCount)
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +0000101 : fGLEffects(reserveCount)
commit-bot@chromium.org261dc562013-10-04 15:42:56 +0000102 , fSamplers(reserveCount) {
103 }
104
105 /**
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +0000106 * 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 /**
commit-bot@chromium.org261dc562013-10-04 15:42:56 +0000113 * 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;
commit-bot@chromium.orga05fa062014-05-30 18:55:03 +0000125
126private:
127 typedef SkRefCnt INHERITED;
commit-bot@chromium.org261dc562013-10-04 15:42:56 +0000128};
129
130/**
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +0000131 * This is an abstract base class for constructing different types of GrGLProgramEffects objects.
132 */
133class GrGLProgramEffectsBuilder {
134public:
mtklein@google.comf1077f92013-11-20 15:13:49 +0000135 virtual ~GrGLProgramEffectsBuilder() { }
136
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +0000137 /**
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/**
commit-bot@chromium.org261dc562013-10-04 15:42:56 +0000150 * This is a GrGLProgramEffects implementation that does coord transforms with the vertex shader.
151 */
152class GrGLVertexProgramEffects : public GrGLProgramEffects {
153public:
154 virtual void setData(GrGpuGL*,
155 const GrGLUniformManager&,
156 const GrEffectStage* effectStages[]) SK_OVERRIDE;
157
158private:
159 friend class GrGLVertexProgramEffectsBuilder;
160
161 GrGLVertexProgramEffects(int reserveCount, bool explicitLocalCoords)
162 : INHERITED(reserveCount)
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +0000163 , fTransforms(reserveCount)
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +0000164 , fHasExplicitLocalCoords(explicitLocalCoords) {
165 }
166
167 /**
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +0000168 * 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 /**
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +0000196 * Helper for setData(). Sets all the transform matrices for an effect.
197 */
198 void setTransformData(const GrGLUniformManager&, const GrDrawEffect&, int effectIdx);
199
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +0000200 struct Transform {
201 Transform() { fCurrentValue = SkMatrix::InvalidMatrix(); }
202 UniformHandle fHandle;
203 GrSLType fType;
204 SkMatrix fCurrentValue;
205 };
206
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +0000207 SkTArray<SkSTArray<2, Transform, true> > fTransforms;
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +0000208 bool fHasExplicitLocalCoords;
commit-bot@chromium.org261dc562013-10-04 15:42:56 +0000209
210 typedef GrGLProgramEffects INHERITED;
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +0000211};
212
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +0000213/**
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +0000214 * This class is used to construct a GrGLVertexProgramEffects* object.
commit-bot@chromium.org261dc562013-10-04 15:42:56 +0000215 */
216class GrGLVertexProgramEffectsBuilder : public GrGLProgramEffectsBuilder {
217public:
218 GrGLVertexProgramEffectsBuilder(GrGLFullShaderBuilder*, int reserveCount);
mtklein@google.comf1077f92013-11-20 15:13:49 +0000219 virtual ~GrGLVertexProgramEffectsBuilder() { }
commit-bot@chromium.org261dc562013-10-04 15:42:56 +0000220
221 virtual void emitEffect(const GrEffectStage&,
222 GrGLProgramEffects::EffectKey,
223 const char* outColor,
224 const char* inColor,
225 int stageIndex) SK_OVERRIDE;
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +0000226
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
233private:
commit-bot@chromium.org261dc562013-10-04 15:42:56 +0000234 GrGLFullShaderBuilder* fBuilder;
235 SkAutoTDelete<GrGLVertexProgramEffects> fProgramEffects;
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +0000236
commit-bot@chromium.org261dc562013-10-04 15:42:56 +0000237 typedef GrGLProgramEffectsBuilder INHERITED;
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +0000238};
239
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +0000240////////////////////////////////////////////////////////////////////////////////
241
242/**
commit-bot@chromium.org0a6fe712014-04-23 19:26:26 +0000243 * This is a GrGLProgramEffects implementation that does coord transforms with
244 * the the NV_path_rendering PathTexGen functionality.
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +0000245 */
commit-bot@chromium.org0a6fe712014-04-23 19:26:26 +0000246class GrGLPathTexGenProgramEffects : public GrGLProgramEffects {
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +0000247public:
248 virtual void setData(GrGpuGL*,
249 const GrGLUniformManager&,
250 const GrEffectStage* effectStages[]) SK_OVERRIDE;
251
252private:
commit-bot@chromium.org0a6fe712014-04-23 19:26:26 +0000253 friend class GrGLPathTexGenProgramEffectsBuilder;
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +0000254
commit-bot@chromium.org0a6fe712014-04-23 19:26:26 +0000255 GrGLPathTexGenProgramEffects(int reserveCount)
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +0000256 : 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 */
commit-bot@chromium.org0a6fe712014-04-23 19:26:26 +0000279 void setupPathTexGen(GrGLFragmentOnlyShaderBuilder*,
280 const GrEffectRef&,
281 EffectKey,
282 TransformedCoordsArray*);
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +0000283
284 /**
commit-bot@chromium.org0a6fe712014-04-23 19:26:26 +0000285 * Helper for setData(). Sets the PathTexGen state for each transform in an effect.
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +0000286 */
commit-bot@chromium.org0a6fe712014-04-23 19:26:26 +0000287 void setPathTexGenState(GrGpuGL*, const GrDrawEffect&, int effectIdx);
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +0000288
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/**
commit-bot@chromium.org0a6fe712014-04-23 19:26:26 +0000302 * This class is used to construct a GrGLPathTexGenProgramEffects* object.
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +0000303 */
commit-bot@chromium.org0a6fe712014-04-23 19:26:26 +0000304class GrGLPathTexGenProgramEffectsBuilder : public GrGLProgramEffectsBuilder {
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +0000305public:
commit-bot@chromium.org0a6fe712014-04-23 19:26:26 +0000306 GrGLPathTexGenProgramEffectsBuilder(GrGLFragmentOnlyShaderBuilder*, int reserveCount);
307 virtual ~GrGLPathTexGenProgramEffectsBuilder() { }
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +0000308
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
321private:
322 GrGLFragmentOnlyShaderBuilder* fBuilder;
commit-bot@chromium.org0a6fe712014-04-23 19:26:26 +0000323 SkAutoTDelete<GrGLPathTexGenProgramEffects> fProgramEffects;
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +0000324
325 typedef GrGLProgramEffectsBuilder INHERITED;
326};
327
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +0000328#endif