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