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