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