blob: 6c84e82bede7322585f71b6fa35a8524a13dc8d5 [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
Lingfeng Yangb0176982016-03-01 21:27:49 -0800274 case GL_MAX_VERTEX_ATTRIBS:
275 if (!ctx->m_state->getClientStateParameter<GLint>(param, ptr)) {
276 ctx->m_glGetIntegerv_enc(self, param, ptr);
277 ctx->m_state->setMaxVertexAttribs(*ptr);
278 }
279 break;
keunyoungb85b2752013-03-08 12:28:03 -0800280 default:
281 if (!ctx->m_state->getClientStateParameter<GLint>(param, ptr)) {
282 ctx->m_glGetIntegerv_enc(self, param, ptr);
283 }
284 break;
285 }
286}
287
288
289void GL2Encoder::s_glGetFloatv(void *self, GLenum param, GLfloat *ptr)
290{
291 GL2Encoder *ctx = (GL2Encoder *)self;
292 assert(ctx->m_state != NULL);
293 GLClientState* state = ctx->m_state;
294
295 switch (param) {
296 case GL_NUM_SHADER_BINARY_FORMATS:
297 *ptr = 0;
298 break;
299 case GL_SHADER_BINARY_FORMATS:
300 // do nothing
301 break;
302
303 case GL_COMPRESSED_TEXTURE_FORMATS: {
304 GLint *compressedTextureFormats = ctx->getCompressedTextureFormats();
305 if (ctx->m_num_compressedTextureFormats > 0 &&
306 compressedTextureFormats != NULL) {
307 for (int i = 0; i < ctx->m_num_compressedTextureFormats; i++) {
308 ptr[i] = (GLfloat) compressedTextureFormats[i];
309 }
310 }
311 break;
312 }
313
314 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
315 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
316 case GL_MAX_TEXTURE_IMAGE_UNITS:
317 ctx->m_glGetFloatv_enc(self, param, ptr);
318 *ptr = MIN(*ptr, (GLfloat)GLClientState::MAX_TEXTURE_UNITS);
319 break;
320
321 case GL_TEXTURE_BINDING_2D:
322 *ptr = (GLfloat)state->getBoundTexture(GL_TEXTURE_2D);
323 break;
324 case GL_TEXTURE_BINDING_EXTERNAL_OES:
325 *ptr = (GLfloat)state->getBoundTexture(GL_TEXTURE_EXTERNAL_OES);
326 break;
327
328 default:
329 if (!ctx->m_state->getClientStateParameter<GLfloat>(param, ptr)) {
330 ctx->m_glGetFloatv_enc(self, param, ptr);
331 }
332 break;
333 }
334}
335
336
337void GL2Encoder::s_glGetBooleanv(void *self, GLenum param, GLboolean *ptr)
338{
339 GL2Encoder *ctx = (GL2Encoder *)self;
340 assert(ctx->m_state != NULL);
341 GLClientState* state = ctx->m_state;
342
343 switch (param) {
344 case GL_NUM_SHADER_BINARY_FORMATS:
345 *ptr = GL_FALSE;
346 break;
347 case GL_SHADER_BINARY_FORMATS:
348 // do nothing
349 break;
350
351 case GL_COMPRESSED_TEXTURE_FORMATS: {
352 GLint *compressedTextureFormats = ctx->getCompressedTextureFormats();
353 if (ctx->m_num_compressedTextureFormats > 0 &&
354 compressedTextureFormats != NULL) {
355 for (int i = 0; i < ctx->m_num_compressedTextureFormats; i++) {
356 ptr[i] = compressedTextureFormats[i] != 0 ? GL_TRUE : GL_FALSE;
357 }
358 }
359 break;
360 }
361
362 case GL_TEXTURE_BINDING_2D:
363 *ptr = state->getBoundTexture(GL_TEXTURE_2D) != 0 ? GL_TRUE : GL_FALSE;
364 break;
365 case GL_TEXTURE_BINDING_EXTERNAL_OES:
366 *ptr = state->getBoundTexture(GL_TEXTURE_EXTERNAL_OES) != 0
367 ? GL_TRUE : GL_FALSE;
368 break;
369
370 default:
371 if (!ctx->m_state->getClientStateParameter<GLboolean>(param, ptr)) {
372 ctx->m_glGetBooleanv_enc(self, param, ptr);
373 }
bohu05101d22014-11-17 16:28:42 -0800374 *ptr = (*ptr != 0) ? GL_TRUE : GL_FALSE;
keunyoungb85b2752013-03-08 12:28:03 -0800375 break;
376 }
377}
378
379
380void GL2Encoder::s_glEnableVertexAttribArray(void *self, GLuint index)
381{
382 GL2Encoder *ctx = (GL2Encoder *)self;
383 assert(ctx->m_state);
384 ctx->m_state->enable(index, 1);
385}
386
387void GL2Encoder::s_glDisableVertexAttribArray(void *self, GLuint index)
388{
389 GL2Encoder *ctx = (GL2Encoder *)self;
390 assert(ctx->m_state);
391 ctx->m_state->enable(index, 0);
392}
393
394
395void GL2Encoder::s_glGetVertexAttribiv(void *self, GLuint index, GLenum pname, GLint *params)
396{
397 GL2Encoder *ctx = (GL2Encoder *)self;
398 assert(ctx->m_state);
399
400 if (!ctx->m_state->getVertexAttribParameter<GLint>(index, pname, params)) {
401 ctx->m_glGetVertexAttribiv_enc(self, index, pname, params);
402 }
403}
404
405void GL2Encoder::s_glGetVertexAttribfv(void *self, GLuint index, GLenum pname, GLfloat *params)
406{
407 GL2Encoder *ctx = (GL2Encoder *)self;
408 assert(ctx->m_state);
409
410 if (!ctx->m_state->getVertexAttribParameter<GLfloat>(index, pname, params)) {
411 ctx->m_glGetVertexAttribfv_enc(self, index, pname, params);
412 }
413}
414
415void GL2Encoder::s_glGetVertexAttribPointerv(void *self, GLuint index, GLenum pname, GLvoid **pointer)
416{
417 GL2Encoder *ctx = (GL2Encoder *)self;
418 if (ctx->m_state == NULL) return;
419
David 'Digit' Turnere01d5f42014-10-30 21:32:28 +0100420 (void)pname;
421
keunyoungb85b2752013-03-08 12:28:03 -0800422 const GLClientState::VertexAttribState *va_state = ctx->m_state->getState(index);
423 if (va_state != NULL) {
424 *pointer = va_state->data;
425 }
426}
427
428
429void GL2Encoder::sendVertexAttributes(GLint first, GLsizei count)
430{
431 assert(m_state);
432
433 for (int i = 0; i < m_state->nLocations(); i++) {
434 bool enableDirty;
435 const GLClientState::VertexAttribState *state = m_state->getStateAndEnableDirty(i, &enableDirty);
436
437 if (!state) {
438 continue;
439 }
440
441 if (!enableDirty && !state->enabled) {
442 continue;
443 }
444
445
446 if (state->enabled) {
447 m_glEnableVertexAttribArray_enc(this, i);
448
449 unsigned int datalen = state->elementSize * count;
450 int stride = state->stride == 0 ? state->elementSize : state->stride;
451 int firstIndex = stride * first;
452
bohu52371ec2014-10-13 11:45:06 -0700453 this->m_glBindBuffer_enc(this, GL_ARRAY_BUFFER, state->bufferObject);
keunyoungb85b2752013-03-08 12:28:03 -0800454 if (state->bufferObject == 0) {
455 this->glVertexAttribPointerData(this, i, state->size, state->type, state->normalized, state->stride,
456 (unsigned char *)state->data + firstIndex, datalen);
457 } else {
keunyoungb85b2752013-03-08 12:28:03 -0800458 this->glVertexAttribPointerOffset(this, i, state->size, state->type, state->normalized, state->stride,
Tina Zhang163119f2014-03-21 08:14:41 +0800459 (uintptr_t) state->data + firstIndex);
keunyoungb85b2752013-03-08 12:28:03 -0800460 }
bohu52371ec2014-10-13 11:45:06 -0700461 this->m_glBindBuffer_enc(this, GL_ARRAY_BUFFER, m_state->currentArrayVbo());
keunyoungb85b2752013-03-08 12:28:03 -0800462 } else {
463 this->m_glDisableVertexAttribArray_enc(this, i);
464 }
465 }
466}
467
468void GL2Encoder::s_glDrawArrays(void *self, GLenum mode, GLint first, GLsizei count)
469{
470 GL2Encoder *ctx = (GL2Encoder *)self;
Yahan Zhoud6217a52016-02-10 16:10:46 -0800471
472 bool has_arrays = false;
473 int nLocations = ctx->m_state->nLocations();
474 for (int i = 0; i < nLocations; i++) {
475 const GLClientState::VertexAttribState *state = ctx->m_state->getState(i);
476 if (state->enabled) {
477 if (state->bufferObject || state->data) {
478 has_arrays = true;
479 }
480 else {
481 ALOGE("glDrawArrays: a vertex attribute array is enabled with no data bound\n");
482 ctx->setError(GL_INVALID_OPERATION);
483 return;
484 }
485 }
486 }
487 if (!has_arrays) {
488 ALOGE("glDrawArrays: no data bound to the command - ignoring\n");
489 return;
490 }
491
keunyoungb85b2752013-03-08 12:28:03 -0800492 ctx->sendVertexAttributes(first, count);
493 ctx->m_glDrawArrays_enc(ctx, mode, 0, count);
494}
495
496
497void GL2Encoder::s_glDrawElements(void *self, GLenum mode, GLsizei count, GLenum type, const void *indices)
498{
499
500 GL2Encoder *ctx = (GL2Encoder *)self;
501 assert(ctx->m_state != NULL);
502 SET_ERROR_IF(count<0, GL_INVALID_VALUE);
503
504 bool has_immediate_arrays = false;
505 bool has_indirect_arrays = false;
506 int nLocations = ctx->m_state->nLocations();
507
508 for (int i = 0; i < nLocations; i++) {
509 const GLClientState::VertexAttribState *state = ctx->m_state->getState(i);
510 if (state->enabled) {
511 if (state->bufferObject != 0) {
512 has_indirect_arrays = true;
Yahan Zhoud6217a52016-02-10 16:10:46 -0800513 } else if (state->data) {
keunyoungb85b2752013-03-08 12:28:03 -0800514 has_immediate_arrays = true;
Yahan Zhoud6217a52016-02-10 16:10:46 -0800515 } else {
516 ALOGW("glDrawElements: a vertex attribute array is enabled with no data bound\n");
517 ctx->setError(GL_INVALID_OPERATION);
518 return;
keunyoungb85b2752013-03-08 12:28:03 -0800519 }
520 }
521 }
522
523 if (!has_immediate_arrays && !has_indirect_arrays) {
524 ALOGE("glDrawElements: no data bound to the command - ignoring\n");
525 return;
526 }
527
528 bool adjustIndices = true;
529 if (ctx->m_state->currentIndexVbo() != 0) {
530 if (!has_immediate_arrays) {
531 ctx->sendVertexAttributes(0, count);
532 ctx->m_glBindBuffer_enc(self, GL_ELEMENT_ARRAY_BUFFER, ctx->m_state->currentIndexVbo());
Tina Zhang163119f2014-03-21 08:14:41 +0800533 ctx->glDrawElementsOffset(ctx, mode, count, type, (uintptr_t)indices);
keunyoungb85b2752013-03-08 12:28:03 -0800534 adjustIndices = false;
535 } else {
536 BufferData * buf = ctx->m_shared->getBufferData(ctx->m_state->currentIndexVbo());
537 ctx->m_glBindBuffer_enc(self, GL_ELEMENT_ARRAY_BUFFER, 0);
538 indices = (void*)((GLintptr)buf->m_fixedBuffer.ptr() + (GLintptr)indices);
539 }
540 }
541 if (adjustIndices) {
542 void *adjustedIndices = (void*)indices;
543 int minIndex = 0, maxIndex = 0;
544
545 switch(type) {
546 case GL_BYTE:
547 case GL_UNSIGNED_BYTE:
548 GLUtils::minmax<unsigned char>((unsigned char *)indices, count, &minIndex, &maxIndex);
549 if (minIndex != 0) {
550 adjustedIndices = ctx->m_fixedBuffer.alloc(glSizeof(type) * count);
551 GLUtils::shiftIndices<unsigned char>((unsigned char *)indices,
552 (unsigned char *)adjustedIndices,
553 count, -minIndex);
554 }
555 break;
556 case GL_SHORT:
557 case GL_UNSIGNED_SHORT:
558 GLUtils::minmax<unsigned short>((unsigned short *)indices, count, &minIndex, &maxIndex);
559 if (minIndex != 0) {
560 adjustedIndices = ctx->m_fixedBuffer.alloc(glSizeof(type) * count);
561 GLUtils::shiftIndices<unsigned short>((unsigned short *)indices,
562 (unsigned short *)adjustedIndices,
563 count, -minIndex);
564 }
565 break;
Yahan Zhou59508522016-02-09 17:42:33 -0800566 case GL_INT:
567 case GL_UNSIGNED_INT:
568 GLUtils::minmax<unsigned int>((unsigned int *)indices, count, &minIndex, &maxIndex);
569 if (minIndex != 0) {
570 adjustedIndices = ctx->m_fixedBuffer.alloc(glSizeof(type) * count);
571 GLUtils::shiftIndices<unsigned int>((unsigned int *)indices,
572 (unsigned int *)adjustedIndices,
573 count, -minIndex);
574 }
575 break;
keunyoungb85b2752013-03-08 12:28:03 -0800576 default:
577 ALOGE("unsupported index buffer type %d\n", type);
578 }
579 if (has_indirect_arrays || 1) {
580 ctx->sendVertexAttributes(minIndex, maxIndex - minIndex + 1);
581 ctx->glDrawElementsData(ctx, mode, count, type, adjustedIndices,
582 count * glSizeof(type));
583 // XXX - OPTIMIZATION (see the other else branch) should be implemented
584 if(!has_indirect_arrays) {
585 //ALOGD("unoptimized drawelements !!!\n");
586 }
587 } else {
588 // we are all direct arrays and immidate mode index array -
589 // rebuild the arrays and the index array;
590 ALOGE("glDrawElements: direct index & direct buffer data - will be implemented in later versions;\n");
591 }
592 }
593}
594
595
596GLint * GL2Encoder::getCompressedTextureFormats()
597{
598 if (m_compressedTextureFormats == NULL) {
599 this->glGetIntegerv(this, GL_NUM_COMPRESSED_TEXTURE_FORMATS,
600 &m_num_compressedTextureFormats);
601 if (m_num_compressedTextureFormats > 0) {
602 // get number of texture formats;
603 m_compressedTextureFormats = new GLint[m_num_compressedTextureFormats];
604 this->glGetCompressedTextureFormats(this, m_num_compressedTextureFormats, m_compressedTextureFormats);
605 }
606 }
607 return m_compressedTextureFormats;
608}
609
610// Replace uses of samplerExternalOES with sampler2D, recording the names of
611// modified shaders in data. Also remove
612// #extension GL_OES_EGL_image_external : require
613// statements.
614//
615// This implementation assumes the input has already been pre-processed. If not,
616// a few cases will be mishandled:
617//
618// 1. "mySampler" will be incorrectly recorded as being a samplerExternalOES in
619// the following code:
620// #if 1
621// uniform sampler2D mySampler;
622// #else
623// uniform samplerExternalOES mySampler;
624// #endif
625//
626// 2. Comments that look like sampler declarations will be incorrectly modified
627// and recorded:
628// // samplerExternalOES hahaFooledYou
629//
630// 3. However, GLSL ES does not have a concatentation operator, so things like
631// this (valid in C) are invalid and not a problem:
632// #define SAMPLER(TYPE, NAME) uniform sampler#TYPE NAME
633// SAMPLER(ExternalOES, mySampler);
634//
635static bool replaceSamplerExternalWith2D(char* const str, ShaderData* const data)
636{
637 static const char STR_HASH_EXTENSION[] = "#extension";
638 static const char STR_GL_OES_EGL_IMAGE_EXTERNAL[] = "GL_OES_EGL_image_external";
639 static const char STR_SAMPLER_EXTERNAL_OES[] = "samplerExternalOES";
640 static const char STR_SAMPLER2D_SPACE[] = "sampler2D ";
641
642 // -- overwrite all "#extension GL_OES_EGL_image_external : xxx" statements
643 char* c = str;
644 while ((c = strstr(c, STR_HASH_EXTENSION))) {
645 char* start = c;
646 c += sizeof(STR_HASH_EXTENSION)-1;
647 while (isspace(*c) && *c != '\0') {
648 c++;
649 }
650 if (strncmp(c, STR_GL_OES_EGL_IMAGE_EXTERNAL,
651 sizeof(STR_GL_OES_EGL_IMAGE_EXTERNAL)-1) == 0)
652 {
653 // #extension statements are terminated by end of line
654 c = start;
655 while (*c != '\0' && *c != '\r' && *c != '\n') {
656 *c++ = ' ';
657 }
658 }
659 }
660
661 // -- replace "samplerExternalOES" with "sampler2D" and record name
662 c = str;
663 while ((c = strstr(c, STR_SAMPLER_EXTERNAL_OES))) {
664 // Make sure "samplerExternalOES" isn't a substring of a larger token
665 if (c == str || !isspace(*(c-1))) {
666 c++;
667 continue;
668 }
669 char* sampler_start = c;
670 c += sizeof(STR_SAMPLER_EXTERNAL_OES)-1;
671 if (!isspace(*c) && *c != '\0') {
672 continue;
673 }
674
675 // capture sampler name
676 while (isspace(*c) && *c != '\0') {
677 c++;
678 }
679 if (!isalpha(*c) && *c != '_') {
680 // not an identifier
681 return false;
682 }
683 char* name_start = c;
684 do {
685 c++;
686 } while (isalnum(*c) || *c == '_');
687 data->samplerExternalNames.push_back(
688 android::String8(name_start, c - name_start));
689
690 // memcpy instead of strcpy since we don't want the NUL terminator
691 memcpy(sampler_start, STR_SAMPLER2D_SPACE, sizeof(STR_SAMPLER2D_SPACE)-1);
692 }
693
694 return true;
695}
696
Bo Hu73568cd2015-01-20 16:29:50 -0800697void GL2Encoder::s_glShaderBinary(void *self, GLsizei n, const GLuint *shaders, GLenum binaryformat, const void* binary, GLsizei length)
698{
699 GL2Encoder* ctx = (GL2Encoder*)self;
700 // Although it is not supported, need to set proper error code.
701 SET_ERROR_IF(1, GL_INVALID_ENUM);
702}
703
David 'Digit' Turner02fdb692014-10-30 18:07:56 +0100704void GL2Encoder::s_glShaderSource(void *self, GLuint shader, GLsizei count, const GLchar * const *string, const GLint *length)
keunyoungb85b2752013-03-08 12:28:03 -0800705{
706 GL2Encoder* ctx = (GL2Encoder*)self;
707 ShaderData* shaderData = ctx->m_shared->getShaderData(shader);
Tina Zhang7a84f652014-12-04 12:37:30 +0800708 SET_ERROR_IF(!ctx->m_shared->isObject(shader), GL_INVALID_VALUE);
709 SET_ERROR_IF(!shaderData, GL_INVALID_OPERATION);
710 SET_ERROR_IF((count<0), GL_INVALID_VALUE);
keunyoungb85b2752013-03-08 12:28:03 -0800711
712 int len = glUtilsCalcShaderSourceLen((char**)string, (GLint*)length, count);
713 char *str = new char[len + 1];
714 glUtilsPackStrings(str, (char**)string, (GLint*)length, count);
715
716 // TODO: pre-process str before calling replaceSamplerExternalWith2D().
717 // Perhaps we can borrow Mesa's pre-processor?
718
719 if (!replaceSamplerExternalWith2D(str, shaderData)) {
720 delete str;
721 ctx->setError(GL_OUT_OF_MEMORY);
722 return;
723 }
724
725 ctx->glShaderString(ctx, shader, str, len + 1);
726 delete str;
727}
728
729void GL2Encoder::s_glFinish(void *self)
730{
731 GL2Encoder *ctx = (GL2Encoder *)self;
732 ctx->glFinishRoundTrip(self);
733}
734
735void GL2Encoder::s_glLinkProgram(void * self, GLuint program)
736{
737 GL2Encoder *ctx = (GL2Encoder *)self;
738 ctx->m_glLinkProgram_enc(self, program);
739
740 GLint linkStatus = 0;
741 ctx->glGetProgramiv(self,program,GL_LINK_STATUS,&linkStatus);
742 if (!linkStatus)
743 return;
744
745 //get number of active uniforms in the program
746 GLint numUniforms=0;
747 ctx->glGetProgramiv(self, program, GL_ACTIVE_UNIFORMS, &numUniforms);
748 ctx->m_shared->initProgramData(program,numUniforms);
749
750 //get the length of the longest uniform name
751 GLint maxLength=0;
752 ctx->glGetProgramiv(self, program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxLength);
753
754 GLint size;
755 GLenum type;
756 GLchar *name = new GLchar[maxLength+1];
757 GLint location;
758 //for each active uniform, get its size and starting location.
759 for (GLint i=0 ; i<numUniforms ; ++i)
760 {
761 ctx->glGetActiveUniform(self, program, i, maxLength, NULL, &size, &type, name);
762 location = ctx->m_glGetUniformLocation_enc(self, program, name);
763 ctx->m_shared->setProgramIndexInfo(program, i, location, size, type, name);
764 }
765 ctx->m_shared->setupLocationShiftWAR(program);
766
767 delete[] name;
768}
769
770void GL2Encoder::s_glDeleteProgram(void *self, GLuint program)
771{
772 GL2Encoder *ctx = (GL2Encoder*)self;
773 ctx->m_glDeleteProgram_enc(self, program);
774
775 ctx->m_shared->deleteProgramData(program);
776}
777
778void GL2Encoder::s_glGetUniformiv(void *self, GLuint program, GLint location, GLint* params)
779{
780 GL2Encoder *ctx = (GL2Encoder*)self;
781 SET_ERROR_IF(!ctx->m_shared->isProgram(program), GL_INVALID_VALUE);
782 SET_ERROR_IF(!ctx->m_shared->isProgramInitialized(program), GL_INVALID_OPERATION);
783 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
784 SET_ERROR_IF(ctx->m_shared->getProgramUniformType(program,hostLoc)==0, GL_INVALID_OPERATION);
785 ctx->m_glGetUniformiv_enc(self, program, hostLoc, params);
786}
787void GL2Encoder::s_glGetUniformfv(void *self, GLuint program, GLint location, GLfloat* params)
788{
789 GL2Encoder *ctx = (GL2Encoder*)self;
790 SET_ERROR_IF(!ctx->m_shared->isProgram(program), GL_INVALID_VALUE);
791 SET_ERROR_IF(!ctx->m_shared->isProgramInitialized(program), GL_INVALID_OPERATION);
792 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program,location);
793 SET_ERROR_IF(ctx->m_shared->getProgramUniformType(program,hostLoc)==0, GL_INVALID_OPERATION);
794 ctx->m_glGetUniformfv_enc(self, program, hostLoc, params);
795}
796
797GLuint GL2Encoder::s_glCreateProgram(void * self)
798{
799 GL2Encoder *ctx = (GL2Encoder*)self;
800 GLuint program = ctx->m_glCreateProgram_enc(self);
801 if (program!=0)
802 ctx->m_shared->addProgramData(program);
803 return program;
804}
805
806GLuint GL2Encoder::s_glCreateShader(void *self, GLenum shaderType)
807{
808 GL2Encoder *ctx = (GL2Encoder*)self;
Tina Zhanga45cd9a2015-03-26 14:45:29 +0800809 RET_AND_SET_ERROR_IF(((shaderType != GL_VERTEX_SHADER) && (shaderType != GL_FRAGMENT_SHADER)),
810 GL_INVALID_ENUM, 0);
keunyoungb85b2752013-03-08 12:28:03 -0800811 GLuint shader = ctx->m_glCreateShader_enc(self, shaderType);
812 if (shader != 0) {
813 if (!ctx->m_shared->addShaderData(shader)) {
814 ctx->m_glDeleteShader_enc(self, shader);
815 return 0;
816 }
817 }
818 return shader;
819}
820
bohu56bf82f2014-10-17 15:35:48 -0700821void GL2Encoder::s_glGetAttachedShaders(void *self, GLuint program, GLsizei maxCount,
822 GLsizei* count, GLuint* shaders)
823{
824 GL2Encoder *ctx = (GL2Encoder*)self;
825 SET_ERROR_IF(maxCount < 0, GL_INVALID_VALUE);
826 ctx->m_glGetAttachedShaders_enc(self, program, maxCount, count, shaders);
827}
828
829void GL2Encoder::s_glGetShaderSource(void *self, GLuint shader, GLsizei bufsize,
830 GLsizei* length, GLchar* source)
831{
832 GL2Encoder *ctx = (GL2Encoder*)self;
833 SET_ERROR_IF(bufsize < 0, GL_INVALID_VALUE);
834 ctx->m_glGetShaderSource_enc(self, shader, bufsize, length, source);
835}
836
837void GL2Encoder::s_glGetShaderInfoLog(void *self, GLuint shader, GLsizei bufsize,
838 GLsizei* length, GLchar* infolog)
839{
840 GL2Encoder *ctx = (GL2Encoder*)self;
841 SET_ERROR_IF(bufsize < 0, GL_INVALID_VALUE);
842 ctx->m_glGetShaderInfoLog_enc(self, shader, bufsize, length, infolog);
843}
844
845void GL2Encoder::s_glGetProgramInfoLog(void *self, GLuint program, GLsizei bufsize,
846 GLsizei* length, GLchar* infolog)
847{
848 GL2Encoder *ctx = (GL2Encoder*)self;
849 SET_ERROR_IF(bufsize < 0, GL_INVALID_VALUE);
850 ctx->m_glGetProgramInfoLog_enc(self, program, bufsize, length, infolog);
851}
852
keunyoungb85b2752013-03-08 12:28:03 -0800853void GL2Encoder::s_glDeleteShader(void *self, GLenum shader)
854{
855 GL2Encoder *ctx = (GL2Encoder*)self;
856 ctx->m_glDeleteShader_enc(self,shader);
857 ctx->m_shared->unrefShaderData(shader);
858}
859
860void GL2Encoder::s_glAttachShader(void *self, GLuint program, GLuint shader)
861{
862 GL2Encoder *ctx = (GL2Encoder*)self;
863 ctx->m_glAttachShader_enc(self, program, shader);
864 ctx->m_shared->attachShader(program, shader);
865}
866
867void GL2Encoder::s_glDetachShader(void *self, GLuint program, GLuint shader)
868{
869 GL2Encoder *ctx = (GL2Encoder*)self;
870 ctx->m_glDetachShader_enc(self, program, shader);
871 ctx->m_shared->detachShader(program, shader);
872}
873
874int GL2Encoder::s_glGetUniformLocation(void *self, GLuint program, const GLchar *name)
875{
876 if (!name) return -1;
877
878 GL2Encoder *ctx = (GL2Encoder*)self;
879
880 // if we need the uniform location WAR
881 // parse array index from the end of the name string
882 int arrIndex = 0;
883 bool needLocationWAR = ctx->m_shared->needUniformLocationWAR(program);
884 if (needLocationWAR) {
885 int namelen = strlen(name);
886 if (name[namelen-1] == ']') {
887 char *brace = strrchr(name,'[');
888 if (!brace || sscanf(brace+1,"%d",&arrIndex) != 1) {
889 return -1;
890 }
891
892 }
893 }
894
895 int hostLoc = ctx->m_glGetUniformLocation_enc(self, program, name);
896 if (hostLoc >= 0 && needLocationWAR) {
897 return ctx->m_shared->locationWARHostToApp(program, hostLoc, arrIndex);
898 }
899 return hostLoc;
900}
901
902bool GL2Encoder::updateHostTexture2DBinding(GLenum texUnit, GLenum newTarget)
903{
904 if (newTarget != GL_TEXTURE_2D && newTarget != GL_TEXTURE_EXTERNAL_OES)
905 return false;
906
907 m_state->setActiveTextureUnit(texUnit);
908
909 GLenum oldTarget = m_state->getPriorityEnabledTarget(GL_TEXTURE_2D);
910 if (newTarget != oldTarget) {
911 if (newTarget == GL_TEXTURE_EXTERNAL_OES) {
912 m_state->disableTextureTarget(GL_TEXTURE_2D);
913 m_state->enableTextureTarget(GL_TEXTURE_EXTERNAL_OES);
914 } else {
915 m_state->disableTextureTarget(GL_TEXTURE_EXTERNAL_OES);
916 m_state->enableTextureTarget(GL_TEXTURE_2D);
917 }
918 m_glActiveTexture_enc(this, texUnit);
919 m_glBindTexture_enc(this, GL_TEXTURE_2D,
920 m_state->getBoundTexture(newTarget));
921 return true;
922 }
923
924 return false;
925}
926
927void GL2Encoder::s_glUseProgram(void *self, GLuint program)
928{
929 GL2Encoder *ctx = (GL2Encoder*)self;
930 GLClientState* state = ctx->m_state;
931 GLSharedGroupPtr shared = ctx->m_shared;
932
933 ctx->m_glUseProgram_enc(self, program);
934 ctx->m_state->setCurrentProgram(program);
935
936 GLenum origActiveTexture = state->getActiveTextureUnit();
937 GLenum hostActiveTexture = origActiveTexture;
938 GLint samplerIdx = -1;
939 GLint samplerVal;
940 GLenum samplerTarget;
941 while ((samplerIdx = shared->getNextSamplerUniform(program, samplerIdx, &samplerVal, &samplerTarget)) != -1) {
942 if (samplerVal < 0 || samplerVal >= GLClientState::MAX_TEXTURE_UNITS)
943 continue;
944 if (ctx->updateHostTexture2DBinding(GL_TEXTURE0 + samplerVal,
945 samplerTarget))
946 {
947 hostActiveTexture = GL_TEXTURE0 + samplerVal;
948 }
949 }
950 state->setActiveTextureUnit(origActiveTexture);
951 if (hostActiveTexture != origActiveTexture) {
952 ctx->m_glActiveTexture_enc(self, origActiveTexture);
953 }
954}
955
956void GL2Encoder::s_glUniform1f(void *self , GLint location, GLfloat x)
957{
958 GL2Encoder *ctx = (GL2Encoder*)self;
959 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
960 ctx->m_glUniform1f_enc(self, hostLoc, x);
961}
962
963void GL2Encoder::s_glUniform1fv(void *self , GLint location, GLsizei count, const GLfloat* v)
964{
965 GL2Encoder *ctx = (GL2Encoder*)self;
966 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
967 ctx->m_glUniform1fv_enc(self, hostLoc, count, v);
968}
969
970void GL2Encoder::s_glUniform1i(void *self , GLint location, GLint x)
971{
972 GL2Encoder *ctx = (GL2Encoder*)self;
973 GLClientState* state = ctx->m_state;
974 GLSharedGroupPtr shared = ctx->m_shared;
975
976 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
977 ctx->m_glUniform1i_enc(self, hostLoc, x);
978
979 GLenum target;
980 if (shared->setSamplerUniform(state->currentProgram(), location, x, &target)) {
981 GLenum origActiveTexture = state->getActiveTextureUnit();
982 if (ctx->updateHostTexture2DBinding(GL_TEXTURE0 + x, target)) {
983 ctx->m_glActiveTexture_enc(self, origActiveTexture);
984 }
985 state->setActiveTextureUnit(origActiveTexture);
986 }
987}
988
989void GL2Encoder::s_glUniform1iv(void *self , GLint location, GLsizei count, const GLint* v)
990{
991 GL2Encoder *ctx = (GL2Encoder*)self;
992 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
993 ctx->m_glUniform1iv_enc(self, hostLoc, count, v);
994}
995
996void GL2Encoder::s_glUniform2f(void *self , GLint location, GLfloat x, GLfloat y)
997{
998 GL2Encoder *ctx = (GL2Encoder*)self;
999 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
1000 ctx->m_glUniform2f_enc(self, hostLoc, x, y);
1001}
1002
1003void GL2Encoder::s_glUniform2fv(void *self , GLint location, GLsizei count, const GLfloat* v)
1004{
1005 GL2Encoder *ctx = (GL2Encoder*)self;
1006 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
1007 ctx->m_glUniform2fv_enc(self, hostLoc, count, v);
1008}
1009
1010void GL2Encoder::s_glUniform2i(void *self , GLint location, GLint x, GLint y)
1011{
1012 GL2Encoder *ctx = (GL2Encoder*)self;
1013 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
1014 ctx->m_glUniform2i_enc(self, hostLoc, x, y);
1015}
1016
1017void GL2Encoder::s_glUniform2iv(void *self , GLint location, GLsizei count, const GLint* v)
1018{
1019 GL2Encoder *ctx = (GL2Encoder*)self;
1020 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
1021 ctx->m_glUniform2iv_enc(self, hostLoc, count, v);
1022}
1023
1024void GL2Encoder::s_glUniform3f(void *self , GLint location, GLfloat x, GLfloat y, GLfloat z)
1025{
1026 GL2Encoder *ctx = (GL2Encoder*)self;
1027 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
1028 ctx->m_glUniform3f_enc(self, hostLoc, x, y, z);
1029}
1030
1031void GL2Encoder::s_glUniform3fv(void *self , GLint location, GLsizei count, const GLfloat* v)
1032{
1033 GL2Encoder *ctx = (GL2Encoder*)self;
1034 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
1035 ctx->m_glUniform3fv_enc(self, hostLoc, count, v);
1036}
1037
1038void GL2Encoder::s_glUniform3i(void *self , GLint location, GLint x, GLint y, GLint z)
1039{
1040 GL2Encoder *ctx = (GL2Encoder*)self;
1041 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
1042 ctx->m_glUniform3i_enc(self, hostLoc, x, y, z);
1043}
1044
1045void GL2Encoder::s_glUniform3iv(void *self , GLint location, GLsizei count, const GLint* v)
1046{
1047 GL2Encoder *ctx = (GL2Encoder*)self;
1048 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
1049 ctx->m_glUniform3iv_enc(self, hostLoc, count, v);
1050}
1051
1052void GL2Encoder::s_glUniform4f(void *self , GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
1053{
1054 GL2Encoder *ctx = (GL2Encoder*)self;
1055 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
1056 ctx->m_glUniform4f_enc(self, hostLoc, x, y, z, w);
1057}
1058
1059void GL2Encoder::s_glUniform4fv(void *self , GLint location, GLsizei count, const GLfloat* v)
1060{
1061 GL2Encoder *ctx = (GL2Encoder*)self;
1062 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
1063 ctx->m_glUniform4fv_enc(self, hostLoc, count, v);
1064}
1065
1066void GL2Encoder::s_glUniform4i(void *self , GLint location, GLint x, GLint y, GLint z, GLint w)
1067{
1068 GL2Encoder *ctx = (GL2Encoder*)self;
1069 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
1070 ctx->m_glUniform4i_enc(self, hostLoc, x, y, z, w);
1071}
1072
1073void GL2Encoder::s_glUniform4iv(void *self , GLint location, GLsizei count, const GLint* v)
1074{
1075 GL2Encoder *ctx = (GL2Encoder*)self;
1076 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
1077 ctx->m_glUniform4iv_enc(self, hostLoc, count, v);
1078}
1079
1080void GL2Encoder::s_glUniformMatrix2fv(void *self , GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
1081{
1082 GL2Encoder *ctx = (GL2Encoder*)self;
1083 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
1084 ctx->m_glUniformMatrix2fv_enc(self, hostLoc, count, transpose, value);
1085}
1086
1087void GL2Encoder::s_glUniformMatrix3fv(void *self , GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
1088{
1089 GL2Encoder *ctx = (GL2Encoder*)self;
1090 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
1091 ctx->m_glUniformMatrix3fv_enc(self, hostLoc, count, transpose, value);
1092}
1093
1094void GL2Encoder::s_glUniformMatrix4fv(void *self , GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
1095{
1096 GL2Encoder *ctx = (GL2Encoder*)self;
1097 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
1098 ctx->m_glUniformMatrix4fv_enc(self, hostLoc, count, transpose, value);
1099}
1100
1101void GL2Encoder::s_glActiveTexture(void* self, GLenum texture)
1102{
1103 GL2Encoder* ctx = (GL2Encoder*)self;
1104 GLClientState* state = ctx->m_state;
1105 GLenum err;
1106
1107 SET_ERROR_IF((err = state->setActiveTextureUnit(texture)) != GL_NO_ERROR, err);
1108
1109 ctx->m_glActiveTexture_enc(ctx, texture);
1110}
1111
1112void GL2Encoder::s_glBindTexture(void* self, GLenum target, GLuint texture)
1113{
1114 GL2Encoder* ctx = (GL2Encoder*)self;
1115 GLClientState* state = ctx->m_state;
1116 GLenum err;
1117 GLboolean firstUse;
1118
1119 SET_ERROR_IF((err = state->bindTexture(target, texture, &firstUse)) != GL_NO_ERROR, err);
1120
1121 if (target != GL_TEXTURE_2D && target != GL_TEXTURE_EXTERNAL_OES) {
1122 ctx->m_glBindTexture_enc(ctx, target, texture);
1123 return;
1124 }
1125
1126 GLenum priorityTarget = state->getPriorityEnabledTarget(GL_TEXTURE_2D);
1127
1128 if (target == GL_TEXTURE_EXTERNAL_OES && firstUse) {
1129 ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D, texture);
1130 ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D,
1131 GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1132 ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D,
1133 GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1134 ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D,
1135 GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1136
1137 if (target != priorityTarget) {
1138 ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D,
1139 state->getBoundTexture(GL_TEXTURE_2D));
1140 }
1141 }
1142
1143 if (target == priorityTarget) {
1144 ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D, texture);
1145 }
1146}
1147
1148void GL2Encoder::s_glDeleteTextures(void* self, GLsizei n, const GLuint* textures)
1149{
1150 GL2Encoder* ctx = (GL2Encoder*)self;
1151 GLClientState* state = ctx->m_state;
1152
1153 state->deleteTextures(n, textures);
1154 ctx->m_glDeleteTextures_enc(ctx, n, textures);
1155}
1156
1157void GL2Encoder::s_glGetTexParameterfv(void* self,
1158 GLenum target, GLenum pname, GLfloat* params)
1159{
1160 GL2Encoder* ctx = (GL2Encoder*)self;
1161 const GLClientState* state = ctx->m_state;
1162
1163 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
1164 ctx->override2DTextureTarget(target);
1165 ctx->m_glGetTexParameterfv_enc(ctx, GL_TEXTURE_2D, pname, params);
1166 ctx->restore2DTextureTarget();
1167 } else {
1168 ctx->m_glGetTexParameterfv_enc(ctx, target, pname, params);
1169 }
1170}
1171
1172void GL2Encoder::s_glGetTexParameteriv(void* self,
1173 GLenum target, GLenum pname, GLint* params)
1174{
1175 GL2Encoder* ctx = (GL2Encoder*)self;
1176 const GLClientState* state = ctx->m_state;
1177
1178 switch (pname) {
1179 case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
1180 *params = 1;
1181 break;
1182
1183 default:
1184 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
1185 ctx->override2DTextureTarget(target);
1186 ctx->m_glGetTexParameteriv_enc(ctx, GL_TEXTURE_2D, pname, params);
1187 ctx->restore2DTextureTarget();
1188 } else {
1189 ctx->m_glGetTexParameteriv_enc(ctx, target, pname, params);
1190 }
1191 break;
1192 }
1193}
1194
1195static bool isValidTextureExternalParam(GLenum pname, GLenum param)
1196{
1197 switch (pname) {
1198 case GL_TEXTURE_MIN_FILTER:
1199 case GL_TEXTURE_MAG_FILTER:
1200 return param == GL_NEAREST || param == GL_LINEAR;
1201
1202 case GL_TEXTURE_WRAP_S:
1203 case GL_TEXTURE_WRAP_T:
1204 return param == GL_CLAMP_TO_EDGE;
1205
1206 default:
1207 return true;
1208 }
1209}
1210
1211void GL2Encoder::s_glTexParameterf(void* self,
1212 GLenum target, GLenum pname, GLfloat param)
1213{
1214 GL2Encoder* ctx = (GL2Encoder*)self;
1215 const GLClientState* state = ctx->m_state;
1216
1217 SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
1218 !isValidTextureExternalParam(pname, (GLenum)param)),
1219 GL_INVALID_ENUM);
1220
1221 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
1222 ctx->override2DTextureTarget(target);
1223 ctx->m_glTexParameterf_enc(ctx, GL_TEXTURE_2D, pname, param);
1224 ctx->restore2DTextureTarget();
1225 } else {
1226 ctx->m_glTexParameterf_enc(ctx, target, pname, param);
1227 }
1228}
1229
1230void GL2Encoder::s_glTexParameterfv(void* self,
1231 GLenum target, GLenum pname, const GLfloat* params)
1232{
1233 GL2Encoder* ctx = (GL2Encoder*)self;
1234 const GLClientState* state = ctx->m_state;
1235
1236 SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
1237 !isValidTextureExternalParam(pname, (GLenum)params[0])),
1238 GL_INVALID_ENUM);
1239
1240 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
1241 ctx->override2DTextureTarget(target);
1242 ctx->m_glTexParameterfv_enc(ctx, GL_TEXTURE_2D, pname, params);
1243 ctx->restore2DTextureTarget();
1244 } else {
1245 ctx->m_glTexParameterfv_enc(ctx, target, pname, params);
1246 }
1247}
1248
1249void GL2Encoder::s_glTexParameteri(void* self,
1250 GLenum target, GLenum pname, GLint param)
1251{
1252 GL2Encoder* ctx = (GL2Encoder*)self;
1253 const GLClientState* state = ctx->m_state;
1254
1255 SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
1256 !isValidTextureExternalParam(pname, (GLenum)param)),
1257 GL_INVALID_ENUM);
1258
1259 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
1260 ctx->override2DTextureTarget(target);
1261 ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D, pname, param);
1262 ctx->restore2DTextureTarget();
1263 } else {
1264 ctx->m_glTexParameteri_enc(ctx, target, pname, param);
1265 }
1266}
1267
bohu26a92982014-11-25 16:50:37 -08001268void GL2Encoder::s_glTexImage2D(void* self, GLenum target, GLint level,
1269 GLint internalformat, GLsizei width, GLsizei height, GLint border,
1270 GLenum format, GLenum type, const GLvoid* pixels)
1271{
1272 GL2Encoder* ctx = (GL2Encoder*)self;
1273 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
1274 ctx->override2DTextureTarget(target);
1275 ctx->m_glTexImage2D_enc(ctx, target, level, internalformat, width,
1276 height, border, format, type, pixels);
1277 ctx->restore2DTextureTarget();
1278 } else {
1279 ctx->m_glTexImage2D_enc(ctx, target, level, internalformat, width,
1280 height, border, format, type, pixels);
1281 }
1282}
1283
1284
keunyoungb85b2752013-03-08 12:28:03 -08001285void GL2Encoder::s_glTexParameteriv(void* self,
1286 GLenum target, GLenum pname, const GLint* params)
1287{
1288 GL2Encoder* ctx = (GL2Encoder*)self;
1289 const GLClientState* state = ctx->m_state;
1290
1291 SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
1292 !isValidTextureExternalParam(pname, (GLenum)params[0])),
1293 GL_INVALID_ENUM);
1294
1295 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
1296 ctx->override2DTextureTarget(target);
1297 ctx->m_glTexParameteriv_enc(ctx, GL_TEXTURE_2D, pname, params);
1298 ctx->restore2DTextureTarget();
1299 } else {
1300 ctx->m_glTexParameteriv_enc(ctx, target, pname, params);
1301 }
1302}
1303
1304void GL2Encoder::override2DTextureTarget(GLenum target)
1305{
1306 if ((target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) &&
1307 target != m_state->getPriorityEnabledTarget(GL_TEXTURE_2D)) {
1308 m_glBindTexture_enc(this, GL_TEXTURE_2D,
1309 m_state->getBoundTexture(target));
1310 }
1311}
1312
1313void GL2Encoder::restore2DTextureTarget()
1314{
1315 GLenum priorityTarget = m_state->getPriorityEnabledTarget(GL_TEXTURE_2D);
1316 m_glBindTexture_enc(this, GL_TEXTURE_2D,
1317 m_state->getBoundTexture(priorityTarget));
1318}