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