blob: 2c4152d4cafabb6d263e16d99c2af6bbf594758e [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,
125
126 kCoordMappingCnt
tomhudson@google.com0d831722011-06-02 15:37:14 +0000127 };
junov@google.comf93e7172011-03-31 21:26:24 +0000128
tomhudson@google.com0d831722011-06-02 15:37:14 +0000129 uint8_t fOptFlags;
130 uint8_t fModulation; // casts to enum Modulation
131 uint8_t fFetchMode; // casts to enum FetchMode
132 uint8_t fCoordMapping; // casts to enum CoordMapping
133
134 inline bool isEnabled() const {
135 return fOptFlags & kIsEnabled_OptFlagBit;
136 }
137 inline void setEnabled(bool newValue) {
138 if (newValue) {
139 fOptFlags |= kIsEnabled_OptFlagBit;
140 } else {
141 fOptFlags &= ~kIsEnabled_OptFlagBit;
142 }
143 }
144 };
145
146 enum ColorType {
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000147 kNone_ColorType = 0,
148 kAttribute_ColorType = 1,
149 kUniform_ColorType = 2,
tomhudson@google.com0d831722011-06-02 15:37:14 +0000150 };
151 // Dual-src blending makes use of a secondary output color that can be
bsalomon@google.com271cffc2011-05-20 14:13:56 +0000152 // used as a per-pixel blend coeffecient. This controls whether a
153 // secondary source is output and what value it holds.
154 enum DualSrcOutput {
155 kNone_DualSrcOutput,
156 kCoverage_DualSrcOutput,
157 kCoverageISA_DualSrcOutput,
158 kCoverageISC_DualSrcOutput,
bsalomon@google.com1e257a52011-07-06 19:52:16 +0000159
bsalomon@google.com271cffc2011-05-20 14:13:56 +0000160 kDualSrcOutputCnt
tomhudson@google.com0d831722011-06-02 15:37:14 +0000161 };
bsalomon@google.com271cffc2011-05-20 14:13:56 +0000162
tomhudson@google.com0d831722011-06-02 15:37:14 +0000163 // stripped of bits that don't affect prog generation
164 GrVertexLayout fVertexLayout;
junov@google.comf93e7172011-03-31 21:26:24 +0000165
tomhudson@google.com0d831722011-06-02 15:37:14 +0000166 StageDesc fStages[GrDrawTarget::kNumStages];
Scroggo97c88c22011-05-11 14:05:25 +0000167
tomhudson@google.com0d831722011-06-02 15:37:14 +0000168 uint8_t fColorType; // casts to enum ColorType
169 uint8_t fDualSrcOutput; // casts to enum DualSrcOutput
170 int8_t fFirstCoverageStage;
171 SkBool8 fEmitsPointSize;
senorblanco@chromium.org129b8e32011-06-15 17:52:09 +0000172 SkBool8 fEdgeAAConcave;
junov@google.comf93e7172011-03-31 21:26:24 +0000173
tomhudson@google.com0d831722011-06-02 15:37:14 +0000174 int8_t fEdgeAANumEdges;
175 uint8_t fColorFilterXfermode; // casts to enum SkXfermode::Mode
junov@google.comf93e7172011-03-31 21:26:24 +0000176
senorblanco@chromium.org129b8e32011-06-15 17:52:09 +0000177 uint8_t fPadTo32bLengthMultiple [1];
bsalomon@google.com6aef1fb2011-05-05 12:33:22 +0000178
junov@google.comf93e7172011-03-31 21:26:24 +0000179 } fProgramDesc;
180
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000181 const ProgramDesc& getDesc() { return fProgramDesc; }
182
junov@google.comf93e7172011-03-31 21:26:24 +0000183public:
bsalomon@google.com91961302011-05-09 18:39:58 +0000184 enum {
185 kUnusedUniform = -1,
186 kSetAsAttribute = 1000,
187 };
188
junov@google.comf93e7172011-03-31 21:26:24 +0000189 struct StageUniLocations {
190 GrGLint fTextureMatrixUni;
bsalomon@google.com6aef1fb2011-05-05 12:33:22 +0000191 GrGLint fNormalizedTexelSizeUni;
junov@google.comf93e7172011-03-31 21:26:24 +0000192 GrGLint fSamplerUni;
193 GrGLint fRadial2Uni;
junov@google.com6acc9b32011-05-16 18:32:07 +0000194 GrGLint fTexDomUni;
bsalomon@google.com91961302011-05-09 18:39:58 +0000195 void reset() {
196 fTextureMatrixUni = kUnusedUniform;
197 fNormalizedTexelSizeUni = kUnusedUniform;
198 fSamplerUni = kUnusedUniform;
199 fRadial2Uni = kUnusedUniform;
junov@google.com6acc9b32011-05-16 18:32:07 +0000200 fTexDomUni = kUnusedUniform;
bsalomon@google.com91961302011-05-09 18:39:58 +0000201 }
junov@google.comf93e7172011-03-31 21:26:24 +0000202 };
203
204 struct UniLocations {
205 GrGLint fViewMatrixUni;
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000206 GrGLint fColorUni;
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +0000207 GrGLint fEdgesUni;
Scroggo97c88c22011-05-11 14:05:25 +0000208 GrGLint fColorFilterUni;
junov@google.comf93e7172011-03-31 21:26:24 +0000209 StageUniLocations fStages[GrDrawTarget::kNumStages];
bsalomon@google.com91961302011-05-09 18:39:58 +0000210 void reset() {
211 fViewMatrixUni = kUnusedUniform;
212 fColorUni = kUnusedUniform;
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +0000213 fEdgesUni = kUnusedUniform;
Scroggo97c88c22011-05-11 14:05:25 +0000214 fColorFilterUni = kUnusedUniform;
bsalomon@google.com91961302011-05-09 18:39:58 +0000215 for (int s = 0; s < GrDrawTarget::kNumStages; ++s) {
216 fStages[s].reset();
217 }
218 }
junov@google.comf93e7172011-03-31 21:26:24 +0000219 };
220
221 class CachedData : public ::GrNoncopyable {
222 public:
223 CachedData() {
junov@google.comf93e7172011-03-31 21:26:24 +0000224 }
225
226 ~CachedData() {
junov@google.comf93e7172011-03-31 21:26:24 +0000227 }
228
229 void copyAndTakeOwnership(CachedData& other) {
bsalomon@google.com2d9ddf92011-05-11 16:52:59 +0000230 memcpy(this, &other, sizeof(*this));
junov@google.comf93e7172011-03-31 21:26:24 +0000231 }
232
junov@google.comf93e7172011-03-31 21:26:24 +0000233 public:
234
235 // IDs
236 GrGLuint fVShaderID;
237 GrGLuint fFShaderID;
238 GrGLuint fProgramID;
239 // shader uniform locations (-1 if shader doesn't use them)
240 UniLocations fUniLocations;
241
242 GrMatrix fViewMatrix;
243
244 // these reflect the current values of uniforms
245 // (GL uniform values travel with program)
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000246 GrColor fColor;
Scroggo97c88c22011-05-11 14:05:25 +0000247 GrColor fColorFilterColor;
junov@google.comf93e7172011-03-31 21:26:24 +0000248 GrMatrix fTextureMatrices[GrDrawTarget::kNumStages];
bsalomon@google.com6aef1fb2011-05-05 12:33:22 +0000249 // width and height used for normalized texel size
250 int fTextureWidth[GrDrawTarget::kNumStages];
251 int fTextureHeight[GrDrawTarget::kNumStages];
junov@google.comf93e7172011-03-31 21:26:24 +0000252 GrScalar fRadial2CenterX1[GrDrawTarget::kNumStages];
253 GrScalar fRadial2Radius0[GrDrawTarget::kNumStages];
254 bool fRadial2PosRoot[GrDrawTarget::kNumStages];
junov@google.com2f839402011-05-24 15:13:01 +0000255 GrRect fTextureDomain[GrDrawTarget::kNumStages];
junov@google.comf93e7172011-03-31 21:26:24 +0000256
257 private:
258 enum Constants {
259 kUniLocationPreAllocSize = 8
260 };
261
junov@google.comf93e7172011-03-31 21:26:24 +0000262 }; // CachedData
263
junov@google.comf93e7172011-03-31 21:26:24 +0000264private:
bsalomon@google.com91961302011-05-09 18:39:58 +0000265 enum {
266 kUseUniform = 2000
267 };
268
269 // should set all fields in locations var to kUseUniform if the
270 // corresponding uniform is required for the program.
junov@google.comf93e7172011-03-31 21:26:24 +0000271 void genStageCode(int stageNum,
272 const ProgramDesc::StageDesc& desc,
273 const char* fsInColor, // NULL means no incoming color
274 const char* fsOutColor,
275 const char* vsInCoord,
276 ShaderCodeSegments* segments,
277 StageUniLocations* locations) const;
278
bsalomon@google.com91961302011-05-09 18:39:58 +0000279 static bool CompileFSAndVS(const ShaderCodeSegments& segments,
280 CachedData* programData);
281
junov@google.comf93e7172011-03-31 21:26:24 +0000282 // Compiles a GL shader, returns shader ID or 0 if failed
283 // params have same meaning as glShaderSource
284 static GrGLuint CompileShader(GrGLenum type, int stringCnt,
285 const char** strings,
286 int* stringLengths);
287
bsalomon@google.com91961302011-05-09 18:39:58 +0000288 // Creates a GL program ID, binds shader attributes to GL vertex attrs, and
289 // links the program
bsalomon@google.com271cffc2011-05-20 14:13:56 +0000290 bool bindOutputsAttribsAndLinkProgram(
291 GrStringBuilder texCoordAttrNames[GrDrawTarget::kMaxTexCoords],
292 bool bindColorOut,
293 bool bindDualSrcOut,
294 CachedData* programData) const;
bsalomon@google.com91961302011-05-09 18:39:58 +0000295
296 // Gets locations for all uniforms set to kUseUniform and initializes cache
297 // to invalid values.
298 void getUniformLocationsAndInitCache(CachedData* programData) const;
299
junov@google.comf93e7172011-03-31 21:26:24 +0000300 friend class GrGpuGLShaders;
301};
302
303#endif