blob: edd47374ab81f8977e1da7b4509a7519c09b286c [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,
bsalomon@google.com1e257a52011-07-06 19:52:16 +0000110 kAlpha_Modulation,
111
112 kModulationCnt
tomhudson@google.com0d831722011-06-02 15:37:14 +0000113 };
114 enum FetchMode {
115 kSingle_FetchMode,
bsalomon@google.com1e257a52011-07-06 19:52:16 +0000116 k2x2_FetchMode,
117
118 kFetchModeCnt,
tomhudson@google.com0d831722011-06-02 15:37:14 +0000119 };
120 enum CoordMapping {
121 kIdentity_CoordMapping,
122 kRadialGradient_CoordMapping,
123 kSweepGradient_CoordMapping,
bsalomon@google.com1e257a52011-07-06 19:52:16 +0000124 kRadial2Gradient_CoordMapping,
bsalomon@google.com22c5dea2011-07-07 14:38:03 +0000125 // need different shader computation when quadratic
126 // eq describing the gradient degenerates to a linear eq.
127 kRadial2GradientDegenerate_CoordMapping,
bsalomon@google.com1e257a52011-07-06 19:52:16 +0000128 kCoordMappingCnt
tomhudson@google.com0d831722011-06-02 15:37:14 +0000129 };
junov@google.comf93e7172011-03-31 21:26:24 +0000130
tomhudson@google.com0d831722011-06-02 15:37:14 +0000131 uint8_t fOptFlags;
132 uint8_t fModulation; // casts to enum Modulation
133 uint8_t fFetchMode; // casts to enum FetchMode
134 uint8_t fCoordMapping; // casts to enum CoordMapping
135
136 inline bool isEnabled() const {
137 return fOptFlags & kIsEnabled_OptFlagBit;
138 }
139 inline void setEnabled(bool newValue) {
140 if (newValue) {
141 fOptFlags |= kIsEnabled_OptFlagBit;
142 } else {
143 fOptFlags &= ~kIsEnabled_OptFlagBit;
144 }
145 }
146 };
147
148 enum ColorType {
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000149 kNone_ColorType = 0,
150 kAttribute_ColorType = 1,
151 kUniform_ColorType = 2,
tomhudson@google.com0d831722011-06-02 15:37:14 +0000152 };
153 // Dual-src blending makes use of a secondary output color that can be
bsalomon@google.com271cffc2011-05-20 14:13:56 +0000154 // used as a per-pixel blend coeffecient. This controls whether a
155 // secondary source is output and what value it holds.
156 enum DualSrcOutput {
157 kNone_DualSrcOutput,
158 kCoverage_DualSrcOutput,
159 kCoverageISA_DualSrcOutput,
160 kCoverageISC_DualSrcOutput,
bsalomon@google.com1e257a52011-07-06 19:52:16 +0000161
bsalomon@google.com271cffc2011-05-20 14:13:56 +0000162 kDualSrcOutputCnt
tomhudson@google.com0d831722011-06-02 15:37:14 +0000163 };
bsalomon@google.com271cffc2011-05-20 14:13:56 +0000164
tomhudson@google.com0d831722011-06-02 15:37:14 +0000165 // stripped of bits that don't affect prog generation
166 GrVertexLayout fVertexLayout;
junov@google.comf93e7172011-03-31 21:26:24 +0000167
tomhudson@google.com0d831722011-06-02 15:37:14 +0000168 StageDesc fStages[GrDrawTarget::kNumStages];
Scroggo97c88c22011-05-11 14:05:25 +0000169
tomhudson@google.com0d831722011-06-02 15:37:14 +0000170 uint8_t fColorType; // casts to enum ColorType
171 uint8_t fDualSrcOutput; // casts to enum DualSrcOutput
172 int8_t fFirstCoverageStage;
173 SkBool8 fEmitsPointSize;
senorblanco@chromium.org129b8e32011-06-15 17:52:09 +0000174 SkBool8 fEdgeAAConcave;
junov@google.comf93e7172011-03-31 21:26:24 +0000175
tomhudson@google.com0d831722011-06-02 15:37:14 +0000176 int8_t fEdgeAANumEdges;
177 uint8_t fColorFilterXfermode; // casts to enum SkXfermode::Mode
junov@google.comf93e7172011-03-31 21:26:24 +0000178
senorblanco@chromium.org129b8e32011-06-15 17:52:09 +0000179 uint8_t fPadTo32bLengthMultiple [1];
bsalomon@google.com6aef1fb2011-05-05 12:33:22 +0000180
junov@google.comf93e7172011-03-31 21:26:24 +0000181 } fProgramDesc;
182
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000183 const ProgramDesc& getDesc() { return fProgramDesc; }
184
bsalomon@google.com22c5dea2011-07-07 14:38:03 +0000185 // for code readability
186 typedef ProgramDesc::StageDesc StageDesc;
187
junov@google.comf93e7172011-03-31 21:26:24 +0000188public:
bsalomon@google.com91961302011-05-09 18:39:58 +0000189 enum {
190 kUnusedUniform = -1,
191 kSetAsAttribute = 1000,
192 };
193
junov@google.comf93e7172011-03-31 21:26:24 +0000194 struct StageUniLocations {
195 GrGLint fTextureMatrixUni;
bsalomon@google.com6aef1fb2011-05-05 12:33:22 +0000196 GrGLint fNormalizedTexelSizeUni;
junov@google.comf93e7172011-03-31 21:26:24 +0000197 GrGLint fSamplerUni;
198 GrGLint fRadial2Uni;
junov@google.com6acc9b32011-05-16 18:32:07 +0000199 GrGLint fTexDomUni;
bsalomon@google.com91961302011-05-09 18:39:58 +0000200 void reset() {
201 fTextureMatrixUni = kUnusedUniform;
202 fNormalizedTexelSizeUni = kUnusedUniform;
203 fSamplerUni = kUnusedUniform;
204 fRadial2Uni = kUnusedUniform;
junov@google.com6acc9b32011-05-16 18:32:07 +0000205 fTexDomUni = kUnusedUniform;
bsalomon@google.com91961302011-05-09 18:39:58 +0000206 }
junov@google.comf93e7172011-03-31 21:26:24 +0000207 };
208
209 struct UniLocations {
210 GrGLint fViewMatrixUni;
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000211 GrGLint fColorUni;
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +0000212 GrGLint fEdgesUni;
Scroggo97c88c22011-05-11 14:05:25 +0000213 GrGLint fColorFilterUni;
junov@google.comf93e7172011-03-31 21:26:24 +0000214 StageUniLocations fStages[GrDrawTarget::kNumStages];
bsalomon@google.com91961302011-05-09 18:39:58 +0000215 void reset() {
216 fViewMatrixUni = kUnusedUniform;
217 fColorUni = kUnusedUniform;
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +0000218 fEdgesUni = kUnusedUniform;
Scroggo97c88c22011-05-11 14:05:25 +0000219 fColorFilterUni = kUnusedUniform;
bsalomon@google.com91961302011-05-09 18:39:58 +0000220 for (int s = 0; s < GrDrawTarget::kNumStages; ++s) {
221 fStages[s].reset();
222 }
223 }
junov@google.comf93e7172011-03-31 21:26:24 +0000224 };
225
226 class CachedData : public ::GrNoncopyable {
227 public:
228 CachedData() {
junov@google.comf93e7172011-03-31 21:26:24 +0000229 }
230
231 ~CachedData() {
junov@google.comf93e7172011-03-31 21:26:24 +0000232 }
233
234 void copyAndTakeOwnership(CachedData& other) {
bsalomon@google.com2d9ddf92011-05-11 16:52:59 +0000235 memcpy(this, &other, sizeof(*this));
junov@google.comf93e7172011-03-31 21:26:24 +0000236 }
237
junov@google.comf93e7172011-03-31 21:26:24 +0000238 public:
239
240 // IDs
241 GrGLuint fVShaderID;
242 GrGLuint fFShaderID;
243 GrGLuint fProgramID;
244 // shader uniform locations (-1 if shader doesn't use them)
245 UniLocations fUniLocations;
246
247 GrMatrix fViewMatrix;
248
249 // these reflect the current values of uniforms
250 // (GL uniform values travel with program)
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000251 GrColor fColor;
Scroggo97c88c22011-05-11 14:05:25 +0000252 GrColor fColorFilterColor;
junov@google.comf93e7172011-03-31 21:26:24 +0000253 GrMatrix fTextureMatrices[GrDrawTarget::kNumStages];
bsalomon@google.com6aef1fb2011-05-05 12:33:22 +0000254 // width and height used for normalized texel size
255 int fTextureWidth[GrDrawTarget::kNumStages];
256 int fTextureHeight[GrDrawTarget::kNumStages];
junov@google.comf93e7172011-03-31 21:26:24 +0000257 GrScalar fRadial2CenterX1[GrDrawTarget::kNumStages];
258 GrScalar fRadial2Radius0[GrDrawTarget::kNumStages];
259 bool fRadial2PosRoot[GrDrawTarget::kNumStages];
junov@google.com2f839402011-05-24 15:13:01 +0000260 GrRect fTextureDomain[GrDrawTarget::kNumStages];
junov@google.comf93e7172011-03-31 21:26:24 +0000261
262 private:
263 enum Constants {
264 kUniLocationPreAllocSize = 8
265 };
266
junov@google.comf93e7172011-03-31 21:26:24 +0000267 }; // CachedData
268
junov@google.comf93e7172011-03-31 21:26:24 +0000269private:
bsalomon@google.com91961302011-05-09 18:39:58 +0000270 enum {
271 kUseUniform = 2000
272 };
273
274 // should set all fields in locations var to kUseUniform if the
275 // corresponding uniform is required for the program.
junov@google.comf93e7172011-03-31 21:26:24 +0000276 void genStageCode(int stageNum,
277 const ProgramDesc::StageDesc& desc,
278 const char* fsInColor, // NULL means no incoming color
279 const char* fsOutColor,
280 const char* vsInCoord,
281 ShaderCodeSegments* segments,
282 StageUniLocations* locations) const;
283
bsalomon@google.com91961302011-05-09 18:39:58 +0000284 static bool CompileFSAndVS(const ShaderCodeSegments& segments,
285 CachedData* programData);
286
junov@google.comf93e7172011-03-31 21:26:24 +0000287 // Compiles a GL shader, returns shader ID or 0 if failed
288 // params have same meaning as glShaderSource
289 static GrGLuint CompileShader(GrGLenum type, int stringCnt,
290 const char** strings,
291 int* stringLengths);
292
bsalomon@google.com91961302011-05-09 18:39:58 +0000293 // Creates a GL program ID, binds shader attributes to GL vertex attrs, and
294 // links the program
bsalomon@google.com271cffc2011-05-20 14:13:56 +0000295 bool bindOutputsAttribsAndLinkProgram(
296 GrStringBuilder texCoordAttrNames[GrDrawTarget::kMaxTexCoords],
297 bool bindColorOut,
298 bool bindDualSrcOut,
299 CachedData* programData) const;
bsalomon@google.com91961302011-05-09 18:39:58 +0000300
301 // Gets locations for all uniforms set to kUseUniform and initializes cache
302 // to invalid values.
303 void getUniformLocationsAndInitCache(CachedData* programData) const;
304
junov@google.comf93e7172011-03-31 21:26:24 +0000305 friend class GrGpuGLShaders;
306};
307
308#endif