blob: daaebd6b37d8265313d4f5da6c4f2bf7d3d75f99 [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"
kkinnunen7510b222014-07-30 00:04:16 -070012#include "GrGLProgramDataManager.h"
kkinnunenec56e452014-08-25 22:21:16 -070013#include "GrGpu.h"
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +000014#include "GrTexture.h"
15#include "GrTextureAccess.h"
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +000016
bsalomonf99f8842014-07-07 11:54:23 -070017class GrEffect;
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +000018class GrEffectStage;
commit-bot@chromium.org261dc562013-10-04 15:42:56 +000019class GrGLVertexProgramEffectsBuilder;
joshualitt30ba4362014-08-21 20:18:45 -070020class GrGLProgramBuilder;
21class GrGLFullProgramBuilder;
22class GrGLFragmentOnlyProgramBuilder;
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +000023
24/**
25 * This class encapsulates an array of GrGLEffects and their supporting data (coord transforms
26 * and textures). It is built with GrGLProgramEffectsBuilder, then used to manage the necessary GL
27 * state and shader uniforms.
28 */
commit-bot@chromium.orga05fa062014-05-30 18:55:03 +000029class GrGLProgramEffects : public SkRefCnt {
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +000030public:
kkinnunen7510b222014-07-30 00:04:16 -070031 typedef GrGLProgramDataManager::UniformHandle UniformHandle;
kkinnunenec56e452014-08-25 22:21:16 -070032 typedef GrGLProgramDataManager::VaryingHandle VaryingHandle;
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +000033
34 /**
bsalomon929f29a2014-07-17 07:55:11 -070035 * This class emits some of the code inserted into the shaders for an effect. The code it
36 * creates may be dependent on properties of the effect that the effect itself doesn't use
37 * in its key (e.g. the pixel format of textures used). So this class inserts a meta-key for
38 * every effect using this function. It is also responsible for inserting the effect's class ID
39 * which must be different for every GrEffect subclass. It can fail if an effect uses too many
40 * textures, attributes, etc for the space allotted in the meta-key.
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +000041 */
bsalomon929f29a2014-07-17 07:55:11 -070042 static bool GenEffectMetaKey(const GrDrawEffect&, const GrGLCaps&, GrEffectKeyBuilder*);
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +000043
commit-bot@chromium.org261dc562013-10-04 15:42:56 +000044 virtual ~GrGLProgramEffects();
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +000045
46 /**
47 * Assigns a texture unit to each sampler. It starts on *texUnitIdx and writes the next
48 * available unit to *texUnitIdx when it returns.
49 */
kkinnunen7510b222014-07-30 00:04:16 -070050 void initSamplers(const GrGLProgramDataManager&, int* texUnitIdx);
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +000051
52 /**
53 * Calls setData() on each effect, and sets their transformation matrices and texture bindings.
54 */
commit-bot@chromium.org261dc562013-10-04 15:42:56 +000055 virtual void setData(GrGpuGL*,
kkinnunenec56e452014-08-25 22:21:16 -070056 GrGpu::DrawType,
kkinnunen7510b222014-07-30 00:04:16 -070057 const GrGLProgramDataManager&,
commit-bot@chromium.org261dc562013-10-04 15:42:56 +000058 const GrEffectStage* effectStages[]) = 0;
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +000059
joshualittbd769d02014-09-04 08:56:46 -070060 virtual void setData(GrGpuGL*,
61 GrGpu::DrawType,
62 const GrGLProgramDataManager&,
63 const GrEffectStage* effectStages) { SkFAIL("DO NOT USE"); }
64
joshualitt30ba4362014-08-21 20:18:45 -070065 void addEffect(GrGLEffect* effect) { fGLEffects.push_back(effect); }
66
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +000067 /**
68 * Passed to GrGLEffects so they can add transformed coordinates to their shader code.
69 */
70 class TransformedCoords {
71 public:
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +000072 TransformedCoords(const SkString& name, GrSLType type)
commit-bot@chromium.org5fd7d5c2013-10-04 01:20:09 +000073 : fName(name), fType(type) {
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +000074 }
75
76 const char* c_str() const { return fName.c_str(); }
77 GrSLType type() const { return fType; }
78 const SkString& getName() const { return fName; }
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +000079
80 private:
81 SkString fName;
82 GrSLType fType;
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +000083 };
84
85 typedef SkTArray<TransformedCoords> TransformedCoordsArray;
86
87 /**
88 * Passed to GrGLEffects so they can add texture reads to their shader code.
89 */
90 class TextureSampler {
91 public:
92 TextureSampler(UniformHandle uniform, const GrTextureAccess& access)
93 : fSamplerUniform(uniform)
94 , fConfigComponentMask(GrPixelConfigComponentMask(access.getTexture()->config())) {
95 SkASSERT(0 != fConfigComponentMask);
96 memcpy(fSwizzle, access.getSwizzle(), 5);
97 }
98
99 UniformHandle samplerUniform() const { return fSamplerUniform; }
100 // bitfield of GrColorComponentFlags present in the texture's config.
101 uint32_t configComponentMask() const { return fConfigComponentMask; }
102 const char* swizzle() const { return fSwizzle; }
103
104 private:
105 UniformHandle fSamplerUniform;
106 uint32_t fConfigComponentMask;
107 char fSwizzle[5];
108 };
109
110 typedef SkTArray<TextureSampler> TextureSamplerArray;
111
commit-bot@chromium.org261dc562013-10-04 15:42:56 +0000112protected:
joshualitt30ba4362014-08-21 20:18:45 -0700113
bsalomon929f29a2014-07-17 07:55:11 -0700114 /**
115 * Helpers for GenEffectMetaKey.
116 */
bsalomon63e99f72014-07-21 08:03:14 -0700117 static uint32_t GenAttribKey(const GrDrawEffect&);
118 static uint32_t GenTransformKey(const GrDrawEffect&);
119 static uint32_t GenTextureKey(const GrDrawEffect&, const GrGLCaps&);
bsalomon929f29a2014-07-17 07:55:11 -0700120
commit-bot@chromium.org261dc562013-10-04 15:42:56 +0000121 GrGLProgramEffects(int reserveCount)
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +0000122 : fGLEffects(reserveCount)
commit-bot@chromium.org261dc562013-10-04 15:42:56 +0000123 , fSamplers(reserveCount) {
124 }
125
126 /**
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +0000127 * Helper for emitEffect() in a subclasses. Emits uniforms for an effect's texture accesses and
128 * appends the necessary data to the TextureSamplerArray* object so effects can add texture
129 * lookups to their code. This method is only meant to be called during the construction phase.
130 */
joshualitt30ba4362014-08-21 20:18:45 -0700131 void emitSamplers(GrGLProgramBuilder*, const GrEffect*, TextureSamplerArray*);
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +0000132
133 /**
commit-bot@chromium.org261dc562013-10-04 15:42:56 +0000134 * Helper for setData(). Binds all the textures for an effect.
135 */
bsalomonf99f8842014-07-07 11:54:23 -0700136 void bindTextures(GrGpuGL*, const GrEffect*, int effectIdx);
commit-bot@chromium.org261dc562013-10-04 15:42:56 +0000137
138 struct Sampler {
139 SkDEBUGCODE(Sampler() : fTextureUnit(-1) {})
140 UniformHandle fUniform;
141 int fTextureUnit;
142 };
143
144 SkTArray<GrGLEffect*> fGLEffects;
145 SkTArray<SkSTArray<4, Sampler, true> > fSamplers;
commit-bot@chromium.orga05fa062014-05-30 18:55:03 +0000146
147private:
148 typedef SkRefCnt INHERITED;
commit-bot@chromium.org261dc562013-10-04 15:42:56 +0000149};
150
151/**
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +0000152 * This is an abstract base class for constructing different types of GrGLProgramEffects objects.
153 */
154class GrGLProgramEffectsBuilder {
155public:
mtklein@google.comf1077f92013-11-20 15:13:49 +0000156 virtual ~GrGLProgramEffectsBuilder() { }
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +0000157 /**
158 * Emits the effect's shader code, and stores the necessary uniforms internally.
159 */
160 virtual void emitEffect(const GrEffectStage&,
bsalomon63e99f72014-07-21 08:03:14 -0700161 const GrEffectKey&,
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +0000162 const char* outColor,
163 const char* inColor,
164 int stageIndex) = 0;
165};
166
167////////////////////////////////////////////////////////////////////////////////
168
169/**
commit-bot@chromium.org261dc562013-10-04 15:42:56 +0000170 * This is a GrGLProgramEffects implementation that does coord transforms with the vertex shader.
171 */
172class GrGLVertexProgramEffects : public GrGLProgramEffects {
173public:
174 virtual void setData(GrGpuGL*,
kkinnunenec56e452014-08-25 22:21:16 -0700175 GrGpu::DrawType,
kkinnunen7510b222014-07-30 00:04:16 -0700176 const GrGLProgramDataManager&,
commit-bot@chromium.org261dc562013-10-04 15:42:56 +0000177 const GrEffectStage* effectStages[]) SK_OVERRIDE;
178
joshualittbd769d02014-09-04 08:56:46 -0700179 virtual void setData(GrGpuGL*,
180 GrGpu::DrawType,
181 const GrGLProgramDataManager&,
182 const GrEffectStage* effectStages) SK_OVERRIDE;
183
commit-bot@chromium.org261dc562013-10-04 15:42:56 +0000184private:
joshualitt30ba4362014-08-21 20:18:45 -0700185 friend class GrGLFullProgramBuilder;
commit-bot@chromium.org261dc562013-10-04 15:42:56 +0000186
187 GrGLVertexProgramEffects(int reserveCount, bool explicitLocalCoords)
188 : INHERITED(reserveCount)
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +0000189 , fTransforms(reserveCount)
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +0000190 , fHasExplicitLocalCoords(explicitLocalCoords) {
191 }
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +0000192 /**
joshualitt30ba4362014-08-21 20:18:45 -0700193 * This method is meant to only be called during the construction phase.
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +0000194 */
joshualitt30ba4362014-08-21 20:18:45 -0700195 void emitEffect(GrGLFullProgramBuilder*,
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +0000196 const GrEffectStage&,
bsalomon63e99f72014-07-21 08:03:14 -0700197 const GrEffectKey&,
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +0000198 const char* outColor,
199 const char* inColor,
200 int stageIndex);
201
202 /**
203 * Helper for emitEffect(). Emits any attributes an effect may have.
204 */
joshualitt30ba4362014-08-21 20:18:45 -0700205 void emitAttributes(GrGLFullProgramBuilder*, const GrEffectStage&);
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +0000206
207 /**
208 * Helper for emitEffect(). Emits code to implement an effect's coord transforms in the VS.
209 * Varyings are added as an outputs of the VS and inputs to the FS. The varyings may be either a
210 * vec2f or vec3f depending upon whether perspective interpolation is required or not. The names
211 * of the varyings in the VS and FS as well their types are appended to the
212 * TransformedCoordsArray* object, which is in turn passed to the effect's emitCode() function.
213 */
joshualitt30ba4362014-08-21 20:18:45 -0700214 void emitTransforms(GrGLFullProgramBuilder*,
bsalomon848faf02014-07-11 10:01:02 -0700215 const GrDrawEffect&,
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +0000216 TransformedCoordsArray*);
217
218 /**
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +0000219 * Helper for setData(). Sets all the transform matrices for an effect.
220 */
kkinnunenec56e452014-08-25 22:21:16 -0700221 void setTransformData(GrGpuGL* gpu, const GrGLProgramDataManager&, const GrDrawEffect&, int effectIdx);
222 void setPathTransformData(GrGpuGL* gpu, const GrGLProgramDataManager&, const GrDrawEffect&,
223 int effectIdx);
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +0000224
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +0000225 struct Transform {
226 Transform() { fCurrentValue = SkMatrix::InvalidMatrix(); }
227 UniformHandle fHandle;
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +0000228 SkMatrix fCurrentValue;
229 };
230
kkinnunenec56e452014-08-25 22:21:16 -0700231 struct PathTransform {
232 PathTransform() { fCurrentValue = SkMatrix::InvalidMatrix(); }
233 VaryingHandle fHandle;
234 SkMatrix fCurrentValue;
235 GrSLType fType;
236 };
237
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +0000238 SkTArray<SkSTArray<2, Transform, true> > fTransforms;
kkinnunenec56e452014-08-25 22:21:16 -0700239 SkTArray<SkTArray<PathTransform, true> > fPathTransforms;
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +0000240 bool fHasExplicitLocalCoords;
commit-bot@chromium.org261dc562013-10-04 15:42:56 +0000241
joshualitt30ba4362014-08-21 20:18:45 -0700242 friend class GrGLVertexProgramEffectsBuilder;
243
commit-bot@chromium.org261dc562013-10-04 15:42:56 +0000244 typedef GrGLProgramEffects INHERITED;
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +0000245};
246
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +0000247/**
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +0000248 * This class is used to construct a GrGLVertexProgramEffects* object.
commit-bot@chromium.org261dc562013-10-04 15:42:56 +0000249 */
250class GrGLVertexProgramEffectsBuilder : public GrGLProgramEffectsBuilder {
251public:
joshualitt30ba4362014-08-21 20:18:45 -0700252 GrGLVertexProgramEffectsBuilder(GrGLFullProgramBuilder*, int reserveCount);
mtklein@google.comf1077f92013-11-20 15:13:49 +0000253 virtual ~GrGLVertexProgramEffectsBuilder() { }
commit-bot@chromium.org261dc562013-10-04 15:42:56 +0000254 virtual void emitEffect(const GrEffectStage&,
bsalomon63e99f72014-07-21 08:03:14 -0700255 const GrEffectKey&,
commit-bot@chromium.org261dc562013-10-04 15:42:56 +0000256 const char* outColor,
257 const char* inColor,
258 int stageIndex) SK_OVERRIDE;
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +0000259 /**
260 * Finalizes the building process and returns the effect array. After this call, the builder
261 * becomes invalid.
262 */
263 GrGLProgramEffects* finish() { return fProgramEffects.detach(); }
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +0000264private:
joshualitt30ba4362014-08-21 20:18:45 -0700265 GrGLFullProgramBuilder* fBuilder;
commit-bot@chromium.org261dc562013-10-04 15:42:56 +0000266 SkAutoTDelete<GrGLVertexProgramEffects> fProgramEffects;
commit-bot@chromium.org261dc562013-10-04 15:42:56 +0000267 typedef GrGLProgramEffectsBuilder INHERITED;
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +0000268};
269
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +0000270////////////////////////////////////////////////////////////////////////////////
271
272/**
commit-bot@chromium.org0a6fe712014-04-23 19:26:26 +0000273 * This is a GrGLProgramEffects implementation that does coord transforms with
274 * the the NV_path_rendering PathTexGen functionality.
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +0000275 */
commit-bot@chromium.org0a6fe712014-04-23 19:26:26 +0000276class GrGLPathTexGenProgramEffects : public GrGLProgramEffects {
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +0000277public:
278 virtual void setData(GrGpuGL*,
kkinnunenec56e452014-08-25 22:21:16 -0700279 GrGpu::DrawType,
kkinnunen7510b222014-07-30 00:04:16 -0700280 const GrGLProgramDataManager&,
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +0000281 const GrEffectStage* effectStages[]) SK_OVERRIDE;
282
283private:
joshualitt30ba4362014-08-21 20:18:45 -0700284 friend class GrGLFragmentOnlyProgramBuilder;
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +0000285
commit-bot@chromium.org0a6fe712014-04-23 19:26:26 +0000286 GrGLPathTexGenProgramEffects(int reserveCount)
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +0000287 : INHERITED(reserveCount)
288 , fTransforms(reserveCount) {
289 }
290
291 /**
joshualitt30ba4362014-08-21 20:18:45 -0700292 * This method is meant to only be called during the construction phase.
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +0000293 */
joshualitt30ba4362014-08-21 20:18:45 -0700294 void emitEffect(GrGLFragmentOnlyProgramBuilder*,
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +0000295 const GrEffectStage&,
bsalomon63e99f72014-07-21 08:03:14 -0700296 const GrEffectKey&,
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +0000297 const char* outColor,
298 const char* inColor,
299 int stageIndex);
300
301 /**
302 * Helper for emitEffect(). Allocates texture units from the builder for each transform in an
303 * effect. The transforms all use adjacent texture units. They either use two or three of the
304 * coordinates at a given texture unit, depending on if they need perspective interpolation.
305 * The expressions to access the transformed coords (i.e. 'vec2(gl_TexCoord[0])') as well as the
306 * types are appended to the TransformedCoordsArray* object, which is in turn passed to the
307 * effect's emitCode() function.
308 */
joshualitt30ba4362014-08-21 20:18:45 -0700309 void setupPathTexGen(GrGLFragmentOnlyProgramBuilder*,
bsalomon848faf02014-07-11 10:01:02 -0700310 const GrDrawEffect&,
commit-bot@chromium.org0a6fe712014-04-23 19:26:26 +0000311 TransformedCoordsArray*);
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +0000312
313 /**
commit-bot@chromium.org0a6fe712014-04-23 19:26:26 +0000314 * Helper for setData(). Sets the PathTexGen state for each transform in an effect.
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +0000315 */
commit-bot@chromium.org0a6fe712014-04-23 19:26:26 +0000316 void setPathTexGenState(GrGpuGL*, const GrDrawEffect&, int effectIdx);
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +0000317
318 struct Transforms {
bsalomon63e99f72014-07-21 08:03:14 -0700319 Transforms(uint32_t transformKey, int texCoordIndex)
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +0000320 : fTransformKey(transformKey), fTexCoordIndex(texCoordIndex) {}
bsalomon63e99f72014-07-21 08:03:14 -0700321 uint32_t fTransformKey;
322 int fTexCoordIndex;
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +0000323 };
324
325 SkTArray<Transforms> fTransforms;
326
joshualitt30ba4362014-08-21 20:18:45 -0700327 friend class GrGLPathTexGenProgramEffectsBuilder;
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +0000328 typedef GrGLProgramEffects INHERITED;
329};
330
331/**
commit-bot@chromium.org0a6fe712014-04-23 19:26:26 +0000332 * This class is used to construct a GrGLPathTexGenProgramEffects* object.
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +0000333 */
commit-bot@chromium.org0a6fe712014-04-23 19:26:26 +0000334class GrGLPathTexGenProgramEffectsBuilder : public GrGLProgramEffectsBuilder {
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +0000335public:
joshualitt30ba4362014-08-21 20:18:45 -0700336 GrGLPathTexGenProgramEffectsBuilder(GrGLFragmentOnlyProgramBuilder*, int reserveCount);
commit-bot@chromium.org0a6fe712014-04-23 19:26:26 +0000337 virtual ~GrGLPathTexGenProgramEffectsBuilder() { }
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +0000338 virtual void emitEffect(const GrEffectStage&,
bsalomon63e99f72014-07-21 08:03:14 -0700339 const GrEffectKey&,
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +0000340 const char* outColor,
341 const char* inColor,
342 int stageIndex) SK_OVERRIDE;
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +0000343 /**
344 * Finalizes the building process and returns the effect array. After this call, the builder
345 * becomes invalid.
346 */
347 GrGLProgramEffects* finish() { return fProgramEffects.detach(); }
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +0000348private:
joshualitt30ba4362014-08-21 20:18:45 -0700349 GrGLFragmentOnlyProgramBuilder* fBuilder;
commit-bot@chromium.org0a6fe712014-04-23 19:26:26 +0000350 SkAutoTDelete<GrGLPathTexGenProgramEffects> fProgramEffects;
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +0000351 typedef GrGLProgramEffectsBuilder INHERITED;
352};
353
joshualitt30ba4362014-08-21 20:18:45 -0700354
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +0000355#endif