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