blob: 60a71770714f65ae080173dd99543e72dca5ffa8 [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,
senorblanco@chromium.org027de5f2011-07-08 18:03:33 +0000117 kConvolution_FetchMode,
bsalomon@google.com1e257a52011-07-06 19:52:16 +0000118
119 kFetchModeCnt,
tomhudson@google.com0d831722011-06-02 15:37:14 +0000120 };
121 enum CoordMapping {
122 kIdentity_CoordMapping,
123 kRadialGradient_CoordMapping,
124 kSweepGradient_CoordMapping,
bsalomon@google.com1e257a52011-07-06 19:52:16 +0000125 kRadial2Gradient_CoordMapping,
bsalomon@google.com22c5dea2011-07-07 14:38:03 +0000126 // need different shader computation when quadratic
127 // eq describing the gradient degenerates to a linear eq.
128 kRadial2GradientDegenerate_CoordMapping,
bsalomon@google.com1e257a52011-07-06 19:52:16 +0000129 kCoordMappingCnt
tomhudson@google.com0d831722011-06-02 15:37:14 +0000130 };
junov@google.comf93e7172011-03-31 21:26:24 +0000131
tomhudson@google.com0d831722011-06-02 15:37:14 +0000132 uint8_t fOptFlags;
133 uint8_t fModulation; // casts to enum Modulation
134 uint8_t fFetchMode; // casts to enum FetchMode
135 uint8_t fCoordMapping; // casts to enum CoordMapping
senorblanco@chromium.org027de5f2011-07-08 18:03:33 +0000136 uint8_t fKernelWidth;
tomhudson@google.com0d831722011-06-02 15:37:14 +0000137
138 inline bool isEnabled() const {
139 return fOptFlags & kIsEnabled_OptFlagBit;
140 }
141 inline void setEnabled(bool newValue) {
142 if (newValue) {
143 fOptFlags |= kIsEnabled_OptFlagBit;
144 } else {
145 fOptFlags &= ~kIsEnabled_OptFlagBit;
146 }
147 }
148 };
149
150 enum ColorType {
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000151 kNone_ColorType = 0,
152 kAttribute_ColorType = 1,
153 kUniform_ColorType = 2,
tomhudson@google.com0d831722011-06-02 15:37:14 +0000154 };
155 // Dual-src blending makes use of a secondary output color that can be
bsalomon@google.com271cffc2011-05-20 14:13:56 +0000156 // used as a per-pixel blend coeffecient. This controls whether a
157 // secondary source is output and what value it holds.
158 enum DualSrcOutput {
159 kNone_DualSrcOutput,
160 kCoverage_DualSrcOutput,
161 kCoverageISA_DualSrcOutput,
162 kCoverageISC_DualSrcOutput,
bsalomon@google.com1e257a52011-07-06 19:52:16 +0000163
bsalomon@google.com271cffc2011-05-20 14:13:56 +0000164 kDualSrcOutputCnt
tomhudson@google.com0d831722011-06-02 15:37:14 +0000165 };
bsalomon@google.com271cffc2011-05-20 14:13:56 +0000166
tomhudson@google.com0d831722011-06-02 15:37:14 +0000167 // stripped of bits that don't affect prog generation
168 GrVertexLayout fVertexLayout;
junov@google.comf93e7172011-03-31 21:26:24 +0000169
tomhudson@google.com0d831722011-06-02 15:37:14 +0000170 StageDesc fStages[GrDrawTarget::kNumStages];
Scroggo97c88c22011-05-11 14:05:25 +0000171
tomhudson@google.com0d831722011-06-02 15:37:14 +0000172 uint8_t fColorType; // casts to enum ColorType
173 uint8_t fDualSrcOutput; // casts to enum DualSrcOutput
174 int8_t fFirstCoverageStage;
175 SkBool8 fEmitsPointSize;
senorblanco@chromium.org129b8e32011-06-15 17:52:09 +0000176 SkBool8 fEdgeAAConcave;
junov@google.comf93e7172011-03-31 21:26:24 +0000177
tomhudson@google.com0d831722011-06-02 15:37:14 +0000178 int8_t fEdgeAANumEdges;
179 uint8_t fColorFilterXfermode; // casts to enum SkXfermode::Mode
junov@google.comf93e7172011-03-31 21:26:24 +0000180
senorblanco@chromium.org129b8e32011-06-15 17:52:09 +0000181 uint8_t fPadTo32bLengthMultiple [1];
bsalomon@google.com6aef1fb2011-05-05 12:33:22 +0000182
junov@google.comf93e7172011-03-31 21:26:24 +0000183 } fProgramDesc;
184
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000185 const ProgramDesc& getDesc() { return fProgramDesc; }
186
bsalomon@google.com22c5dea2011-07-07 14:38:03 +0000187 // for code readability
188 typedef ProgramDesc::StageDesc StageDesc;
189
junov@google.comf93e7172011-03-31 21:26:24 +0000190public:
bsalomon@google.com91961302011-05-09 18:39:58 +0000191 enum {
192 kUnusedUniform = -1,
193 kSetAsAttribute = 1000,
194 };
195
junov@google.comf93e7172011-03-31 21:26:24 +0000196 struct StageUniLocations {
197 GrGLint fTextureMatrixUni;
bsalomon@google.com6aef1fb2011-05-05 12:33:22 +0000198 GrGLint fNormalizedTexelSizeUni;
junov@google.comf93e7172011-03-31 21:26:24 +0000199 GrGLint fSamplerUni;
200 GrGLint fRadial2Uni;
junov@google.com6acc9b32011-05-16 18:32:07 +0000201 GrGLint fTexDomUni;
senorblanco@chromium.org027de5f2011-07-08 18:03:33 +0000202 GrGLint fKernelUni;
203 GrGLint fImageIncrementUni;
bsalomon@google.com91961302011-05-09 18:39:58 +0000204 void reset() {
205 fTextureMatrixUni = kUnusedUniform;
206 fNormalizedTexelSizeUni = kUnusedUniform;
207 fSamplerUni = kUnusedUniform;
208 fRadial2Uni = kUnusedUniform;
junov@google.com6acc9b32011-05-16 18:32:07 +0000209 fTexDomUni = kUnusedUniform;
senorblanco@chromium.org027de5f2011-07-08 18:03:33 +0000210 fKernelUni = kUnusedUniform;
211 fImageIncrementUni = kUnusedUniform;
bsalomon@google.com91961302011-05-09 18:39:58 +0000212 }
junov@google.comf93e7172011-03-31 21:26:24 +0000213 };
214
215 struct UniLocations {
216 GrGLint fViewMatrixUni;
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000217 GrGLint fColorUni;
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +0000218 GrGLint fEdgesUni;
Scroggo97c88c22011-05-11 14:05:25 +0000219 GrGLint fColorFilterUni;
junov@google.comf93e7172011-03-31 21:26:24 +0000220 StageUniLocations fStages[GrDrawTarget::kNumStages];
bsalomon@google.com91961302011-05-09 18:39:58 +0000221 void reset() {
222 fViewMatrixUni = kUnusedUniform;
223 fColorUni = kUnusedUniform;
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +0000224 fEdgesUni = kUnusedUniform;
Scroggo97c88c22011-05-11 14:05:25 +0000225 fColorFilterUni = kUnusedUniform;
bsalomon@google.com91961302011-05-09 18:39:58 +0000226 for (int s = 0; s < GrDrawTarget::kNumStages; ++s) {
227 fStages[s].reset();
228 }
229 }
junov@google.comf93e7172011-03-31 21:26:24 +0000230 };
231
232 class CachedData : public ::GrNoncopyable {
233 public:
234 CachedData() {
junov@google.comf93e7172011-03-31 21:26:24 +0000235 }
236
237 ~CachedData() {
junov@google.comf93e7172011-03-31 21:26:24 +0000238 }
239
240 void copyAndTakeOwnership(CachedData& other) {
bsalomon@google.com2d9ddf92011-05-11 16:52:59 +0000241 memcpy(this, &other, sizeof(*this));
junov@google.comf93e7172011-03-31 21:26:24 +0000242 }
243
junov@google.comf93e7172011-03-31 21:26:24 +0000244 public:
245
246 // IDs
247 GrGLuint fVShaderID;
248 GrGLuint fFShaderID;
249 GrGLuint fProgramID;
250 // shader uniform locations (-1 if shader doesn't use them)
251 UniLocations fUniLocations;
252
253 GrMatrix fViewMatrix;
254
255 // these reflect the current values of uniforms
256 // (GL uniform values travel with program)
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000257 GrColor fColor;
Scroggo97c88c22011-05-11 14:05:25 +0000258 GrColor fColorFilterColor;
junov@google.comf93e7172011-03-31 21:26:24 +0000259 GrMatrix fTextureMatrices[GrDrawTarget::kNumStages];
bsalomon@google.com6aef1fb2011-05-05 12:33:22 +0000260 // width and height used for normalized texel size
261 int fTextureWidth[GrDrawTarget::kNumStages];
262 int fTextureHeight[GrDrawTarget::kNumStages];
junov@google.comf93e7172011-03-31 21:26:24 +0000263 GrScalar fRadial2CenterX1[GrDrawTarget::kNumStages];
264 GrScalar fRadial2Radius0[GrDrawTarget::kNumStages];
265 bool fRadial2PosRoot[GrDrawTarget::kNumStages];
junov@google.com2f839402011-05-24 15:13:01 +0000266 GrRect fTextureDomain[GrDrawTarget::kNumStages];
junov@google.comf93e7172011-03-31 21:26:24 +0000267
268 private:
269 enum Constants {
270 kUniLocationPreAllocSize = 8
271 };
272
junov@google.comf93e7172011-03-31 21:26:24 +0000273 }; // CachedData
274
junov@google.comf93e7172011-03-31 21:26:24 +0000275private:
bsalomon@google.com91961302011-05-09 18:39:58 +0000276 enum {
277 kUseUniform = 2000
278 };
279
280 // should set all fields in locations var to kUseUniform if the
281 // corresponding uniform is required for the program.
junov@google.comf93e7172011-03-31 21:26:24 +0000282 void genStageCode(int stageNum,
283 const ProgramDesc::StageDesc& desc,
284 const char* fsInColor, // NULL means no incoming color
285 const char* fsOutColor,
286 const char* vsInCoord,
287 ShaderCodeSegments* segments,
288 StageUniLocations* locations) const;
289
bsalomon@google.com91961302011-05-09 18:39:58 +0000290 static bool CompileFSAndVS(const ShaderCodeSegments& segments,
291 CachedData* programData);
292
junov@google.comf93e7172011-03-31 21:26:24 +0000293 // Compiles a GL shader, returns shader ID or 0 if failed
294 // params have same meaning as glShaderSource
295 static GrGLuint CompileShader(GrGLenum type, int stringCnt,
296 const char** strings,
297 int* stringLengths);
298
bsalomon@google.com91961302011-05-09 18:39:58 +0000299 // Creates a GL program ID, binds shader attributes to GL vertex attrs, and
300 // links the program
bsalomon@google.com271cffc2011-05-20 14:13:56 +0000301 bool bindOutputsAttribsAndLinkProgram(
302 GrStringBuilder texCoordAttrNames[GrDrawTarget::kMaxTexCoords],
303 bool bindColorOut,
304 bool bindDualSrcOut,
305 CachedData* programData) const;
bsalomon@google.com91961302011-05-09 18:39:58 +0000306
307 // Gets locations for all uniforms set to kUseUniform and initializes cache
308 // to invalid values.
309 void getUniformLocationsAndInitCache(CachedData* programData) const;
310
junov@google.comf93e7172011-03-31 21:26:24 +0000311 friend class GrGpuGLShaders;
312};
313
314#endif