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