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