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