blob: 5c4727b229f04a5526dc74167bb99017cea05f6e [file] [log] [blame]
junov@google.comf93e7172011-03-31 21:26:24 +00001/*
2 Copyright 2011 Google Inc.
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15 */
16
17#ifndef GrGLProgram_DEFINED
18#define GrGLProgram_DEFINED
19
20#include "GrGLInterface.h"
bsalomon@google.com91961302011-05-09 18:39:58 +000021#include "GrStringBuilder.h"
bsalomon@google.com271cffc2011-05-20 14:13:56 +000022#include "GrGpu.h"
junov@google.comf93e7172011-03-31 21:26:24 +000023
Scroggo97c88c22011-05-11 14:05:25 +000024#include "SkXfermode.h"
25
junov@google.comf93e7172011-03-31 21:26:24 +000026class GrBinHashKeyBuilder;
junov@google.comd31cbc42011-05-17 17:01:17 +000027
28struct ShaderCodeSegments {
bsalomon@google.com271cffc2011-05-20 14:13:56 +000029 GrStringBuilder fHeader; // VS+FS, GLSL version, etc
junov@google.comd31cbc42011-05-17 17:01:17 +000030 GrStringBuilder fVSUnis;
31 GrStringBuilder fVSAttrs;
32 GrStringBuilder fVaryings;
33 GrStringBuilder fFSUnis;
bsalomon@google.com271cffc2011-05-20 14:13:56 +000034 GrStringBuilder fFSOutputs;
senorblanco@chromium.org129b8e32011-06-15 17:52:09 +000035 GrStringBuilder fFSFunctions;
junov@google.comd31cbc42011-05-17 17:01:17 +000036 GrStringBuilder fVSCode;
37 GrStringBuilder fFSCode;
38};
junov@google.comf93e7172011-03-31 21:26:24 +000039
40/**
41 * This class manages a GPU program and records per-program information.
42 * We can specify the attribute locations so that they are constant
43 * across our shaders. But the driver determines the uniform locations
44 * at link time. We don't need to remember the sampler uniform location
45 * because we will bind a texture slot to it and never change it
46 * Uniforms are program-local so we can't rely on fHWState to hold the
47 * previous uniform state after a program change.
48 */
49class GrGLProgram {
50public:
51 class CachedData;
52
53 GrGLProgram();
54 ~GrGLProgram();
55
56 /**
57 * Streams data that can uniquely identifies the generated
58 * gpu program into a key, for cache indexing purposes.
59 *
60 * @param key The key object to receive the key data
61 */
62 void buildKey(GrBinHashKeyBuilder& key) const;
63
64 /**
65 * This is the heavy initilization routine for building a GLProgram.
66 * The result of heavy init is not stored in datamembers of GrGLProgam,
67 * but in a separate cacheable container.
68 */
bsalomon@google.com91961302011-05-09 18:39:58 +000069 bool genProgram(CachedData* programData) const;
junov@google.comf93e7172011-03-31 21:26:24 +000070
bsalomon@google.com271cffc2011-05-20 14:13:56 +000071 /**
72 * The shader may modify the blend coeffecients. Params are in/out
73 */
74 void overrideBlend(GrBlendCoeff* srcCoeff, GrBlendCoeff* dstCoeff) const;
75
76 /**
77 * Attribute indices
78 */
bsalomon@google.com91961302011-05-09 18:39:58 +000079 static int PositionAttributeIdx() { return 0; }
80 static int TexCoordAttributeIdx(int tcIdx) { return 1 + tcIdx; }
81 static int ColorAttributeIdx() { return 1 + GrDrawTarget::kMaxTexCoords; }
tomhudson@google.com0d831722011-06-02 15:37:14 +000082 static int ViewMatrixAttributeIdx() {
83 return 2 + GrDrawTarget::kMaxTexCoords;
bsalomon@google.com91961302011-05-09 18:39:58 +000084 }
tomhudson@google.com0d831722011-06-02 15:37:14 +000085 static int TextureMatrixAttributeIdx(int stage) {
86 return 5 + GrDrawTarget::kMaxTexCoords + 3 * stage;
bsalomon@google.com91961302011-05-09 18:39:58 +000087 }
88
junov@google.comf93e7172011-03-31 21:26:24 +000089private:
90
tomhudson@google.com0d831722011-06-02 15:37:14 +000091 // Parameters that affect code generation
92 // These structs should be kept compact; they are the input to an
93 // expensive hash key generator.
junov@google.comf93e7172011-03-31 21:26:24 +000094 struct ProgramDesc {
bsalomon@google.com4be283f2011-04-19 21:15:09 +000095 ProgramDesc() {
96 // since we use this as part of a key we can't have any unitialized
97 // padding
98 memset(this, 0, sizeof(ProgramDesc));
99 }
100
tomhudson@google.com0d831722011-06-02 15:37:14 +0000101 struct StageDesc {
102 enum OptFlagBits {
103 kNoPerspective_OptFlagBit = 1 << 0,
104 kIdentityMatrix_OptFlagBit = 1 << 1,
105 kCustomTextureDomain_OptFlagBit = 1 << 2,
106 kIsEnabled_OptFlagBit = 1 << 7
107 };
108 enum Modulation {
109 kColor_Modulation,
110 kAlpha_Modulation
111 };
112 enum FetchMode {
113 kSingle_FetchMode,
114 k2x2_FetchMode
115 };
116 enum CoordMapping {
117 kIdentity_CoordMapping,
118 kRadialGradient_CoordMapping,
119 kSweepGradient_CoordMapping,
120 kRadial2Gradient_CoordMapping
121 };
junov@google.comf93e7172011-03-31 21:26:24 +0000122
tomhudson@google.com0d831722011-06-02 15:37:14 +0000123 uint8_t fOptFlags;
124 uint8_t fModulation; // casts to enum Modulation
125 uint8_t fFetchMode; // casts to enum FetchMode
126 uint8_t fCoordMapping; // casts to enum CoordMapping
127
128 inline bool isEnabled() const {
129 return fOptFlags & kIsEnabled_OptFlagBit;
130 }
131 inline void setEnabled(bool newValue) {
132 if (newValue) {
133 fOptFlags |= kIsEnabled_OptFlagBit;
134 } else {
135 fOptFlags &= ~kIsEnabled_OptFlagBit;
136 }
137 }
138 };
139
140 enum ColorType {
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000141 kNone_ColorType = 0,
142 kAttribute_ColorType = 1,
143 kUniform_ColorType = 2,
tomhudson@google.com0d831722011-06-02 15:37:14 +0000144 };
145 // Dual-src blending makes use of a secondary output color that can be
bsalomon@google.com271cffc2011-05-20 14:13:56 +0000146 // used as a per-pixel blend coeffecient. This controls whether a
147 // secondary source is output and what value it holds.
148 enum DualSrcOutput {
149 kNone_DualSrcOutput,
150 kCoverage_DualSrcOutput,
151 kCoverageISA_DualSrcOutput,
152 kCoverageISC_DualSrcOutput,
153 kDualSrcOutputCnt
tomhudson@google.com0d831722011-06-02 15:37:14 +0000154 };
bsalomon@google.com271cffc2011-05-20 14:13:56 +0000155
tomhudson@google.com0d831722011-06-02 15:37:14 +0000156 // stripped of bits that don't affect prog generation
157 GrVertexLayout fVertexLayout;
junov@google.comf93e7172011-03-31 21:26:24 +0000158
tomhudson@google.com0d831722011-06-02 15:37:14 +0000159 StageDesc fStages[GrDrawTarget::kNumStages];
Scroggo97c88c22011-05-11 14:05:25 +0000160
tomhudson@google.com0d831722011-06-02 15:37:14 +0000161 uint8_t fColorType; // casts to enum ColorType
162 uint8_t fDualSrcOutput; // casts to enum DualSrcOutput
163 int8_t fFirstCoverageStage;
164 SkBool8 fEmitsPointSize;
senorblanco@chromium.org129b8e32011-06-15 17:52:09 +0000165 SkBool8 fEdgeAAConcave;
junov@google.comf93e7172011-03-31 21:26:24 +0000166
tomhudson@google.com0d831722011-06-02 15:37:14 +0000167 int8_t fEdgeAANumEdges;
168 uint8_t fColorFilterXfermode; // casts to enum SkXfermode::Mode
junov@google.comf93e7172011-03-31 21:26:24 +0000169
senorblanco@chromium.org129b8e32011-06-15 17:52:09 +0000170 uint8_t fPadTo32bLengthMultiple [1];
bsalomon@google.com6aef1fb2011-05-05 12:33:22 +0000171
junov@google.comf93e7172011-03-31 21:26:24 +0000172 } fProgramDesc;
173
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000174 const ProgramDesc& getDesc() { return fProgramDesc; }
175
junov@google.comf93e7172011-03-31 21:26:24 +0000176public:
bsalomon@google.com91961302011-05-09 18:39:58 +0000177 enum {
178 kUnusedUniform = -1,
179 kSetAsAttribute = 1000,
180 };
181
junov@google.comf93e7172011-03-31 21:26:24 +0000182 struct StageUniLocations {
183 GrGLint fTextureMatrixUni;
bsalomon@google.com6aef1fb2011-05-05 12:33:22 +0000184 GrGLint fNormalizedTexelSizeUni;
junov@google.comf93e7172011-03-31 21:26:24 +0000185 GrGLint fSamplerUni;
186 GrGLint fRadial2Uni;
junov@google.com6acc9b32011-05-16 18:32:07 +0000187 GrGLint fTexDomUni;
bsalomon@google.com91961302011-05-09 18:39:58 +0000188 void reset() {
189 fTextureMatrixUni = kUnusedUniform;
190 fNormalizedTexelSizeUni = kUnusedUniform;
191 fSamplerUni = kUnusedUniform;
192 fRadial2Uni = kUnusedUniform;
junov@google.com6acc9b32011-05-16 18:32:07 +0000193 fTexDomUni = kUnusedUniform;
bsalomon@google.com91961302011-05-09 18:39:58 +0000194 }
junov@google.comf93e7172011-03-31 21:26:24 +0000195 };
196
197 struct UniLocations {
198 GrGLint fViewMatrixUni;
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000199 GrGLint fColorUni;
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +0000200 GrGLint fEdgesUni;
Scroggo97c88c22011-05-11 14:05:25 +0000201 GrGLint fColorFilterUni;
junov@google.comf93e7172011-03-31 21:26:24 +0000202 StageUniLocations fStages[GrDrawTarget::kNumStages];
bsalomon@google.com91961302011-05-09 18:39:58 +0000203 void reset() {
204 fViewMatrixUni = kUnusedUniform;
205 fColorUni = kUnusedUniform;
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +0000206 fEdgesUni = kUnusedUniform;
Scroggo97c88c22011-05-11 14:05:25 +0000207 fColorFilterUni = kUnusedUniform;
bsalomon@google.com91961302011-05-09 18:39:58 +0000208 for (int s = 0; s < GrDrawTarget::kNumStages; ++s) {
209 fStages[s].reset();
210 }
211 }
junov@google.comf93e7172011-03-31 21:26:24 +0000212 };
213
214 class CachedData : public ::GrNoncopyable {
215 public:
216 CachedData() {
junov@google.comf93e7172011-03-31 21:26:24 +0000217 }
218
219 ~CachedData() {
junov@google.comf93e7172011-03-31 21:26:24 +0000220 }
221
222 void copyAndTakeOwnership(CachedData& other) {
bsalomon@google.com2d9ddf92011-05-11 16:52:59 +0000223 memcpy(this, &other, sizeof(*this));
junov@google.comf93e7172011-03-31 21:26:24 +0000224 }
225
junov@google.comf93e7172011-03-31 21:26:24 +0000226 public:
227
228 // IDs
229 GrGLuint fVShaderID;
230 GrGLuint fFShaderID;
231 GrGLuint fProgramID;
232 // shader uniform locations (-1 if shader doesn't use them)
233 UniLocations fUniLocations;
234
235 GrMatrix fViewMatrix;
236
237 // these reflect the current values of uniforms
238 // (GL uniform values travel with program)
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000239 GrColor fColor;
Scroggo97c88c22011-05-11 14:05:25 +0000240 GrColor fColorFilterColor;
junov@google.comf93e7172011-03-31 21:26:24 +0000241 GrMatrix fTextureMatrices[GrDrawTarget::kNumStages];
bsalomon@google.com6aef1fb2011-05-05 12:33:22 +0000242 // width and height used for normalized texel size
243 int fTextureWidth[GrDrawTarget::kNumStages];
244 int fTextureHeight[GrDrawTarget::kNumStages];
junov@google.comf93e7172011-03-31 21:26:24 +0000245 GrScalar fRadial2CenterX1[GrDrawTarget::kNumStages];
246 GrScalar fRadial2Radius0[GrDrawTarget::kNumStages];
247 bool fRadial2PosRoot[GrDrawTarget::kNumStages];
junov@google.com2f839402011-05-24 15:13:01 +0000248 GrRect fTextureDomain[GrDrawTarget::kNumStages];
junov@google.comf93e7172011-03-31 21:26:24 +0000249
250 private:
251 enum Constants {
252 kUniLocationPreAllocSize = 8
253 };
254
junov@google.comf93e7172011-03-31 21:26:24 +0000255 }; // CachedData
256
junov@google.comf93e7172011-03-31 21:26:24 +0000257private:
bsalomon@google.com91961302011-05-09 18:39:58 +0000258 enum {
259 kUseUniform = 2000
260 };
261
262 // should set all fields in locations var to kUseUniform if the
263 // corresponding uniform is required for the program.
junov@google.comf93e7172011-03-31 21:26:24 +0000264 void genStageCode(int stageNum,
265 const ProgramDesc::StageDesc& desc,
266 const char* fsInColor, // NULL means no incoming color
267 const char* fsOutColor,
268 const char* vsInCoord,
269 ShaderCodeSegments* segments,
270 StageUniLocations* locations) const;
271
bsalomon@google.com91961302011-05-09 18:39:58 +0000272 static bool CompileFSAndVS(const ShaderCodeSegments& segments,
273 CachedData* programData);
274
junov@google.comf93e7172011-03-31 21:26:24 +0000275 // Compiles a GL shader, returns shader ID or 0 if failed
276 // params have same meaning as glShaderSource
277 static GrGLuint CompileShader(GrGLenum type, int stringCnt,
278 const char** strings,
279 int* stringLengths);
280
bsalomon@google.com91961302011-05-09 18:39:58 +0000281 // Creates a GL program ID, binds shader attributes to GL vertex attrs, and
282 // links the program
bsalomon@google.com271cffc2011-05-20 14:13:56 +0000283 bool bindOutputsAttribsAndLinkProgram(
284 GrStringBuilder texCoordAttrNames[GrDrawTarget::kMaxTexCoords],
285 bool bindColorOut,
286 bool bindDualSrcOut,
287 CachedData* programData) const;
bsalomon@google.com91961302011-05-09 18:39:58 +0000288
289 // Gets locations for all uniforms set to kUseUniform and initializes cache
290 // to invalid values.
291 void getUniformLocationsAndInitCache(CachedData* programData) const;
292
junov@google.comf93e7172011-03-31 21:26:24 +0000293 friend class GrGpuGLShaders;
294};
295
296#endif