blob: f6f975ae4e76106a4c342e6b70d02248392657dc [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;
17class GrGLProgramEffectsBuilder;
commit-bot@chromium.org261dc562013-10-04 15:42:56 +000018class GrGLVertexProgramEffectsBuilder;
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +000019class GrGLShaderBuilder;
commit-bot@chromium.org261dc562013-10-04 15:42:56 +000020class GrGLFullShaderBuilder;
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 */
27class GrGLProgramEffects {
28public:
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.org5fd7d5c2013-10-04 01:20:09 +000059 TransformedCoords(const char* name, GrSLType type)
60 : 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.org3390b9a2013-10-03 15:17:58 +0000100 friend class GrGLProgramEffectsBuilder;
101
commit-bot@chromium.org261dc562013-10-04 15:42:56 +0000102 GrGLProgramEffects(int reserveCount)
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +0000103 : fGLEffects(reserveCount)
commit-bot@chromium.org261dc562013-10-04 15:42:56 +0000104 , fSamplers(reserveCount) {
105 }
106
107 /**
108 * Helper for setData(). Binds all the textures for an effect.
109 */
110 void bindTextures(GrGpuGL*, const GrEffectRef&, int effectIdx);
111
112 struct Sampler {
113 SkDEBUGCODE(Sampler() : fTextureUnit(-1) {})
114 UniformHandle fUniform;
115 int fTextureUnit;
116 };
117
118 SkTArray<GrGLEffect*> fGLEffects;
119 SkTArray<SkSTArray<4, Sampler, true> > fSamplers;
120};
121
122/**
123 * This is a GrGLProgramEffects implementation that does coord transforms with the vertex shader.
124 */
125class GrGLVertexProgramEffects : public GrGLProgramEffects {
126public:
127 virtual void setData(GrGpuGL*,
128 const GrGLUniformManager&,
129 const GrEffectStage* effectStages[]) SK_OVERRIDE;
130
131private:
132 friend class GrGLVertexProgramEffectsBuilder;
133
134 GrGLVertexProgramEffects(int reserveCount, bool explicitLocalCoords)
135 : INHERITED(reserveCount)
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +0000136 , fTransforms(reserveCount)
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +0000137 , fHasExplicitLocalCoords(explicitLocalCoords) {
138 }
139
140 /**
141 * Helper for setData(). Sets all the transform matrices for an effect.
142 */
143 void setTransformData(const GrGLUniformManager&, const GrDrawEffect&, int effectIdx);
144
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +0000145 struct Transform {
146 Transform() { fCurrentValue = SkMatrix::InvalidMatrix(); }
147 UniformHandle fHandle;
148 GrSLType fType;
149 SkMatrix fCurrentValue;
150 };
151
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +0000152 SkTArray<SkSTArray<2, Transform, true> > fTransforms;
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +0000153 bool fHasExplicitLocalCoords;
commit-bot@chromium.org261dc562013-10-04 15:42:56 +0000154
155 typedef GrGLProgramEffects INHERITED;
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +0000156};
157
158////////////////////////////////////////////////////////////////////////////////
159
160/**
commit-bot@chromium.org261dc562013-10-04 15:42:56 +0000161 * This is an abstract base class for constructing different types of GrGLProgramEffects objects.
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +0000162 */
163class GrGLProgramEffectsBuilder {
164public:
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +0000165 /**
166 * Emits the effect's shader code, and stores the necessary uniforms internally.
167 */
commit-bot@chromium.org261dc562013-10-04 15:42:56 +0000168 virtual void emitEffect(const GrEffectStage&,
169 GrGLProgramEffects::EffectKey,
170 const char* outColor,
171 const char* inColor,
172 int stageIndex) = 0;
173
174protected:
175 /**
176 * Helper for emitEffect(). Emits uniforms for an effect's texture accesses and appends the
177 * necessary data to the TextureSamplerArray* object so effects can add texture lookups.
178 */
179 static void emitSamplers(GrGLShaderBuilder*,
180 GrGLProgramEffects*,
181 const GrEffectRef&,
182 GrGLProgramEffects::TextureSamplerArray*);
183};
184
185/**
186 * This class is used to construct a GrGLVertexProgramEffects object.
187 */
188class GrGLVertexProgramEffectsBuilder : public GrGLProgramEffectsBuilder {
189public:
190 GrGLVertexProgramEffectsBuilder(GrGLFullShaderBuilder*, int reserveCount);
191
192 virtual void emitEffect(const GrEffectStage&,
193 GrGLProgramEffects::EffectKey,
194 const char* outColor,
195 const char* inColor,
196 int stageIndex) SK_OVERRIDE;
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +0000197
198 /**
199 * Finalizes the building process and returns the effect array. After this call, the builder
200 * becomes invalid.
201 */
202 GrGLProgramEffects* finish() { return fProgramEffects.detach(); }
203
204private:
205 /**
206 * Helper for emitEffect(). Emits any attributes an effect might have.
207 */
208 void emitAttributes(const GrEffectStage&);
209
210 /**
211 * Helper for emitEffect(). Emits code to implement an effect's coord transforms in the VS.
212 * Varyings are added as an outputs of the VS and inputs to the FS. The varyings may be either a
213 * vec2f or vec3f depending upon whether perspective interpolation is required or not. The names
214 * of the varyings in the VS and FS as well their types are appended to the
215 * TransformedCoordsArray* object, which is in turn passed to the effect's emitCode() function.
216 */
217 void emitTransforms(const GrEffectRef&,
218 GrGLProgramEffects::EffectKey,
219 GrGLProgramEffects::TransformedCoordsArray*);
220
commit-bot@chromium.org261dc562013-10-04 15:42:56 +0000221 GrGLFullShaderBuilder* fBuilder;
222 SkAutoTDelete<GrGLVertexProgramEffects> fProgramEffects;
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +0000223
commit-bot@chromium.org261dc562013-10-04 15:42:56 +0000224 typedef GrGLProgramEffectsBuilder INHERITED;
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +0000225};
226
227#endif