blob: f6258abe4da7749adb4e08541b8fbbd1f568c38f [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; }
81 static int ViewMatrixAttributeIdx() {
82 return 2 + GrDrawTarget::kMaxTexCoords;
83 }
84 static int TextureMatrixAttributeIdx(int stage) {
85 return 5 + GrDrawTarget::kMaxTexCoords + 3 * stage;
86 }
87
junov@google.comf93e7172011-03-31 21:26:24 +000088private:
89
90 //Parameters that affect code generation
91 struct ProgramDesc {
bsalomon@google.com4be283f2011-04-19 21:15:09 +000092 ProgramDesc() {
93 // since we use this as part of a key we can't have any unitialized
94 // padding
95 memset(this, 0, sizeof(ProgramDesc));
96 }
97
98 // stripped of bits that don't affect prog generation
junov@google.comf93e7172011-03-31 21:26:24 +000099 GrVertexLayout fVertexLayout;
100
101 enum {
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000102 kNone_ColorType = 0,
103 kAttribute_ColorType = 1,
104 kUniform_ColorType = 2,
105 } fColorType;
106
bsalomon@google.com271cffc2011-05-20 14:13:56 +0000107 // Dual-src blending makes use of a secondary output color that can be
108 // used as a per-pixel blend coeffecient. This controls whether a
109 // secondary source is output and what value it holds.
110 enum DualSrcOutput {
111 kNone_DualSrcOutput,
112 kCoverage_DualSrcOutput,
113 kCoverageISA_DualSrcOutput,
114 kCoverageISC_DualSrcOutput,
115 kDualSrcOutputCnt
116 } fDualSrcOutput;
117
bsalomon@google.comf2d91552011-05-16 20:56:06 +0000118 int fFirstCoverageStage;
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000119 bool fEmitsPointSize;
senorblanco@chromium.orgef3913b2011-05-19 17:11:07 +0000120 int fEdgeAANumEdges;
junov@google.comf93e7172011-03-31 21:26:24 +0000121
Scroggo97c88c22011-05-11 14:05:25 +0000122 SkXfermode::Mode fColorFilterXfermode;
123
junov@google.comf93e7172011-03-31 21:26:24 +0000124 struct StageDesc {
125 enum OptFlagBits {
junov@google.com6acc9b32011-05-16 18:32:07 +0000126 kNoPerspective_OptFlagBit = 1 << 0,
127 kIdentityMatrix_OptFlagBit = 1 << 1,
128 kCustomTextureDomain_OptFlagBit = 1 << 2
junov@google.comf93e7172011-03-31 21:26:24 +0000129 };
130
bsalomon@google.com6aef1fb2011-05-05 12:33:22 +0000131 unsigned fOptFlags;
132 bool fEnabled;
junov@google.comf93e7172011-03-31 21:26:24 +0000133
134 enum Modulation {
135 kColor_Modulation,
136 kAlpha_Modulation
bsalomon@google.com6aef1fb2011-05-05 12:33:22 +0000137 } fModulation;
138
139 enum FetchMode {
140 kSingle_FetchMode,
141 k2x2_FetchMode
142 } fFetchMode;
junov@google.comf93e7172011-03-31 21:26:24 +0000143
144 enum CoordMapping {
145 kIdentity_CoordMapping,
146 kRadialGradient_CoordMapping,
147 kSweepGradient_CoordMapping,
148 kRadial2Gradient_CoordMapping
bsalomon@google.com6aef1fb2011-05-05 12:33:22 +0000149 } fCoordMapping;
junov@google.comf93e7172011-03-31 21:26:24 +0000150 } fStages[GrDrawTarget::kNumStages];
151 } fProgramDesc;
152
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000153 const ProgramDesc& getDesc() { return fProgramDesc; }
154
junov@google.comf93e7172011-03-31 21:26:24 +0000155public:
bsalomon@google.com91961302011-05-09 18:39:58 +0000156 enum {
157 kUnusedUniform = -1,
158 kSetAsAttribute = 1000,
159 };
160
junov@google.comf93e7172011-03-31 21:26:24 +0000161 struct StageUniLocations {
162 GrGLint fTextureMatrixUni;
bsalomon@google.com6aef1fb2011-05-05 12:33:22 +0000163 GrGLint fNormalizedTexelSizeUni;
junov@google.comf93e7172011-03-31 21:26:24 +0000164 GrGLint fSamplerUni;
165 GrGLint fRadial2Uni;
junov@google.com6acc9b32011-05-16 18:32:07 +0000166 GrGLint fTexDomUni;
bsalomon@google.com91961302011-05-09 18:39:58 +0000167 void reset() {
168 fTextureMatrixUni = kUnusedUniform;
169 fNormalizedTexelSizeUni = kUnusedUniform;
170 fSamplerUni = kUnusedUniform;
171 fRadial2Uni = kUnusedUniform;
junov@google.com6acc9b32011-05-16 18:32:07 +0000172 fTexDomUni = kUnusedUniform;
bsalomon@google.com91961302011-05-09 18:39:58 +0000173 }
junov@google.comf93e7172011-03-31 21:26:24 +0000174 };
175
176 struct UniLocations {
177 GrGLint fViewMatrixUni;
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000178 GrGLint fColorUni;
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +0000179 GrGLint fEdgesUni;
Scroggo97c88c22011-05-11 14:05:25 +0000180 GrGLint fColorFilterUni;
junov@google.comf93e7172011-03-31 21:26:24 +0000181 StageUniLocations fStages[GrDrawTarget::kNumStages];
bsalomon@google.com91961302011-05-09 18:39:58 +0000182 void reset() {
183 fViewMatrixUni = kUnusedUniform;
184 fColorUni = kUnusedUniform;
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +0000185 fEdgesUni = kUnusedUniform;
Scroggo97c88c22011-05-11 14:05:25 +0000186 fColorFilterUni = kUnusedUniform;
bsalomon@google.com91961302011-05-09 18:39:58 +0000187 for (int s = 0; s < GrDrawTarget::kNumStages; ++s) {
188 fStages[s].reset();
189 }
190 }
junov@google.comf93e7172011-03-31 21:26:24 +0000191 };
192
193 class CachedData : public ::GrNoncopyable {
194 public:
195 CachedData() {
junov@google.comf93e7172011-03-31 21:26:24 +0000196 }
197
198 ~CachedData() {
junov@google.comf93e7172011-03-31 21:26:24 +0000199 }
200
201 void copyAndTakeOwnership(CachedData& other) {
bsalomon@google.com2d9ddf92011-05-11 16:52:59 +0000202 memcpy(this, &other, sizeof(*this));
junov@google.comf93e7172011-03-31 21:26:24 +0000203 }
204
junov@google.comf93e7172011-03-31 21:26:24 +0000205 public:
206
207 // IDs
208 GrGLuint fVShaderID;
209 GrGLuint fFShaderID;
210 GrGLuint fProgramID;
211 // shader uniform locations (-1 if shader doesn't use them)
212 UniLocations fUniLocations;
213
214 GrMatrix fViewMatrix;
215
216 // these reflect the current values of uniforms
217 // (GL uniform values travel with program)
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000218 GrColor fColor;
Scroggo97c88c22011-05-11 14:05:25 +0000219 GrColor fColorFilterColor;
junov@google.comf93e7172011-03-31 21:26:24 +0000220 GrMatrix fTextureMatrices[GrDrawTarget::kNumStages];
bsalomon@google.com6aef1fb2011-05-05 12:33:22 +0000221 // width and height used for normalized texel size
222 int fTextureWidth[GrDrawTarget::kNumStages];
223 int fTextureHeight[GrDrawTarget::kNumStages];
junov@google.comf93e7172011-03-31 21:26:24 +0000224 GrScalar fRadial2CenterX1[GrDrawTarget::kNumStages];
225 GrScalar fRadial2Radius0[GrDrawTarget::kNumStages];
226 bool fRadial2PosRoot[GrDrawTarget::kNumStages];
junov@google.com2f839402011-05-24 15:13:01 +0000227 GrRect fTextureDomain[GrDrawTarget::kNumStages];
junov@google.comf93e7172011-03-31 21:26:24 +0000228
229 private:
230 enum Constants {
231 kUniLocationPreAllocSize = 8
232 };
233
junov@google.comf93e7172011-03-31 21:26:24 +0000234 }; // CachedData
235
junov@google.comf93e7172011-03-31 21:26:24 +0000236private:
bsalomon@google.com91961302011-05-09 18:39:58 +0000237 enum {
238 kUseUniform = 2000
239 };
240
241 // should set all fields in locations var to kUseUniform if the
242 // corresponding uniform is required for the program.
junov@google.comf93e7172011-03-31 21:26:24 +0000243 void genStageCode(int stageNum,
244 const ProgramDesc::StageDesc& desc,
245 const char* fsInColor, // NULL means no incoming color
246 const char* fsOutColor,
247 const char* vsInCoord,
248 ShaderCodeSegments* segments,
249 StageUniLocations* locations) const;
250
bsalomon@google.com91961302011-05-09 18:39:58 +0000251 static bool CompileFSAndVS(const ShaderCodeSegments& segments,
252 CachedData* programData);
253
junov@google.comf93e7172011-03-31 21:26:24 +0000254 // Compiles a GL shader, returns shader ID or 0 if failed
255 // params have same meaning as glShaderSource
256 static GrGLuint CompileShader(GrGLenum type, int stringCnt,
257 const char** strings,
258 int* stringLengths);
259
bsalomon@google.com91961302011-05-09 18:39:58 +0000260 // Creates a GL program ID, binds shader attributes to GL vertex attrs, and
261 // links the program
bsalomon@google.com271cffc2011-05-20 14:13:56 +0000262 bool bindOutputsAttribsAndLinkProgram(
263 GrStringBuilder texCoordAttrNames[GrDrawTarget::kMaxTexCoords],
264 bool bindColorOut,
265 bool bindDualSrcOut,
266 CachedData* programData) const;
bsalomon@google.com91961302011-05-09 18:39:58 +0000267
268 // Gets locations for all uniforms set to kUseUniform and initializes cache
269 // to invalid values.
270 void getUniformLocationsAndInitCache(CachedData* programData) const;
271
junov@google.comf93e7172011-03-31 21:26:24 +0000272 friend class GrGpuGLShaders;
273};
274
275#endif