blob: 473bcb65a0e798b5fdf23a54e977cf415ffdb444 [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;
junov@google.comd31cbc42011-05-17 17:01:17 +000035 GrStringBuilder fVSCode;
36 GrStringBuilder fFSCode;
37};
junov@google.comf93e7172011-03-31 21:26:24 +000038
39/**
40 * This class manages a GPU program and records per-program information.
41 * We can specify the attribute locations so that they are constant
42 * across our shaders. But the driver determines the uniform locations
43 * at link time. We don't need to remember the sampler uniform location
44 * because we will bind a texture slot to it and never change it
45 * Uniforms are program-local so we can't rely on fHWState to hold the
46 * previous uniform state after a program change.
47 */
48class GrGLProgram {
49public:
50 class CachedData;
51
52 GrGLProgram();
53 ~GrGLProgram();
54
55 /**
56 * Streams data that can uniquely identifies the generated
57 * gpu program into a key, for cache indexing purposes.
58 *
59 * @param key The key object to receive the key data
60 */
61 void buildKey(GrBinHashKeyBuilder& key) const;
62
63 /**
64 * This is the heavy initilization routine for building a GLProgram.
65 * The result of heavy init is not stored in datamembers of GrGLProgam,
66 * but in a separate cacheable container.
67 */
bsalomon@google.com91961302011-05-09 18:39:58 +000068 bool genProgram(CachedData* programData) const;
junov@google.comf93e7172011-03-31 21:26:24 +000069
bsalomon@google.com271cffc2011-05-20 14:13:56 +000070 /**
71 * The shader may modify the blend coeffecients. Params are in/out
72 */
73 void overrideBlend(GrBlendCoeff* srcCoeff, GrBlendCoeff* dstCoeff) const;
74
75 /**
76 * Attribute indices
77 */
bsalomon@google.com91961302011-05-09 18:39:58 +000078 static int PositionAttributeIdx() { return 0; }
79 static int TexCoordAttributeIdx(int tcIdx) { return 1 + tcIdx; }
80 static int ColorAttributeIdx() { return 1 + GrDrawTarget::kMaxTexCoords; }
tomhudson@google.com0d831722011-06-02 15:37:14 +000081 static int ViewMatrixAttributeIdx() {
82 return 2 + GrDrawTarget::kMaxTexCoords;
bsalomon@google.com91961302011-05-09 18:39:58 +000083 }
tomhudson@google.com0d831722011-06-02 15:37:14 +000084 static int TextureMatrixAttributeIdx(int stage) {
85 return 5 + GrDrawTarget::kMaxTexCoords + 3 * stage;
bsalomon@google.com91961302011-05-09 18:39:58 +000086 }
87
junov@google.comf93e7172011-03-31 21:26:24 +000088private:
89
tomhudson@google.com0d831722011-06-02 15:37:14 +000090 // Parameters that affect code generation
91 // These structs should be kept compact; they are the input to an
92 // expensive hash key generator.
junov@google.comf93e7172011-03-31 21:26:24 +000093 struct ProgramDesc {
bsalomon@google.com4be283f2011-04-19 21:15:09 +000094 ProgramDesc() {
95 // since we use this as part of a key we can't have any unitialized
96 // padding
97 memset(this, 0, sizeof(ProgramDesc));
98 }
99
tomhudson@google.com0d831722011-06-02 15:37:14 +0000100 struct StageDesc {
101 enum OptFlagBits {
102 kNoPerspective_OptFlagBit = 1 << 0,
103 kIdentityMatrix_OptFlagBit = 1 << 1,
104 kCustomTextureDomain_OptFlagBit = 1 << 2,
105 kIsEnabled_OptFlagBit = 1 << 7
106 };
107 enum Modulation {
108 kColor_Modulation,
109 kAlpha_Modulation
110 };
111 enum FetchMode {
112 kSingle_FetchMode,
113 k2x2_FetchMode
114 };
115 enum CoordMapping {
116 kIdentity_CoordMapping,
117 kRadialGradient_CoordMapping,
118 kSweepGradient_CoordMapping,
119 kRadial2Gradient_CoordMapping
120 };
junov@google.comf93e7172011-03-31 21:26:24 +0000121
tomhudson@google.com0d831722011-06-02 15:37:14 +0000122 uint8_t fOptFlags;
123 uint8_t fModulation; // casts to enum Modulation
124 uint8_t fFetchMode; // casts to enum FetchMode
125 uint8_t fCoordMapping; // casts to enum CoordMapping
126
127 inline bool isEnabled() const {
128 return fOptFlags & kIsEnabled_OptFlagBit;
129 }
130 inline void setEnabled(bool newValue) {
131 if (newValue) {
132 fOptFlags |= kIsEnabled_OptFlagBit;
133 } else {
134 fOptFlags &= ~kIsEnabled_OptFlagBit;
135 }
136 }
137 };
138
139 enum ColorType {
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000140 kNone_ColorType = 0,
141 kAttribute_ColorType = 1,
142 kUniform_ColorType = 2,
tomhudson@google.com0d831722011-06-02 15:37:14 +0000143 };
144 // Dual-src blending makes use of a secondary output color that can be
bsalomon@google.com271cffc2011-05-20 14:13:56 +0000145 // used as a per-pixel blend coeffecient. This controls whether a
146 // secondary source is output and what value it holds.
147 enum DualSrcOutput {
148 kNone_DualSrcOutput,
149 kCoverage_DualSrcOutput,
150 kCoverageISA_DualSrcOutput,
151 kCoverageISC_DualSrcOutput,
152 kDualSrcOutputCnt
tomhudson@google.com0d831722011-06-02 15:37:14 +0000153 };
bsalomon@google.com271cffc2011-05-20 14:13:56 +0000154
tomhudson@google.com0d831722011-06-02 15:37:14 +0000155 // stripped of bits that don't affect prog generation
156 GrVertexLayout fVertexLayout;
junov@google.comf93e7172011-03-31 21:26:24 +0000157
tomhudson@google.com0d831722011-06-02 15:37:14 +0000158 StageDesc fStages[GrDrawTarget::kNumStages];
Scroggo97c88c22011-05-11 14:05:25 +0000159
tomhudson@google.com0d831722011-06-02 15:37:14 +0000160 uint8_t fColorType; // casts to enum ColorType
161 uint8_t fDualSrcOutput; // casts to enum DualSrcOutput
162 int8_t fFirstCoverageStage;
163 SkBool8 fEmitsPointSize;
junov@google.comf93e7172011-03-31 21:26:24 +0000164
tomhudson@google.com0d831722011-06-02 15:37:14 +0000165 int8_t fEdgeAANumEdges;
166 uint8_t fColorFilterXfermode; // casts to enum SkXfermode::Mode
junov@google.comf93e7172011-03-31 21:26:24 +0000167
tomhudson@google.com0d831722011-06-02 15:37:14 +0000168 uint8_t fPadTo32bLengthMultiple [2];
bsalomon@google.com6aef1fb2011-05-05 12:33:22 +0000169
junov@google.comf93e7172011-03-31 21:26:24 +0000170 } fProgramDesc;
171
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000172 const ProgramDesc& getDesc() { return fProgramDesc; }
173
junov@google.comf93e7172011-03-31 21:26:24 +0000174public:
bsalomon@google.com91961302011-05-09 18:39:58 +0000175 enum {
176 kUnusedUniform = -1,
177 kSetAsAttribute = 1000,
178 };
179
junov@google.comf93e7172011-03-31 21:26:24 +0000180 struct StageUniLocations {
181 GrGLint fTextureMatrixUni;
bsalomon@google.com6aef1fb2011-05-05 12:33:22 +0000182 GrGLint fNormalizedTexelSizeUni;
junov@google.comf93e7172011-03-31 21:26:24 +0000183 GrGLint fSamplerUni;
184 GrGLint fRadial2Uni;
junov@google.com6acc9b32011-05-16 18:32:07 +0000185 GrGLint fTexDomUni;
bsalomon@google.com91961302011-05-09 18:39:58 +0000186 void reset() {
187 fTextureMatrixUni = kUnusedUniform;
188 fNormalizedTexelSizeUni = kUnusedUniform;
189 fSamplerUni = kUnusedUniform;
190 fRadial2Uni = kUnusedUniform;
junov@google.com6acc9b32011-05-16 18:32:07 +0000191 fTexDomUni = kUnusedUniform;
bsalomon@google.com91961302011-05-09 18:39:58 +0000192 }
junov@google.comf93e7172011-03-31 21:26:24 +0000193 };
194
195 struct UniLocations {
196 GrGLint fViewMatrixUni;
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000197 GrGLint fColorUni;
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +0000198 GrGLint fEdgesUni;
Scroggo97c88c22011-05-11 14:05:25 +0000199 GrGLint fColorFilterUni;
junov@google.comf93e7172011-03-31 21:26:24 +0000200 StageUniLocations fStages[GrDrawTarget::kNumStages];
bsalomon@google.com91961302011-05-09 18:39:58 +0000201 void reset() {
202 fViewMatrixUni = kUnusedUniform;
203 fColorUni = kUnusedUniform;
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +0000204 fEdgesUni = kUnusedUniform;
Scroggo97c88c22011-05-11 14:05:25 +0000205 fColorFilterUni = kUnusedUniform;
bsalomon@google.com91961302011-05-09 18:39:58 +0000206 for (int s = 0; s < GrDrawTarget::kNumStages; ++s) {
207 fStages[s].reset();
208 }
209 }
junov@google.comf93e7172011-03-31 21:26:24 +0000210 };
211
212 class CachedData : public ::GrNoncopyable {
213 public:
214 CachedData() {
junov@google.comf93e7172011-03-31 21:26:24 +0000215 }
216
217 ~CachedData() {
junov@google.comf93e7172011-03-31 21:26:24 +0000218 }
219
220 void copyAndTakeOwnership(CachedData& other) {
bsalomon@google.com2d9ddf92011-05-11 16:52:59 +0000221 memcpy(this, &other, sizeof(*this));
junov@google.comf93e7172011-03-31 21:26:24 +0000222 }
223
junov@google.comf93e7172011-03-31 21:26:24 +0000224 public:
225
226 // IDs
227 GrGLuint fVShaderID;
228 GrGLuint fFShaderID;
229 GrGLuint fProgramID;
230 // shader uniform locations (-1 if shader doesn't use them)
231 UniLocations fUniLocations;
232
233 GrMatrix fViewMatrix;
234
235 // these reflect the current values of uniforms
236 // (GL uniform values travel with program)
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000237 GrColor fColor;
Scroggo97c88c22011-05-11 14:05:25 +0000238 GrColor fColorFilterColor;
junov@google.comf93e7172011-03-31 21:26:24 +0000239 GrMatrix fTextureMatrices[GrDrawTarget::kNumStages];
bsalomon@google.com6aef1fb2011-05-05 12:33:22 +0000240 // width and height used for normalized texel size
241 int fTextureWidth[GrDrawTarget::kNumStages];
242 int fTextureHeight[GrDrawTarget::kNumStages];
junov@google.comf93e7172011-03-31 21:26:24 +0000243 GrScalar fRadial2CenterX1[GrDrawTarget::kNumStages];
244 GrScalar fRadial2Radius0[GrDrawTarget::kNumStages];
245 bool fRadial2PosRoot[GrDrawTarget::kNumStages];
junov@google.com2f839402011-05-24 15:13:01 +0000246 GrRect fTextureDomain[GrDrawTarget::kNumStages];
junov@google.comf93e7172011-03-31 21:26:24 +0000247
248 private:
249 enum Constants {
250 kUniLocationPreAllocSize = 8
251 };
252
junov@google.comf93e7172011-03-31 21:26:24 +0000253 }; // CachedData
254
junov@google.comf93e7172011-03-31 21:26:24 +0000255private:
bsalomon@google.com91961302011-05-09 18:39:58 +0000256 enum {
257 kUseUniform = 2000
258 };
259
260 // should set all fields in locations var to kUseUniform if the
261 // corresponding uniform is required for the program.
junov@google.comf93e7172011-03-31 21:26:24 +0000262 void genStageCode(int stageNum,
263 const ProgramDesc::StageDesc& desc,
264 const char* fsInColor, // NULL means no incoming color
265 const char* fsOutColor,
266 const char* vsInCoord,
267 ShaderCodeSegments* segments,
268 StageUniLocations* locations) const;
269
bsalomon@google.com91961302011-05-09 18:39:58 +0000270 static bool CompileFSAndVS(const ShaderCodeSegments& segments,
271 CachedData* programData);
272
junov@google.comf93e7172011-03-31 21:26:24 +0000273 // Compiles a GL shader, returns shader ID or 0 if failed
274 // params have same meaning as glShaderSource
275 static GrGLuint CompileShader(GrGLenum type, int stringCnt,
276 const char** strings,
277 int* stringLengths);
278
bsalomon@google.com91961302011-05-09 18:39:58 +0000279 // Creates a GL program ID, binds shader attributes to GL vertex attrs, and
280 // links the program
bsalomon@google.com271cffc2011-05-20 14:13:56 +0000281 bool bindOutputsAttribsAndLinkProgram(
282 GrStringBuilder texCoordAttrNames[GrDrawTarget::kMaxTexCoords],
283 bool bindColorOut,
284 bool bindDualSrcOut,
285 CachedData* programData) const;
bsalomon@google.com91961302011-05-09 18:39:58 +0000286
287 // Gets locations for all uniforms set to kUseUniform and initializes cache
288 // to invalid values.
289 void getUniformLocationsAndInitCache(CachedData* programData) const;
290
junov@google.comf93e7172011-03-31 21:26:24 +0000291 friend class GrGpuGLShaders;
292};
293
294#endif