blob: 76494de34c2d8c576d4ea77ca6f201e357af4120 [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];
bsalomon@google.com5782d712011-01-21 21:03:59 +000029
reed@google.comac10a2d2010-12-22 21:39:39 +000030 void reset() {
31 Gr_bzero(fMat, sizeof(fMat));
32 fMat[0] = fMat[5] = fMat[10] = fMat[15] = GR_Scalar1;
33 }
bsalomon@google.com5782d712011-01-21 21:03:59 +000034
reed@google.comac10a2d2010-12-22 21:39:39 +000035 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];
bsalomon@google.com5782d712011-01-21 21:03:59 +000040
reed@google.comac10a2d2010-12-22 21:39:39 +000041 fMat[1] = m[GrMatrix::kSkewY];
42 fMat[5] = m[GrMatrix::kScaleY];
43 fMat[13] = m[GrMatrix::kTransY];
bsalomon@google.com5782d712011-01-21 21:03:59 +000044
reed@google.comac10a2d2010-12-22 21:39:39 +000045 fMat[3] = m[GrMatrix::kPersp0];
46 fMat[7] = m[GrMatrix::kPersp1];
47 fMat[15] = m[GrMatrix::kPersp2];
bsalomon@google.com5782d712011-01-21 21:03:59 +000048
reed@google.comac10a2d2010-12-22 21:39:39 +000049 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);
bsalomon@google.com5782d712011-01-21 21:03:59 +000077 GR_GL(EnableClientState(GL_VERTEX_ARRAY));
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000078 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));
bsalomon@google.com5782d712011-01-21 21:03:59 +000089
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
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000092 // texture, e.g.:
93 //glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
bsalomon@google.com5782d712011-01-21 21:03:59 +000094 fHWRGBOperand0[s] = (TextureEnvRGBOperands) -1;
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000095 }
reed@google.comac10a2d2010-12-22 21:39:39 +000096
97 fHWGeometryState.fVertexLayout = 0;
bsalomon@google.com1c13c962011-02-14 16:51:21 +000098 fHWGeometryState.fVertexOffset = ~0;
reed@google.comac10a2d2010-12-22 21:39:39 +000099 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));
bsalomon@google.com5782d712011-01-21 21:03:59 +0000103
104 GR_GL(PointSize(1.f));
105
reed@google.comac10a2d2010-12-22 21:39:39 +0000106 GrGLClearErr();
107 fTextVerts = false;
108
bsalomon@google.com5782d712011-01-21 21:03:59 +0000109 fHWTextureOrientation = (GrGLTexture::Orientation)-1; // illegal
reed@google.comac10a2d2010-12-22 21:39:39 +0000110 fBaseVertex = 0xffffffff;
111}
112
113
114void GrGpuGLFixed::flushProjectionMatrix() {
115 float mat[16];
116 Gr_bzero(mat, sizeof(mat));
bsalomon@google.com5782d712011-01-21 21:03:59 +0000117
reed@google.comac10a2d2010-12-22 21:39:39 +0000118 GrAssert(NULL != fCurrDrawState.fRenderTarget);
bsalomon@google.com5782d712011-01-21 21:03:59 +0000119
reed@google.comac10a2d2010-12-22 21:39:39 +0000120 mat[0] = 2.f / fCurrDrawState.fRenderTarget->width();
121 mat[5] = -2.f / fCurrDrawState.fRenderTarget->height();
122 mat[10] = -1.f;
123 mat[15] = 1;
bsalomon@google.com5782d712011-01-21 21:03:59 +0000124
reed@google.comac10a2d2010-12-22 21:39:39 +0000125 mat[12] = -1.f;
126 mat[13] = 1.f;
bsalomon@google.com5782d712011-01-21 21:03:59 +0000127
reed@google.comac10a2d2010-12-22 21:39:39 +0000128 GR_GL(MatrixMode(GL_PROJECTION));
129 GR_GL(LoadMatrixf(mat));
130}
131
132bool GrGpuGLFixed::flushGraphicsState(PrimitiveType type) {
bsalomon@google.com5782d712011-01-21 21:03:59 +0000133
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000134 bool usingTextures[kNumStages];
bsalomon@google.com5782d712011-01-21 21:03:59 +0000135
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000136 for (int s = 0; s < kNumStages; ++s) {
137 usingTextures[s] = VertexUsesStage(s, fGeometrySrc.fVertexLayout);
reed@google.comac10a2d2010-12-22 21:39:39 +0000138
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000139 if (usingTextures[s] && fCurrDrawState.fSamplerStates[s].isGradient()) {
140 unimpl("Fixed pipe doesn't support radial/sweep gradients");
141 return false;
142 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000143 }
bsalomon@google.com5782d712011-01-21 21:03:59 +0000144
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000145 if (!flushGLStateCommon(type)) {
146 return false;
147 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000148
bsalomon@google.com5782d712011-01-21 21:03:59 +0000149 if (fRenderTargetChanged) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000150 flushProjectionMatrix();
151 fRenderTargetChanged = false;
152 }
bsalomon@google.com5782d712011-01-21 21:03:59 +0000153
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000154 for (int s = 0; s < kNumStages; ++s) {
155 bool wasUsingTexture = VertexUsesStage(s, fHWGeometryState.fVertexLayout);
156 if (usingTextures[s] != wasUsingTexture) {
157 setTextureUnit(s);
158 if (usingTextures[s]) {
159 GR_GL(Enable(GL_TEXTURE_2D));
160 } else {
161 GR_GL(Disable(GL_TEXTURE_2D));
162 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000163 }
164 }
bsalomon@google.com5782d712011-01-21 21:03:59 +0000165
reed@google.comac10a2d2010-12-22 21:39:39 +0000166 uint32_t vertColor = (fGeometrySrc.fVertexLayout & kColor_VertexLayoutBit);
bsalomon@google.com5782d712011-01-21 21:03:59 +0000167 uint32_t prevVertColor = (fHWGeometryState.fVertexLayout &
reed@google.comac10a2d2010-12-22 21:39:39 +0000168 kColor_VertexLayoutBit);
bsalomon@google.com5782d712011-01-21 21:03:59 +0000169
reed@google.comac10a2d2010-12-22 21:39:39 +0000170 if (vertColor != prevVertColor) {
171 if (vertColor) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000172 GR_GL(ShadeModel(GL_SMOOTH));
173 // invalidate the immediate mode color
174 fHWDrawState.fColor = GrColor_ILLEGAL;
175 } else {
176 GR_GL(ShadeModel(GL_FLAT));
177 }
178 }
179
bsalomon@google.com5782d712011-01-21 21:03:59 +0000180
reed@google.comac10a2d2010-12-22 21:39:39 +0000181 if (!vertColor && fHWDrawState.fColor != fCurrDrawState.fColor) {
182 GR_GL(Color4ub(GrColorUnpackR(fCurrDrawState.fColor),
183 GrColorUnpackG(fCurrDrawState.fColor),
184 GrColorUnpackB(fCurrDrawState.fColor),
185 GrColorUnpackA(fCurrDrawState.fColor)));
186 fHWDrawState.fColor = fCurrDrawState.fColor;
187 }
188
189 // set texture environment, decide whether we are modulating by RGB or A.
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000190 for (int s = 0; s < kNumStages; ++s) {
191 if (usingTextures[s]) {
192 GrGLTexture* texture = (GrGLTexture*)fCurrDrawState.fTextures[s];
193 if (NULL != texture) {
bsalomon@google.com5782d712011-01-21 21:03:59 +0000194 TextureEnvRGBOperands nextRGBOperand0 =
195 (texture->config() == GrTexture::kAlpha_8_PixelConfig) ?
196 kAlpha_TextureEnvRGBOperand :
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000197 kColor_TextureEnvRGBOperand;
198 if (fHWRGBOperand0[s] != nextRGBOperand0) {
199 setTextureUnit(s);
bsalomon@google.com5782d712011-01-21 21:03:59 +0000200 GR_GL(TexEnvi(GL_TEXTURE_ENV,
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000201 GL_OPERAND0_RGB,
bsalomon@google.com5782d712011-01-21 21:03:59 +0000202 (nextRGBOperand0==kAlpha_TextureEnvRGBOperand) ?
203 GL_SRC_ALPHA :
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000204 GL_SRC_COLOR));
205 fHWRGBOperand0[s] = nextRGBOperand0;
reed@google.comac10a2d2010-12-22 21:39:39 +0000206 }
bsalomon@google.com5782d712011-01-21 21:03:59 +0000207
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000208 if (fHWTextureOrientation != texture->orientation() ||
bsalomon@google.com5782d712011-01-21 21:03:59 +0000209 fHWDrawState.fTextureMatrices[s] !=
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000210 fCurrDrawState.fTextureMatrices[s]) {
211 GrGpuMatrix glm;
bsalomon@google.com5782d712011-01-21 21:03:59 +0000212 if (GrGLTexture::kBottomUp_Orientation ==
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000213 texture->orientation()) {
214 GrMatrix m(
215 GR_Scalar1, 0, 0,
216 0, -GR_Scalar1, GR_Scalar1,
217 0, 0, GrMatrix::I()[8]
218 );
219 m.preConcat(fCurrDrawState.fTextureMatrices[s]);
220 glm.set(m);
221 } else {
222 glm.set(fCurrDrawState.fTextureMatrices[s]);
223 }
224 setTextureUnit(s);
225 GR_GL(MatrixMode(GL_TEXTURE));
226 GR_GL(LoadMatrixf(glm.fMat));
bsalomon@google.com5782d712011-01-21 21:03:59 +0000227 fHWDrawState.fTextureMatrices[s] =
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000228 fCurrDrawState.fTextureMatrices[s];
229 fHWTextureOrientation = texture->orientation();
230 }
231 } else {
232 GrAssert(!"Rendering with texture vert flag set but no bound texture");
233 return false;
reed@google.comac10a2d2010-12-22 21:39:39 +0000234 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000235 }
236 }
237
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000238 if (fHWDrawState.fViewMatrix != fCurrDrawState.fViewMatrix) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000239 GrGpuMatrix glm;
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000240 glm.set(fCurrDrawState.fViewMatrix);
241 GR_GL(MatrixMode(GL_MODELVIEW));
reed@google.comac10a2d2010-12-22 21:39:39 +0000242 GR_GL(LoadMatrixf(glm.fMat));
bsalomon@google.com5782d712011-01-21 21:03:59 +0000243 fHWDrawState.fViewMatrix =
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000244 fCurrDrawState.fViewMatrix;
reed@google.comac10a2d2010-12-22 21:39:39 +0000245 }
246 return true;
247}
248
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000249void GrGpuGLFixed::setupGeometry(int* startVertex,
250 int* startIndex,
251 int vertexCount,
252 int indexCount) {
bsalomon@google.com5782d712011-01-21 21:03:59 +0000253
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000254 int newColorOffset;
255 int newTexCoordOffsets[kNumStages];
bsalomon@google.com5782d712011-01-21 21:03:59 +0000256
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000257 GLsizei newStride = VertexSizeAndOffsetsByStage(fGeometrySrc.fVertexLayout,
bsalomon@google.com5782d712011-01-21 21:03:59 +0000258 newTexCoordOffsets,
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000259 &newColorOffset);
260 int oldColorOffset;
261 int oldTexCoordOffsets[kNumStages];
262 GLsizei oldStride = VertexSizeAndOffsetsByStage(fHWGeometryState.fVertexLayout,
bsalomon@google.com5782d712011-01-21 21:03:59 +0000263 oldTexCoordOffsets,
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000264 &oldColorOffset);
bsalomon@google.com5782d712011-01-21 21:03:59 +0000265
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000266 bool indexed = NULL == startIndex;
267
268 int extraVertexOffset;
269 int extraIndexOffset;
270 setBuffers(indexed, &extraVertexOffset, &extraIndexOffset);
bsalomon@google.com5782d712011-01-21 21:03:59 +0000271
reed@google.comac10a2d2010-12-22 21:39:39 +0000272 GLenum scalarType;
273 if (fGeometrySrc.fVertexLayout & kTextFormat_VertexLayoutBit) {
274 scalarType = GrGLTextType;
275 } else {
276 scalarType = GrGLType;
277 }
bsalomon@google.com5782d712011-01-21 21:03:59 +0000278
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000279 size_t vertexOffset = (*startVertex + extraVertexOffset) * newStride;
280 *startVertex = 0;
281 if (indexed) {
282 *startIndex += extraIndexOffset;
283 }
bsalomon@google.com5782d712011-01-21 21:03:59 +0000284
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000285 // all the Pointers must be set if any of these are true
286 bool allOffsetsChange = fHWGeometryState.fArrayPtrsDirty ||
287 vertexOffset != fHWGeometryState.fVertexOffset ||
288 newStride != oldStride;
289
290 // position and tex coord offsets change if above conditions are true
291 // or the type changed based on text vs nontext type coords.
292 bool posAndTexChange = allOffsetsChange ||
293 ((GrGLTextType != GrGLType) &&
294 (kTextFormat_VertexLayoutBit &
295 (fHWGeometryState.fVertexLayout ^
296 fGeometrySrc.fVertexLayout)));
297
298 if (posAndTexChange) {
299 GR_GL(VertexPointer(2, scalarType, newStride, (GLvoid*)vertexOffset));
300 fHWGeometryState.fVertexOffset = vertexOffset;
reed@google.comac10a2d2010-12-22 21:39:39 +0000301 }
bsalomon@google.com5782d712011-01-21 21:03:59 +0000302
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000303 for (int s = 0; s < kNumStages; ++s) {
bsalomon@google.com5782d712011-01-21 21:03:59 +0000304 // need to enable array if tex coord offset is 0
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000305 // (using positions as coords)
306 if (newTexCoordOffsets[s] >= 0) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000307 GLvoid* texCoordOffset = (GLvoid*)(vertexOffset + newTexCoordOffsets[s]);
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000308 if (oldTexCoordOffsets[s] < 0) {
309 GR_GL(ClientActiveTexture(GL_TEXTURE0+s));
310 GR_GL(EnableClientState(GL_TEXTURE_COORD_ARRAY));
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000311 GR_GL(TexCoordPointer(2, scalarType, newStride, texCoordOffset));
312 } else if (posAndTexChange ||
bsalomon@google.com7acdb8e2011-02-11 14:07:02 +0000313 newTexCoordOffsets[s] != oldTexCoordOffsets[s]) {
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000314 GR_GL(ClientActiveTexture(GL_TEXTURE0+s));
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000315 GR_GL(TexCoordPointer(2, scalarType, newStride, texCoordOffset));
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000316 }
317 } else if (oldTexCoordOffsets[s] >= 0) {
318 GR_GL(ClientActiveTexture(GL_TEXTURE0+s));
319 GR_GL(DisableClientState(GL_TEXTURE_COORD_ARRAY));
reed@google.comac10a2d2010-12-22 21:39:39 +0000320 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000321 }
bsalomon@google.com5782d712011-01-21 21:03:59 +0000322
reed@google.comac10a2d2010-12-22 21:39:39 +0000323 if (newColorOffset > 0) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000324 GLvoid* colorOffset = (GLvoid*)(vertexOffset + newColorOffset);
reed@google.comac10a2d2010-12-22 21:39:39 +0000325 if (oldColorOffset <= 0) {
326 GR_GL(EnableClientState(GL_COLOR_ARRAY));
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000327 GR_GL(ColorPointer(4, GL_UNSIGNED_BYTE, newStride, colorOffset));
328 } else if (allOffsetsChange || newColorOffset != oldColorOffset) {
329 GR_GL(ColorPointer(4, GL_UNSIGNED_BYTE, newStride, colorOffset));
reed@google.comac10a2d2010-12-22 21:39:39 +0000330 }
331 } else if (oldColorOffset > 0) {
332 GR_GL(DisableClientState(GL_COLOR_ARRAY));
333 }
bsalomon@google.com5782d712011-01-21 21:03:59 +0000334
reed@google.comac10a2d2010-12-22 21:39:39 +0000335 fHWGeometryState.fVertexLayout = fGeometrySrc.fVertexLayout;
bsalomon@google.com7acdb8e2011-02-11 14:07:02 +0000336 fHWGeometryState.fArrayPtrsDirty = false;
reed@google.comac10a2d2010-12-22 21:39:39 +0000337}
338
339#endif
340