blob: d142b66a0b7339ac9ead6b43d60cd7b5a16bb5e2 [file] [log] [blame]
reed@google.comac10a2d2010-12-22 21:39:39 +00001/*
2 Copyright 2010 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
18#include "GrGLConfig.h"
19
20#if GR_SUPPORT_GLES1 || GR_SUPPORT_GLDESKTOP
21
22#include "GrGpuGLFixed.h"
23#include "GrGpuVertex.h"
24
25#define SKIP_CACHE_CHECK true
26
27struct GrGpuMatrix {
28 GrScalar fMat[16];
29
30 void reset() {
31 Gr_bzero(fMat, sizeof(fMat));
32 fMat[0] = fMat[5] = fMat[10] = fMat[15] = GR_Scalar1;
33 }
34
35 void set(const GrMatrix& m) {
36 Gr_bzero(fMat, sizeof(fMat));
37 fMat[0] = m[GrMatrix::kScaleX];
38 fMat[4] = m[GrMatrix::kSkewX];
39 fMat[12] = m[GrMatrix::kTransX];
40
41 fMat[1] = m[GrMatrix::kSkewY];
42 fMat[5] = m[GrMatrix::kScaleY];
43 fMat[13] = m[GrMatrix::kTransY];
44
45 fMat[3] = m[GrMatrix::kPersp0];
46 fMat[7] = m[GrMatrix::kPersp1];
47 fMat[15] = m[GrMatrix::kPersp2];
48
49 fMat[10] = GR_Scalar1; // z-scale
50 }
51};
52
53// these must match the order in the corresponding enum in GrGpu.h
54static const GLenum gMatrixMode2Enum[] = {
55 GL_MODELVIEW, GL_TEXTURE
56};
57
58///////////////////////////////////////////////////////////////////////////////
59
60GrGpuGLFixed::GrGpuGLFixed() {
61 resetContextHelper();
62}
63
64GrGpuGLFixed::~GrGpuGLFixed() {
65}
66
67void GrGpuGLFixed::resetContext() {
68 INHERITED::resetContext();
69 resetContextHelper();
70}
71
72void GrGpuGLFixed::resetContextHelper() {
73 GR_GL(Disable(GL_TEXTURE_2D));
74
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000075 for (int s = 0; s < kNumStages; ++s) {
76 setTextureUnit(s);
77 GR_GL(EnableClientState(GL_VERTEX_ARRAY));
78 GR_GL(TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE));
79 GR_GL(TexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE));
80 GR_GL(TexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE0+s));
81 GR_GL(TexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PREVIOUS));
82 GR_GL(TexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR));
reed@google.comac10a2d2010-12-22 21:39:39 +000083
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000084 GR_GL(TexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE));
85 GR_GL(TexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_TEXTURE0+s));
86 GR_GL(TexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA));
87 GR_GL(TexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_PREVIOUS));
88 GR_GL(TexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA));
89
90 // color oprand0 changes between GL_SRC_COLR and GL_SRC_ALPHA depending
91 // upon whether we have a (premultiplied) RGBA texture or just an ALPHA
92 // texture, e.g.:
93 //glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
94 fHWRGBOperand0[s] = (TextureEnvRGBOperands) -1;
95 }
reed@google.comac10a2d2010-12-22 21:39:39 +000096
97 fHWGeometryState.fVertexLayout = 0;
98 fHWGeometryState.fPositionPtr = (void*) ~0;
99 GR_GL(EnableClientState(GL_VERTEX_ARRAY));
100 GR_GL(DisableClientState(GL_TEXTURE_COORD_ARRAY));
101 GR_GL(ShadeModel(GL_FLAT));
102 GR_GL(DisableClientState(GL_COLOR_ARRAY));
103
104 GrGLClearErr();
105 fTextVerts = false;
106
107 fHWTextureOrientation = (GrGLTexture::Orientation)-1; // illegal
108 fBaseVertex = 0xffffffff;
109}
110
111
112void GrGpuGLFixed::flushProjectionMatrix() {
113 float mat[16];
114 Gr_bzero(mat, sizeof(mat));
115
116 GrAssert(NULL != fCurrDrawState.fRenderTarget);
117
118 mat[0] = 2.f / fCurrDrawState.fRenderTarget->width();
119 mat[5] = -2.f / fCurrDrawState.fRenderTarget->height();
120 mat[10] = -1.f;
121 mat[15] = 1;
122
123 mat[12] = -1.f;
124 mat[13] = 1.f;
125
126 GR_GL(MatrixMode(GL_PROJECTION));
127 GR_GL(LoadMatrixf(mat));
128}
129
130bool GrGpuGLFixed::flushGraphicsState(PrimitiveType type) {
131
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000132 bool usingTextures[kNumStages];
133
134 for (int s = 0; s < kNumStages; ++s) {
135 usingTextures[s] = VertexUsesStage(s, fGeometrySrc.fVertexLayout);
reed@google.comac10a2d2010-12-22 21:39:39 +0000136
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000137 if (usingTextures[s] && fCurrDrawState.fSamplerStates[s].isGradient()) {
138 unimpl("Fixed pipe doesn't support radial/sweep gradients");
139 return false;
140 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000141 }
142
143 flushGLStateCommon(type);
144
145 if (fRenderTargetChanged) {
146 flushProjectionMatrix();
147 fRenderTargetChanged = false;
148 }
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000149
150 for (int s = 0; s < kNumStages; ++s) {
151 bool wasUsingTexture = VertexUsesStage(s, fHWGeometryState.fVertexLayout);
152 if (usingTextures[s] != wasUsingTexture) {
153 setTextureUnit(s);
154 if (usingTextures[s]) {
155 GR_GL(Enable(GL_TEXTURE_2D));
156 } else {
157 GR_GL(Disable(GL_TEXTURE_2D));
158 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000159 }
160 }
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000161
reed@google.comac10a2d2010-12-22 21:39:39 +0000162 uint32_t vertColor = (fGeometrySrc.fVertexLayout & kColor_VertexLayoutBit);
163 uint32_t prevVertColor = (fHWGeometryState.fVertexLayout &
164 kColor_VertexLayoutBit);
165
166 if (vertColor != prevVertColor) {
167 if (vertColor) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000168 GR_GL(ShadeModel(GL_SMOOTH));
169 // invalidate the immediate mode color
170 fHWDrawState.fColor = GrColor_ILLEGAL;
171 } else {
172 GR_GL(ShadeModel(GL_FLAT));
173 }
174 }
175
176 if (kPoints_PrimitiveType == type &&
177 fHWDrawState.fPointSize != fCurrDrawState.fPointSize) {
178 GR_GL(PointSize(fCurrDrawState.fPointSize));
179 fHWDrawState.fPointSize = fCurrDrawState.fPointSize;
180 }
181
182 if (!vertColor && fHWDrawState.fColor != fCurrDrawState.fColor) {
183 GR_GL(Color4ub(GrColorUnpackR(fCurrDrawState.fColor),
184 GrColorUnpackG(fCurrDrawState.fColor),
185 GrColorUnpackB(fCurrDrawState.fColor),
186 GrColorUnpackA(fCurrDrawState.fColor)));
187 fHWDrawState.fColor = fCurrDrawState.fColor;
188 }
189
190 // set texture environment, decide whether we are modulating by RGB or A.
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000191 for (int s = 0; s < kNumStages; ++s) {
192 if (usingTextures[s]) {
193 GrGLTexture* texture = (GrGLTexture*)fCurrDrawState.fTextures[s];
194 if (NULL != texture) {
195 TextureEnvRGBOperands nextRGBOperand0 =
196 (texture->config() == GrTexture::kAlpha_8_PixelConfig) ?
197 kAlpha_TextureEnvRGBOperand :
198 kColor_TextureEnvRGBOperand;
199 if (fHWRGBOperand0[s] != nextRGBOperand0) {
200 setTextureUnit(s);
201 GR_GL(TexEnvi(GL_TEXTURE_ENV,
202 GL_OPERAND0_RGB,
203 (nextRGBOperand0==kAlpha_TextureEnvRGBOperand) ?
204 GL_SRC_ALPHA :
205 GL_SRC_COLOR));
206 fHWRGBOperand0[s] = nextRGBOperand0;
reed@google.comac10a2d2010-12-22 21:39:39 +0000207 }
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000208
209 if (fHWTextureOrientation != texture->orientation() ||
210 fHWDrawState.fTextureMatrices[s] !=
211 fCurrDrawState.fTextureMatrices[s]) {
212 GrGpuMatrix glm;
213 if (GrGLTexture::kBottomUp_Orientation ==
214 texture->orientation()) {
215 GrMatrix m(
216 GR_Scalar1, 0, 0,
217 0, -GR_Scalar1, GR_Scalar1,
218 0, 0, GrMatrix::I()[8]
219 );
220 m.preConcat(fCurrDrawState.fTextureMatrices[s]);
221 glm.set(m);
222 } else {
223 glm.set(fCurrDrawState.fTextureMatrices[s]);
224 }
225 setTextureUnit(s);
226 GR_GL(MatrixMode(GL_TEXTURE));
227 GR_GL(LoadMatrixf(glm.fMat));
228 fHWDrawState.fTextureMatrices[s] =
229 fCurrDrawState.fTextureMatrices[s];
230 fHWTextureOrientation = texture->orientation();
231 }
232 } else {
233 GrAssert(!"Rendering with texture vert flag set but no bound texture");
234 return false;
reed@google.comac10a2d2010-12-22 21:39:39 +0000235 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000236 }
237 }
238
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000239 if (fHWDrawState.fViewMatrix != fCurrDrawState.fViewMatrix) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000240 GrGpuMatrix glm;
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000241 glm.set(fCurrDrawState.fViewMatrix);
242 GR_GL(MatrixMode(GL_MODELVIEW));
reed@google.comac10a2d2010-12-22 21:39:39 +0000243 GR_GL(LoadMatrixf(glm.fMat));
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000244 fHWDrawState.fViewMatrix =
245 fCurrDrawState.fViewMatrix;
reed@google.comac10a2d2010-12-22 21:39:39 +0000246 }
247 return true;
248}
249
250void GrGpuGLFixed::setupGeometry(uint32_t startVertex,
251 uint32_t startIndex,
252 uint32_t vertexCount,
253 uint32_t indexCount) {
254
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000255 int newColorOffset;
256 int newTexCoordOffsets[kNumStages];
reed@google.comac10a2d2010-12-22 21:39:39 +0000257
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000258 GLsizei newStride = VertexSizeAndOffsetsByStage(fGeometrySrc.fVertexLayout,
259 newTexCoordOffsets,
260 &newColorOffset);
261 int oldColorOffset;
262 int oldTexCoordOffsets[kNumStages];
263 GLsizei oldStride = VertexSizeAndOffsetsByStage(fHWGeometryState.fVertexLayout,
264 oldTexCoordOffsets,
265 &oldColorOffset);
reed@google.comac10a2d2010-12-22 21:39:39 +0000266
267 const GLvoid* posPtr = (GLvoid*)(newStride * startVertex);
268
269 if (kBuffer_GeometrySrcType == fGeometrySrc.fVertexSrc) {
270 GrAssert(NULL != fGeometrySrc.fVertexBuffer);
271 GrAssert(!fGeometrySrc.fVertexBuffer->isLocked());
272 if (fHWGeometryState.fVertexBuffer != fGeometrySrc.fVertexBuffer) {
273 GrGLVertexBuffer* buf =
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000274 (GrGLVertexBuffer*)fGeometrySrc.fVertexBuffer;
reed@google.comac10a2d2010-12-22 21:39:39 +0000275 GR_GL(BindBuffer(GL_ARRAY_BUFFER, buf->bufferID()));
276 fHWGeometryState.fVertexBuffer = fGeometrySrc.fVertexBuffer;
277 }
278 } else {
279 if (kArray_GeometrySrcType == fGeometrySrc.fVertexSrc) {
280 posPtr = (void*)((intptr_t)fGeometrySrc.fVertexArray +
281 (intptr_t)posPtr);
282 } else {
283 GrAssert(kReserved_GeometrySrcType == fGeometrySrc.fVertexSrc);
284 posPtr = (void*)((intptr_t)fVertices.get() + (intptr_t)posPtr);
285 }
286 if (NULL != fHWGeometryState.fVertexBuffer) {
287 GR_GL(BindBuffer(GL_ARRAY_BUFFER, 0));
288 fHWGeometryState.fVertexBuffer = NULL;
289 }
290 }
291
292 if (kBuffer_GeometrySrcType == fGeometrySrc.fIndexSrc) {
293 GrAssert(NULL != fGeometrySrc.fIndexBuffer);
294 GrAssert(!fGeometrySrc.fIndexBuffer->isLocked());
295 if (fHWGeometryState.fIndexBuffer != fGeometrySrc.fIndexBuffer) {
296 GrGLIndexBuffer* buf =
297 (GrGLIndexBuffer*)fGeometrySrc.fIndexBuffer;
298 GR_GL(BindBuffer(GL_ELEMENT_ARRAY_BUFFER, buf->bufferID()));
299 fHWGeometryState.fIndexBuffer = fGeometrySrc.fIndexBuffer;
300 }
301 } else if (NULL != fHWGeometryState.fIndexBuffer) {
302 GR_GL(BindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
303 fHWGeometryState.fIndexBuffer = NULL;
304 }
305
306 GLenum scalarType;
307 if (fGeometrySrc.fVertexLayout & kTextFormat_VertexLayoutBit) {
308 scalarType = GrGLTextType;
309 } else {
310 scalarType = GrGLType;
311 }
312
313 bool baseChange = posPtr != fHWGeometryState.fPositionPtr;
314 bool scalarChange =
315 (GrGLTextType != GrGLType) &&
316 (kTextFormat_VertexLayoutBit &
317 (fHWGeometryState.fVertexLayout ^ fGeometrySrc.fVertexLayout));
318 bool strideChange = newStride != oldStride;
319 bool posChange = baseChange || scalarChange || strideChange;
320
321 if (posChange) {
322 GR_GL(VertexPointer(2, scalarType, newStride, posPtr));
323 fHWGeometryState.fPositionPtr = posPtr;
324 }
325
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000326 for (int s = 0; s < kNumStages; ++s) {
327 // need to enable array if tex coord offset is 0
328 // (using positions as coords)
329 if (newTexCoordOffsets[s] >= 0) {
330 GLvoid* texCoordPtr = (int8_t*)posPtr + newTexCoordOffsets[s];
331 if (oldTexCoordOffsets[s] < 0) {
332 GR_GL(ClientActiveTexture(GL_TEXTURE0+s));
333 GR_GL(EnableClientState(GL_TEXTURE_COORD_ARRAY));
334 }
335 if (posChange || newTexCoordOffsets[s] != oldTexCoordOffsets[s]) {
336 GR_GL(ClientActiveTexture(GL_TEXTURE0+s));
337 GR_GL(TexCoordPointer(2, scalarType, newStride, texCoordPtr));
338 }
339 } else if (oldTexCoordOffsets[s] >= 0) {
340 GR_GL(ClientActiveTexture(GL_TEXTURE0+s));
341 GR_GL(DisableClientState(GL_TEXTURE_COORD_ARRAY));
reed@google.comac10a2d2010-12-22 21:39:39 +0000342 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000343 }
344
345 if (newColorOffset > 0) {
346 GLvoid* colorPtr = (int8_t*)posPtr + newColorOffset;
347 if (oldColorOffset <= 0) {
348 GR_GL(EnableClientState(GL_COLOR_ARRAY));
349 }
350 if (posChange || newColorOffset != oldColorOffset) {
351 GR_GL(ColorPointer(4, GL_UNSIGNED_BYTE, newStride, colorPtr));
352 }
353 } else if (oldColorOffset > 0) {
354 GR_GL(DisableClientState(GL_COLOR_ARRAY));
355 }
356
357 fHWGeometryState.fVertexLayout = fGeometrySrc.fVertexLayout;
358}
359
360#endif
361