• Home
  • History
  • Annotate
  • 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 
17 #include "GL2Encoder.h"
18 #include <assert.h>
19 #include <ctype.h>
20 
21 #ifndef MIN
22 #define MIN(a, b) ((a) < (b) ? (a) : (b))
23 #endif
24 
25 static GLubyte *gVendorString= (GLubyte *) "Android";
26 static GLubyte *gRendererString= (GLubyte *) "Android HW-GLES 2.0";
27 static GLubyte *gVersionString= (GLubyte *) "OpenGL ES 2.0";
28 static GLubyte *gExtensionsString= (GLubyte *) ""; // no extensions at this point;
29 
30 #define SET_ERROR_IF(condition,err) if((condition)) {                            \
31         ALOGE("%s:%s:%d GL error 0x%x\n", __FILE__, __FUNCTION__, __LINE__, err); \
32         ctx->setError(err);                                    \
33         return;                                                  \
34     }
35 
36 
37 #define RET_AND_SET_ERROR_IF(condition,err,ret) if((condition)) {                \
38         ALOGE("%s:%s:%d GL error 0x%x\n", __FILE__, __FUNCTION__, __LINE__, err); \
39         ctx->setError(err);                                    \
40         return ret;                                              \
41     }
42 
43 
GL2Encoder(IOStream * stream)44 GL2Encoder::GL2Encoder(IOStream *stream) : gl2_encoder_context_t(stream)
45 {
46     m_initialized = false;
47     m_state = NULL;
48     m_error = GL_NO_ERROR;
49     m_num_compressedTextureFormats = 0;
50     m_compressedTextureFormats = NULL;
51 
52     //overrides
53 #define OVERRIDE(name)  m_##name##_enc = this-> name ; this-> name = &s_##name
54 
55     OVERRIDE(glFlush);
56     OVERRIDE(glPixelStorei);
57     OVERRIDE(glGetString);
58     OVERRIDE(glBindBuffer);
59     OVERRIDE(glBufferData);
60     OVERRIDE(glBufferSubData);
61     OVERRIDE(glDeleteBuffers);
62     OVERRIDE(glDrawArrays);
63     OVERRIDE(glDrawElements);
64     OVERRIDE(glGetIntegerv);
65     OVERRIDE(glGetFloatv);
66     OVERRIDE(glGetBooleanv);
67     OVERRIDE(glVertexAttribPointer);
68     OVERRIDE(glEnableVertexAttribArray);
69     OVERRIDE(glDisableVertexAttribArray);
70     OVERRIDE(glGetVertexAttribiv);
71     OVERRIDE(glGetVertexAttribfv);
72     OVERRIDE(glGetVertexAttribPointerv);
73 
74     this->glShaderBinary = &s_glShaderBinary;
75     this->glShaderSource = &s_glShaderSource;
76     this->glFinish = &s_glFinish;
77 
78     OVERRIDE(glGetError);
79     OVERRIDE(glLinkProgram);
80     OVERRIDE(glDeleteProgram);
81     OVERRIDE(glGetUniformiv);
82     OVERRIDE(glGetUniformfv);
83     OVERRIDE(glCreateProgram);
84     OVERRIDE(glCreateShader);
85     OVERRIDE(glDeleteShader);
86     OVERRIDE(glAttachShader);
87     OVERRIDE(glDetachShader);
88     OVERRIDE(glGetAttachedShaders);
89     OVERRIDE(glGetShaderSource);
90     OVERRIDE(glGetShaderInfoLog);
91     OVERRIDE(glGetProgramInfoLog);
92 
93     OVERRIDE(glGetUniformLocation);
94     OVERRIDE(glUseProgram);
95 
96     OVERRIDE(glUniform1f);
97     OVERRIDE(glUniform1fv);
98     OVERRIDE(glUniform1i);
99     OVERRIDE(glUniform1iv);
100     OVERRIDE(glUniform2f);
101     OVERRIDE(glUniform2fv);
102     OVERRIDE(glUniform2i);
103     OVERRIDE(glUniform2iv);
104     OVERRIDE(glUniform3f);
105     OVERRIDE(glUniform3fv);
106     OVERRIDE(glUniform3i);
107     OVERRIDE(glUniform3iv);
108     OVERRIDE(glUniform4f);
109     OVERRIDE(glUniform4fv);
110     OVERRIDE(glUniform4i);
111     OVERRIDE(glUniform4iv);
112     OVERRIDE(glUniformMatrix2fv);
113     OVERRIDE(glUniformMatrix3fv);
114     OVERRIDE(glUniformMatrix4fv);
115 
116     OVERRIDE(glActiveTexture);
117     OVERRIDE(glBindTexture);
118     OVERRIDE(glDeleteTextures);
119     OVERRIDE(glGetTexParameterfv);
120     OVERRIDE(glGetTexParameteriv);
121     OVERRIDE(glTexParameterf);
122     OVERRIDE(glTexParameterfv);
123     OVERRIDE(glTexParameteri);
124     OVERRIDE(glTexParameteriv);
125     OVERRIDE(glTexImage2D);
126 }
127 
~GL2Encoder()128 GL2Encoder::~GL2Encoder()
129 {
130     delete m_compressedTextureFormats;
131 }
132 
s_glGetError(void * self)133 GLenum GL2Encoder::s_glGetError(void * self)
134 {
135     GL2Encoder *ctx = (GL2Encoder *)self;
136     GLenum err = ctx->getError();
137     if(err != GL_NO_ERROR) {
138         ctx->setError(GL_NO_ERROR);
139         return err;
140     }
141 
142     return ctx->m_glGetError_enc(self);
143 
144 }
145 
s_glFlush(void * self)146 void GL2Encoder::s_glFlush(void *self)
147 {
148     GL2Encoder *ctx = (GL2Encoder *) self;
149     ctx->m_glFlush_enc(self);
150     ctx->m_stream->flush();
151 }
152 
s_glGetString(void * self,GLenum name)153 const GLubyte *GL2Encoder::s_glGetString(void *self, GLenum name)
154 {
155     (void)self;
156 
157     GLubyte *retval =  (GLubyte *) "";
158     switch(name) {
159     case GL_VENDOR:
160         retval = gVendorString;
161         break;
162     case GL_RENDERER:
163         retval = gRendererString;
164         break;
165     case GL_VERSION:
166         retval = gVersionString;
167         break;
168     case GL_EXTENSIONS:
169         retval = gExtensionsString;
170         break;
171     }
172     return retval;
173 }
174 
s_glPixelStorei(void * self,GLenum param,GLint value)175 void GL2Encoder::s_glPixelStorei(void *self, GLenum param, GLint value)
176 {
177     GL2Encoder *ctx = (GL2Encoder *)self;
178     ctx->m_glPixelStorei_enc(ctx, param, value);
179     assert(ctx->m_state != NULL);
180     ctx->m_state->setPixelStore(param, value);
181 }
182 
183 
s_glBindBuffer(void * self,GLenum target,GLuint id)184 void GL2Encoder::s_glBindBuffer(void *self, GLenum target, GLuint id)
185 {
186     GL2Encoder *ctx = (GL2Encoder *) self;
187     assert(ctx->m_state != NULL);
188     ctx->m_state->bindBuffer(target, id);
189     // TODO set error state if needed;
190     ctx->m_glBindBuffer_enc(self, target, id);
191 }
192 
s_glBufferData(void * self,GLenum target,GLsizeiptr size,const GLvoid * data,GLenum usage)193 void GL2Encoder::s_glBufferData(void * self, GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage)
194 {
195     GL2Encoder *ctx = (GL2Encoder *) self;
196     SET_ERROR_IF(!(target == GL_ARRAY_BUFFER || target == GL_ELEMENT_ARRAY_BUFFER), GL_INVALID_ENUM);
197     GLuint bufferId = ctx->m_state->getBuffer(target);
198     SET_ERROR_IF(bufferId==0, GL_INVALID_OPERATION);
199     SET_ERROR_IF(size<0, GL_INVALID_VALUE);
200 
201     ctx->m_shared->updateBufferData(bufferId, size, (void*)data);
202     ctx->m_glBufferData_enc(self, target, size, data, usage);
203 }
204 
s_glBufferSubData(void * self,GLenum target,GLintptr offset,GLsizeiptr size,const GLvoid * data)205 void GL2Encoder::s_glBufferSubData(void * self, GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data)
206 {
207     GL2Encoder *ctx = (GL2Encoder *) self;
208     SET_ERROR_IF(!(target == GL_ARRAY_BUFFER || target == GL_ELEMENT_ARRAY_BUFFER), GL_INVALID_ENUM);
209     GLuint bufferId = ctx->m_state->getBuffer(target);
210     SET_ERROR_IF(bufferId==0, GL_INVALID_OPERATION);
211 
212     GLenum res = ctx->m_shared->subUpdateBufferData(bufferId, offset, size, (void*)data);
213     SET_ERROR_IF(res, res);
214 
215     ctx->m_glBufferSubData_enc(self, target, offset, size, data);
216 }
217 
s_glDeleteBuffers(void * self,GLsizei n,const GLuint * buffers)218 void GL2Encoder::s_glDeleteBuffers(void * self, GLsizei n, const GLuint * buffers)
219 {
220     GL2Encoder *ctx = (GL2Encoder *) self;
221     SET_ERROR_IF(n<0, GL_INVALID_VALUE);
222     for (int i=0; i<n; i++) {
223         ctx->m_shared->deleteBufferData(buffers[i]);
224         ctx->m_state->unBindBuffer(buffers[i]);
225         ctx->m_glDeleteBuffers_enc(self,1,&buffers[i]);
226     }
227 }
228 
s_glVertexAttribPointer(void * self,GLuint indx,GLint size,GLenum type,GLboolean normalized,GLsizei stride,const GLvoid * ptr)229 void GL2Encoder::s_glVertexAttribPointer(void *self, GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid * ptr)
230 {
231     GL2Encoder *ctx = (GL2Encoder *)self;
232     assert(ctx->m_state != NULL);
233     ctx->m_state->setState(indx, size, type, normalized, stride, ptr);
234 }
235 
s_glGetIntegerv(void * self,GLenum param,GLint * ptr)236 void GL2Encoder::s_glGetIntegerv(void *self, GLenum param, GLint *ptr)
237 {
238     GL2Encoder *ctx = (GL2Encoder *) self;
239     assert(ctx->m_state != NULL);
240     GLClientState* state = ctx->m_state;
241 
242     switch (param) {
243     case GL_NUM_SHADER_BINARY_FORMATS:
244         *ptr = 0;
245         break;
246     case GL_SHADER_BINARY_FORMATS:
247         // do nothing
248         break;
249 
250     case GL_COMPRESSED_TEXTURE_FORMATS: {
251         GLint *compressedTextureFormats = ctx->getCompressedTextureFormats();
252         if (ctx->m_num_compressedTextureFormats > 0 &&
253                 compressedTextureFormats != NULL) {
254             memcpy(ptr, compressedTextureFormats,
255                     ctx->m_num_compressedTextureFormats * sizeof(GLint));
256         }
257         break;
258     }
259 
260     case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
261     case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
262     case GL_MAX_TEXTURE_IMAGE_UNITS:
263         ctx->m_glGetIntegerv_enc(self, param, ptr);
264         *ptr = MIN(*ptr, GLClientState::MAX_TEXTURE_UNITS);
265         break;
266 
267     case GL_TEXTURE_BINDING_2D:
268         *ptr = state->getBoundTexture(GL_TEXTURE_2D);
269         break;
270     case GL_TEXTURE_BINDING_EXTERNAL_OES:
271         *ptr = state->getBoundTexture(GL_TEXTURE_EXTERNAL_OES);
272         break;
273 
274     default:
275         if (!ctx->m_state->getClientStateParameter<GLint>(param, ptr)) {
276             ctx->m_glGetIntegerv_enc(self, param, ptr);
277         }
278         break;
279     }
280 }
281 
282 
s_glGetFloatv(void * self,GLenum param,GLfloat * ptr)283 void GL2Encoder::s_glGetFloatv(void *self, GLenum param, GLfloat *ptr)
284 {
285     GL2Encoder *ctx = (GL2Encoder *)self;
286     assert(ctx->m_state != NULL);
287     GLClientState* state = ctx->m_state;
288 
289     switch (param) {
290     case GL_NUM_SHADER_BINARY_FORMATS:
291         *ptr = 0;
292         break;
293     case GL_SHADER_BINARY_FORMATS:
294         // do nothing
295         break;
296 
297     case GL_COMPRESSED_TEXTURE_FORMATS: {
298         GLint *compressedTextureFormats = ctx->getCompressedTextureFormats();
299         if (ctx->m_num_compressedTextureFormats > 0 &&
300                 compressedTextureFormats != NULL) {
301             for (int i = 0; i < ctx->m_num_compressedTextureFormats; i++) {
302                 ptr[i] = (GLfloat) compressedTextureFormats[i];
303             }
304         }
305         break;
306     }
307 
308     case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
309     case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
310     case GL_MAX_TEXTURE_IMAGE_UNITS:
311         ctx->m_glGetFloatv_enc(self, param, ptr);
312         *ptr = MIN(*ptr, (GLfloat)GLClientState::MAX_TEXTURE_UNITS);
313         break;
314 
315     case GL_TEXTURE_BINDING_2D:
316         *ptr = (GLfloat)state->getBoundTexture(GL_TEXTURE_2D);
317         break;
318     case GL_TEXTURE_BINDING_EXTERNAL_OES:
319         *ptr = (GLfloat)state->getBoundTexture(GL_TEXTURE_EXTERNAL_OES);
320         break;
321 
322     default:
323         if (!ctx->m_state->getClientStateParameter<GLfloat>(param, ptr)) {
324             ctx->m_glGetFloatv_enc(self, param, ptr);
325         }
326         break;
327     }
328 }
329 
330 
s_glGetBooleanv(void * self,GLenum param,GLboolean * ptr)331 void GL2Encoder::s_glGetBooleanv(void *self, GLenum param, GLboolean *ptr)
332 {
333     GL2Encoder *ctx = (GL2Encoder *)self;
334     assert(ctx->m_state != NULL);
335     GLClientState* state = ctx->m_state;
336 
337     switch (param) {
338     case GL_NUM_SHADER_BINARY_FORMATS:
339         *ptr = GL_FALSE;
340         break;
341     case GL_SHADER_BINARY_FORMATS:
342         // do nothing
343         break;
344 
345     case GL_COMPRESSED_TEXTURE_FORMATS: {
346         GLint *compressedTextureFormats = ctx->getCompressedTextureFormats();
347         if (ctx->m_num_compressedTextureFormats > 0 &&
348                 compressedTextureFormats != NULL) {
349             for (int i = 0; i < ctx->m_num_compressedTextureFormats; i++) {
350                 ptr[i] = compressedTextureFormats[i] != 0 ? GL_TRUE : GL_FALSE;
351             }
352         }
353         break;
354     }
355 
356     case GL_TEXTURE_BINDING_2D:
357         *ptr = state->getBoundTexture(GL_TEXTURE_2D) != 0 ? GL_TRUE : GL_FALSE;
358         break;
359     case GL_TEXTURE_BINDING_EXTERNAL_OES:
360         *ptr = state->getBoundTexture(GL_TEXTURE_EXTERNAL_OES) != 0
361                 ? GL_TRUE : GL_FALSE;
362         break;
363 
364     default:
365         if (!ctx->m_state->getClientStateParameter<GLboolean>(param, ptr)) {
366             ctx->m_glGetBooleanv_enc(self, param, ptr);
367         }
368         *ptr = (*ptr != 0) ? GL_TRUE : GL_FALSE;
369         break;
370     }
371 }
372 
373 
s_glEnableVertexAttribArray(void * self,GLuint index)374 void GL2Encoder::s_glEnableVertexAttribArray(void *self, GLuint index)
375 {
376     GL2Encoder *ctx = (GL2Encoder *)self;
377     assert(ctx->m_state);
378     ctx->m_state->enable(index, 1);
379 }
380 
s_glDisableVertexAttribArray(void * self,GLuint index)381 void GL2Encoder::s_glDisableVertexAttribArray(void *self, GLuint index)
382 {
383     GL2Encoder *ctx = (GL2Encoder *)self;
384     assert(ctx->m_state);
385     ctx->m_state->enable(index, 0);
386 }
387 
388 
s_glGetVertexAttribiv(void * self,GLuint index,GLenum pname,GLint * params)389 void GL2Encoder::s_glGetVertexAttribiv(void *self, GLuint index, GLenum pname, GLint *params)
390 {
391     GL2Encoder *ctx = (GL2Encoder *)self;
392     assert(ctx->m_state);
393 
394     if (!ctx->m_state->getVertexAttribParameter<GLint>(index, pname, params)) {
395         ctx->m_glGetVertexAttribiv_enc(self, index, pname, params);
396     }
397 }
398 
s_glGetVertexAttribfv(void * self,GLuint index,GLenum pname,GLfloat * params)399 void GL2Encoder::s_glGetVertexAttribfv(void *self, GLuint index, GLenum pname, GLfloat *params)
400 {
401     GL2Encoder *ctx = (GL2Encoder *)self;
402     assert(ctx->m_state);
403 
404     if (!ctx->m_state->getVertexAttribParameter<GLfloat>(index, pname, params)) {
405         ctx->m_glGetVertexAttribfv_enc(self, index, pname, params);
406     }
407 }
408 
s_glGetVertexAttribPointerv(void * self,GLuint index,GLenum pname,GLvoid ** pointer)409 void GL2Encoder::s_glGetVertexAttribPointerv(void *self, GLuint index, GLenum pname, GLvoid **pointer)
410 {
411     GL2Encoder *ctx = (GL2Encoder *)self;
412     if (ctx->m_state == NULL) return;
413 
414     (void)pname;
415 
416     const GLClientState::VertexAttribState *va_state = ctx->m_state->getState(index);
417     if (va_state != NULL) {
418         *pointer = va_state->data;
419     }
420 }
421 
422 
sendVertexAttributes(GLint first,GLsizei count)423 void GL2Encoder::sendVertexAttributes(GLint first, GLsizei count)
424 {
425     assert(m_state);
426 
427     for (int i = 0; i < m_state->nLocations(); i++) {
428         bool enableDirty;
429         const GLClientState::VertexAttribState *state = m_state->getStateAndEnableDirty(i, &enableDirty);
430 
431         if (!state) {
432             continue;
433         }
434 
435         if (!enableDirty && !state->enabled) {
436             continue;
437         }
438 
439 
440         if (state->enabled) {
441             m_glEnableVertexAttribArray_enc(this, i);
442 
443             unsigned int datalen = state->elementSize * count;
444             int stride = state->stride == 0 ? state->elementSize : state->stride;
445             int firstIndex = stride * first;
446 
447             this->m_glBindBuffer_enc(this, GL_ARRAY_BUFFER, state->bufferObject);
448             if (state->bufferObject == 0) {
449                 this->glVertexAttribPointerData(this, i, state->size, state->type, state->normalized, state->stride,
450                                                 (unsigned char *)state->data + firstIndex, datalen);
451             } else {
452                 this->glVertexAttribPointerOffset(this, i, state->size, state->type, state->normalized, state->stride,
453                                                   (uintptr_t) state->data + firstIndex);
454             }
455             this->m_glBindBuffer_enc(this, GL_ARRAY_BUFFER, m_state->currentArrayVbo());
456         } else {
457             this->m_glDisableVertexAttribArray_enc(this, i);
458         }
459     }
460 }
461 
s_glDrawArrays(void * self,GLenum mode,GLint first,GLsizei count)462 void GL2Encoder::s_glDrawArrays(void *self, GLenum mode, GLint first, GLsizei count)
463 {
464     GL2Encoder *ctx = (GL2Encoder *)self;
465     ctx->sendVertexAttributes(first, count);
466     ctx->m_glDrawArrays_enc(ctx, mode, 0, count);
467 }
468 
469 
s_glDrawElements(void * self,GLenum mode,GLsizei count,GLenum type,const void * indices)470 void GL2Encoder::s_glDrawElements(void *self, GLenum mode, GLsizei count, GLenum type, const void *indices)
471 {
472 
473     GL2Encoder *ctx = (GL2Encoder *)self;
474     assert(ctx->m_state != NULL);
475     SET_ERROR_IF(count<0, GL_INVALID_VALUE);
476 
477     bool has_immediate_arrays = false;
478     bool has_indirect_arrays = false;
479     int nLocations = ctx->m_state->nLocations();
480 
481     for (int i = 0; i < nLocations; i++) {
482         const GLClientState::VertexAttribState *state = ctx->m_state->getState(i);
483         if (state->enabled) {
484             if (state->bufferObject != 0) {
485                 has_indirect_arrays = true;
486             } else {
487                 has_immediate_arrays = true;
488             }
489         }
490     }
491 
492     if (!has_immediate_arrays && !has_indirect_arrays) {
493         ALOGE("glDrawElements: no data bound to the command - ignoring\n");
494         return;
495     }
496 
497     bool adjustIndices = true;
498     if (ctx->m_state->currentIndexVbo() != 0) {
499         if (!has_immediate_arrays) {
500             ctx->sendVertexAttributes(0, count);
501             ctx->m_glBindBuffer_enc(self, GL_ELEMENT_ARRAY_BUFFER, ctx->m_state->currentIndexVbo());
502             ctx->glDrawElementsOffset(ctx, mode, count, type, (uintptr_t)indices);
503             adjustIndices = false;
504         } else {
505             BufferData * buf = ctx->m_shared->getBufferData(ctx->m_state->currentIndexVbo());
506             ctx->m_glBindBuffer_enc(self, GL_ELEMENT_ARRAY_BUFFER, 0);
507             indices = (void*)((GLintptr)buf->m_fixedBuffer.ptr() + (GLintptr)indices);
508         }
509     }
510     if (adjustIndices) {
511         void *adjustedIndices = (void*)indices;
512         int minIndex = 0, maxIndex = 0;
513 
514         switch(type) {
515         case GL_BYTE:
516         case GL_UNSIGNED_BYTE:
517             GLUtils::minmax<unsigned char>((unsigned char *)indices, count, &minIndex, &maxIndex);
518             if (minIndex != 0) {
519                 adjustedIndices =  ctx->m_fixedBuffer.alloc(glSizeof(type) * count);
520                 GLUtils::shiftIndices<unsigned char>((unsigned char *)indices,
521                                                  (unsigned char *)adjustedIndices,
522                                                  count, -minIndex);
523             }
524             break;
525         case GL_SHORT:
526         case GL_UNSIGNED_SHORT:
527             GLUtils::minmax<unsigned short>((unsigned short *)indices, count, &minIndex, &maxIndex);
528             if (minIndex != 0) {
529                 adjustedIndices = ctx->m_fixedBuffer.alloc(glSizeof(type) * count);
530                 GLUtils::shiftIndices<unsigned short>((unsigned short *)indices,
531                                                   (unsigned short *)adjustedIndices,
532                                                   count, -minIndex);
533             }
534             break;
535         default:
536             ALOGE("unsupported index buffer type %d\n", type);
537         }
538         if (has_indirect_arrays || 1) {
539             ctx->sendVertexAttributes(minIndex, maxIndex - minIndex + 1);
540             ctx->glDrawElementsData(ctx, mode, count, type, adjustedIndices,
541                                     count * glSizeof(type));
542             // XXX - OPTIMIZATION (see the other else branch) should be implemented
543             if(!has_indirect_arrays) {
544                 //ALOGD("unoptimized drawelements !!!\n");
545             }
546         } else {
547             // we are all direct arrays and immidate mode index array -
548             // rebuild the arrays and the index array;
549             ALOGE("glDrawElements: direct index & direct buffer data - will be implemented in later versions;\n");
550         }
551     }
552 }
553 
554 
getCompressedTextureFormats()555 GLint * GL2Encoder::getCompressedTextureFormats()
556 {
557     if (m_compressedTextureFormats == NULL) {
558         this->glGetIntegerv(this, GL_NUM_COMPRESSED_TEXTURE_FORMATS,
559                             &m_num_compressedTextureFormats);
560         if (m_num_compressedTextureFormats > 0) {
561             // get number of texture formats;
562             m_compressedTextureFormats = new GLint[m_num_compressedTextureFormats];
563             this->glGetCompressedTextureFormats(this, m_num_compressedTextureFormats, m_compressedTextureFormats);
564         }
565     }
566     return m_compressedTextureFormats;
567 }
568 
569 // Replace uses of samplerExternalOES with sampler2D, recording the names of
570 // modified shaders in data. Also remove
571 //   #extension GL_OES_EGL_image_external : require
572 // statements.
573 //
574 // This implementation assumes the input has already been pre-processed. If not,
575 // a few cases will be mishandled:
576 //
577 // 1. "mySampler" will be incorrectly recorded as being a samplerExternalOES in
578 //    the following code:
579 //      #if 1
580 //      uniform sampler2D mySampler;
581 //      #else
582 //      uniform samplerExternalOES mySampler;
583 //      #endif
584 //
585 // 2. Comments that look like sampler declarations will be incorrectly modified
586 //    and recorded:
587 //      // samplerExternalOES hahaFooledYou
588 //
589 // 3. However, GLSL ES does not have a concatentation operator, so things like
590 //    this (valid in C) are invalid and not a problem:
591 //      #define SAMPLER(TYPE, NAME) uniform sampler#TYPE NAME
592 //      SAMPLER(ExternalOES, mySampler);
593 //
replaceSamplerExternalWith2D(char * const str,ShaderData * const data)594 static bool replaceSamplerExternalWith2D(char* const str, ShaderData* const data)
595 {
596     static const char STR_HASH_EXTENSION[] = "#extension";
597     static const char STR_GL_OES_EGL_IMAGE_EXTERNAL[] = "GL_OES_EGL_image_external";
598     static const char STR_SAMPLER_EXTERNAL_OES[] = "samplerExternalOES";
599     static const char STR_SAMPLER2D_SPACE[]      = "sampler2D         ";
600 
601     // -- overwrite all "#extension GL_OES_EGL_image_external : xxx" statements
602     char* c = str;
603     while ((c = strstr(c, STR_HASH_EXTENSION))) {
604         char* start = c;
605         c += sizeof(STR_HASH_EXTENSION)-1;
606         while (isspace(*c) && *c != '\0') {
607             c++;
608         }
609         if (strncmp(c, STR_GL_OES_EGL_IMAGE_EXTERNAL,
610                 sizeof(STR_GL_OES_EGL_IMAGE_EXTERNAL)-1) == 0)
611         {
612             // #extension statements are terminated by end of line
613             c = start;
614             while (*c != '\0' && *c != '\r' && *c != '\n') {
615                 *c++ = ' ';
616             }
617         }
618     }
619 
620     // -- replace "samplerExternalOES" with "sampler2D" and record name
621     c = str;
622     while ((c = strstr(c, STR_SAMPLER_EXTERNAL_OES))) {
623         // Make sure "samplerExternalOES" isn't a substring of a larger token
624         if (c == str || !isspace(*(c-1))) {
625             c++;
626             continue;
627         }
628         char* sampler_start = c;
629         c += sizeof(STR_SAMPLER_EXTERNAL_OES)-1;
630         if (!isspace(*c) && *c != '\0') {
631             continue;
632         }
633 
634         // capture sampler name
635         while (isspace(*c) && *c != '\0') {
636             c++;
637         }
638         if (!isalpha(*c) && *c != '_') {
639             // not an identifier
640             return false;
641         }
642         char* name_start = c;
643         do {
644             c++;
645         } while (isalnum(*c) || *c == '_');
646         data->samplerExternalNames.push_back(
647                 android::String8(name_start, c - name_start));
648 
649         // memcpy instead of strcpy since we don't want the NUL terminator
650         memcpy(sampler_start, STR_SAMPLER2D_SPACE, sizeof(STR_SAMPLER2D_SPACE)-1);
651     }
652 
653     return true;
654 }
655 
s_glShaderBinary(void * self,GLsizei n,const GLuint * shaders,GLenum binaryformat,const void * binary,GLsizei length)656 void GL2Encoder::s_glShaderBinary(void *self, GLsizei n, const GLuint *shaders, GLenum binaryformat, const void* binary, GLsizei length)
657 {
658     GL2Encoder* ctx = (GL2Encoder*)self;
659     // Although it is not supported, need to set proper error code.
660     SET_ERROR_IF(1, GL_INVALID_ENUM);
661 }
662 
s_glShaderSource(void * self,GLuint shader,GLsizei count,const GLchar * const * string,const GLint * length)663 void GL2Encoder::s_glShaderSource(void *self, GLuint shader, GLsizei count, const GLchar * const *string, const GLint *length)
664 {
665     GL2Encoder* ctx = (GL2Encoder*)self;
666     ShaderData* shaderData = ctx->m_shared->getShaderData(shader);
667     SET_ERROR_IF(!ctx->m_shared->isObject(shader), GL_INVALID_VALUE);
668     SET_ERROR_IF(!shaderData, GL_INVALID_OPERATION);
669     SET_ERROR_IF((count<0), GL_INVALID_VALUE);
670 
671     int len = glUtilsCalcShaderSourceLen((char**)string, (GLint*)length, count);
672     char *str = new char[len + 1];
673     glUtilsPackStrings(str, (char**)string, (GLint*)length, count);
674 
675     // TODO: pre-process str before calling replaceSamplerExternalWith2D().
676     // Perhaps we can borrow Mesa's pre-processor?
677 
678     if (!replaceSamplerExternalWith2D(str, shaderData)) {
679         delete str;
680         ctx->setError(GL_OUT_OF_MEMORY);
681         return;
682     }
683 
684     ctx->glShaderString(ctx, shader, str, len + 1);
685     delete str;
686 }
687 
s_glFinish(void * self)688 void GL2Encoder::s_glFinish(void *self)
689 {
690     GL2Encoder *ctx = (GL2Encoder *)self;
691     ctx->glFinishRoundTrip(self);
692 }
693 
s_glLinkProgram(void * self,GLuint program)694 void GL2Encoder::s_glLinkProgram(void * self, GLuint program)
695 {
696     GL2Encoder *ctx = (GL2Encoder *)self;
697     ctx->m_glLinkProgram_enc(self, program);
698 
699     GLint linkStatus = 0;
700     ctx->glGetProgramiv(self,program,GL_LINK_STATUS,&linkStatus);
701     if (!linkStatus)
702         return;
703 
704     //get number of active uniforms in the program
705     GLint numUniforms=0;
706     ctx->glGetProgramiv(self, program, GL_ACTIVE_UNIFORMS, &numUniforms);
707     ctx->m_shared->initProgramData(program,numUniforms);
708 
709     //get the length of the longest uniform name
710     GLint maxLength=0;
711     ctx->glGetProgramiv(self, program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxLength);
712 
713     GLint size;
714     GLenum type;
715     GLchar *name = new GLchar[maxLength+1];
716     GLint location;
717     //for each active uniform, get its size and starting location.
718     for (GLint i=0 ; i<numUniforms ; ++i)
719     {
720         ctx->glGetActiveUniform(self, program, i, maxLength, NULL, &size, &type, name);
721         location = ctx->m_glGetUniformLocation_enc(self, program, name);
722         ctx->m_shared->setProgramIndexInfo(program, i, location, size, type, name);
723     }
724     ctx->m_shared->setupLocationShiftWAR(program);
725 
726     delete[] name;
727 }
728 
s_glDeleteProgram(void * self,GLuint program)729 void GL2Encoder::s_glDeleteProgram(void *self, GLuint program)
730 {
731     GL2Encoder *ctx = (GL2Encoder*)self;
732     ctx->m_glDeleteProgram_enc(self, program);
733 
734     ctx->m_shared->deleteProgramData(program);
735 }
736 
s_glGetUniformiv(void * self,GLuint program,GLint location,GLint * params)737 void GL2Encoder::s_glGetUniformiv(void *self, GLuint program, GLint location, GLint* params)
738 {
739     GL2Encoder *ctx = (GL2Encoder*)self;
740     SET_ERROR_IF(!ctx->m_shared->isProgram(program), GL_INVALID_VALUE);
741     SET_ERROR_IF(!ctx->m_shared->isProgramInitialized(program), GL_INVALID_OPERATION);
742     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
743     SET_ERROR_IF(ctx->m_shared->getProgramUniformType(program,hostLoc)==0, GL_INVALID_OPERATION);
744     ctx->m_glGetUniformiv_enc(self, program, hostLoc, params);
745 }
s_glGetUniformfv(void * self,GLuint program,GLint location,GLfloat * params)746 void GL2Encoder::s_glGetUniformfv(void *self, GLuint program, GLint location, GLfloat* params)
747 {
748     GL2Encoder *ctx = (GL2Encoder*)self;
749     SET_ERROR_IF(!ctx->m_shared->isProgram(program), GL_INVALID_VALUE);
750     SET_ERROR_IF(!ctx->m_shared->isProgramInitialized(program), GL_INVALID_OPERATION);
751     GLint hostLoc = ctx->m_shared->locationWARAppToHost(program,location);
752     SET_ERROR_IF(ctx->m_shared->getProgramUniformType(program,hostLoc)==0, GL_INVALID_OPERATION);
753     ctx->m_glGetUniformfv_enc(self, program, hostLoc, params);
754 }
755 
s_glCreateProgram(void * self)756 GLuint GL2Encoder::s_glCreateProgram(void * self)
757 {
758     GL2Encoder *ctx = (GL2Encoder*)self;
759     GLuint program = ctx->m_glCreateProgram_enc(self);
760     if (program!=0)
761         ctx->m_shared->addProgramData(program);
762     return program;
763 }
764 
s_glCreateShader(void * self,GLenum shaderType)765 GLuint GL2Encoder::s_glCreateShader(void *self, GLenum shaderType)
766 {
767     GL2Encoder *ctx = (GL2Encoder*)self;
768     RET_AND_SET_ERROR_IF(((shaderType != GL_VERTEX_SHADER) && (shaderType != GL_FRAGMENT_SHADER)),
769         GL_INVALID_ENUM, 0);
770     GLuint shader = ctx->m_glCreateShader_enc(self, shaderType);
771     if (shader != 0) {
772         if (!ctx->m_shared->addShaderData(shader)) {
773             ctx->m_glDeleteShader_enc(self, shader);
774             return 0;
775         }
776     }
777     return shader;
778 }
779 
s_glGetAttachedShaders(void * self,GLuint program,GLsizei maxCount,GLsizei * count,GLuint * shaders)780 void GL2Encoder::s_glGetAttachedShaders(void *self, GLuint program, GLsizei maxCount,
781         GLsizei* count, GLuint* shaders)
782 {
783     GL2Encoder *ctx = (GL2Encoder*)self;
784     SET_ERROR_IF(maxCount < 0, GL_INVALID_VALUE);
785     ctx->m_glGetAttachedShaders_enc(self, program, maxCount, count, shaders);
786 }
787 
s_glGetShaderSource(void * self,GLuint shader,GLsizei bufsize,GLsizei * length,GLchar * source)788 void GL2Encoder::s_glGetShaderSource(void *self, GLuint shader, GLsizei bufsize,
789             GLsizei* length, GLchar* source)
790 {
791     GL2Encoder *ctx = (GL2Encoder*)self;
792     SET_ERROR_IF(bufsize < 0, GL_INVALID_VALUE);
793     ctx->m_glGetShaderSource_enc(self, shader, bufsize, length, source);
794 }
795 
s_glGetShaderInfoLog(void * self,GLuint shader,GLsizei bufsize,GLsizei * length,GLchar * infolog)796 void GL2Encoder::s_glGetShaderInfoLog(void *self, GLuint shader, GLsizei bufsize,
797         GLsizei* length, GLchar* infolog)
798 {
799     GL2Encoder *ctx = (GL2Encoder*)self;
800     SET_ERROR_IF(bufsize < 0, GL_INVALID_VALUE);
801     ctx->m_glGetShaderInfoLog_enc(self, shader, bufsize, length, infolog);
802 }
803 
s_glGetProgramInfoLog(void * self,GLuint program,GLsizei bufsize,GLsizei * length,GLchar * infolog)804 void GL2Encoder::s_glGetProgramInfoLog(void *self, GLuint program, GLsizei bufsize,
805         GLsizei* length, GLchar* infolog)
806 {
807     GL2Encoder *ctx = (GL2Encoder*)self;
808     SET_ERROR_IF(bufsize < 0, GL_INVALID_VALUE);
809     ctx->m_glGetProgramInfoLog_enc(self, program, bufsize, length, infolog);
810 }
811 
s_glDeleteShader(void * self,GLenum shader)812 void GL2Encoder::s_glDeleteShader(void *self, GLenum shader)
813 {
814     GL2Encoder *ctx = (GL2Encoder*)self;
815     ctx->m_glDeleteShader_enc(self,shader);
816     ctx->m_shared->unrefShaderData(shader);
817 }
818 
s_glAttachShader(void * self,GLuint program,GLuint shader)819 void GL2Encoder::s_glAttachShader(void *self, GLuint program, GLuint shader)
820 {
821     GL2Encoder *ctx = (GL2Encoder*)self;
822     ctx->m_glAttachShader_enc(self, program, shader);
823     ctx->m_shared->attachShader(program, shader);
824 }
825 
s_glDetachShader(void * self,GLuint program,GLuint shader)826 void GL2Encoder::s_glDetachShader(void *self, GLuint program, GLuint shader)
827 {
828     GL2Encoder *ctx = (GL2Encoder*)self;
829     ctx->m_glDetachShader_enc(self, program, shader);
830     ctx->m_shared->detachShader(program, shader);
831 }
832 
s_glGetUniformLocation(void * self,GLuint program,const GLchar * name)833 int GL2Encoder::s_glGetUniformLocation(void *self, GLuint program, const GLchar *name)
834 {
835     if (!name) return -1;
836 
837     GL2Encoder *ctx = (GL2Encoder*)self;
838 
839     // if we need the uniform location WAR
840     // parse array index from the end of the name string
841     int arrIndex = 0;
842     bool needLocationWAR = ctx->m_shared->needUniformLocationWAR(program);
843     if (needLocationWAR) {
844         int namelen = strlen(name);
845         if (name[namelen-1] == ']') {
846             char *brace = strrchr(name,'[');
847             if (!brace || sscanf(brace+1,"%d",&arrIndex) != 1) {
848                 return -1;
849             }
850 
851         }
852     }
853 
854     int hostLoc = ctx->m_glGetUniformLocation_enc(self, program, name);
855     if (hostLoc >= 0 && needLocationWAR) {
856         return ctx->m_shared->locationWARHostToApp(program, hostLoc, arrIndex);
857     }
858     return hostLoc;
859 }
860 
updateHostTexture2DBinding(GLenum texUnit,GLenum newTarget)861 bool GL2Encoder::updateHostTexture2DBinding(GLenum texUnit, GLenum newTarget)
862 {
863     if (newTarget != GL_TEXTURE_2D && newTarget != GL_TEXTURE_EXTERNAL_OES)
864         return false;
865 
866     m_state->setActiveTextureUnit(texUnit);
867 
868     GLenum oldTarget = m_state->getPriorityEnabledTarget(GL_TEXTURE_2D);
869     if (newTarget != oldTarget) {
870         if (newTarget == GL_TEXTURE_EXTERNAL_OES) {
871             m_state->disableTextureTarget(GL_TEXTURE_2D);
872             m_state->enableTextureTarget(GL_TEXTURE_EXTERNAL_OES);
873         } else {
874             m_state->disableTextureTarget(GL_TEXTURE_EXTERNAL_OES);
875             m_state->enableTextureTarget(GL_TEXTURE_2D);
876         }
877         m_glActiveTexture_enc(this, texUnit);
878         m_glBindTexture_enc(this, GL_TEXTURE_2D,
879                 m_state->getBoundTexture(newTarget));
880         return true;
881     }
882 
883     return false;
884 }
885 
s_glUseProgram(void * self,GLuint program)886 void GL2Encoder::s_glUseProgram(void *self, GLuint program)
887 {
888     GL2Encoder *ctx = (GL2Encoder*)self;
889     GLClientState* state = ctx->m_state;
890     GLSharedGroupPtr shared = ctx->m_shared;
891 
892     ctx->m_glUseProgram_enc(self, program);
893     ctx->m_state->setCurrentProgram(program);
894 
895     GLenum origActiveTexture = state->getActiveTextureUnit();
896     GLenum hostActiveTexture = origActiveTexture;
897     GLint samplerIdx = -1;
898     GLint samplerVal;
899     GLenum samplerTarget;
900     while ((samplerIdx = shared->getNextSamplerUniform(program, samplerIdx, &samplerVal, &samplerTarget)) != -1) {
901         if (samplerVal < 0 || samplerVal >= GLClientState::MAX_TEXTURE_UNITS)
902             continue;
903         if (ctx->updateHostTexture2DBinding(GL_TEXTURE0 + samplerVal,
904                 samplerTarget))
905         {
906             hostActiveTexture = GL_TEXTURE0 + samplerVal;
907         }
908     }
909     state->setActiveTextureUnit(origActiveTexture);
910     if (hostActiveTexture != origActiveTexture) {
911         ctx->m_glActiveTexture_enc(self, origActiveTexture);
912     }
913 }
914 
s_glUniform1f(void * self,GLint location,GLfloat x)915 void GL2Encoder::s_glUniform1f(void *self , GLint location, GLfloat x)
916 {
917     GL2Encoder *ctx = (GL2Encoder*)self;
918     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
919     ctx->m_glUniform1f_enc(self, hostLoc, x);
920 }
921 
s_glUniform1fv(void * self,GLint location,GLsizei count,const GLfloat * v)922 void GL2Encoder::s_glUniform1fv(void *self , GLint location, GLsizei count, const GLfloat* v)
923 {
924     GL2Encoder *ctx = (GL2Encoder*)self;
925     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
926     ctx->m_glUniform1fv_enc(self, hostLoc, count, v);
927 }
928 
s_glUniform1i(void * self,GLint location,GLint x)929 void GL2Encoder::s_glUniform1i(void *self , GLint location, GLint x)
930 {
931     GL2Encoder *ctx = (GL2Encoder*)self;
932     GLClientState* state = ctx->m_state;
933     GLSharedGroupPtr shared = ctx->m_shared;
934 
935     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
936     ctx->m_glUniform1i_enc(self, hostLoc, x);
937 
938     GLenum target;
939     if (shared->setSamplerUniform(state->currentProgram(), location, x, &target)) {
940         GLenum origActiveTexture = state->getActiveTextureUnit();
941         if (ctx->updateHostTexture2DBinding(GL_TEXTURE0 + x, target)) {
942             ctx->m_glActiveTexture_enc(self, origActiveTexture);
943         }
944         state->setActiveTextureUnit(origActiveTexture);
945     }
946 }
947 
s_glUniform1iv(void * self,GLint location,GLsizei count,const GLint * v)948 void GL2Encoder::s_glUniform1iv(void *self , GLint location, GLsizei count, const GLint* v)
949 {
950     GL2Encoder *ctx = (GL2Encoder*)self;
951     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
952     ctx->m_glUniform1iv_enc(self, hostLoc, count, v);
953 }
954 
s_glUniform2f(void * self,GLint location,GLfloat x,GLfloat y)955 void GL2Encoder::s_glUniform2f(void *self , GLint location, GLfloat x, GLfloat y)
956 {
957     GL2Encoder *ctx = (GL2Encoder*)self;
958     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
959     ctx->m_glUniform2f_enc(self, hostLoc, x, y);
960 }
961 
s_glUniform2fv(void * self,GLint location,GLsizei count,const GLfloat * v)962 void GL2Encoder::s_glUniform2fv(void *self , GLint location, GLsizei count, const GLfloat* v)
963 {
964     GL2Encoder *ctx = (GL2Encoder*)self;
965     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
966     ctx->m_glUniform2fv_enc(self, hostLoc, count, v);
967 }
968 
s_glUniform2i(void * self,GLint location,GLint x,GLint y)969 void GL2Encoder::s_glUniform2i(void *self , GLint location, GLint x, GLint y)
970 {
971     GL2Encoder *ctx = (GL2Encoder*)self;
972     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
973     ctx->m_glUniform2i_enc(self, hostLoc, x, y);
974 }
975 
s_glUniform2iv(void * self,GLint location,GLsizei count,const GLint * v)976 void GL2Encoder::s_glUniform2iv(void *self , GLint location, GLsizei count, const GLint* v)
977 {
978     GL2Encoder *ctx = (GL2Encoder*)self;
979     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
980     ctx->m_glUniform2iv_enc(self, hostLoc, count, v);
981 }
982 
s_glUniform3f(void * self,GLint location,GLfloat x,GLfloat y,GLfloat z)983 void GL2Encoder::s_glUniform3f(void *self , GLint location, GLfloat x, GLfloat y, GLfloat z)
984 {
985     GL2Encoder *ctx = (GL2Encoder*)self;
986     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
987     ctx->m_glUniform3f_enc(self, hostLoc, x, y, z);
988 }
989 
s_glUniform3fv(void * self,GLint location,GLsizei count,const GLfloat * v)990 void GL2Encoder::s_glUniform3fv(void *self , GLint location, GLsizei count, const GLfloat* v)
991 {
992     GL2Encoder *ctx = (GL2Encoder*)self;
993     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
994     ctx->m_glUniform3fv_enc(self, hostLoc, count, v);
995 }
996 
s_glUniform3i(void * self,GLint location,GLint x,GLint y,GLint z)997 void GL2Encoder::s_glUniform3i(void *self , GLint location, GLint x, GLint y, GLint z)
998 {
999     GL2Encoder *ctx = (GL2Encoder*)self;
1000     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
1001     ctx->m_glUniform3i_enc(self, hostLoc, x, y, z);
1002 }
1003 
s_glUniform3iv(void * self,GLint location,GLsizei count,const GLint * v)1004 void GL2Encoder::s_glUniform3iv(void *self , GLint location, GLsizei count, const GLint* v)
1005 {
1006     GL2Encoder *ctx = (GL2Encoder*)self;
1007     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
1008     ctx->m_glUniform3iv_enc(self, hostLoc, count, v);
1009 }
1010 
s_glUniform4f(void * self,GLint location,GLfloat x,GLfloat y,GLfloat z,GLfloat w)1011 void GL2Encoder::s_glUniform4f(void *self , GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
1012 {
1013     GL2Encoder *ctx = (GL2Encoder*)self;
1014     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
1015     ctx->m_glUniform4f_enc(self, hostLoc, x, y, z, w);
1016 }
1017 
s_glUniform4fv(void * self,GLint location,GLsizei count,const GLfloat * v)1018 void GL2Encoder::s_glUniform4fv(void *self , GLint location, GLsizei count, const GLfloat* v)
1019 {
1020     GL2Encoder *ctx = (GL2Encoder*)self;
1021     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
1022     ctx->m_glUniform4fv_enc(self, hostLoc, count, v);
1023 }
1024 
s_glUniform4i(void * self,GLint location,GLint x,GLint y,GLint z,GLint w)1025 void GL2Encoder::s_glUniform4i(void *self , GLint location, GLint x, GLint y, GLint z, GLint w)
1026 {
1027     GL2Encoder *ctx = (GL2Encoder*)self;
1028     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
1029     ctx->m_glUniform4i_enc(self, hostLoc, x, y, z, w);
1030 }
1031 
s_glUniform4iv(void * self,GLint location,GLsizei count,const GLint * v)1032 void GL2Encoder::s_glUniform4iv(void *self , GLint location, GLsizei count, const GLint* v)
1033 {
1034     GL2Encoder *ctx = (GL2Encoder*)self;
1035     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
1036     ctx->m_glUniform4iv_enc(self, hostLoc, count, v);
1037 }
1038 
s_glUniformMatrix2fv(void * self,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)1039 void GL2Encoder::s_glUniformMatrix2fv(void *self , GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
1040 {
1041     GL2Encoder *ctx = (GL2Encoder*)self;
1042     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
1043     ctx->m_glUniformMatrix2fv_enc(self, hostLoc, count, transpose, value);
1044 }
1045 
s_glUniformMatrix3fv(void * self,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)1046 void GL2Encoder::s_glUniformMatrix3fv(void *self , GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
1047 {
1048     GL2Encoder *ctx = (GL2Encoder*)self;
1049     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
1050     ctx->m_glUniformMatrix3fv_enc(self, hostLoc, count, transpose, value);
1051 }
1052 
s_glUniformMatrix4fv(void * self,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)1053 void GL2Encoder::s_glUniformMatrix4fv(void *self , GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
1054 {
1055     GL2Encoder *ctx = (GL2Encoder*)self;
1056     GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
1057     ctx->m_glUniformMatrix4fv_enc(self, hostLoc, count, transpose, value);
1058 }
1059 
s_glActiveTexture(void * self,GLenum texture)1060 void GL2Encoder::s_glActiveTexture(void* self, GLenum texture)
1061 {
1062     GL2Encoder* ctx = (GL2Encoder*)self;
1063     GLClientState* state = ctx->m_state;
1064     GLenum err;
1065 
1066     SET_ERROR_IF((err = state->setActiveTextureUnit(texture)) != GL_NO_ERROR, err);
1067 
1068     ctx->m_glActiveTexture_enc(ctx, texture);
1069 }
1070 
s_glBindTexture(void * self,GLenum target,GLuint texture)1071 void GL2Encoder::s_glBindTexture(void* self, GLenum target, GLuint texture)
1072 {
1073     GL2Encoder* ctx = (GL2Encoder*)self;
1074     GLClientState* state = ctx->m_state;
1075     GLenum err;
1076     GLboolean firstUse;
1077 
1078     SET_ERROR_IF((err = state->bindTexture(target, texture, &firstUse)) != GL_NO_ERROR, err);
1079 
1080     if (target != GL_TEXTURE_2D && target != GL_TEXTURE_EXTERNAL_OES) {
1081         ctx->m_glBindTexture_enc(ctx, target, texture);
1082         return;
1083     }
1084 
1085     GLenum priorityTarget = state->getPriorityEnabledTarget(GL_TEXTURE_2D);
1086 
1087     if (target == GL_TEXTURE_EXTERNAL_OES && firstUse) {
1088         ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D, texture);
1089         ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D,
1090                 GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1091         ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D,
1092                 GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1093         ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D,
1094                 GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1095 
1096         if (target != priorityTarget) {
1097             ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D,
1098                     state->getBoundTexture(GL_TEXTURE_2D));
1099         }
1100     }
1101 
1102     if (target == priorityTarget) {
1103         ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D, texture);
1104     }
1105 }
1106 
s_glDeleteTextures(void * self,GLsizei n,const GLuint * textures)1107 void GL2Encoder::s_glDeleteTextures(void* self, GLsizei n, const GLuint* textures)
1108 {
1109     GL2Encoder* ctx = (GL2Encoder*)self;
1110     GLClientState* state = ctx->m_state;
1111 
1112     state->deleteTextures(n, textures);
1113     ctx->m_glDeleteTextures_enc(ctx, n, textures);
1114 }
1115 
s_glGetTexParameterfv(void * self,GLenum target,GLenum pname,GLfloat * params)1116 void GL2Encoder::s_glGetTexParameterfv(void* self,
1117         GLenum target, GLenum pname, GLfloat* params)
1118 {
1119     GL2Encoder* ctx = (GL2Encoder*)self;
1120     const GLClientState* state = ctx->m_state;
1121 
1122     if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
1123         ctx->override2DTextureTarget(target);
1124         ctx->m_glGetTexParameterfv_enc(ctx, GL_TEXTURE_2D, pname, params);
1125         ctx->restore2DTextureTarget();
1126     } else {
1127         ctx->m_glGetTexParameterfv_enc(ctx, target, pname, params);
1128     }
1129 }
1130 
s_glGetTexParameteriv(void * self,GLenum target,GLenum pname,GLint * params)1131 void GL2Encoder::s_glGetTexParameteriv(void* self,
1132         GLenum target, GLenum pname, GLint* params)
1133 {
1134     GL2Encoder* ctx = (GL2Encoder*)self;
1135     const GLClientState* state = ctx->m_state;
1136 
1137     switch (pname) {
1138     case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
1139         *params = 1;
1140         break;
1141 
1142     default:
1143         if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
1144             ctx->override2DTextureTarget(target);
1145             ctx->m_glGetTexParameteriv_enc(ctx, GL_TEXTURE_2D, pname, params);
1146             ctx->restore2DTextureTarget();
1147         } else {
1148             ctx->m_glGetTexParameteriv_enc(ctx, target, pname, params);
1149         }
1150         break;
1151     }
1152 }
1153 
isValidTextureExternalParam(GLenum pname,GLenum param)1154 static bool isValidTextureExternalParam(GLenum pname, GLenum param)
1155 {
1156     switch (pname) {
1157     case GL_TEXTURE_MIN_FILTER:
1158     case GL_TEXTURE_MAG_FILTER:
1159         return param == GL_NEAREST || param == GL_LINEAR;
1160 
1161     case GL_TEXTURE_WRAP_S:
1162     case GL_TEXTURE_WRAP_T:
1163         return param == GL_CLAMP_TO_EDGE;
1164 
1165     default:
1166         return true;
1167     }
1168 }
1169 
s_glTexParameterf(void * self,GLenum target,GLenum pname,GLfloat param)1170 void GL2Encoder::s_glTexParameterf(void* self,
1171         GLenum target, GLenum pname, GLfloat param)
1172 {
1173     GL2Encoder* ctx = (GL2Encoder*)self;
1174     const GLClientState* state = ctx->m_state;
1175 
1176     SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
1177             !isValidTextureExternalParam(pname, (GLenum)param)),
1178             GL_INVALID_ENUM);
1179 
1180     if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
1181         ctx->override2DTextureTarget(target);
1182         ctx->m_glTexParameterf_enc(ctx, GL_TEXTURE_2D, pname, param);
1183         ctx->restore2DTextureTarget();
1184     } else {
1185         ctx->m_glTexParameterf_enc(ctx, target, pname, param);
1186     }
1187 }
1188 
s_glTexParameterfv(void * self,GLenum target,GLenum pname,const GLfloat * params)1189 void GL2Encoder::s_glTexParameterfv(void* self,
1190         GLenum target, GLenum pname, const GLfloat* params)
1191 {
1192     GL2Encoder* ctx = (GL2Encoder*)self;
1193     const GLClientState* state = ctx->m_state;
1194 
1195     SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
1196             !isValidTextureExternalParam(pname, (GLenum)params[0])),
1197             GL_INVALID_ENUM);
1198 
1199     if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
1200         ctx->override2DTextureTarget(target);
1201         ctx->m_glTexParameterfv_enc(ctx, GL_TEXTURE_2D, pname, params);
1202         ctx->restore2DTextureTarget();
1203     } else {
1204         ctx->m_glTexParameterfv_enc(ctx, target, pname, params);
1205     }
1206 }
1207 
s_glTexParameteri(void * self,GLenum target,GLenum pname,GLint param)1208 void GL2Encoder::s_glTexParameteri(void* self,
1209         GLenum target, GLenum pname, GLint param)
1210 {
1211     GL2Encoder* ctx = (GL2Encoder*)self;
1212     const GLClientState* state = ctx->m_state;
1213 
1214     SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
1215             !isValidTextureExternalParam(pname, (GLenum)param)),
1216             GL_INVALID_ENUM);
1217 
1218     if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
1219         ctx->override2DTextureTarget(target);
1220         ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D, pname, param);
1221         ctx->restore2DTextureTarget();
1222     } else {
1223         ctx->m_glTexParameteri_enc(ctx, target, pname, param);
1224     }
1225 }
1226 
s_glTexImage2D(void * self,GLenum target,GLint level,GLint internalformat,GLsizei width,GLsizei height,GLint border,GLenum format,GLenum type,const GLvoid * pixels)1227 void GL2Encoder::s_glTexImage2D(void* self, GLenum target, GLint level,
1228         GLint internalformat, GLsizei width, GLsizei height, GLint border,
1229         GLenum format, GLenum type, const GLvoid* pixels)
1230 {
1231     GL2Encoder* ctx = (GL2Encoder*)self;
1232     if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
1233         ctx->override2DTextureTarget(target);
1234         ctx->m_glTexImage2D_enc(ctx, target, level, internalformat, width,
1235                 height, border, format, type, pixels);
1236         ctx->restore2DTextureTarget();
1237     } else {
1238         ctx->m_glTexImage2D_enc(ctx, target, level, internalformat, width,
1239                 height, border, format, type, pixels);
1240     }
1241 }
1242 
1243 
s_glTexParameteriv(void * self,GLenum target,GLenum pname,const GLint * params)1244 void GL2Encoder::s_glTexParameteriv(void* self,
1245         GLenum target, GLenum pname, const GLint* params)
1246 {
1247     GL2Encoder* ctx = (GL2Encoder*)self;
1248     const GLClientState* state = ctx->m_state;
1249 
1250     SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
1251             !isValidTextureExternalParam(pname, (GLenum)params[0])),
1252             GL_INVALID_ENUM);
1253 
1254     if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
1255         ctx->override2DTextureTarget(target);
1256         ctx->m_glTexParameteriv_enc(ctx, GL_TEXTURE_2D, pname, params);
1257         ctx->restore2DTextureTarget();
1258     } else {
1259         ctx->m_glTexParameteriv_enc(ctx, target, pname, params);
1260     }
1261 }
1262 
override2DTextureTarget(GLenum target)1263 void GL2Encoder::override2DTextureTarget(GLenum target)
1264 {
1265     if ((target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) &&
1266         target != m_state->getPriorityEnabledTarget(GL_TEXTURE_2D)) {
1267             m_glBindTexture_enc(this, GL_TEXTURE_2D,
1268                     m_state->getBoundTexture(target));
1269     }
1270 }
1271 
restore2DTextureTarget()1272 void GL2Encoder::restore2DTextureTarget()
1273 {
1274     GLenum priorityTarget = m_state->getPriorityEnabledTarget(GL_TEXTURE_2D);
1275     m_glBindTexture_enc(this, GL_TEXTURE_2D,
1276             m_state->getBoundTexture(priorityTarget));
1277 }
1278