blob: c16e9e05fc54fde85db12749bd40844ac5a90e4d [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#include "GrBinHashKey.h"
18#include "GrGLEffect.h"
19#include "GrGLProgram.h"
20#include "GrGpuGLShaders.h"
21#include "GrGpuVertex.h"
22#include "GrMemory.h"
23#include "GrNoncopyable.h"
24#include "GrStringBuilder.h"
25
junov@google.comf93e7172011-03-31 21:26:24 +000026#define PRINT_SHADERS 0
27#define SKIP_CACHE_CHECK true
28#define GR_UINT32_MAX static_cast<uint32_t>(-1)
29
bsalomon@google.com4be283f2011-04-19 21:15:09 +000030#if GR_GL_ATTRIBUTE_MATRICES
31 #define VIEWMAT_ATTR_LOCATION (3 + GrDrawTarget::kMaxTexCoords)
32 #define TEXMAT_ATTR_LOCATION(X) (6 + GrDrawTarget::kMaxTexCoords + 3 * (X))
33 #define BOGUS_MATRIX_UNI_LOCATION 1000
junov@google.comf93e7172011-03-31 21:26:24 +000034#endif
35
36#include "GrTHashCache.h"
37
38class GrGpuGLShaders::ProgramCache : public ::GrNoncopyable {
39private:
40 class Entry;
41
42#if GR_DEBUG
43 typedef GrBinHashKey<Entry, 4> ProgramHashKey; // Flex the dynamic allocation muscle in debug
44#else
45 typedef GrBinHashKey<Entry, 32> ProgramHashKey;
46#endif
47
48 class Entry : public ::GrNoncopyable {
49 public:
50 Entry() {}
51 private:
52 void copyAndTakeOwnership(Entry& entry) {
53 fProgramData.copyAndTakeOwnership(entry.fProgramData);
54 fKey.copyAndTakeOwnership(entry.fKey); // ownership transfer
55 fLRUStamp = entry.fLRUStamp;
56 }
57
58 public:
59 int compare(const ProgramHashKey& key) const { return fKey.compare(key); }
60
61 public:
62 GrGLProgram::CachedData fProgramData;
63 ProgramHashKey fKey;
64 unsigned int fLRUStamp;
65 };
66
67 GrTHashTable<Entry, ProgramHashKey, 8> fHashCache;
68
69 enum {
70 kMaxEntries = 32
71 };
72 Entry fEntries[kMaxEntries];
73 int fCount;
74 unsigned int fCurrLRUStamp;
75
76public:
77 ProgramCache()
78 : fCount(0)
79 , fCurrLRUStamp(0) {
80 }
81
82 ~ProgramCache() {
83 for (int i = 0; i < fCount; ++i) {
84 GrGpuGLShaders::DeleteProgram(&fEntries[i].fProgramData);
85 }
86 }
87
88 void abandon() {
89 fCount = 0;
90 }
91
92 void invalidateViewMatrices() {
93 for (int i = 0; i < fCount; ++i) {
94 // set to illegal matrix
95 fEntries[i].fProgramData.fViewMatrix = GrMatrix::InvalidMatrix();
96 }
97 }
98
99 GrGLProgram::CachedData* getProgramData(const GrGLProgram& desc,
100 const GrDrawTarget* target) {
101 ProgramHashKey key;
102 while (key.doPass()) {
103 desc.buildKey(key);
104 }
105 Entry* entry = fHashCache.find(key);
106 if (NULL == entry) {
107 if (fCount < kMaxEntries) {
108 entry = fEntries + fCount;
109 ++fCount;
110 } else {
111 GrAssert(kMaxEntries == fCount);
112 entry = fEntries;
113 for (int i = 1; i < kMaxEntries; ++i) {
114 if (fEntries[i].fLRUStamp < entry->fLRUStamp) {
115 entry = fEntries + i;
116 }
117 }
118 fHashCache.remove(entry->fKey, entry);
119 GrGpuGLShaders::DeleteProgram(&entry->fProgramData);
120 }
121 entry->fKey.copyAndTakeOwnership(key);
122 desc.genProgram(&entry->fProgramData, target);
123 fHashCache.insert(entry->fKey, entry);
124 }
125
126 entry->fLRUStamp = fCurrLRUStamp;
127 if (GR_UINT32_MAX == fCurrLRUStamp) {
128 // wrap around! just trash our LRU, one time hit.
129 for (int i = 0; i < fCount; ++i) {
130 fEntries[i].fLRUStamp = 0;
131 }
132 }
133 ++fCurrLRUStamp;
134 return &entry->fProgramData;
135 }
136};
137
138void GrGpuGLShaders::DeleteProgram(GrGLProgram::CachedData* programData) {
139 GR_GL(DeleteShader(programData->fVShaderID));
140 GR_GL(DeleteShader(programData->fFShaderID));
141 GR_GL(DeleteProgram(programData->fProgramID));
142 GR_DEBUGCODE(memset(programData, 0, sizeof(*programData));)
143}
144
145
146GrGpuGLShaders::GrGpuGLShaders() {
147
bsalomon@google.combcdbbe62011-04-12 15:40:00 +0000148 resetContext();
junov@google.comf93e7172011-03-31 21:26:24 +0000149
150 fProgramData = NULL;
151 fProgramCache = new ProgramCache();
152}
153
154GrGpuGLShaders::~GrGpuGLShaders() {
155 delete fProgramCache;
156}
157
158const GrMatrix& GrGpuGLShaders::getHWSamplerMatrix(int stage) {
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000159#if GR_GL_ATTRIBUTE_MATRICES
junov@google.comf93e7172011-03-31 21:26:24 +0000160 return fHWDrawState.fSamplerStates[stage].getMatrix();
161#else
162 GrAssert(fProgramData);
163 return fProgramData->fTextureMatrices[stage];
164#endif
165}
166
167void GrGpuGLShaders::recordHWSamplerMatrix(int stage, const GrMatrix& matrix) {
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000168#if GR_GL_ATTRIBUTE_MATRICES
junov@google.comf93e7172011-03-31 21:26:24 +0000169 fHWDrawState.fSamplerStates[stage].setMatrix(matrix);
170#else
171 GrAssert(fProgramData);
172 fProgramData->fTextureMatrices[stage] = matrix;
173#endif
174}
175
176void GrGpuGLShaders::resetContext() {
177 INHERITED::resetContext();
junov@google.comf93e7172011-03-31 21:26:24 +0000178
junov@google.comf93e7172011-03-31 21:26:24 +0000179 fHWGeometryState.fVertexLayout = 0;
180 fHWGeometryState.fVertexOffset = ~0;
181 GR_GL(DisableVertexAttribArray(COL_ATTR_LOCATION));
182 for (int t = 0; t < kMaxTexCoords; ++t) {
183 GR_GL(DisableVertexAttribArray(TEX_ATTR_LOCATION(t)));
184 }
185 GR_GL(EnableVertexAttribArray(POS_ATTR_LOCATION));
186
187 fHWProgramID = 0;
188}
189
190void GrGpuGLShaders::flushViewMatrix() {
191 GrAssert(NULL != fCurrDrawState.fRenderTarget);
192 GrMatrix m (
193 GrIntToScalar(2) / fCurrDrawState.fRenderTarget->width(), 0, -GR_Scalar1,
194 0,-GrIntToScalar(2) / fCurrDrawState.fRenderTarget->height(), GR_Scalar1,
195 0, 0, GrMatrix::I()[8]);
196 m.setConcat(m, fCurrDrawState.fViewMatrix);
197
198 // ES doesn't allow you to pass true to the transpose param,
199 // so do our own transpose
200 GrScalar mt[] = {
201 m[GrMatrix::kScaleX],
202 m[GrMatrix::kSkewY],
203 m[GrMatrix::kPersp0],
204 m[GrMatrix::kSkewX],
205 m[GrMatrix::kScaleY],
206 m[GrMatrix::kPersp1],
207 m[GrMatrix::kTransX],
208 m[GrMatrix::kTransY],
209 m[GrMatrix::kPersp2]
210 };
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000211#if GR_GL_ATTRIBUTE_MATRICES
junov@google.comf93e7172011-03-31 21:26:24 +0000212 GR_GL(VertexAttrib4fv(VIEWMAT_ATTR_LOCATION+0, mt+0));
213 GR_GL(VertexAttrib4fv(VIEWMAT_ATTR_LOCATION+1, mt+3));
214 GR_GL(VertexAttrib4fv(VIEWMAT_ATTR_LOCATION+2, mt+6));
215#else
216 GR_GL(UniformMatrix3fv(fProgramData->fUniLocations.fViewMatrixUni,1,false,mt));
217#endif
218}
219
220void GrGpuGLShaders::flushTextureMatrix(int stage) {
221 GrAssert(NULL != fCurrDrawState.fTextures[stage]);
222
223 GrGLTexture* texture = (GrGLTexture*) fCurrDrawState.fTextures[stage];
224
225 GrMatrix m = getSamplerMatrix(stage);
226 GrSamplerState::SampleMode mode =
227 fCurrDrawState.fSamplerStates[0].getSampleMode();
228 AdjustTextureMatrix(texture, mode, &m);
229
230 // ES doesn't allow you to pass true to the transpose param,
231 // so do our own transpose
232 GrScalar mt[] = {
233 m[GrMatrix::kScaleX],
234 m[GrMatrix::kSkewY],
235 m[GrMatrix::kPersp0],
236 m[GrMatrix::kSkewX],
237 m[GrMatrix::kScaleY],
238 m[GrMatrix::kPersp1],
239 m[GrMatrix::kTransX],
240 m[GrMatrix::kTransY],
241 m[GrMatrix::kPersp2]
242 };
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000243#if GR_GL_ATTRIBUTE_MATRICES
junov@google.comf93e7172011-03-31 21:26:24 +0000244 GR_GL(VertexAttrib4fv(TEXMAT_ATTR_LOCATION(0)+0, mt+0));
245 GR_GL(VertexAttrib4fv(TEXMAT_ATTR_LOCATION(0)+1, mt+3));
246 GR_GL(VertexAttrib4fv(TEXMAT_ATTR_LOCATION(0)+2, mt+6));
247#else
248 GR_GL(UniformMatrix3fv(fProgramData->fUniLocations.fStages[stage].fTextureMatrixUni,
249 1, false, mt));
250#endif
251}
252
253void GrGpuGLShaders::flushRadial2(int stage) {
254
255 const GrSamplerState& sampler = fCurrDrawState.fSamplerStates[stage];
256
257 GrScalar centerX1 = sampler.getRadial2CenterX1();
258 GrScalar radius0 = sampler.getRadial2Radius0();
259
260 GrScalar a = GrMul(centerX1, centerX1) - GR_Scalar1;
261
262 float unis[6] = {
263 GrScalarToFloat(a),
264 1 / (2.f * unis[0]),
265 GrScalarToFloat(centerX1),
266 GrScalarToFloat(radius0),
267 GrScalarToFloat(GrMul(radius0, radius0)),
268 sampler.isRadial2PosRoot() ? 1.f : -1.f
269 };
270 GR_GL(Uniform1fv(fProgramData->fUniLocations.fStages[stage].fRadial2Uni,
271 6,
272 unis));
273}
274
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000275void GrGpuGLShaders::flushColor() {
276 const GrGLProgram::ProgramDesc& desc = fCurrentProgram.getDesc();
277 if (fGeometrySrc.fVertexLayout & kColor_VertexLayoutBit) {
278 // color will be specified per-vertex as an attribute
279 // invalidate the const vertex attrib color
280 fHWDrawState.fColor = GrColor_ILLEGAL;
281 } else {
282 switch (desc.fColorType) {
283 case GrGLProgram::ProgramDesc::kAttribute_ColorType:
284 if (fHWDrawState.fColor != fCurrDrawState.fColor) {
285 // OpenGL ES only supports the float varities of glVertexAttrib
286 float c[] = {
287 GrColorUnpackR(fCurrDrawState.fColor) / 255.f,
288 GrColorUnpackG(fCurrDrawState.fColor) / 255.f,
289 GrColorUnpackB(fCurrDrawState.fColor) / 255.f,
290 GrColorUnpackA(fCurrDrawState.fColor) / 255.f
291 };
292 GR_GL(VertexAttrib4fv(COL_ATTR_LOCATION, c));
293 fHWDrawState.fColor = fCurrDrawState.fColor;
294 }
295 break;
296 case GrGLProgram::ProgramDesc::kUniform_ColorType:
297 if (fProgramData->fColor != fCurrDrawState.fColor) {
298 // OpenGL ES only supports the float varities of glVertexAttrib
299 float c[] = {
300 GrColorUnpackR(fCurrDrawState.fColor) / 255.f,
301 GrColorUnpackG(fCurrDrawState.fColor) / 255.f,
302 GrColorUnpackB(fCurrDrawState.fColor) / 255.f,
303 GrColorUnpackA(fCurrDrawState.fColor) / 255.f
304 };
305 GrAssert(-1 != fProgramData->fUniLocations.fColorUni);
306 GR_GL(Uniform4fv(fProgramData->fUniLocations.fColorUni, 1, c));
307 fProgramData->fColor = fCurrDrawState.fColor;
308 }
309 break;
310 case GrGLProgram::ProgramDesc::kNone_ColorType:
311 GrAssert(0xffffffff == fCurrDrawState.fColor);
312 break;
313 default:
314 GrCrash("Unknown color type.");
315 }
316 }
317}
318
319
junov@google.comf93e7172011-03-31 21:26:24 +0000320bool GrGpuGLShaders::flushGraphicsState(GrPrimitiveType type) {
321 if (!flushGLStateCommon(type)) {
322 return false;
323 }
324
325 if (fDirtyFlags.fRenderTargetChanged) {
326 // our coords are in pixel space and the GL matrices map to NDC
327 // so if the viewport changed, our matrix is now wrong.
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000328#if GR_GL_ATTRIBUTE_MATRICES
junov@google.comf93e7172011-03-31 21:26:24 +0000329 fHWDrawState.fViewMatrix = GrMatrix::InvalidMatrix();
330#else
331 // we assume all shader matrices may be wrong after viewport changes
332 fProgramCache->invalidateViewMatrices();
333#endif
334 }
335
junov@google.comf93e7172011-03-31 21:26:24 +0000336 buildProgram(type);
337 fProgramData = fProgramCache->getProgramData(fCurrentProgram, this);
338
339 if (fHWProgramID != fProgramData->fProgramID) {
340 GR_GL(UseProgram(fProgramData->fProgramID));
341 fHWProgramID = fProgramData->fProgramID;
342 }
343
344 if (!fCurrentProgram.doGLSetup(type, fProgramData)) {
345 return false;
346 }
347
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000348 flushColor();
349
350#if GR_GL_ATTRIBUTE_MATRICES
junov@google.comf93e7172011-03-31 21:26:24 +0000351 GrMatrix& currViewMatrix = fHWDrawState.fViewMatrix;
352#else
353 GrMatrix& currViewMatrix = fProgramData->fViewMatrix;
354#endif
355
356 if (currViewMatrix != fCurrDrawState.fViewMatrix) {
357 flushViewMatrix();
358 currViewMatrix = fCurrDrawState.fViewMatrix;
359 }
360
361 for (int s = 0; s < kNumStages; ++s) {
362 GrGLTexture* texture = (GrGLTexture*) fCurrDrawState.fTextures[s];
363 if (NULL != texture) {
364 if (-1 != fProgramData->fUniLocations.fStages[s].fTextureMatrixUni &&
365 (((1 << s) & fDirtyFlags.fTextureChangedMask) ||
366 getHWSamplerMatrix(s) != getSamplerMatrix(s))) {
367 flushTextureMatrix(s);
368 recordHWSamplerMatrix(s, getSamplerMatrix(s));
369 }
370 }
371
372 const GrSamplerState& sampler = fCurrDrawState.fSamplerStates[s];
373 if (-1 != fProgramData->fUniLocations.fStages[s].fRadial2Uni &&
374 (fProgramData->fRadial2CenterX1[s] != sampler.getRadial2CenterX1() ||
375 fProgramData->fRadial2Radius0[s] != sampler.getRadial2Radius0() ||
376 fProgramData->fRadial2PosRoot[s] != sampler.isRadial2PosRoot())) {
377
378 flushRadial2(s);
379
380 fProgramData->fRadial2CenterX1[s] = sampler.getRadial2CenterX1();
381 fProgramData->fRadial2Radius0[s] = sampler.getRadial2Radius0();
382 fProgramData->fRadial2PosRoot[s] = sampler.isRadial2PosRoot();
383 }
384 }
385 resetDirtyFlags();
386 return true;
387}
388
389void GrGpuGLShaders::postDraw() {
390 fCurrentProgram.doGLPost();
391}
392
393void GrGpuGLShaders::setupGeometry(int* startVertex,
394 int* startIndex,
395 int vertexCount,
396 int indexCount) {
397
398 int newColorOffset;
399 int newTexCoordOffsets[kMaxTexCoords];
400
401 GrGLsizei newStride = VertexSizeAndOffsetsByIdx(fGeometrySrc.fVertexLayout,
402 newTexCoordOffsets,
403 &newColorOffset);
404 int oldColorOffset;
405 int oldTexCoordOffsets[kMaxTexCoords];
406 GrGLsizei oldStride = VertexSizeAndOffsetsByIdx(fHWGeometryState.fVertexLayout,
407 oldTexCoordOffsets,
408 &oldColorOffset);
409 bool indexed = NULL != startIndex;
410
411 int extraVertexOffset;
412 int extraIndexOffset;
413 setBuffers(indexed, &extraVertexOffset, &extraIndexOffset);
414
415 GrGLenum scalarType;
416 bool texCoordNorm;
417 if (fGeometrySrc.fVertexLayout & kTextFormat_VertexLayoutBit) {
418 scalarType = GrGLTextType;
419 texCoordNorm = GR_GL_TEXT_TEXTURE_NORMALIZED;
420 } else {
421 scalarType = GrGLType;
422 texCoordNorm = false;
423 }
424
425 size_t vertexOffset = (*startVertex + extraVertexOffset) * newStride;
426 *startVertex = 0;
427 if (indexed) {
428 *startIndex += extraIndexOffset;
429 }
430
431 // all the Pointers must be set if any of these are true
432 bool allOffsetsChange = fHWGeometryState.fArrayPtrsDirty ||
433 vertexOffset != fHWGeometryState.fVertexOffset ||
434 newStride != oldStride;
435
436 // position and tex coord offsets change if above conditions are true
437 // or the type/normalization changed based on text vs nontext type coords.
438 bool posAndTexChange = allOffsetsChange ||
439 (((GrGLTextType != GrGLType) || GR_GL_TEXT_TEXTURE_NORMALIZED) &&
440 (kTextFormat_VertexLayoutBit &
441 (fHWGeometryState.fVertexLayout ^
442 fGeometrySrc.fVertexLayout)));
443
444 if (posAndTexChange) {
445 GR_GL(VertexAttribPointer(POS_ATTR_LOCATION, 2, scalarType,
446 false, newStride, (GrGLvoid*)vertexOffset));
447 fHWGeometryState.fVertexOffset = vertexOffset;
448 }
449
450 for (int t = 0; t < kMaxTexCoords; ++t) {
451 if (newTexCoordOffsets[t] > 0) {
452 GrGLvoid* texCoordOffset = (GrGLvoid*)(vertexOffset + newTexCoordOffsets[t]);
453 if (oldTexCoordOffsets[t] <= 0) {
454 GR_GL(EnableVertexAttribArray(TEX_ATTR_LOCATION(t)));
455 GR_GL(VertexAttribPointer(TEX_ATTR_LOCATION(t), 2, scalarType,
456 texCoordNorm, newStride, texCoordOffset));
457 } else if (posAndTexChange ||
458 newTexCoordOffsets[t] != oldTexCoordOffsets[t]) {
459 GR_GL(VertexAttribPointer(TEX_ATTR_LOCATION(t), 2, scalarType,
460 texCoordNorm, newStride, texCoordOffset));
461 }
462 } else if (oldTexCoordOffsets[t] > 0) {
463 GR_GL(DisableVertexAttribArray(TEX_ATTR_LOCATION(t)));
464 }
465 }
466
467 if (newColorOffset > 0) {
468 GrGLvoid* colorOffset = (int8_t*)(vertexOffset + newColorOffset);
469 if (oldColorOffset <= 0) {
470 GR_GL(EnableVertexAttribArray(COL_ATTR_LOCATION));
471 GR_GL(VertexAttribPointer(COL_ATTR_LOCATION, 4,
472 GR_GL_UNSIGNED_BYTE,
473 true, newStride, colorOffset));
474 } else if (allOffsetsChange || newColorOffset != oldColorOffset) {
475 GR_GL(VertexAttribPointer(COL_ATTR_LOCATION, 4,
476 GR_GL_UNSIGNED_BYTE,
477 true, newStride, colorOffset));
478 }
479 } else if (oldColorOffset > 0) {
480 GR_GL(DisableVertexAttribArray(COL_ATTR_LOCATION));
481 }
482
483 fHWGeometryState.fVertexLayout = fGeometrySrc.fVertexLayout;
484 fHWGeometryState.fArrayPtrsDirty = false;
485}
486
487void GrGpuGLShaders::buildProgram(GrPrimitiveType type) {
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000488 GrGLProgram::ProgramDesc& desc = fCurrentProgram.fProgramDesc;
junov@google.comf93e7172011-03-31 21:26:24 +0000489
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000490 // Must initialize all fields or cache will have false negatives!
491 desc.fVertexLayout = fGeometrySrc.fVertexLayout;
492
493 desc.fEmitsPointSize = kPoints_PrimitiveType == type;
494
495 bool requiresAttributeColors = desc.fVertexLayout & kColor_VertexLayoutBit;
496 // fColorType records how colors are specified for the program. Strip
497 // the bit from the layout to avoid false negatives when searching for an
498 // existing program in the cache.
499 desc.fVertexLayout &= ~(kColor_VertexLayoutBit);
500
junov@google.comf93e7172011-03-31 21:26:24 +0000501#if GR_AGGRESSIVE_SHADER_OPTS
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000502 if (!requiresAttributeColors && (0xffffffff == fCurrDrawState.fColor)) {
503 desc.fColorType = ProgramDesc::kNone_ColorType;
504 } else
junov@google.comf93e7172011-03-31 21:26:24 +0000505#endif
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000506#if GR_GL_NO_CONSTANT_ATTRIBUTES
507 if (!requiresAttributeColors) {
508 desc.fColorType = GrGLProgram::ProgramDesc::kUniform_ColorType;
509 } else
510#endif
511 {
512 desc.fColorType = GrGLProgram::ProgramDesc::kAttribute_ColorType;
513 }
junov@google.comf93e7172011-03-31 21:26:24 +0000514
515 for (int s = 0; s < kNumStages; ++s) {
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000516 GrGLProgram::ProgramDesc::StageDesc& stage = desc.fStages[s];
junov@google.comf93e7172011-03-31 21:26:24 +0000517
518 stage.fEnabled = VertexUsesStage(s, fGeometrySrc.fVertexLayout);
519
520 if (stage.fEnabled) {
521 GrGLTexture* texture = (GrGLTexture*) fCurrDrawState.fTextures[s];
522 GrAssert(NULL != texture);
523 // we matrix to invert when orientation is TopDown, so make sure
524 // we aren't in that case before flagging as identity.
525 if (TextureMatrixIsIdentity(texture, fCurrDrawState.fSamplerStates[s])) {
526 stage.fOptFlags = GrGLProgram::ProgramDesc::StageDesc::kIdentityMatrix_OptFlagBit;
527 } else if (!getSamplerMatrix(s).hasPerspective()) {
528 stage.fOptFlags = GrGLProgram::ProgramDesc::StageDesc::kNoPerspective_OptFlagBit;
529 } else {
530 stage.fOptFlags = 0;
531 }
532 switch (fCurrDrawState.fSamplerStates[s].getSampleMode()) {
533 case GrSamplerState::kNormal_SampleMode:
534 stage.fCoordMapping = GrGLProgram::ProgramDesc::StageDesc::kIdentity_CoordMapping;
535 break;
536 case GrSamplerState::kRadial_SampleMode:
537 stage.fCoordMapping = GrGLProgram::ProgramDesc::StageDesc::kRadialGradient_CoordMapping;
538 break;
539 case GrSamplerState::kRadial2_SampleMode:
540 stage.fCoordMapping = GrGLProgram::ProgramDesc::StageDesc::kRadial2Gradient_CoordMapping;
541 break;
542 case GrSamplerState::kSweep_SampleMode:
543 stage.fCoordMapping = GrGLProgram::ProgramDesc::StageDesc::kSweepGradient_CoordMapping;
544 break;
545 default:
546 GrAssert(!"Unexpected sample mode!");
547 break;
548 }
549
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000550 if (GrPixelConfigIsAlphaOnly(texture->config())) {
junov@google.comf93e7172011-03-31 21:26:24 +0000551 stage.fModulation = GrGLProgram::ProgramDesc::StageDesc::kAlpha_Modulation;
552 } else {
553 stage.fModulation = GrGLProgram::ProgramDesc::StageDesc::kColor_Modulation;
554 }
555
556 if (fCurrDrawState.fEffects[s]) {
557 fCurrentProgram.fStageEffects[s] = GrGLEffect::Create(fCurrDrawState.fEffects[s]);
558 } else {
559 delete fCurrentProgram.fStageEffects[s];
560 fCurrentProgram.fStageEffects[s] = NULL;
561 }
562 } else {
563 stage.fOptFlags = 0;
564 stage.fCoordMapping = (GrGLProgram::ProgramDesc::StageDesc::CoordMapping)0;
565 stage.fModulation = (GrGLProgram::ProgramDesc::StageDesc::Modulation)0;
566 fCurrentProgram.fStageEffects[s] = NULL;
567 }
568 }
569}
570
571
572