1 /*
2 * Copyright (C) 2011 The Android Open Source Project
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 #include "GLEncoder.h"
17 #include "glUtils.h"
18 #include "FixedBuffer.h"
19 #include <cutils/log.h>
20 #include <assert.h>
21
22 #ifndef MIN
23 #define MIN(a, b) ((a) < (b) ? (a) : (b))
24 #endif
25
26 static GLubyte *gVendorString= (GLubyte *) "Android";
27 static GLubyte *gRendererString= (GLubyte *) "Android HW-GLES 1.0";
28 static GLubyte *gVersionString= (GLubyte *) "OpenGL ES-CM 1.0";
29 static GLubyte *gExtensionsString= (GLubyte *) ""; // no extensions at this point;
30
31 #define SET_ERROR_IF(condition,err) if((condition)) { \
32 ALOGE("%s:%s:%d GL error 0x%x\n", __FILE__, __FUNCTION__, __LINE__, err); \
33 ctx->setError(err); \
34 return; \
35 }
36
37
38 #define RET_AND_SET_ERROR_IF(condition,err,ret) if((condition)) { \
39 ALOGE("%s:%s:%d GL error 0x%x\n", __FILE__, __FUNCTION__, __LINE__, err); \
40 ctx->setError(err); \
41 return ret; \
42 }
43
s_glGetError(void * self)44 GLenum GLEncoder::s_glGetError(void * self)
45 {
46 GLEncoder *ctx = (GLEncoder *)self;
47 GLenum err = ctx->getError();
48 if(err != GL_NO_ERROR) {
49 ctx->setError(GL_NO_ERROR);
50 return err;
51 }
52
53 return ctx->m_glGetError_enc(self);
54
55 }
56
getCompressedTextureFormats()57 GLint * GLEncoder::getCompressedTextureFormats()
58 {
59 if (m_compressedTextureFormats == NULL) {
60 this->glGetIntegerv(this, GL_NUM_COMPRESSED_TEXTURE_FORMATS,
61 &m_num_compressedTextureFormats);
62 if (m_num_compressedTextureFormats > 0) {
63 // get number of texture formats;
64 m_compressedTextureFormats = new GLint[m_num_compressedTextureFormats];
65 this->glGetCompressedTextureFormats(this, m_num_compressedTextureFormats, m_compressedTextureFormats);
66 }
67 }
68 return m_compressedTextureFormats;
69 }
70
s_glGetIntegerv(void * self,GLenum param,GLint * ptr)71 void GLEncoder::s_glGetIntegerv(void *self, GLenum param, GLint *ptr)
72 {
73 GLEncoder *ctx = (GLEncoder *)self;
74 assert(ctx->m_state != NULL);
75 GLClientState* state = ctx->m_state;
76
77 switch (param) {
78 case GL_COMPRESSED_TEXTURE_FORMATS: {
79 GLint * compressedTextureFormats = ctx->getCompressedTextureFormats();
80 if (ctx->m_num_compressedTextureFormats > 0 &&
81 compressedTextureFormats != NULL) {
82 memcpy(ptr, compressedTextureFormats,
83 ctx->m_num_compressedTextureFormats * sizeof(GLint));
84 }
85 break;
86 }
87
88 case GL_MAX_TEXTURE_UNITS:
89 ctx->m_glGetIntegerv_enc(self, param, ptr);
90 *ptr = MIN(*ptr, GLClientState::MAX_TEXTURE_UNITS);
91 break;
92
93 case GL_TEXTURE_BINDING_2D:
94 *ptr = state->getBoundTexture(GL_TEXTURE_2D);
95 break;
96
97 case GL_TEXTURE_BINDING_EXTERNAL_OES:
98 *ptr = state->getBoundTexture(GL_TEXTURE_EXTERNAL_OES);
99 break;
100
101 default:
102 if (!state->getClientStateParameter<GLint>(param,ptr)) {
103 ctx->m_glGetIntegerv_enc(self, param, ptr);
104 }
105 break;
106 }
107 }
108
s_glGetFloatv(void * self,GLenum param,GLfloat * ptr)109 void GLEncoder::s_glGetFloatv(void *self, GLenum param, GLfloat *ptr)
110 {
111 GLEncoder *ctx = (GLEncoder *)self;
112 assert(ctx->m_state != NULL);
113 GLClientState* state = ctx->m_state;
114
115 switch (param) {
116 case GL_COMPRESSED_TEXTURE_FORMATS: {
117 GLint * compressedTextureFormats = ctx->getCompressedTextureFormats();
118 if (ctx->m_num_compressedTextureFormats > 0 &&
119 compressedTextureFormats != NULL) {
120 for (int i = 0; i < ctx->m_num_compressedTextureFormats; i++) {
121 ptr[i] = (GLfloat) compressedTextureFormats[i];
122 }
123 }
124 break;
125 }
126
127 case GL_MAX_TEXTURE_UNITS:
128 ctx->m_glGetFloatv_enc(self, param, ptr);
129 *ptr = MIN(*ptr, (GLfloat)GLClientState::MAX_TEXTURE_UNITS);
130 break;
131
132 case GL_TEXTURE_BINDING_2D:
133 *ptr = (GLfloat)state->getBoundTexture(GL_TEXTURE_2D);
134 break;
135
136 case GL_TEXTURE_BINDING_EXTERNAL_OES:
137 *ptr = (GLfloat)state->getBoundTexture(GL_TEXTURE_EXTERNAL_OES);
138 break;
139
140 default:
141 if (!state->getClientStateParameter<GLfloat>(param,ptr)) {
142 ctx->m_glGetFloatv_enc(self, param, ptr);
143 }
144 break;
145 }
146 }
147
s_glGetFixedv(void * self,GLenum param,GLfixed * ptr)148 void GLEncoder::s_glGetFixedv(void *self, GLenum param, GLfixed *ptr)
149 {
150 GLEncoder *ctx = (GLEncoder *)self;
151 assert(ctx->m_state != NULL);
152 GLClientState* state = ctx->m_state;
153
154 switch (param) {
155 case GL_COMPRESSED_TEXTURE_FORMATS: {
156 GLint * compressedTextureFormats = ctx->getCompressedTextureFormats();
157 if (ctx->m_num_compressedTextureFormats > 0 &&
158 compressedTextureFormats != NULL) {
159 for (int i = 0; i < ctx->m_num_compressedTextureFormats; i++) {
160 ptr[i] = compressedTextureFormats[i] << 16;
161 }
162 }
163 break;
164 }
165
166 case GL_MAX_TEXTURE_UNITS:
167 ctx->m_glGetFixedv_enc(self, param, ptr);
168 *ptr = MIN(*ptr, GLClientState::MAX_TEXTURE_UNITS << 16);
169 break;
170
171 case GL_TEXTURE_BINDING_2D:
172 *ptr = state->getBoundTexture(GL_TEXTURE_2D) << 16;
173 break;
174
175 case GL_TEXTURE_BINDING_EXTERNAL_OES:
176 *ptr = state->getBoundTexture(GL_TEXTURE_EXTERNAL_OES) << 16;
177 break;
178
179 default:
180 if (!state->getClientStateParameter<GLfixed>(param,ptr)) {
181 ctx->m_glGetFixedv_enc(self, param, ptr);
182 }
183 break;
184 }
185 }
186
s_glGetBooleanv(void * self,GLenum param,GLboolean * ptr)187 void GLEncoder::s_glGetBooleanv(void *self, GLenum param, GLboolean *ptr)
188 {
189 GLEncoder *ctx = (GLEncoder *)self;
190 assert(ctx->m_state != NULL);
191 GLClientState* state = ctx->m_state;
192
193 switch (param) {
194 case GL_COMPRESSED_TEXTURE_FORMATS: {
195 GLint* compressedTextureFormats = ctx->getCompressedTextureFormats();
196 if (ctx->m_num_compressedTextureFormats > 0 &&
197 compressedTextureFormats != NULL) {
198 for (int i = 0; i < ctx->m_num_compressedTextureFormats; i++) {
199 ptr[i] = compressedTextureFormats[i] != 0 ? GL_TRUE : GL_FALSE;
200 }
201 }
202 break;
203 }
204
205 case GL_TEXTURE_BINDING_2D:
206 *ptr = state->getBoundTexture(GL_TEXTURE_2D) != 0 ? GL_TRUE : GL_FALSE;
207 break;
208
209 case GL_TEXTURE_BINDING_EXTERNAL_OES:
210 *ptr = state->getBoundTexture(GL_TEXTURE_EXTERNAL_OES) != 0
211 ? GL_TRUE : GL_FALSE;
212 break;
213
214 default:
215 if (!state->getClientStateParameter<GLboolean>(param,ptr)) {
216 ctx->m_glGetBooleanv_enc(self, param, ptr);
217 }
218 break;
219 }
220 }
221
s_glGetPointerv(void * self,GLenum param,GLvoid ** params)222 void GLEncoder::s_glGetPointerv(void * self, GLenum param, GLvoid **params)
223 {
224 GLEncoder * ctx = (GLEncoder *) self;
225 assert(ctx->m_state != NULL);
226 ctx->m_state->getClientStatePointer(param,params);
227 }
228
s_glFlush(void * self)229 void GLEncoder::s_glFlush(void *self)
230 {
231 GLEncoder *ctx = (GLEncoder *)self;
232 ctx->m_glFlush_enc(self);
233 ctx->m_stream->flush();
234 }
235
s_glGetString(void * self,GLenum name)236 const GLubyte *GLEncoder::s_glGetString(void *self, GLenum name)
237 {
238 GLubyte *retval = (GLubyte *) "";
239 switch(name) {
240 case GL_VENDOR:
241 retval = gVendorString;
242 break;
243 case GL_RENDERER:
244 retval = gRendererString;
245 break;
246 case GL_VERSION:
247 retval = gVersionString;
248 break;
249 case GL_EXTENSIONS:
250 retval = gExtensionsString;
251 break;
252 }
253 return retval;
254 }
255
s_glPixelStorei(void * self,GLenum param,GLint value)256 void GLEncoder::s_glPixelStorei(void *self, GLenum param, GLint value)
257 {
258 GLEncoder *ctx = (GLEncoder *)self;
259 ctx->m_glPixelStorei_enc(ctx, param, value);
260 ALOG_ASSERT(ctx->m_state, "GLEncoder::s_glPixelStorei");
261 ctx->m_state->setPixelStore(param, value);
262 }
263
s_glVertexPointer(void * self,int size,GLenum type,GLsizei stride,const void * data)264 void GLEncoder::s_glVertexPointer(void *self, int size, GLenum type, GLsizei stride, const void *data)
265 {
266 GLEncoder *ctx = (GLEncoder *)self;
267 assert(ctx->m_state != NULL);
268 ctx->m_state->setState(GLClientState::VERTEX_LOCATION, size, type, false, stride, data);
269 }
270
s_glNormalPointer(void * self,GLenum type,GLsizei stride,const void * data)271 void GLEncoder::s_glNormalPointer(void *self, GLenum type, GLsizei stride, const void *data)
272 {
273 GLEncoder *ctx = (GLEncoder *)self;
274 assert(ctx->m_state != NULL);
275 ctx->m_state->setState(GLClientState::NORMAL_LOCATION, 3, type, false, stride, data);
276 }
277
s_glColorPointer(void * self,int size,GLenum type,GLsizei stride,const void * data)278 void GLEncoder::s_glColorPointer(void *self, int size, GLenum type, GLsizei stride, const void *data)
279 {
280 GLEncoder *ctx = (GLEncoder *)self;
281 assert(ctx->m_state != NULL);
282 ctx->m_state->setState(GLClientState::COLOR_LOCATION, size, type, false, stride, data);
283 }
284
s_glPointsizePointer(void * self,GLenum type,GLsizei stride,const void * data)285 void GLEncoder::s_glPointsizePointer(void *self, GLenum type, GLsizei stride, const void *data)
286 {
287 GLEncoder *ctx = (GLEncoder *)self;
288 assert(ctx->m_state != NULL);
289 ctx->m_state->setState(GLClientState::POINTSIZE_LOCATION, 1, type, false, stride, data);
290 }
291
s_glClientActiveTexture(void * self,GLenum texture)292 void GLEncoder::s_glClientActiveTexture(void *self, GLenum texture)
293 {
294 GLEncoder *ctx = (GLEncoder *)self;
295 assert(ctx->m_state != NULL);
296 ctx->m_state->setActiveTexture(texture - GL_TEXTURE0);
297 }
298
s_glTexcoordPointer(void * self,int size,GLenum type,GLsizei stride,const void * data)299 void GLEncoder::s_glTexcoordPointer(void *self, int size, GLenum type, GLsizei stride, const void *data)
300 {
301 GLEncoder *ctx = (GLEncoder *)self;
302 assert(ctx->m_state != NULL);
303 int loc = ctx->m_state->getLocation(GL_TEXTURE_COORD_ARRAY);
304 ctx->m_state->setState(loc, size, type, false, stride, data);
305 }
306
s_glMatrixIndexPointerOES(void * self,int size,GLenum type,GLsizei stride,const void * data)307 void GLEncoder::s_glMatrixIndexPointerOES(void *self, int size, GLenum type, GLsizei stride, const void * data)
308 {
309 GLEncoder *ctx = (GLEncoder *)self;
310 assert(ctx->m_state != NULL);
311 int loc = ctx->m_state->getLocation(GL_MATRIX_INDEX_ARRAY_OES);
312 ctx->m_state->setState(loc, size, type, false, stride, data);
313 }
314
s_glWeightPointerOES(void * self,int size,GLenum type,GLsizei stride,const void * data)315 void GLEncoder::s_glWeightPointerOES(void * self, int size, GLenum type, GLsizei stride, const void * data)
316 {
317 GLEncoder *ctx = (GLEncoder *)self;
318 assert(ctx->m_state != NULL);
319 int loc = ctx->m_state->getLocation(GL_WEIGHT_ARRAY_OES);
320 ctx->m_state->setState(loc, size, type, false, stride, data);
321 }
322
s_glEnableClientState(void * self,GLenum state)323 void GLEncoder::s_glEnableClientState(void *self, GLenum state)
324 {
325 GLEncoder *ctx = (GLEncoder *) self;
326 assert(ctx->m_state != NULL);
327 int loc = ctx->m_state->getLocation(state);
328 ctx->m_state->enable(loc, 1);
329 }
330
s_glDisableClientState(void * self,GLenum state)331 void GLEncoder::s_glDisableClientState(void *self, GLenum state)
332 {
333 GLEncoder *ctx = (GLEncoder *) self;
334 assert(ctx->m_state != NULL);
335 int loc = ctx->m_state->getLocation(state);
336 ctx->m_state->enable(loc, 0);
337 }
338
s_glIsEnabled(void * self,GLenum cap)339 GLboolean GLEncoder::s_glIsEnabled(void *self, GLenum cap)
340 {
341 GLEncoder *ctx = (GLEncoder *) self;
342 assert(ctx->m_state != NULL);
343 int loc = ctx->m_state->getLocation(cap);
344 const GLClientState::VertexAttribState *state = ctx->m_state->getState(loc);
345
346 if (state!=NULL)
347 return state->enabled;
348
349 return ctx->m_glIsEnabled_enc(self,cap);
350 }
351
s_glBindBuffer(void * self,GLenum target,GLuint id)352 void GLEncoder::s_glBindBuffer(void *self, GLenum target, GLuint id)
353 {
354 GLEncoder *ctx = (GLEncoder *) self;
355 assert(ctx->m_state != NULL);
356 ctx->m_state->bindBuffer(target, id);
357 // TODO set error state if needed;
358 ctx->m_glBindBuffer_enc(self, target, id);
359 }
360
s_glBufferData(void * self,GLenum target,GLsizeiptr size,const GLvoid * data,GLenum usage)361 void GLEncoder::s_glBufferData(void * self, GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage)
362 {
363 GLEncoder *ctx = (GLEncoder *) self;
364 GLuint bufferId = ctx->m_state->getBuffer(target);
365 SET_ERROR_IF(bufferId==0, GL_INVALID_OPERATION);
366 SET_ERROR_IF(size<0, GL_INVALID_VALUE);
367
368 ctx->m_shared->updateBufferData(bufferId, size, (void*)data);
369 ctx->m_glBufferData_enc(self, target, size, data, usage);
370 }
371
s_glBufferSubData(void * self,GLenum target,GLintptr offset,GLsizeiptr size,const GLvoid * data)372 void GLEncoder::s_glBufferSubData(void * self, GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data)
373 {
374 GLEncoder *ctx = (GLEncoder *) self;
375 GLuint bufferId = ctx->m_state->getBuffer(target);
376 SET_ERROR_IF(bufferId==0, GL_INVALID_OPERATION);
377
378 GLenum res = ctx->m_shared->subUpdateBufferData(bufferId, offset, size, (void*)data);
379 SET_ERROR_IF(res, res);
380
381 ctx->m_glBufferSubData_enc(self, target, offset, size, data);
382 }
383
s_glDeleteBuffers(void * self,GLsizei n,const GLuint * buffers)384 void GLEncoder::s_glDeleteBuffers(void * self, GLsizei n, const GLuint * buffers)
385 {
386 GLEncoder *ctx = (GLEncoder *) self;
387 SET_ERROR_IF(n<0, GL_INVALID_VALUE);
388 for (int i=0; i<n; i++) {
389 ctx->m_shared->deleteBufferData(buffers[i]);
390 ctx->m_glDeleteBuffers_enc(self,1,&buffers[i]);
391 }
392 }
393
sendVertexData(unsigned int first,unsigned int count)394 void GLEncoder::sendVertexData(unsigned int first, unsigned int count)
395 {
396 assert(m_state != NULL);
397 for (int i = 0; i < GLClientState::LAST_LOCATION; i++) {
398 bool enableDirty;
399 const GLClientState::VertexAttribState *state = m_state->getStateAndEnableDirty(i, &enableDirty);
400
401 // do not process if state not valid
402 if (!state) continue;
403
404 // do not send disable state if state was already disabled
405 if (!enableDirty && !state->enabled) continue;
406
407 if ( i >= GLClientState::TEXCOORD0_LOCATION &&
408 i <= GLClientState::TEXCOORD7_LOCATION ) {
409 m_glClientActiveTexture_enc(this, GL_TEXTURE0 + i - GLClientState::TEXCOORD0_LOCATION);
410 }
411
412 if (state->enabled) {
413
414 if (enableDirty)
415 m_glEnableClientState_enc(this, state->glConst);
416
417 unsigned int datalen = state->elementSize * count;
418 int stride = state->stride;
419 if (stride == 0) stride = state->elementSize;
420 int firstIndex = stride * first;
421
422 if (state->bufferObject == 0) {
423
424 switch(i) {
425 case GLClientState::VERTEX_LOCATION:
426 this->glVertexPointerData(this, state->size, state->type, state->stride,
427 (unsigned char *)state->data + firstIndex, datalen);
428 break;
429 case GLClientState::NORMAL_LOCATION:
430 this->glNormalPointerData(this, state->type, state->stride,
431 (unsigned char *)state->data + firstIndex, datalen);
432 break;
433 case GLClientState::COLOR_LOCATION:
434 this->glColorPointerData(this, state->size, state->type, state->stride,
435 (unsigned char *)state->data + firstIndex, datalen);
436 break;
437 case GLClientState::TEXCOORD0_LOCATION:
438 case GLClientState::TEXCOORD1_LOCATION:
439 case GLClientState::TEXCOORD2_LOCATION:
440 case GLClientState::TEXCOORD3_LOCATION:
441 case GLClientState::TEXCOORD4_LOCATION:
442 case GLClientState::TEXCOORD5_LOCATION:
443 case GLClientState::TEXCOORD6_LOCATION:
444 case GLClientState::TEXCOORD7_LOCATION:
445 this->glTexCoordPointerData(this, i - GLClientState::TEXCOORD0_LOCATION, state->size, state->type, state->stride,
446 (unsigned char *)state->data + firstIndex, datalen);
447 break;
448 case GLClientState::POINTSIZE_LOCATION:
449 this->glPointSizePointerData(this, state->type, state->stride,
450 (unsigned char *) state->data + firstIndex, datalen);
451 break;
452 case GLClientState::WEIGHT_LOCATION:
453 this->glWeightPointerData(this, state->size, state->type, state->stride,
454 (unsigned char * ) state->data + firstIndex, datalen);
455 break;
456 case GLClientState::MATRIXINDEX_LOCATION:
457 this->glMatrixIndexPointerData(this, state->size, state->type, state->stride,
458 (unsigned char *)state->data + firstIndex, datalen);
459 break;
460 }
461 } else {
462 this->m_glBindBuffer_enc(this, GL_ARRAY_BUFFER, state->bufferObject);
463
464 switch(i) {
465 case GLClientState::VERTEX_LOCATION:
466 this->glVertexPointerOffset(this, state->size, state->type, state->stride,
467 (GLuint)state->data + firstIndex);
468 break;
469 case GLClientState::NORMAL_LOCATION:
470 this->glNormalPointerOffset(this, state->type, state->stride,
471 (GLuint) state->data + firstIndex);
472 break;
473 case GLClientState::POINTSIZE_LOCATION:
474 this->glPointSizePointerOffset(this, state->type, state->stride,
475 (GLuint) state->data + firstIndex);
476 break;
477 case GLClientState::COLOR_LOCATION:
478 this->glColorPointerOffset(this, state->size, state->type, state->stride,
479 (GLuint) state->data + firstIndex);
480 break;
481 case GLClientState::TEXCOORD0_LOCATION:
482 case GLClientState::TEXCOORD1_LOCATION:
483 case GLClientState::TEXCOORD2_LOCATION:
484 case GLClientState::TEXCOORD3_LOCATION:
485 case GLClientState::TEXCOORD4_LOCATION:
486 case GLClientState::TEXCOORD5_LOCATION:
487 case GLClientState::TEXCOORD6_LOCATION:
488 case GLClientState::TEXCOORD7_LOCATION:
489 this->glTexCoordPointerOffset(this, state->size, state->type, state->stride,
490 (GLuint) state->data + firstIndex);
491 break;
492 case GLClientState::WEIGHT_LOCATION:
493 this->glWeightPointerOffset(this,state->size,state->type,state->stride,
494 (GLuint)state->data+firstIndex);
495 break;
496 case GLClientState::MATRIXINDEX_LOCATION:
497 this->glMatrixIndexPointerOffset(this,state->size,state->type,state->stride,
498 (GLuint)state->data+firstIndex);
499 break;
500 }
501 this->m_glBindBuffer_enc(this, GL_ARRAY_BUFFER, m_state->currentArrayVbo());
502 }
503 } else {
504 this->m_glDisableClientState_enc(this, state->glConst);
505 }
506 }
507 }
508
s_glDrawArrays(void * self,GLenum mode,GLint first,GLsizei count)509 void GLEncoder::s_glDrawArrays(void *self, GLenum mode, GLint first, GLsizei count)
510 {
511 GLEncoder *ctx = (GLEncoder *)self;
512
513 ctx->sendVertexData(first, count);
514 ctx->m_glDrawArrays_enc(ctx, mode, /*first*/ 0, count);
515 }
516
s_glDrawElements(void * self,GLenum mode,GLsizei count,GLenum type,const void * indices)517 void GLEncoder::s_glDrawElements(void *self, GLenum mode, GLsizei count, GLenum type, const void *indices)
518 {
519
520 GLEncoder *ctx = (GLEncoder *)self;
521 assert(ctx->m_state != NULL);
522 SET_ERROR_IF(count<0, GL_INVALID_VALUE);
523
524 bool has_immediate_arrays = false;
525 bool has_indirect_arrays = false;
526
527 for (int i = 0; i < GLClientState::LAST_LOCATION; i++) {
528 const GLClientState::VertexAttribState *state = ctx->m_state->getState(i);
529 if (state->enabled) {
530 if (state->bufferObject != 0) {
531 has_indirect_arrays = true;
532 } else {
533 has_immediate_arrays = true;
534 }
535 }
536 }
537
538 if (!has_immediate_arrays && !has_indirect_arrays) {
539 ALOGE("glDrawElements: no data bound to the command - ignoring\n");
540 return;
541 }
542
543 bool adjustIndices = true;
544 if (ctx->m_state->currentIndexVbo() != 0) {
545 if (!has_immediate_arrays) {
546 ctx->sendVertexData(0, count);
547 ctx->m_glBindBuffer_enc(self, GL_ELEMENT_ARRAY_BUFFER, ctx->m_state->currentIndexVbo());
548 ctx->glDrawElementsOffset(ctx, mode, count, type, (GLuint)indices);
549 adjustIndices = false;
550 } else {
551 BufferData * buf = ctx->m_shared->getBufferData(ctx->m_state->currentIndexVbo());
552 ctx->m_glBindBuffer_enc(self, GL_ELEMENT_ARRAY_BUFFER, 0);
553 indices = (void*)((GLintptr)buf->m_fixedBuffer.ptr() + (GLintptr)indices);
554 }
555 }
556 if (adjustIndices) {
557 void *adjustedIndices = (void*)indices;
558 int minIndex = 0, maxIndex = 0;
559
560 switch(type) {
561 case GL_BYTE:
562 case GL_UNSIGNED_BYTE:
563 GLUtils::minmax<unsigned char>((unsigned char *)indices, count, &minIndex, &maxIndex);
564 if (minIndex != 0) {
565 adjustedIndices = ctx->m_fixedBuffer.alloc(glSizeof(type) * count);
566 GLUtils::shiftIndices<unsigned char>((unsigned char *)indices,
567 (unsigned char *)adjustedIndices,
568 count, -minIndex);
569 }
570 break;
571 case GL_SHORT:
572 case GL_UNSIGNED_SHORT:
573 GLUtils::minmax<unsigned short>((unsigned short *)indices, count, &minIndex, &maxIndex);
574 if (minIndex != 0) {
575 adjustedIndices = ctx->m_fixedBuffer.alloc(glSizeof(type) * count);
576 GLUtils::shiftIndices<unsigned short>((unsigned short *)indices,
577 (unsigned short *)adjustedIndices,
578 count, -minIndex);
579 }
580 break;
581 default:
582 ALOGE("unsupported index buffer type %d\n", type);
583 }
584 if (has_indirect_arrays || 1) {
585 ctx->sendVertexData(minIndex, maxIndex - minIndex + 1);
586 ctx->glDrawElementsData(ctx, mode, count, type, adjustedIndices,
587 count * glSizeof(type));
588 // XXX - OPTIMIZATION (see the other else branch) should be implemented
589 if(!has_indirect_arrays) {
590 //ALOGD("unoptimized drawelements !!!\n");
591 }
592 } else {
593 // we are all direct arrays and immidate mode index array -
594 // rebuild the arrays and the index array;
595 ALOGE("glDrawElements: direct index & direct buffer data - will be implemented in later versions;\n");
596 }
597 }
598 }
599
s_glActiveTexture(void * self,GLenum texture)600 void GLEncoder::s_glActiveTexture(void* self, GLenum texture)
601 {
602 GLEncoder* ctx = (GLEncoder*)self;
603 GLClientState* state = ctx->m_state;
604 GLenum err;
605
606 if ((err = state->setActiveTextureUnit(texture)) != GL_NO_ERROR) {
607 ALOGE("%s:%s:%d GL error %#x\n", __FILE__, __FUNCTION__, __LINE__, err);
608 ctx->setError(err);
609 return;
610 }
611
612 ctx->m_glActiveTexture_enc(ctx, texture);
613 }
614
s_glBindTexture(void * self,GLenum target,GLuint texture)615 void GLEncoder::s_glBindTexture(void* self, GLenum target, GLuint texture)
616 {
617 GLEncoder* ctx = (GLEncoder*)self;
618 GLClientState* state = ctx->m_state;
619 GLenum err;
620
621 GLboolean firstUse;
622 if ((err = state->bindTexture(target, texture, &firstUse)) != GL_NO_ERROR) {
623 ALOGE("%s:%s:%d GL error %#x\n", __FILE__, __FUNCTION__, __LINE__, err);
624 ctx->setError(err);
625 return;
626 }
627
628 if (target != GL_TEXTURE_2D && target != GL_TEXTURE_EXTERNAL_OES) {
629 ctx->m_glBindTexture_enc(ctx, target, texture);
630 return;
631 }
632
633 GLenum priorityTarget = state->getPriorityEnabledTarget(GL_TEXTURE_2D);
634
635 if (target == GL_TEXTURE_EXTERNAL_OES && firstUse) {
636 // set TEXTURE_EXTERNAL_OES default states which differ from TEXTURE_2D
637 ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D, texture);
638 ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D,
639 GL_TEXTURE_MIN_FILTER, GL_LINEAR);
640 ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D,
641 GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
642 ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D,
643 GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
644
645 if (target != priorityTarget) {
646 ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D,
647 state->getBoundTexture(GL_TEXTURE_2D));
648 }
649 }
650
651 if (target == priorityTarget) {
652 ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D, texture);
653 }
654 }
655
s_glDeleteTextures(void * self,GLsizei n,const GLuint * textures)656 void GLEncoder::s_glDeleteTextures(void* self, GLsizei n, const GLuint* textures)
657 {
658 GLEncoder* ctx = (GLEncoder*)self;
659 GLClientState* state = ctx->m_state;
660
661 state->deleteTextures(n, textures);
662 ctx->m_glDeleteTextures_enc(ctx, n, textures);
663 }
664
s_glDisable(void * self,GLenum cap)665 void GLEncoder::s_glDisable(void* self, GLenum cap)
666 {
667 GLEncoder* ctx = (GLEncoder*)self;
668 GLClientState* state = ctx->m_state;
669
670 if (cap == GL_TEXTURE_2D || cap == GL_TEXTURE_EXTERNAL_OES) {
671 GLenum prevTarget = state->getPriorityEnabledTarget(GL_INVALID_ENUM);
672 state->disableTextureTarget(cap);
673 GLenum currTarget = state->getPriorityEnabledTarget(GL_INVALID_ENUM);
674
675 if (prevTarget != currTarget) {
676 if (currTarget == GL_INVALID_ENUM) {
677 ctx->m_glDisable_enc(ctx, GL_TEXTURE_2D);
678 currTarget = GL_TEXTURE_2D;
679 }
680 // maintain the invariant that when TEXTURE_EXTERNAL_OES is
681 // disabled, the TEXTURE_2D binding is active, even if
682 // TEXTURE_2D is also disabled.
683 ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D,
684 state->getBoundTexture(currTarget));
685 }
686
687 } else {
688 ctx->m_glDisable_enc(ctx, cap);
689 }
690 }
691
s_glEnable(void * self,GLenum cap)692 void GLEncoder::s_glEnable(void* self, GLenum cap)
693 {
694 GLEncoder* ctx = (GLEncoder*)self;
695 GLClientState* state = ctx->m_state;
696
697 if (cap == GL_TEXTURE_2D || cap == GL_TEXTURE_EXTERNAL_OES) {
698 GLenum prevTarget = state->getPriorityEnabledTarget(GL_INVALID_ENUM);
699 state->enableTextureTarget(cap);
700 GLenum currTarget = state->getPriorityEnabledTarget(GL_INVALID_ENUM);
701
702 if (prevTarget != currTarget) {
703 if (prevTarget == GL_INVALID_ENUM) {
704 ctx->m_glEnable_enc(ctx, GL_TEXTURE_2D);
705 }
706 if (currTarget == GL_TEXTURE_EXTERNAL_OES) {
707 ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D,
708 state->getBoundTexture(currTarget));
709 }
710 }
711
712 } else {
713 ctx->m_glEnable_enc(ctx, cap);
714 }
715 }
716
s_glGetTexParameterfv(void * self,GLenum target,GLenum pname,GLfloat * params)717 void GLEncoder::s_glGetTexParameterfv(void* self,
718 GLenum target, GLenum pname, GLfloat* params)
719 {
720 GLEncoder* ctx = (GLEncoder*)self;
721 const GLClientState* state = ctx->m_state;
722
723 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
724 ctx->override2DTextureTarget(target);
725 ctx->m_glGetTexParameterfv_enc(ctx, GL_TEXTURE_2D, pname, params);
726 ctx->restore2DTextureTarget();
727 } else {
728 ctx->m_glGetTexParameterfv_enc(ctx, target, pname, params);
729 }
730 }
731
s_glGetTexParameteriv(void * self,GLenum target,GLenum pname,GLint * params)732 void GLEncoder::s_glGetTexParameteriv(void* self,
733 GLenum target, GLenum pname, GLint* params)
734 {
735 GLEncoder* ctx = (GLEncoder*)self;
736 const GLClientState* state = ctx->m_state;
737
738 switch (pname) {
739 case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
740 *params = 1;
741 break;
742
743 default:
744 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
745 ctx->override2DTextureTarget(target);
746 ctx->m_glGetTexParameteriv_enc(ctx, GL_TEXTURE_2D, pname, params);
747 ctx->restore2DTextureTarget();
748 } else {
749 ctx->m_glGetTexParameteriv_enc(ctx, target, pname, params);
750 }
751 break;
752 }
753 }
754
s_glGetTexParameterxv(void * self,GLenum target,GLenum pname,GLfixed * params)755 void GLEncoder::s_glGetTexParameterxv(void* self,
756 GLenum target, GLenum pname, GLfixed* params)
757 {
758 GLEncoder* ctx = (GLEncoder*)self;
759 const GLClientState* state = ctx->m_state;
760
761 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
762 ctx->override2DTextureTarget(target);
763 ctx->m_glGetTexParameterxv_enc(ctx, GL_TEXTURE_2D, pname, params);
764 ctx->restore2DTextureTarget();
765 } else {
766 ctx->m_glGetTexParameterxv_enc(ctx, target, pname, params);
767 }
768 }
769
isValidTextureExternalParam(GLenum pname,GLenum param)770 static bool isValidTextureExternalParam(GLenum pname, GLenum param)
771 {
772 switch (pname) {
773 case GL_TEXTURE_MIN_FILTER:
774 case GL_TEXTURE_MAG_FILTER:
775 return param == GL_NEAREST || param == GL_LINEAR;
776
777 case GL_TEXTURE_WRAP_S:
778 case GL_TEXTURE_WRAP_T:
779 return param == GL_CLAMP_TO_EDGE;
780
781 case GL_GENERATE_MIPMAP:
782 return param == GL_FALSE;
783
784 default:
785 return true;
786 }
787 }
788
s_glTexParameterf(void * self,GLenum target,GLenum pname,GLfloat param)789 void GLEncoder::s_glTexParameterf(void* self,
790 GLenum target, GLenum pname, GLfloat param)
791 {
792 GLEncoder* ctx = (GLEncoder*)self;
793 const GLClientState* state = ctx->m_state;
794
795 SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
796 !isValidTextureExternalParam(pname, (GLenum)param)),
797 GL_INVALID_ENUM);
798
799 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
800 ctx->override2DTextureTarget(target);
801 ctx->m_glTexParameterf_enc(ctx, GL_TEXTURE_2D, pname, param);
802 ctx->restore2DTextureTarget();
803 } else {
804 ctx->m_glTexParameterf_enc(ctx, target, pname, param);
805 }
806 }
807
s_glTexParameterfv(void * self,GLenum target,GLenum pname,const GLfloat * params)808 void GLEncoder::s_glTexParameterfv(void* self,
809 GLenum target, GLenum pname, const GLfloat* params)
810 {
811 GLEncoder* ctx = (GLEncoder*)self;
812 const GLClientState* state = ctx->m_state;
813
814 SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
815 !isValidTextureExternalParam(pname, (GLenum)params[0])),
816 GL_INVALID_ENUM);
817
818 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
819 ctx->override2DTextureTarget(target);
820 ctx->m_glTexParameterfv_enc(ctx, GL_TEXTURE_2D, pname, params);
821 ctx->restore2DTextureTarget();
822 } else {
823 ctx->m_glTexParameterfv_enc(ctx, target, pname, params);
824 }
825 }
826
s_glTexParameteri(void * self,GLenum target,GLenum pname,GLint param)827 void GLEncoder::s_glTexParameteri(void* self,
828 GLenum target, GLenum pname, GLint param)
829 {
830 GLEncoder* ctx = (GLEncoder*)self;
831 const GLClientState* state = ctx->m_state;
832
833 SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
834 !isValidTextureExternalParam(pname, (GLenum)param)),
835 GL_INVALID_ENUM);
836
837 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
838 ctx->override2DTextureTarget(target);
839 ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D, pname, param);
840 ctx->restore2DTextureTarget();
841 } else {
842 ctx->m_glTexParameteri_enc(ctx, target, pname, param);
843 }
844 }
845
s_glTexParameterx(void * self,GLenum target,GLenum pname,GLfixed param)846 void GLEncoder::s_glTexParameterx(void* self,
847 GLenum target, GLenum pname, GLfixed param)
848 {
849 GLEncoder* ctx = (GLEncoder*)self;
850 const GLClientState* state = ctx->m_state;
851
852 SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
853 !isValidTextureExternalParam(pname, (GLenum)param)),
854 GL_INVALID_ENUM);
855
856 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
857 ctx->override2DTextureTarget(target);
858 ctx->m_glTexParameterx_enc(ctx, GL_TEXTURE_2D, pname, param);
859 ctx->restore2DTextureTarget();
860 } else {
861 ctx->m_glTexParameterx_enc(ctx, target, pname, param);
862 }
863 }
864
s_glTexParameteriv(void * self,GLenum target,GLenum pname,const GLint * params)865 void GLEncoder::s_glTexParameteriv(void* self,
866 GLenum target, GLenum pname, const GLint* params)
867 {
868 GLEncoder* ctx = (GLEncoder*)self;
869 const GLClientState* state = ctx->m_state;
870
871 SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
872 !isValidTextureExternalParam(pname, (GLenum)params[0])),
873 GL_INVALID_ENUM);
874
875 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
876 ctx->override2DTextureTarget(target);
877 ctx->m_glTexParameteriv_enc(ctx, GL_TEXTURE_2D, pname, params);
878 ctx->restore2DTextureTarget();
879 } else {
880 ctx->m_glTexParameteriv_enc(ctx, target, pname, params);
881 }
882 }
883
s_glTexParameterxv(void * self,GLenum target,GLenum pname,const GLfixed * params)884 void GLEncoder::s_glTexParameterxv(void* self,
885 GLenum target, GLenum pname, const GLfixed* params)
886 {
887 GLEncoder* ctx = (GLEncoder*)self;
888 const GLClientState* state = ctx->m_state;
889
890 SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
891 !isValidTextureExternalParam(pname, (GLenum)params[0])),
892 GL_INVALID_ENUM);
893
894 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
895 ctx->override2DTextureTarget(target);
896 ctx->m_glTexParameterxv_enc(ctx, GL_TEXTURE_2D, pname, params);
897 ctx->restore2DTextureTarget();
898 } else {
899 ctx->m_glTexParameterxv_enc(ctx, target, pname, params);
900 }
901 }
902
override2DTextureTarget(GLenum target)903 void GLEncoder::override2DTextureTarget(GLenum target)
904 {
905 if ((target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) &&
906 target != m_state->getPriorityEnabledTarget(GL_TEXTURE_2D)) {
907 m_glBindTexture_enc(this, GL_TEXTURE_2D,
908 m_state->getBoundTexture(target));
909 }
910 }
911
restore2DTextureTarget()912 void GLEncoder::restore2DTextureTarget()
913 {
914 GLenum priorityTarget = m_state->getPriorityEnabledTarget(GL_TEXTURE_2D);
915 m_glBindTexture_enc(this, GL_TEXTURE_2D,
916 m_state->getBoundTexture(priorityTarget));
917 }
918
GLEncoder(IOStream * stream)919 GLEncoder::GLEncoder(IOStream *stream) : gl_encoder_context_t(stream)
920 {
921 m_initialized = false;
922 m_state = NULL;
923 m_error = GL_NO_ERROR;
924 m_num_compressedTextureFormats = 0;
925 m_compressedTextureFormats = NULL;
926 // overrides;
927 m_glFlush_enc = set_glFlush(s_glFlush);
928 m_glPixelStorei_enc = set_glPixelStorei(s_glPixelStorei);
929 m_glVertexPointer_enc = set_glVertexPointer(s_glVertexPointer);
930 m_glNormalPointer_enc = set_glNormalPointer(s_glNormalPointer);
931 m_glColorPointer_enc = set_glColorPointer(s_glColorPointer);
932 m_glPointSizePointerOES_enc = set_glPointSizePointerOES(s_glPointsizePointer);
933 m_glClientActiveTexture_enc = set_glClientActiveTexture(s_glClientActiveTexture);
934 m_glTexCoordPointer_enc = set_glTexCoordPointer(s_glTexcoordPointer);
935 m_glMatrixIndexPointerOES_enc = set_glMatrixIndexPointerOES(s_glMatrixIndexPointerOES);
936 m_glWeightPointerOES_enc = set_glWeightPointerOES(s_glWeightPointerOES);
937
938 m_glGetIntegerv_enc = set_glGetIntegerv(s_glGetIntegerv);
939 m_glGetFloatv_enc = set_glGetFloatv(s_glGetFloatv);
940 m_glGetBooleanv_enc = set_glGetBooleanv(s_glGetBooleanv);
941 m_glGetFixedv_enc = set_glGetFixedv(s_glGetFixedv);
942 m_glGetPointerv_enc = set_glGetPointerv(s_glGetPointerv);
943
944 m_glBindBuffer_enc = set_glBindBuffer(s_glBindBuffer);
945 m_glBufferData_enc = set_glBufferData(s_glBufferData);
946 m_glBufferSubData_enc = set_glBufferSubData(s_glBufferSubData);
947 m_glDeleteBuffers_enc = set_glDeleteBuffers(s_glDeleteBuffers);
948
949 m_glEnableClientState_enc = set_glEnableClientState(s_glEnableClientState);
950 m_glDisableClientState_enc = set_glDisableClientState(s_glDisableClientState);
951 m_glIsEnabled_enc = set_glIsEnabled(s_glIsEnabled);
952 m_glDrawArrays_enc = set_glDrawArrays(s_glDrawArrays);
953 m_glDrawElements_enc = set_glDrawElements(s_glDrawElements);
954 set_glGetString(s_glGetString);
955 set_glFinish(s_glFinish);
956 m_glGetError_enc = set_glGetError(s_glGetError);
957
958 m_glActiveTexture_enc = set_glActiveTexture(s_glActiveTexture);
959 m_glBindTexture_enc = set_glBindTexture(s_glBindTexture);
960 m_glDeleteTextures_enc = set_glDeleteTextures(s_glDeleteTextures);
961 m_glDisable_enc = set_glDisable(s_glDisable);
962 m_glEnable_enc = set_glEnable(s_glEnable);
963 m_glGetTexParameterfv_enc = set_glGetTexParameterfv(s_glGetTexParameterfv);
964 m_glGetTexParameteriv_enc = set_glGetTexParameteriv(s_glGetTexParameteriv);
965 m_glGetTexParameterxv_enc = set_glGetTexParameterxv(s_glGetTexParameterxv);
966 m_glTexParameterf_enc = set_glTexParameterf(s_glTexParameterf);
967 m_glTexParameterfv_enc = set_glTexParameterfv(s_glTexParameterfv);
968 m_glTexParameteri_enc = set_glTexParameteri(s_glTexParameteri);
969 m_glTexParameterx_enc = set_glTexParameterx(s_glTexParameterx);
970 m_glTexParameteriv_enc = set_glTexParameteriv(s_glTexParameteriv);
971 m_glTexParameterxv_enc = set_glTexParameterxv(s_glTexParameterxv);
972 }
973
~GLEncoder()974 GLEncoder::~GLEncoder()
975 {
976 delete [] m_compressedTextureFormats;
977 }
978
pixelDataSize(GLsizei width,GLsizei height,GLenum format,GLenum type,int pack)979 size_t GLEncoder::pixelDataSize(GLsizei width, GLsizei height, GLenum format, GLenum type, int pack)
980 {
981 assert(m_state != NULL);
982 return m_state->pixelDataSize(width, height, format, type, pack);
983 }
984
s_glFinish(void * self)985 void GLEncoder::s_glFinish(void *self)
986 {
987 GLEncoder *ctx = (GLEncoder *)self;
988 ctx->glFinishRoundTrip(self);
989 }
990