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