blob: e02d15b61743c91eaf239e0407770afc207fc64b [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"
junov@google.comf93e7172011-03-31 21:26:24 +000022#include "GrDrawTarget.h"
23
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 {
29 GrStringBuilder fVSUnis;
30 GrStringBuilder fVSAttrs;
31 GrStringBuilder fVaryings;
32 GrStringBuilder fFSUnis;
33 GrStringBuilder fVSCode;
34 GrStringBuilder fFSCode;
35};
junov@google.comf93e7172011-03-31 21:26:24 +000036
37/**
38 * This class manages a GPU program and records per-program information.
39 * We can specify the attribute locations so that they are constant
40 * across our shaders. But the driver determines the uniform locations
41 * at link time. We don't need to remember the sampler uniform location
42 * because we will bind a texture slot to it and never change it
43 * Uniforms are program-local so we can't rely on fHWState to hold the
44 * previous uniform state after a program change.
45 */
46class GrGLProgram {
47public:
48 class CachedData;
49
50 GrGLProgram();
51 ~GrGLProgram();
52
53 /**
54 * Streams data that can uniquely identifies the generated
55 * gpu program into a key, for cache indexing purposes.
56 *
57 * @param key The key object to receive the key data
58 */
59 void buildKey(GrBinHashKeyBuilder& key) const;
60
61 /**
62 * This is the heavy initilization routine for building a GLProgram.
63 * The result of heavy init is not stored in datamembers of GrGLProgam,
64 * but in a separate cacheable container.
65 */
bsalomon@google.com91961302011-05-09 18:39:58 +000066 bool genProgram(CachedData* programData) const;
junov@google.comf93e7172011-03-31 21:26:24 +000067
bsalomon@google.com91961302011-05-09 18:39:58 +000068 static int PositionAttributeIdx() { return 0; }
69 static int TexCoordAttributeIdx(int tcIdx) { return 1 + tcIdx; }
70 static int ColorAttributeIdx() { return 1 + GrDrawTarget::kMaxTexCoords; }
71 static int ViewMatrixAttributeIdx() {
72 return 2 + GrDrawTarget::kMaxTexCoords;
73 }
74 static int TextureMatrixAttributeIdx(int stage) {
75 return 5 + GrDrawTarget::kMaxTexCoords + 3 * stage;
76 }
77
junov@google.comf93e7172011-03-31 21:26:24 +000078private:
79
80 //Parameters that affect code generation
81 struct ProgramDesc {
bsalomon@google.com4be283f2011-04-19 21:15:09 +000082 ProgramDesc() {
83 // since we use this as part of a key we can't have any unitialized
84 // padding
85 memset(this, 0, sizeof(ProgramDesc));
86 }
87
88 // stripped of bits that don't affect prog generation
junov@google.comf93e7172011-03-31 21:26:24 +000089 GrVertexLayout fVertexLayout;
90
91 enum {
bsalomon@google.com4be283f2011-04-19 21:15:09 +000092 kNone_ColorType = 0,
93 kAttribute_ColorType = 1,
94 kUniform_ColorType = 2,
95 } fColorType;
96
bsalomon@google.comf2d91552011-05-16 20:56:06 +000097 int fFirstCoverageStage;
bsalomon@google.com4be283f2011-04-19 21:15:09 +000098 bool fEmitsPointSize;
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +000099 bool fUsesEdgeAA;
junov@google.comf93e7172011-03-31 21:26:24 +0000100
Scroggo97c88c22011-05-11 14:05:25 +0000101 SkXfermode::Mode fColorFilterXfermode;
102
junov@google.comf93e7172011-03-31 21:26:24 +0000103 struct StageDesc {
104 enum OptFlagBits {
junov@google.com6acc9b32011-05-16 18:32:07 +0000105 kNoPerspective_OptFlagBit = 1 << 0,
106 kIdentityMatrix_OptFlagBit = 1 << 1,
107 kCustomTextureDomain_OptFlagBit = 1 << 2
junov@google.comf93e7172011-03-31 21:26:24 +0000108 };
109
bsalomon@google.com6aef1fb2011-05-05 12:33:22 +0000110 unsigned fOptFlags;
111 bool fEnabled;
junov@google.comf93e7172011-03-31 21:26:24 +0000112
113 enum Modulation {
114 kColor_Modulation,
115 kAlpha_Modulation
bsalomon@google.com6aef1fb2011-05-05 12:33:22 +0000116 } fModulation;
117
118 enum FetchMode {
119 kSingle_FetchMode,
120 k2x2_FetchMode
121 } fFetchMode;
junov@google.comf93e7172011-03-31 21:26:24 +0000122
123 enum CoordMapping {
124 kIdentity_CoordMapping,
125 kRadialGradient_CoordMapping,
126 kSweepGradient_CoordMapping,
127 kRadial2Gradient_CoordMapping
bsalomon@google.com6aef1fb2011-05-05 12:33:22 +0000128 } fCoordMapping;
junov@google.comf93e7172011-03-31 21:26:24 +0000129 } fStages[GrDrawTarget::kNumStages];
130 } fProgramDesc;
131
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000132 const ProgramDesc& getDesc() { return fProgramDesc; }
133
junov@google.comf93e7172011-03-31 21:26:24 +0000134public:
bsalomon@google.com91961302011-05-09 18:39:58 +0000135 enum {
136 kUnusedUniform = -1,
137 kSetAsAttribute = 1000,
138 };
139
junov@google.comf93e7172011-03-31 21:26:24 +0000140 struct StageUniLocations {
141 GrGLint fTextureMatrixUni;
bsalomon@google.com6aef1fb2011-05-05 12:33:22 +0000142 GrGLint fNormalizedTexelSizeUni;
junov@google.comf93e7172011-03-31 21:26:24 +0000143 GrGLint fSamplerUni;
144 GrGLint fRadial2Uni;
junov@google.com6acc9b32011-05-16 18:32:07 +0000145 GrGLint fTexDomUni;
bsalomon@google.com91961302011-05-09 18:39:58 +0000146 void reset() {
147 fTextureMatrixUni = kUnusedUniform;
148 fNormalizedTexelSizeUni = kUnusedUniform;
149 fSamplerUni = kUnusedUniform;
150 fRadial2Uni = kUnusedUniform;
junov@google.com6acc9b32011-05-16 18:32:07 +0000151 fTexDomUni = kUnusedUniform;
bsalomon@google.com91961302011-05-09 18:39:58 +0000152 }
junov@google.comf93e7172011-03-31 21:26:24 +0000153 };
154
155 struct UniLocations {
156 GrGLint fViewMatrixUni;
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000157 GrGLint fColorUni;
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +0000158 GrGLint fEdgesUni;
Scroggo97c88c22011-05-11 14:05:25 +0000159 GrGLint fColorFilterUni;
junov@google.comf93e7172011-03-31 21:26:24 +0000160 StageUniLocations fStages[GrDrawTarget::kNumStages];
bsalomon@google.com91961302011-05-09 18:39:58 +0000161 void reset() {
162 fViewMatrixUni = kUnusedUniform;
163 fColorUni = kUnusedUniform;
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +0000164 fEdgesUni = kUnusedUniform;
Scroggo97c88c22011-05-11 14:05:25 +0000165 fColorFilterUni = kUnusedUniform;
bsalomon@google.com91961302011-05-09 18:39:58 +0000166 for (int s = 0; s < GrDrawTarget::kNumStages; ++s) {
167 fStages[s].reset();
168 }
169 }
junov@google.comf93e7172011-03-31 21:26:24 +0000170 };
171
172 class CachedData : public ::GrNoncopyable {
173 public:
174 CachedData() {
junov@google.comf93e7172011-03-31 21:26:24 +0000175 }
176
177 ~CachedData() {
junov@google.comf93e7172011-03-31 21:26:24 +0000178 }
179
180 void copyAndTakeOwnership(CachedData& other) {
bsalomon@google.com2d9ddf92011-05-11 16:52:59 +0000181 memcpy(this, &other, sizeof(*this));
junov@google.comf93e7172011-03-31 21:26:24 +0000182 }
183
junov@google.comf93e7172011-03-31 21:26:24 +0000184
185 public:
186
187 // IDs
188 GrGLuint fVShaderID;
189 GrGLuint fFShaderID;
190 GrGLuint fProgramID;
191 // shader uniform locations (-1 if shader doesn't use them)
192 UniLocations fUniLocations;
193
194 GrMatrix fViewMatrix;
195
196 // these reflect the current values of uniforms
197 // (GL uniform values travel with program)
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000198 GrColor fColor;
Scroggo97c88c22011-05-11 14:05:25 +0000199 GrColor fColorFilterColor;
junov@google.comf93e7172011-03-31 21:26:24 +0000200 GrMatrix fTextureMatrices[GrDrawTarget::kNumStages];
bsalomon@google.com6aef1fb2011-05-05 12:33:22 +0000201 // width and height used for normalized texel size
202 int fTextureWidth[GrDrawTarget::kNumStages];
203 int fTextureHeight[GrDrawTarget::kNumStages];
junov@google.comf93e7172011-03-31 21:26:24 +0000204 GrScalar fRadial2CenterX1[GrDrawTarget::kNumStages];
205 GrScalar fRadial2Radius0[GrDrawTarget::kNumStages];
206 bool fRadial2PosRoot[GrDrawTarget::kNumStages];
207
208 private:
209 enum Constants {
210 kUniLocationPreAllocSize = 8
211 };
212
junov@google.comf93e7172011-03-31 21:26:24 +0000213 }; // CachedData
214
junov@google.comf93e7172011-03-31 21:26:24 +0000215private:
bsalomon@google.com91961302011-05-09 18:39:58 +0000216 enum {
217 kUseUniform = 2000
218 };
219
220 // should set all fields in locations var to kUseUniform if the
221 // corresponding uniform is required for the program.
junov@google.comf93e7172011-03-31 21:26:24 +0000222 void genStageCode(int stageNum,
223 const ProgramDesc::StageDesc& desc,
224 const char* fsInColor, // NULL means no incoming color
225 const char* fsOutColor,
226 const char* vsInCoord,
227 ShaderCodeSegments* segments,
228 StageUniLocations* locations) const;
229
bsalomon@google.com91961302011-05-09 18:39:58 +0000230 static bool CompileFSAndVS(const ShaderCodeSegments& segments,
231 CachedData* programData);
232
junov@google.comf93e7172011-03-31 21:26:24 +0000233 // Compiles a GL shader, returns shader ID or 0 if failed
234 // params have same meaning as glShaderSource
235 static GrGLuint CompileShader(GrGLenum type, int stringCnt,
236 const char** strings,
237 int* stringLengths);
238
bsalomon@google.com91961302011-05-09 18:39:58 +0000239 // Creates a GL program ID, binds shader attributes to GL vertex attrs, and
240 // links the program
241 bool bindAttribsAndLinkProgram(GrStringBuilder texCoordAttrNames[GrDrawTarget::kMaxTexCoords],
242 CachedData* programData) const;
243
244 // Gets locations for all uniforms set to kUseUniform and initializes cache
245 // to invalid values.
246 void getUniformLocationsAndInitCache(CachedData* programData) const;
247
junov@google.comf93e7172011-03-31 21:26:24 +0000248 friend class GrGpuGLShaders;
249};
250
251#endif