blob: b74dc96c4b80f3f24eefed30fad9ec795a610a5d [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:
commit-bot@chromium.org5fd7d5c2013-10-04 01:20:09 +000057 TransformedCoords(const char* name, GrSLType type)
58 : fName(name), fType(type) {
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +000059 }
60
61 const char* c_str() const { return fName.c_str(); }
62 GrSLType type() const { return fType; }
63 const SkString& getName() const { return fName; }
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +000064
65 private:
66 SkString fName;
67 GrSLType fType;
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +000068 };
69
70 typedef SkTArray<TransformedCoords> TransformedCoordsArray;
71
72 /**
73 * Passed to GrGLEffects so they can add texture reads to their shader code.
74 */
75 class TextureSampler {
76 public:
77 TextureSampler(UniformHandle uniform, const GrTextureAccess& access)
78 : fSamplerUniform(uniform)
79 , fConfigComponentMask(GrPixelConfigComponentMask(access.getTexture()->config())) {
80 SkASSERT(0 != fConfigComponentMask);
81 memcpy(fSwizzle, access.getSwizzle(), 5);
82 }
83
84 UniformHandle samplerUniform() const { return fSamplerUniform; }
85 // bitfield of GrColorComponentFlags present in the texture's config.
86 uint32_t configComponentMask() const { return fConfigComponentMask; }
87 const char* swizzle() const { return fSwizzle; }
88
89 private:
90 UniformHandle fSamplerUniform;
91 uint32_t fConfigComponentMask;
92 char fSwizzle[5];
93 };
94
95 typedef SkTArray<TextureSampler> TextureSamplerArray;
96
97private:
98 friend class GrGLProgramEffectsBuilder;
99
100 GrGLProgramEffects(int reserveCount, bool explicitLocalCoords)
101 : fGLEffects(reserveCount)
102 , fTransforms(reserveCount)
103 , fSamplers(reserveCount)
104 , fHasExplicitLocalCoords(explicitLocalCoords) {
105 }
106
107 /**
108 * Helper for setData(). Sets all the transform matrices for an effect.
109 */
110 void setTransformData(const GrGLUniformManager&, const GrDrawEffect&, int effectIdx);
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 Transform {
118 Transform() { fCurrentValue = SkMatrix::InvalidMatrix(); }
119 UniformHandle fHandle;
120 GrSLType fType;
121 SkMatrix fCurrentValue;
122 };
123
124 struct Sampler {
125 SkDEBUGCODE(Sampler() : fTextureUnit(-1) {})
126 UniformHandle fUniform;
127 int fTextureUnit;
128 };
129
130 SkTArray<GrGLEffect*> fGLEffects;
131 SkTArray<SkSTArray<2, Transform, true> > fTransforms;
132 SkTArray<SkSTArray<4, Sampler, true> > fSamplers;
133 bool fHasExplicitLocalCoords;
134};
135
136////////////////////////////////////////////////////////////////////////////////
137
138/**
139 * This class is used to construct a GrGLProgramEffects.
140 */
141class GrGLProgramEffectsBuilder {
142public:
143 GrGLProgramEffectsBuilder(GrGLShaderBuilder* builder, int reserveCount);
144
145 /**
146 * Emits the effect's shader code, and stores the necessary uniforms internally.
147 */
148 void emitEffect(const GrEffectStage&,
149 GrGLProgramEffects::EffectKey,
150 const char* outColor,
151 const char* inColor,
152 int stageIndex);
153
154 /**
155 * Finalizes the building process and returns the effect array. After this call, the builder
156 * becomes invalid.
157 */
158 GrGLProgramEffects* finish() { return fProgramEffects.detach(); }
159
160private:
161 /**
162 * Helper for emitEffect(). Emits any attributes an effect might have.
163 */
164 void emitAttributes(const GrEffectStage&);
165
166 /**
167 * Helper for emitEffect(). Emits code to implement an effect's coord transforms in the VS.
168 * Varyings are added as an outputs of the VS and inputs to the FS. The varyings may be either a
169 * vec2f or vec3f depending upon whether perspective interpolation is required or not. The names
170 * of the varyings in the VS and FS as well their types are appended to the
171 * TransformedCoordsArray* object, which is in turn passed to the effect's emitCode() function.
172 */
173 void emitTransforms(const GrEffectRef&,
174 GrGLProgramEffects::EffectKey,
175 GrGLProgramEffects::TransformedCoordsArray*);
176
177 /**
178 * Helper for emitEffect(). Emits uniforms for an effect's texture accesses. The uniform info
179 * as well as texture access parameters are appended to the TextureSamplerArray* object, which
180 * is in turn passed to the effect's emitCode() function.
181 */
182 void emitSamplers(const GrEffectRef&,
183 GrGLProgramEffects::TextureSamplerArray*);
184
185 GrGLShaderBuilder* fBuilder;
186 SkAutoTDelete<GrGLProgramEffects> fProgramEffects;
187};
188
189#endif