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