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 <log/log.h>
19 #include <assert.h>
20 #include <vector>
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 *) "GL_OES_EGL_image_external ";
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 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
102 // BUG: 121414786
103 *ptr = GL_LOSE_CONTEXT_ON_RESET_EXT;
104 break;
105
106 default:
107 if (!state->getClientStateParameter<GLint>(param,ptr)) {
108 ctx->m_glGetIntegerv_enc(self, param, ptr);
109 }
110 break;
111 }
112 }
113
s_glGetFloatv(void * self,GLenum param,GLfloat * ptr)114 void GLEncoder::s_glGetFloatv(void *self, GLenum param, GLfloat *ptr)
115 {
116 GLEncoder *ctx = (GLEncoder *)self;
117 assert(ctx->m_state != NULL);
118 GLClientState* state = ctx->m_state;
119
120 switch (param) {
121 case GL_COMPRESSED_TEXTURE_FORMATS: {
122 GLint * compressedTextureFormats = ctx->getCompressedTextureFormats();
123 if (ctx->m_num_compressedTextureFormats > 0 &&
124 compressedTextureFormats != NULL) {
125 for (int i = 0; i < ctx->m_num_compressedTextureFormats; i++) {
126 ptr[i] = (GLfloat) compressedTextureFormats[i];
127 }
128 }
129 break;
130 }
131
132 case GL_MAX_TEXTURE_UNITS:
133 ctx->m_glGetFloatv_enc(self, param, ptr);
134 *ptr = MIN(*ptr, (GLfloat)GLClientState::MAX_TEXTURE_UNITS);
135 break;
136
137 case GL_TEXTURE_BINDING_2D:
138 *ptr = (GLfloat)state->getBoundTexture(GL_TEXTURE_2D);
139 break;
140
141 case GL_TEXTURE_BINDING_EXTERNAL_OES:
142 *ptr = (GLfloat)state->getBoundTexture(GL_TEXTURE_EXTERNAL_OES);
143 break;
144
145 default:
146 if (!state->getClientStateParameter<GLfloat>(param,ptr)) {
147 ctx->m_glGetFloatv_enc(self, param, ptr);
148 }
149 break;
150 }
151 }
152
s_glGetFixedv(void * self,GLenum param,GLfixed * ptr)153 void GLEncoder::s_glGetFixedv(void *self, GLenum param, GLfixed *ptr)
154 {
155 GLEncoder *ctx = (GLEncoder *)self;
156 assert(ctx->m_state != NULL);
157 GLClientState* state = ctx->m_state;
158
159 switch (param) {
160 case GL_COMPRESSED_TEXTURE_FORMATS: {
161 GLint * compressedTextureFormats = ctx->getCompressedTextureFormats();
162 if (ctx->m_num_compressedTextureFormats > 0 &&
163 compressedTextureFormats != NULL) {
164 for (int i = 0; i < ctx->m_num_compressedTextureFormats; i++) {
165 ptr[i] = compressedTextureFormats[i] << 16;
166 }
167 }
168 break;
169 }
170
171 case GL_MAX_TEXTURE_UNITS:
172 ctx->m_glGetFixedv_enc(self, param, ptr);
173 *ptr = MIN(*ptr, GLClientState::MAX_TEXTURE_UNITS << 16);
174 break;
175
176 case GL_TEXTURE_BINDING_2D:
177 *ptr = state->getBoundTexture(GL_TEXTURE_2D) << 16;
178 break;
179
180 case GL_TEXTURE_BINDING_EXTERNAL_OES:
181 *ptr = state->getBoundTexture(GL_TEXTURE_EXTERNAL_OES) << 16;
182 break;
183
184 default:
185 if (!state->getClientStateParameter<GLfixed>(param,ptr)) {
186 ctx->m_glGetFixedv_enc(self, param, ptr);
187 }
188 break;
189 }
190 }
191
s_glGetBooleanv(void * self,GLenum param,GLboolean * ptr)192 void GLEncoder::s_glGetBooleanv(void *self, GLenum param, GLboolean *ptr)
193 {
194 GLEncoder *ctx = (GLEncoder *)self;
195 assert(ctx->m_state != NULL);
196 GLClientState* state = ctx->m_state;
197
198 switch (param) {
199 case GL_COMPRESSED_TEXTURE_FORMATS: {
200 GLint* compressedTextureFormats = ctx->getCompressedTextureFormats();
201 if (ctx->m_num_compressedTextureFormats > 0 &&
202 compressedTextureFormats != NULL) {
203 for (int i = 0; i < ctx->m_num_compressedTextureFormats; i++) {
204 ptr[i] = compressedTextureFormats[i] != 0 ? GL_TRUE : GL_FALSE;
205 }
206 }
207 break;
208 }
209
210 case GL_TEXTURE_BINDING_2D:
211 *ptr = state->getBoundTexture(GL_TEXTURE_2D) != 0 ? GL_TRUE : GL_FALSE;
212 break;
213
214 case GL_TEXTURE_BINDING_EXTERNAL_OES:
215 *ptr = state->getBoundTexture(GL_TEXTURE_EXTERNAL_OES) != 0
216 ? GL_TRUE : GL_FALSE;
217 break;
218
219 default:
220 if (!state->getClientStateParameter<GLboolean>(param,ptr)) {
221 ctx->m_glGetBooleanv_enc(self, param, ptr);
222 }
223 break;
224 }
225 }
226
s_glGetPointerv(void * self,GLenum param,GLvoid ** params)227 void GLEncoder::s_glGetPointerv(void * self, GLenum param, GLvoid **params)
228 {
229 GLEncoder * ctx = (GLEncoder *) self;
230 assert(ctx->m_state != NULL);
231 ctx->m_state->getClientStatePointer(param,params);
232 }
233
s_glFlush(void * self)234 void GLEncoder::s_glFlush(void *self)
235 {
236 GLEncoder *ctx = (GLEncoder *)self;
237 ctx->m_glFlush_enc(self);
238 ctx->m_stream->flush();
239 }
240
s_glGetString(void * self,GLenum name)241 const GLubyte *GLEncoder::s_glGetString(void *self, GLenum name)
242 {
243 (void)self;
244
245 GLubyte *retval = (GLubyte *) "";
246 switch(name) {
247 case GL_VENDOR:
248 retval = gVendorString;
249 break;
250 case GL_RENDERER:
251 retval = gRendererString;
252 break;
253 case GL_VERSION:
254 retval = gVersionString;
255 break;
256 case GL_EXTENSIONS:
257 retval = gExtensionsString;
258 break;
259 }
260 return retval;
261 }
262
s_glPixelStorei(void * self,GLenum param,GLint value)263 void GLEncoder::s_glPixelStorei(void *self, GLenum param, GLint value)
264 {
265 GLEncoder *ctx = (GLEncoder *)self;
266 ctx->m_glPixelStorei_enc(ctx, param, value);
267 ALOG_ASSERT(ctx->m_state, "GLEncoder::s_glPixelStorei");
268 ctx->m_state->setPixelStore(param, value);
269 }
270
s_glVertexPointer(void * self,int size,GLenum type,GLsizei stride,const void * data)271 void GLEncoder::s_glVertexPointer(void *self, int size, GLenum type, GLsizei stride, const void *data)
272 {
273 GLEncoder *ctx = (GLEncoder *)self;
274 assert(ctx->m_state != NULL);
275 ctx->m_state->setVertexAttribState(GLClientState::VERTEX_LOCATION, size, type, false, stride, data);
276 }
277
s_glNormalPointer(void * self,GLenum type,GLsizei stride,const void * data)278 void GLEncoder::s_glNormalPointer(void *self, GLenum type, GLsizei stride, const void *data)
279 {
280 GLEncoder *ctx = (GLEncoder *)self;
281 assert(ctx->m_state != NULL);
282 ctx->m_state->setVertexAttribState(GLClientState::NORMAL_LOCATION, 3, type, false, stride, data);
283 }
284
s_glColorPointer(void * self,int size,GLenum type,GLsizei stride,const void * data)285 void GLEncoder::s_glColorPointer(void *self, int size, GLenum type, GLsizei stride, const void *data)
286 {
287 GLEncoder *ctx = (GLEncoder *)self;
288 assert(ctx->m_state != NULL);
289 ctx->m_state->setVertexAttribState(GLClientState::COLOR_LOCATION, size, type, false, stride, data);
290 }
291
s_glPointSizePointerOES(void * self,GLenum type,GLsizei stride,const void * data)292 void GLEncoder::s_glPointSizePointerOES(void *self, GLenum type, GLsizei stride, const void *data)
293 {
294 GLEncoder *ctx = (GLEncoder *)self;
295 assert(ctx->m_state != NULL);
296 ctx->m_state->setVertexAttribState(GLClientState::POINTSIZE_LOCATION, 1, type, false, stride, data);
297 }
298
s_glClientActiveTexture(void * self,GLenum texture)299 void GLEncoder::s_glClientActiveTexture(void *self, GLenum texture)
300 {
301 GLEncoder *ctx = (GLEncoder *)self;
302 assert(ctx->m_state != NULL);
303 ctx->m_state->setActiveTexture(texture - GL_TEXTURE0);
304 }
305
s_glTexCoordPointer(void * self,int size,GLenum type,GLsizei stride,const void * data)306 void GLEncoder::s_glTexCoordPointer(void *self, int size, GLenum type, GLsizei stride, const void *data)
307 {
308 GLEncoder *ctx = (GLEncoder *)self;
309 assert(ctx->m_state != NULL);
310 int loc = ctx->m_state->getLocation(GL_TEXTURE_COORD_ARRAY);
311 ctx->m_state->setVertexAttribState(loc, size, type, false, stride, data);
312 }
313
s_glMatrixIndexPointerOES(void * self,int size,GLenum type,GLsizei stride,const void * data)314 void GLEncoder::s_glMatrixIndexPointerOES(void *self, int size, GLenum type, GLsizei stride, const void * data)
315 {
316 GLEncoder *ctx = (GLEncoder *)self;
317 assert(ctx->m_state != NULL);
318 int loc = ctx->m_state->getLocation(GL_MATRIX_INDEX_ARRAY_OES);
319 ctx->m_state->setVertexAttribState(loc, size, type, false, stride, data);
320 }
321
s_glWeightPointerOES(void * self,int size,GLenum type,GLsizei stride,const void * data)322 void GLEncoder::s_glWeightPointerOES(void * self, int size, GLenum type, GLsizei stride, const void * data)
323 {
324 GLEncoder *ctx = (GLEncoder *)self;
325 assert(ctx->m_state != NULL);
326 int loc = ctx->m_state->getLocation(GL_WEIGHT_ARRAY_OES);
327 ctx->m_state->setVertexAttribState(loc, size, type, false, stride, data);
328 }
329
s_glEnableClientState(void * self,GLenum state)330 void GLEncoder::s_glEnableClientState(void *self, GLenum state)
331 {
332 GLEncoder *ctx = (GLEncoder *) self;
333 assert(ctx->m_state != NULL);
334 int loc = ctx->m_state->getLocation(state);
335 ctx->m_state->enable(loc, 1);
336 }
337
s_glDisableClientState(void * self,GLenum state)338 void GLEncoder::s_glDisableClientState(void *self, GLenum state)
339 {
340 GLEncoder *ctx = (GLEncoder *) self;
341 assert(ctx->m_state != NULL);
342 int loc = ctx->m_state->getLocation(state);
343 ctx->m_state->enable(loc, 0);
344 }
345
s_glIsEnabled(void * self,GLenum cap)346 GLboolean GLEncoder::s_glIsEnabled(void *self, GLenum cap)
347 {
348 GLEncoder *ctx = (GLEncoder *) self;
349 assert(ctx->m_state != NULL);
350 int loc = ctx->m_state->getLocation(cap);
351 const GLClientState::VertexAttribState& state = ctx->m_state->getState(loc);
352 return state.enabled;
353 }
354
s_glBindBuffer(void * self,GLenum target,GLuint id)355 void GLEncoder::s_glBindBuffer(void *self, GLenum target, GLuint id)
356 {
357 GLEncoder *ctx = (GLEncoder *) self;
358 assert(ctx->m_state != NULL);
359 ctx->m_state->bindBuffer(target, id);
360 // TODO set error state if needed;
361 ctx->m_glBindBuffer_enc(self, target, id);
362 }
363
s_glBufferData(void * self,GLenum target,GLsizeiptr size,const GLvoid * data,GLenum usage)364 void GLEncoder::s_glBufferData(void * self, GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage)
365 {
366 GLEncoder *ctx = (GLEncoder *) self;
367 GLuint bufferId = ctx->m_state->getBuffer(target);
368 SET_ERROR_IF(bufferId==0, GL_INVALID_OPERATION);
369 SET_ERROR_IF(size<0, GL_INVALID_VALUE);
370
371 ctx->m_shared->updateBufferData(bufferId, size, (void*)data);
372 ctx->m_glBufferData_enc(self, target, size, data, usage);
373 }
374
s_glBufferSubData(void * self,GLenum target,GLintptr offset,GLsizeiptr size,const GLvoid * data)375 void GLEncoder::s_glBufferSubData(void * self, GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data)
376 {
377 GLEncoder *ctx = (GLEncoder *) self;
378 GLuint bufferId = ctx->m_state->getBuffer(target);
379 SET_ERROR_IF(bufferId==0, GL_INVALID_OPERATION);
380
381 GLenum res = ctx->m_shared->subUpdateBufferData(bufferId, offset, size, (void*)data);
382 SET_ERROR_IF(res, res);
383
384 ctx->m_glBufferSubData_enc(self, target, offset, size, data);
385 }
386
s_glDeleteBuffers(void * self,GLsizei n,const GLuint * buffers)387 void GLEncoder::s_glDeleteBuffers(void * self, GLsizei n, const GLuint * buffers)
388 {
389 GLEncoder *ctx = (GLEncoder *) self;
390 SET_ERROR_IF(n<0, GL_INVALID_VALUE);
391 for (int i=0; i<n; i++) {
392 ctx->m_shared->deleteBufferData(buffers[i]);
393 ctx->m_glDeleteBuffers_enc(self,1,&buffers[i]);
394 }
395 }
396
sendVertexData(unsigned int first,unsigned int count)397 void GLEncoder::sendVertexData(unsigned int first, unsigned int count)
398 {
399 assert(m_state != NULL);
400 GLenum prevActiveTexUnit = m_state->getActiveTextureUnit();
401 for (int i = 0; i < GLClientState::LAST_LOCATION; i++) {
402 bool enableDirty;
403 const GLClientState::VertexAttribState& state = m_state->getStateAndEnableDirty(i, &enableDirty);
404
405 // do not send disable state if state was already disabled
406 if (!enableDirty && !state.enabled) continue;
407
408 if ( i >= GLClientState::TEXCOORD0_LOCATION &&
409 i <= GLClientState::TEXCOORD7_LOCATION ) {
410 m_glClientActiveTexture_enc(this, GL_TEXTURE0 + i - GLClientState::TEXCOORD0_LOCATION);
411 }
412
413 if (state.enabled) {
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 this->m_glBindBuffer_enc(this, GL_ARRAY_BUFFER, state.bufferObject);
423 if (state.bufferObject == 0) {
424
425 switch(i) {
426 case GLClientState::VERTEX_LOCATION:
427 this->glVertexPointerData(this, state.size, state.type, state.stride,
428 (unsigned char *)state.data + firstIndex, datalen);
429 break;
430 case GLClientState::NORMAL_LOCATION:
431 this->glNormalPointerData(this, state.type, state.stride,
432 (unsigned char *)state.data + firstIndex, datalen);
433 break;
434 case GLClientState::COLOR_LOCATION:
435 this->glColorPointerData(this, state.size, state.type, state.stride,
436 (unsigned char *)state.data + firstIndex, datalen);
437 break;
438 case GLClientState::TEXCOORD0_LOCATION:
439 case GLClientState::TEXCOORD1_LOCATION:
440 case GLClientState::TEXCOORD2_LOCATION:
441 case GLClientState::TEXCOORD3_LOCATION:
442 case GLClientState::TEXCOORD4_LOCATION:
443 case GLClientState::TEXCOORD5_LOCATION:
444 case GLClientState::TEXCOORD6_LOCATION:
445 case GLClientState::TEXCOORD7_LOCATION:
446 m_state->setActiveTextureUnit(i - GLClientState::TEXCOORD0_LOCATION + GL_TEXTURE0);
447 if (m_state->getPriorityEnabledTarget(GL_INVALID_ENUM) != GL_INVALID_ENUM) {
448 this->glTexCoordPointerData(this, i - GLClientState::TEXCOORD0_LOCATION, state.size, state.type, state.stride,
449 (unsigned char *)state.data + firstIndex, datalen);
450 }
451 break;
452 case GLClientState::POINTSIZE_LOCATION:
453 this->glPointSizePointerData(this, state.type, state.stride,
454 (unsigned char *) state.data + firstIndex, datalen);
455 break;
456 case GLClientState::WEIGHT_LOCATION:
457 this->glWeightPointerData(this, state.size, state.type, state.stride,
458 (unsigned char * ) state.data + firstIndex, datalen);
459 break;
460 case GLClientState::MATRIXINDEX_LOCATION:
461 this->glMatrixIndexPointerData(this, state.size, state.type, state.stride,
462 (unsigned char *)state.data + firstIndex, datalen);
463 break;
464 }
465 } else {
466
467 switch(i) {
468 case GLClientState::VERTEX_LOCATION:
469 this->glVertexPointerOffset(this, state.size, state.type, state.stride,
470 (uintptr_t)state.data + firstIndex);
471 break;
472 case GLClientState::NORMAL_LOCATION:
473 this->glNormalPointerOffset(this, state.type, state.stride,
474 (uintptr_t)state.data + firstIndex);
475 break;
476 case GLClientState::POINTSIZE_LOCATION:
477 this->glPointSizePointerOffset(this, state.type, state.stride,
478 (uintptr_t)state.data + firstIndex);
479 break;
480 case GLClientState::COLOR_LOCATION:
481 this->glColorPointerOffset(this, state.size, state.type, state.stride,
482 (uintptr_t)state.data + firstIndex);
483 break;
484 case GLClientState::TEXCOORD0_LOCATION:
485 case GLClientState::TEXCOORD1_LOCATION:
486 case GLClientState::TEXCOORD2_LOCATION:
487 case GLClientState::TEXCOORD3_LOCATION:
488 case GLClientState::TEXCOORD4_LOCATION:
489 case GLClientState::TEXCOORD5_LOCATION:
490 case GLClientState::TEXCOORD6_LOCATION:
491 case GLClientState::TEXCOORD7_LOCATION:
492 this->glTexCoordPointerOffset(this, state.size, state.type, state.stride,
493 (uintptr_t)state.data + firstIndex);
494 break;
495 case GLClientState::WEIGHT_LOCATION:
496 this->glWeightPointerOffset(this,state.size,state.type,state.stride,
497 (uintptr_t)state.data+firstIndex);
498 break;
499 case GLClientState::MATRIXINDEX_LOCATION:
500 this->glMatrixIndexPointerOffset(this,state.size,state.type,state.stride,
501 (uintptr_t)state.data+firstIndex);
502 break;
503 }
504 }
505 this->m_glBindBuffer_enc(this, GL_ARRAY_BUFFER, m_state->currentArrayVbo());
506 } else {
507 this->m_glDisableClientState_enc(this, state.glConst);
508 }
509 }
510 m_state->setActiveTextureUnit(prevActiveTexUnit);
511 }
512
s_glDrawArrays(void * self,GLenum mode,GLint first,GLsizei count)513 void GLEncoder::s_glDrawArrays(void *self, GLenum mode, GLint first, GLsizei count)
514 {
515 GLEncoder *ctx = (GLEncoder *)self;
516
517 bool has_arrays = false;
518 for (int i = 0; i < GLClientState::LAST_LOCATION; i++) {
519 const GLClientState::VertexAttribState& state = ctx->m_state->getState(i);
520 if (state.enabled) {
521 if (state.bufferObject || state.data) {
522 has_arrays = true;
523 } else {
524 ALOGE("glDrawArrays: a vertex attribute array is enabled with no data bound\n");
525 ctx->setError(GL_INVALID_OPERATION);
526 return;
527 }
528 }
529 }
530 if (!has_arrays) {
531 ALOGE("glDrawArrays: no data bound to the command - ignoring\n");
532 return;
533 }
534
535 ctx->sendVertexData(first, count);
536 ctx->m_glDrawArrays_enc(ctx, mode, /*first*/ 0, count);
537 ctx->m_stream->flush();
538 }
539
s_glDrawElements(void * self,GLenum mode,GLsizei count,GLenum type,const void * indices)540 void GLEncoder::s_glDrawElements(void *self, GLenum mode, GLsizei count, GLenum type, const void *indices)
541 {
542
543 GLEncoder *ctx = (GLEncoder *)self;
544 assert(ctx->m_state != NULL);
545 SET_ERROR_IF(count<0, GL_INVALID_VALUE);
546
547 bool has_immediate_arrays = false;
548 bool has_indirect_arrays = false;
549
550 for (int i = 0; i < GLClientState::LAST_LOCATION; i++) {
551 const GLClientState::VertexAttribState& state = ctx->m_state->getState(i);
552 if (state.enabled) {
553 if (state.bufferObject != 0) {
554 has_indirect_arrays = true;
555 } else if (state.data) {
556 has_immediate_arrays = true;
557 } else {
558 ALOGE("glDrawElements: a vertex attribute array is enabled with no data bound\n");
559 ctx->setError(GL_INVALID_OPERATION);
560 return;
561 }
562 }
563 }
564
565 if (!has_immediate_arrays && !has_indirect_arrays) {
566 ALOGE("glDrawElements: no data bound to the command - ignoring\n");
567 return;
568 }
569
570 bool adjustIndices = true;
571 if (ctx->m_state->currentIndexVbo() != 0) {
572 if (!has_immediate_arrays) {
573 ctx->sendVertexData(0, count);
574 ctx->m_glBindBuffer_enc(self, GL_ELEMENT_ARRAY_BUFFER, ctx->m_state->currentIndexVbo());
575 ctx->glDrawElementsOffset(ctx, mode, count, type, (uintptr_t)indices);
576 ctx->m_stream->flush();
577 adjustIndices = false;
578 } else {
579 BufferData * buf = ctx->m_shared->getBufferData(ctx->m_state->currentIndexVbo());
580 ctx->m_glBindBuffer_enc(self, GL_ELEMENT_ARRAY_BUFFER, 0);
581 indices = &buf->m_fixedBuffer[(GLintptr)indices];
582 }
583 }
584 if (adjustIndices) {
585 void *adjustedIndices = (void*)indices;
586 int minIndex = 0, maxIndex = 0;
587
588 switch(type) {
589 case GL_BYTE:
590 case GL_UNSIGNED_BYTE:
591 GLUtils::minmax<unsigned char>((unsigned char *)indices, count, &minIndex, &maxIndex);
592 if (minIndex != 0) {
593 ctx->m_fixedBuffer.resize(glSizeof(type) * count);
594 adjustedIndices = ctx->m_fixedBuffer.data();
595 GLUtils::shiftIndices<unsigned char>((unsigned char *)indices,
596 (unsigned char *)adjustedIndices,
597 count, -minIndex);
598 }
599 break;
600 case GL_SHORT:
601 case GL_UNSIGNED_SHORT:
602 GLUtils::minmax<unsigned short>((unsigned short *)indices, count, &minIndex, &maxIndex);
603 if (minIndex != 0) {
604 ctx->m_fixedBuffer.resize(glSizeof(type) * count);
605 adjustedIndices = ctx->m_fixedBuffer.data();
606 GLUtils::shiftIndices<unsigned short>((unsigned short *)indices,
607 (unsigned short *)adjustedIndices,
608 count, -minIndex);
609 }
610 break;
611 case GL_INT:
612 case GL_UNSIGNED_INT:
613 GLUtils::minmax<unsigned int>((unsigned int *)indices, count, &minIndex, &maxIndex);
614 if (minIndex != 0) {
615 ctx->m_fixedBuffer.resize(glSizeof(type) * count);
616 adjustedIndices = ctx->m_fixedBuffer.data();
617 GLUtils::shiftIndices<unsigned int>((unsigned int *)indices,
618 (unsigned int *)adjustedIndices,
619 count, -minIndex);
620 }
621 break;
622 default:
623 ALOGE("unsupported index buffer type %d\n", type);
624 }
625 if (has_indirect_arrays || 1) {
626 ctx->sendVertexData(minIndex, maxIndex - minIndex + 1);
627 ctx->glDrawElementsData(ctx, mode, count, type, adjustedIndices,
628 count * glSizeof(type));
629 ctx->m_stream->flush();
630 // XXX - OPTIMIZATION (see the other else branch) should be implemented
631 if(!has_indirect_arrays) {
632 //ALOGD("unoptimized drawelements !!!\n");
633 }
634 } else {
635 // we are all direct arrays and immidate mode index array -
636 // rebuild the arrays and the index array;
637 ALOGE("glDrawElements: direct index & direct buffer data - will be implemented in later versions;\n");
638 }
639 }
640 }
641
s_glActiveTexture(void * self,GLenum texture)642 void GLEncoder::s_glActiveTexture(void* self, GLenum texture)
643 {
644 GLEncoder* ctx = (GLEncoder*)self;
645 GLClientState* state = ctx->m_state;
646 GLenum err;
647
648 if ((err = state->setActiveTextureUnit(texture)) != GL_NO_ERROR) {
649 ALOGE("%s:%s:%d GL error %#x\n", __FILE__, __FUNCTION__, __LINE__, err);
650 ctx->setError(err);
651 return;
652 }
653
654 ctx->m_glActiveTexture_enc(ctx, texture);
655 }
656
s_glBindTexture(void * self,GLenum target,GLuint texture)657 void GLEncoder::s_glBindTexture(void* self, GLenum target, GLuint texture)
658 {
659 GLEncoder* ctx = (GLEncoder*)self;
660 GLClientState* state = ctx->m_state;
661 GLenum err;
662
663 GLboolean firstUse;
664 if ((err = state->bindTexture(target, texture, &firstUse)) != GL_NO_ERROR) {
665 ALOGE("%s:%s:%d GL error %#x\n", __FILE__, __FUNCTION__, __LINE__, err);
666 ctx->setError(err);
667 return;
668 }
669
670 if (target != GL_TEXTURE_2D && target != GL_TEXTURE_EXTERNAL_OES) {
671 ctx->m_glBindTexture_enc(ctx, target, texture);
672 return;
673 }
674
675 GLenum priorityTarget = state->getPriorityEnabledTarget(GL_TEXTURE_2D);
676
677 if (target == GL_TEXTURE_EXTERNAL_OES && firstUse) {
678 // set TEXTURE_EXTERNAL_OES default states which differ from TEXTURE_2D
679 ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D, texture);
680 ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D,
681 GL_TEXTURE_MIN_FILTER, GL_LINEAR);
682 ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D,
683 GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
684 ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D,
685 GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
686
687 if (target != priorityTarget) {
688 ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D,
689 state->getBoundTexture(GL_TEXTURE_2D));
690 }
691 }
692
693 if (target == priorityTarget) {
694 ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D, texture);
695 }
696 }
697
s_glDeleteTextures(void * self,GLsizei n,const GLuint * textures)698 void GLEncoder::s_glDeleteTextures(void* self, GLsizei n, const GLuint* textures)
699 {
700 GLEncoder* ctx = (GLEncoder*)self;
701 GLClientState* state = ctx->m_state;
702
703 state->deleteTextures(n, textures);
704 ctx->m_glDeleteTextures_enc(ctx, n, textures);
705 }
706
s_glDisable(void * self,GLenum cap)707 void GLEncoder::s_glDisable(void* self, GLenum cap)
708 {
709 GLEncoder* ctx = (GLEncoder*)self;
710 GLClientState* state = ctx->m_state;
711
712 if (cap == GL_TEXTURE_2D || cap == GL_TEXTURE_EXTERNAL_OES) {
713 GLenum prevTarget = state->getPriorityEnabledTarget(GL_INVALID_ENUM);
714 state->disableTextureTarget(cap);
715 GLenum currTarget = state->getPriorityEnabledTarget(GL_INVALID_ENUM);
716
717 if (prevTarget != currTarget) {
718 if (currTarget == GL_INVALID_ENUM) {
719 ctx->m_glDisable_enc(ctx, GL_TEXTURE_2D);
720 currTarget = GL_TEXTURE_2D;
721 }
722 // maintain the invariant that when TEXTURE_EXTERNAL_OES is
723 // disabled, the TEXTURE_2D binding is active, even if
724 // TEXTURE_2D is also disabled.
725 ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D,
726 state->getBoundTexture(currTarget));
727 }
728
729 } else {
730 ctx->m_glDisable_enc(ctx, cap);
731 }
732 }
733
s_glEnable(void * self,GLenum cap)734 void GLEncoder::s_glEnable(void* self, GLenum cap)
735 {
736 GLEncoder* ctx = (GLEncoder*)self;
737 GLClientState* state = ctx->m_state;
738
739 if (cap == GL_TEXTURE_2D || cap == GL_TEXTURE_EXTERNAL_OES) {
740 GLenum prevTarget = state->getPriorityEnabledTarget(GL_INVALID_ENUM);
741 state->enableTextureTarget(cap);
742 GLenum currTarget = state->getPriorityEnabledTarget(GL_INVALID_ENUM);
743
744 if (prevTarget != currTarget) {
745 if (prevTarget == GL_INVALID_ENUM) {
746 ctx->m_glEnable_enc(ctx, GL_TEXTURE_2D);
747 }
748 if (currTarget == GL_TEXTURE_EXTERNAL_OES) {
749 ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D,
750 state->getBoundTexture(currTarget));
751 }
752 }
753
754 } else {
755 ctx->m_glEnable_enc(ctx, cap);
756 }
757 }
758
s_glGetTexParameterfv(void * self,GLenum target,GLenum pname,GLfloat * params)759 void GLEncoder::s_glGetTexParameterfv(void* self,
760 GLenum target, GLenum pname, GLfloat* params)
761 {
762 GLEncoder* ctx = (GLEncoder*)self;
763 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
764 ctx->override2DTextureTarget(target);
765 ctx->m_glGetTexParameterfv_enc(ctx, GL_TEXTURE_2D, pname, params);
766 ctx->restore2DTextureTarget();
767 } else {
768 ctx->m_glGetTexParameterfv_enc(ctx, target, pname, params);
769 }
770 }
771
s_glGetTexParameteriv(void * self,GLenum target,GLenum pname,GLint * params)772 void GLEncoder::s_glGetTexParameteriv(void* self,
773 GLenum target, GLenum pname, GLint* params)
774 {
775 GLEncoder* ctx = (GLEncoder*)self;
776
777 switch (pname) {
778 case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
779 *params = 1;
780 break;
781
782 default:
783 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
784 ctx->override2DTextureTarget(target);
785 ctx->m_glGetTexParameteriv_enc(ctx, GL_TEXTURE_2D, pname, params);
786 ctx->restore2DTextureTarget();
787 } else {
788 ctx->m_glGetTexParameteriv_enc(ctx, target, pname, params);
789 }
790 break;
791 }
792 }
793
s_glGetTexParameterxv(void * self,GLenum target,GLenum pname,GLfixed * params)794 void GLEncoder::s_glGetTexParameterxv(void* self,
795 GLenum target, GLenum pname, GLfixed* params)
796 {
797 GLEncoder* ctx = (GLEncoder*)self;
798
799 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
800 ctx->override2DTextureTarget(target);
801 ctx->m_glGetTexParameterxv_enc(ctx, GL_TEXTURE_2D, pname, params);
802 ctx->restore2DTextureTarget();
803 } else {
804 ctx->m_glGetTexParameterxv_enc(ctx, target, pname, params);
805 }
806 }
807
isValidTextureExternalParam(GLenum pname,GLenum param)808 static bool isValidTextureExternalParam(GLenum pname, GLenum param)
809 {
810 switch (pname) {
811 case GL_TEXTURE_MIN_FILTER:
812 case GL_TEXTURE_MAG_FILTER:
813 return param == GL_NEAREST || param == GL_LINEAR;
814
815 case GL_TEXTURE_WRAP_S:
816 case GL_TEXTURE_WRAP_T:
817 return param == GL_CLAMP_TO_EDGE;
818
819 case GL_GENERATE_MIPMAP:
820 return param == GL_FALSE;
821
822 default:
823 return true;
824 }
825 }
826
s_glTexParameterf(void * self,GLenum target,GLenum pname,GLfloat param)827 void GLEncoder::s_glTexParameterf(void* self,
828 GLenum target, GLenum pname, GLfloat param)
829 {
830 GLEncoder* ctx = (GLEncoder*)self;
831
832 SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
833 !isValidTextureExternalParam(pname, (GLenum)param)),
834 GL_INVALID_ENUM);
835
836 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
837 ctx->override2DTextureTarget(target);
838 ctx->m_glTexParameterf_enc(ctx, GL_TEXTURE_2D, pname, param);
839 ctx->restore2DTextureTarget();
840 } else {
841 ctx->m_glTexParameterf_enc(ctx, target, pname, param);
842 }
843 }
844
s_glTexParameterfv(void * self,GLenum target,GLenum pname,const GLfloat * params)845 void GLEncoder::s_glTexParameterfv(void* self,
846 GLenum target, GLenum pname, const GLfloat* params)
847 {
848 GLEncoder* ctx = (GLEncoder*)self;
849
850 SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
851 !isValidTextureExternalParam(pname, (GLenum)params[0])),
852 GL_INVALID_ENUM);
853
854 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
855 ctx->override2DTextureTarget(target);
856 ctx->m_glTexParameterfv_enc(ctx, GL_TEXTURE_2D, pname, params);
857 ctx->restore2DTextureTarget();
858 } else {
859 ctx->m_glTexParameterfv_enc(ctx, target, pname, params);
860 }
861 }
862
s_glTexParameteri(void * self,GLenum target,GLenum pname,GLint param)863 void GLEncoder::s_glTexParameteri(void* self,
864 GLenum target, GLenum pname, GLint param)
865 {
866 GLEncoder* ctx = (GLEncoder*)self;
867
868 SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
869 !isValidTextureExternalParam(pname, (GLenum)param)),
870 GL_INVALID_ENUM);
871
872 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
873 ctx->override2DTextureTarget(target);
874 ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D, pname, param);
875 ctx->restore2DTextureTarget();
876 } else {
877 ctx->m_glTexParameteri_enc(ctx, target, pname, param);
878 }
879 }
880
s_glTexParameterx(void * self,GLenum target,GLenum pname,GLfixed param)881 void GLEncoder::s_glTexParameterx(void* self,
882 GLenum target, GLenum pname, GLfixed param)
883 {
884 GLEncoder* ctx = (GLEncoder*)self;
885
886 SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
887 !isValidTextureExternalParam(pname, (GLenum)param)),
888 GL_INVALID_ENUM);
889
890 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
891 ctx->override2DTextureTarget(target);
892 ctx->m_glTexParameterx_enc(ctx, GL_TEXTURE_2D, pname, param);
893 ctx->restore2DTextureTarget();
894 } else {
895 ctx->m_glTexParameterx_enc(ctx, target, pname, param);
896 }
897 }
898
s_glTexParameteriv(void * self,GLenum target,GLenum pname,const GLint * params)899 void GLEncoder::s_glTexParameteriv(void* self,
900 GLenum target, GLenum pname, const GLint* params)
901 {
902 GLEncoder* ctx = (GLEncoder*)self;
903
904 SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
905 !isValidTextureExternalParam(pname, (GLenum)params[0])),
906 GL_INVALID_ENUM);
907
908 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
909 ctx->override2DTextureTarget(target);
910 ctx->m_glTexParameteriv_enc(ctx, GL_TEXTURE_2D, pname, params);
911 ctx->restore2DTextureTarget();
912 } else {
913 ctx->m_glTexParameteriv_enc(ctx, target, pname, params);
914 }
915 }
916
s_glTexParameterxv(void * self,GLenum target,GLenum pname,const GLfixed * params)917 void GLEncoder::s_glTexParameterxv(void* self,
918 GLenum target, GLenum pname, const GLfixed* params)
919 {
920 GLEncoder* ctx = (GLEncoder*)self;
921
922 SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
923 !isValidTextureExternalParam(pname, (GLenum)params[0])),
924 GL_INVALID_ENUM);
925
926 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
927 ctx->override2DTextureTarget(target);
928 ctx->m_glTexParameterxv_enc(ctx, GL_TEXTURE_2D, pname, params);
929 ctx->restore2DTextureTarget();
930 } else {
931 ctx->m_glTexParameterxv_enc(ctx, target, pname, params);
932 }
933 }
934
override2DTextureTarget(GLenum target)935 void GLEncoder::override2DTextureTarget(GLenum target)
936 {
937 if ((target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) &&
938 target != m_state->getPriorityEnabledTarget(GL_TEXTURE_2D)) {
939 m_glBindTexture_enc(this, GL_TEXTURE_2D,
940 m_state->getBoundTexture(target));
941 }
942 }
943
restore2DTextureTarget()944 void GLEncoder::restore2DTextureTarget()
945 {
946 GLenum priorityTarget = m_state->getPriorityEnabledTarget(GL_TEXTURE_2D);
947 m_glBindTexture_enc(this, GL_TEXTURE_2D,
948 m_state->getBoundTexture(priorityTarget));
949 }
950
s_glGenFramebuffersOES(void * self,GLsizei n,GLuint * framebuffers)951 void GLEncoder::s_glGenFramebuffersOES(void* self,
952 GLsizei n, GLuint* framebuffers) {
953 GLEncoder* ctx = (GLEncoder*)self;
954 GLClientState* state = ctx->m_state;
955
956 SET_ERROR_IF(n < 0, GL_INVALID_VALUE);
957
958 ctx->m_glGenFramebuffersOES_enc(self, n, framebuffers);
959 state->addFramebuffers(n, framebuffers);
960 }
961
s_glDeleteFramebuffersOES(void * self,GLsizei n,const GLuint * framebuffers)962 void GLEncoder::s_glDeleteFramebuffersOES(void* self,
963 GLsizei n, const GLuint* framebuffers) {
964 GLEncoder* ctx = (GLEncoder*)self;
965 GLClientState* state = ctx->m_state;
966
967 SET_ERROR_IF(n < 0, GL_INVALID_VALUE);
968
969 ctx->m_glDeleteFramebuffersOES_enc(self, n, framebuffers);
970 state->removeFramebuffers(n, framebuffers);
971 }
972
s_glBindFramebufferOES(void * self,GLenum target,GLuint framebuffer)973 void GLEncoder::s_glBindFramebufferOES(void* self,
974 GLenum target, GLuint framebuffer) {
975 GLEncoder* ctx = (GLEncoder*)self;
976 GLClientState* state = ctx->m_state;
977
978 SET_ERROR_IF((target != GL_FRAMEBUFFER),
979 GL_INVALID_ENUM);
980
981 state->bindFramebuffer(target, framebuffer);
982
983 ctx->m_glBindFramebufferOES_enc(self, target, framebuffer);
984 }
985
s_glFramebufferTexture2DOES(void * self,GLenum target,GLenum attachment,GLenum textarget,GLuint texture,GLint level)986 void GLEncoder::s_glFramebufferTexture2DOES(void*self,
987 GLenum target, GLenum attachment,
988 GLenum textarget, GLuint texture, GLint level) {
989 GLEncoder* ctx = (GLEncoder*)self;
990 GLClientState* state = ctx->m_state;
991
992 state->attachTextureObject(target, attachment, texture);
993
994 ctx->m_glFramebufferTexture2DOES_enc(self, target, attachment, textarget, texture, level);
995 }
996
s_glFramebufferTexture2DMultisampleIMG(void * self,GLenum target,GLenum attachment,GLenum textarget,GLuint texture,GLint level,GLsizei samples)997 void GLEncoder::s_glFramebufferTexture2DMultisampleIMG(void* self,
998 GLenum target, GLenum attachment,
999 GLenum textarget, GLuint texture, GLint level, GLsizei samples) {
1000 GLEncoder* ctx = (GLEncoder*)self;
1001 GLClientState* state = ctx->m_state;
1002
1003 state->attachTextureObject(target, attachment, texture);
1004
1005 ctx->m_glFramebufferTexture2DMultisampleIMG_enc(self, target, attachment, textarget, texture, level, samples);
1006 }
1007
s_glGetFramebufferAttachmentParameterivOES(void * self,GLenum target,GLenum attachment,GLenum pname,GLint * params)1008 void GLEncoder::s_glGetFramebufferAttachmentParameterivOES(void* self,
1009 GLenum target, GLenum attachment, GLenum pname, GLint* params)
1010 {
1011 GLEncoder* ctx = (GLEncoder*)self;
1012 const GLClientState* state = ctx->m_state;
1013
1014 SET_ERROR_IF(state->boundFramebuffer(GL_FRAMEBUFFER) == 0,
1015 GL_INVALID_OPERATION);
1016 SET_ERROR_IF((pname != GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE) &&
1017 (!state->attachmentHasObject(GL_FRAMEBUFFER, attachment)),
1018 GL_INVALID_ENUM);
1019
1020 ctx->m_glGetFramebufferAttachmentParameterivOES_enc(self, target, attachment, pname, params);
1021 }
1022
GLEncoder(IOStream * stream,ChecksumCalculator * protocol)1023 GLEncoder::GLEncoder(IOStream *stream, ChecksumCalculator *protocol)
1024 : gl_encoder_context_t(stream, protocol)
1025 {
1026 m_initialized = false;
1027 m_state = NULL;
1028 m_error = GL_NO_ERROR;
1029 m_num_compressedTextureFormats = 0;
1030 m_compressedTextureFormats = NULL;
1031
1032 // overrides;
1033 #define OVERRIDE(name) m_##name##_enc = this-> name ; this-> name = &s_##name
1034
1035 OVERRIDE(glFlush);
1036 OVERRIDE(glPixelStorei);
1037 OVERRIDE(glVertexPointer);
1038 OVERRIDE(glNormalPointer);
1039 OVERRIDE(glColorPointer);
1040 OVERRIDE(glPointSizePointerOES);
1041 OVERRIDE(glClientActiveTexture);
1042 OVERRIDE(glTexCoordPointer);
1043 OVERRIDE(glMatrixIndexPointerOES);
1044 OVERRIDE(glWeightPointerOES);
1045
1046 OVERRIDE(glGetIntegerv);
1047 OVERRIDE(glGetFloatv);
1048 OVERRIDE(glGetBooleanv);
1049 OVERRIDE(glGetFixedv);
1050 OVERRIDE(glGetPointerv);
1051
1052 OVERRIDE(glBindBuffer);
1053 OVERRIDE(glBufferData);
1054 OVERRIDE(glBufferSubData);
1055 OVERRIDE(glDeleteBuffers);
1056
1057 OVERRIDE(glEnableClientState);
1058 OVERRIDE(glDisableClientState);
1059 OVERRIDE(glIsEnabled);
1060 OVERRIDE(glDrawArrays);
1061 OVERRIDE(glDrawElements);
1062
1063 this->glGetString = s_glGetString;
1064 this->glFinish = s_glFinish;
1065
1066 OVERRIDE(glGetError);
1067
1068 OVERRIDE(glActiveTexture);
1069 OVERRIDE(glBindTexture);
1070 OVERRIDE(glDeleteTextures);
1071 OVERRIDE(glDisable);
1072 OVERRIDE(glEnable);
1073 OVERRIDE(glGetTexParameterfv);
1074 OVERRIDE(glGetTexParameteriv);
1075 OVERRIDE(glGetTexParameterxv);
1076 OVERRIDE(glTexParameterf);
1077 OVERRIDE(glTexParameterfv);
1078 OVERRIDE(glTexParameteri);
1079 OVERRIDE(glTexParameterx);
1080 OVERRIDE(glTexParameteriv);
1081 OVERRIDE(glTexParameterxv);
1082
1083 OVERRIDE(glGenFramebuffersOES);
1084 OVERRIDE(glDeleteFramebuffersOES);
1085 OVERRIDE(glBindFramebufferOES);
1086 OVERRIDE(glFramebufferTexture2DOES);
1087 OVERRIDE(glFramebufferTexture2DMultisampleIMG);
1088 OVERRIDE(glGetFramebufferAttachmentParameterivOES);
1089
1090 this->glReadnPixelsEXT = s_glReadnPixelsEXT;
1091 }
1092
~GLEncoder()1093 GLEncoder::~GLEncoder()
1094 {
1095 delete [] m_compressedTextureFormats;
1096 }
1097
pixelDataSize(GLsizei width,GLsizei height,GLenum format,GLenum type,int pack)1098 size_t GLEncoder::pixelDataSize(GLsizei width, GLsizei height, GLenum format, GLenum type, int pack)
1099 {
1100 assert(m_state != NULL);
1101 return m_state->pixelDataSize(width, height, 1, format, type, pack);
1102 }
1103
s_glFinish(void * self)1104 void GLEncoder::s_glFinish(void *self)
1105 {
1106 GLEncoder *ctx = (GLEncoder *)self;
1107 ctx->glFinishRoundTrip(self);
1108 }
1109
s_glReadnPixelsEXT(void * self,GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLsizei bufSize,GLvoid * pixels)1110 void GLEncoder::s_glReadnPixelsEXT(void* self, GLint x, GLint y, GLsizei width,
1111 GLsizei height, GLenum format, GLenum type, GLsizei bufSize,
1112 GLvoid* pixels) {
1113 GLEncoder *ctx = (GLEncoder*)self;
1114 SET_ERROR_IF(bufSize < ctx->pixelDataSize(width, height, format,
1115 type, 1), GL_INVALID_OPERATION);
1116 ctx->glReadPixels(self, x, y, width, height, format, type, pixels);
1117 }
1118