blob: c2c21042b08d9ac153ac2f52be3b9ec3333b5542 [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;
18class GrGLShaderBuilder;
19
20/**
21 * This class encapsulates an array of GrGLEffects and their supporting data (coord transforms
22 * and textures). It is built with GrGLProgramEffectsBuilder, then used to manage the necessary GL
23 * state and shader uniforms.
24 */
25class GrGLProgramEffects {
26public:
27 typedef GrBackendEffectFactory::EffectKey EffectKey;
28 typedef GrGLUniformManager::UniformHandle UniformHandle;
29
30 /**
31 * These methods generate different portions of an effect's final key.
32 */
33 static EffectKey GenAttribKey(const GrDrawEffect&);
34 static EffectKey GenTransformKey(const GrDrawEffect&);
35 static EffectKey GenTextureKey(const GrDrawEffect&, const GrGLCaps&);
36
37 ~GrGLProgramEffects();
38
39 /**
40 * Assigns a texture unit to each sampler. It starts on *texUnitIdx and writes the next
41 * available unit to *texUnitIdx when it returns.
42 */
43 void initSamplers(const GrGLUniformManager&, int* texUnitIdx);
44
45 /**
46 * Calls setData() on each effect, and sets their transformation matrices and texture bindings.
47 */
48 void setData(GrGpuGL*,
49 const GrGLUniformManager&,
50 const GrEffectStage* effectStages[]);
51
52 /**
53 * Passed to GrGLEffects so they can add transformed coordinates to their shader code.
54 */
55 class TransformedCoords {
56 public:
57 TransformedCoords(const char* name, GrSLType type, const char* vsName)
58 : fName(name), fType(type), fVSName(vsName) {
59 }
60
61 const char* c_str() const { return fName.c_str(); }
62 GrSLType type() const { return fType; }
63 const SkString& getName() const { return fName; }
64 // TODO: Remove the VS name when we have vertexless shaders, and gradients are reworked.
65 const SkString& getVSName() const { return fVSName; }
66
67 private:
68 SkString fName;
69 GrSLType fType;
70 SkString fVSName;
71 };
72
73 typedef SkTArray<TransformedCoords> TransformedCoordsArray;
74
75 /**
76 * Passed to GrGLEffects so they can add texture reads to their shader code.
77 */
78 class TextureSampler {
79 public:
80 TextureSampler(UniformHandle uniform, const GrTextureAccess& access)
81 : fSamplerUniform(uniform)
82 , fConfigComponentMask(GrPixelConfigComponentMask(access.getTexture()->config())) {
83 SkASSERT(0 != fConfigComponentMask);
84 memcpy(fSwizzle, access.getSwizzle(), 5);
85 }
86
87 UniformHandle samplerUniform() const { return fSamplerUniform; }
88 // bitfield of GrColorComponentFlags present in the texture's config.
89 uint32_t configComponentMask() const { return fConfigComponentMask; }
90 const char* swizzle() const { return fSwizzle; }
91
92 private:
93 UniformHandle fSamplerUniform;
94 uint32_t fConfigComponentMask;
95 char fSwizzle[5];
96 };
97
98 typedef SkTArray<TextureSampler> TextureSamplerArray;
99
100private:
101 friend class GrGLProgramEffectsBuilder;
102
103 GrGLProgramEffects(int reserveCount, bool explicitLocalCoords)
104 : fGLEffects(reserveCount)
105 , fTransforms(reserveCount)
106 , fSamplers(reserveCount)
107 , fHasExplicitLocalCoords(explicitLocalCoords) {
108 }
109
110 /**
111 * Helper for setData(). Sets all the transform matrices for an effect.
112 */
113 void setTransformData(const GrGLUniformManager&, const GrDrawEffect&, int effectIdx);
114
115 /**
116 * Helper for setData(). Binds all the textures for an effect.
117 */
118 void bindTextures(GrGpuGL*, const GrEffectRef&, int effectIdx);
119
120 struct Transform {
121 Transform() { fCurrentValue = SkMatrix::InvalidMatrix(); }
122 UniformHandle fHandle;
123 GrSLType fType;
124 SkMatrix fCurrentValue;
125 };
126
127 struct Sampler {
128 SkDEBUGCODE(Sampler() : fTextureUnit(-1) {})
129 UniformHandle fUniform;
130 int fTextureUnit;
131 };
132
133 SkTArray<GrGLEffect*> fGLEffects;
134 SkTArray<SkSTArray<2, Transform, true> > fTransforms;
135 SkTArray<SkSTArray<4, Sampler, true> > fSamplers;
136 bool fHasExplicitLocalCoords;
137};
138
139////////////////////////////////////////////////////////////////////////////////
140
141/**
142 * This class is used to construct a GrGLProgramEffects.
143 */
144class GrGLProgramEffectsBuilder {
145public:
146 GrGLProgramEffectsBuilder(GrGLShaderBuilder* builder, int reserveCount);
147
148 /**
149 * Emits the effect's shader code, and stores the necessary uniforms internally.
150 */
151 void emitEffect(const GrEffectStage&,
152 GrGLProgramEffects::EffectKey,
153 const char* outColor,
154 const char* inColor,
155 int stageIndex);
156
157 /**
158 * Finalizes the building process and returns the effect array. After this call, the builder
159 * becomes invalid.
160 */
161 GrGLProgramEffects* finish() { return fProgramEffects.detach(); }
162
163private:
164 /**
165 * Helper for emitEffect(). Emits any attributes an effect might have.
166 */
167 void emitAttributes(const GrEffectStage&);
168
169 /**
170 * Helper for emitEffect(). Emits code to implement an effect's coord transforms in the VS.
171 * Varyings are added as an outputs of the VS and inputs to the FS. The varyings may be either a
172 * vec2f or vec3f depending upon whether perspective interpolation is required or not. The names
173 * of the varyings in the VS and FS as well their types are appended to the
174 * TransformedCoordsArray* object, which is in turn passed to the effect's emitCode() function.
175 */
176 void emitTransforms(const GrEffectRef&,
177 GrGLProgramEffects::EffectKey,
178 GrGLProgramEffects::TransformedCoordsArray*);
179
180 /**
181 * Helper for emitEffect(). Emits uniforms for an effect's texture accesses. The uniform info
182 * as well as texture access parameters are appended to the TextureSamplerArray* object, which
183 * is in turn passed to the effect's emitCode() function.
184 */
185 void emitSamplers(const GrEffectRef&,
186 GrGLProgramEffects::TextureSamplerArray*);
187
188 GrGLShaderBuilder* fBuilder;
189 SkAutoTDelete<GrGLProgramEffects> fProgramEffects;
190};
191
192#endif