blob: df865e5702e5922bde3294b0f2d0694064b84712 [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"
Lingfeng Yang46153ab2017-01-09 13:37:22 -080018#include "GLESv2Validation.h"
19
20#include <string>
21#include <map>
22
keunyoungb85b2752013-03-08 12:28:03 -080023#include <assert.h>
24#include <ctype.h>
25
Lingfeng Yang69066602016-04-12 09:29:11 -070026#include <GLES2/gl2.h>
27#include <GLES2/gl2ext.h>
28#include <GLES2/gl2platform.h>
29
30#include <GLES3/gl3.h>
Lingfeng Yang46153ab2017-01-09 13:37:22 -080031#include <GLES3/gl31.h>
Lingfeng Yang69066602016-04-12 09:29:11 -070032
keunyoungb85b2752013-03-08 12:28:03 -080033#ifndef MIN
34#define MIN(a, b) ((a) < (b) ? (a) : (b))
35#endif
36
37static GLubyte *gVendorString= (GLubyte *) "Android";
Lingfeng Yang46153ab2017-01-09 13:37:22 -080038static GLubyte *gRendererString= (GLubyte *) "Android HW-GLES 3.0";
39static GLubyte *gVersionString= (GLubyte *) "OpenGL ES 3.0";
Nicolas Capensfe2d51a2015-11-20 15:10:09 -050040static GLubyte *gExtensionsString= (GLubyte *) "GL_OES_EGL_image_external ";
keunyoungb85b2752013-03-08 12:28:03 -080041
Lingfeng Yang07289902017-01-27 12:26:19 -080042#define SET_ERROR_IF(condition, err) if((condition)) { \
keunyoungb85b2752013-03-08 12:28:03 -080043 ALOGE("%s:%s:%d GL error 0x%x\n", __FILE__, __FUNCTION__, __LINE__, err); \
Lingfeng Yang07289902017-01-27 12:26:19 -080044 ctx->setError(err); \
45 return; \
keunyoungb85b2752013-03-08 12:28:03 -080046 }
47
Lingfeng Yang07289902017-01-27 12:26:19 -080048#define SET_ERROR_WITH_MESSAGE_IF(condition, err, generator, genargs) if ((condition)) { \
49 std::string msg = generator genargs; \
50 ALOGE("%s:%s:%d GL error 0x%x\n" \
51 "Info: %s\n", __FILE__, __FUNCTION__, __LINE__, err, msg.c_str()); \
52 ctx->setError(err); \
53 return; \
54 } \
keunyoungb85b2752013-03-08 12:28:03 -080055
Lingfeng Yang07289902017-01-27 12:26:19 -080056#define RET_AND_SET_ERROR_IF(condition, err, ret) if((condition)) { \
keunyoungb85b2752013-03-08 12:28:03 -080057 ALOGE("%s:%s:%d GL error 0x%x\n", __FILE__, __FUNCTION__, __LINE__, err); \
Lingfeng Yang07289902017-01-27 12:26:19 -080058 ctx->setError(err); \
59 return ret; \
60 } \
keunyoungb85b2752013-03-08 12:28:03 -080061
Lingfeng Yang07289902017-01-27 12:26:19 -080062#define RET_AND_SET_ERROR_WITH_MESSAGE_IF(condition, err, ret, generator, genargs) if((condition)) { \
63 std::string msg = generator genargs; \
64 ALOGE("%s:%s:%d GL error 0x%x\n" \
65 "Info: %s\n", __FILE__, __FUNCTION__, __LINE__, err, msg.c_str()); \
66 ctx->setError(err); \
67 return ret; \
68 } \
keunyoungb85b2752013-03-08 12:28:03 -080069
Yahan Zhoub7f09082016-03-10 11:45:02 -080070GL2Encoder::GL2Encoder(IOStream *stream, ChecksumCalculator *protocol)
71 : gl2_encoder_context_t(stream, protocol)
keunyoungb85b2752013-03-08 12:28:03 -080072{
Lingfeng Yange6556dc2017-01-09 12:04:12 -080073 m_currMajorVersion = 2;
74 m_currMinorVersion = 0;
Lingfeng Yang22e361a2019-10-12 07:19:00 -070075 m_hasAsyncUnmapBuffer = false;
keunyoungb85b2752013-03-08 12:28:03 -080076 m_initialized = false;
Lingfeng Yange980c7a2018-01-12 14:50:18 -080077 m_noHostError = false;
keunyoungb85b2752013-03-08 12:28:03 -080078 m_state = NULL;
79 m_error = GL_NO_ERROR;
Roman Kiryanovdaecd142018-11-14 14:56:27 -080080
keunyoungb85b2752013-03-08 12:28:03 -080081 m_num_compressedTextureFormats = 0;
Lingfeng Yang48685bb2018-10-19 06:44:20 -070082 m_max_combinedTextureImageUnits = 0;
Lingfeng Yanga1edab62018-10-19 07:53:49 -070083 m_max_vertexTextureImageUnits = 0;
84 m_max_textureImageUnits = 0;
Lizhe Liue41f4ef2015-05-27 11:13:23 +080085 m_max_cubeMapTextureSize = 0;
86 m_max_renderBufferSize = 0;
87 m_max_textureSize = 0;
Lingfeng Yang46153ab2017-01-09 13:37:22 -080088 m_max_3d_textureSize = 0;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -080089 m_max_vertexAttribStride = 0;
Lingfeng Yanga1edab62018-10-19 07:53:49 -070090
91 m_max_transformFeedbackSeparateAttribs = 0;
92 m_max_uniformBufferBindings = 0;
93 m_max_colorAttachments = 0;
94 m_max_drawBuffers = 0;
95
96 m_max_atomicCounterBufferBindings = 0;
97 m_max_shaderStorageBufferBindings = 0;
98 m_max_vertexAttribBindings = 0;
99
keunyoungb85b2752013-03-08 12:28:03 -0800100 m_compressedTextureFormats = NULL;
David 'Digit' Turner3afd44b2014-10-30 18:15:04 +0100101
Lingfeng Yang46153ab2017-01-09 13:37:22 -0800102 m_ssbo_offset_align = 0;
103 m_ubo_offset_align = 0;
104
Lingfeng Yang4d0ffea2019-10-12 16:51:59 -0700105 m_drawCallFlushInterval = 800;
Lingfeng Yangde51dfb2016-10-17 22:48:59 -0700106 m_drawCallFlushCount = 0;
107 m_primitiveRestartEnabled = false;
108 m_primitiveRestartIndex = 0;
109
Lingfeng Yang07289902017-01-27 12:26:19 -0800110 // overrides
David 'Digit' Turner3afd44b2014-10-30 18:15:04 +0100111#define OVERRIDE(name) m_##name##_enc = this-> name ; this-> name = &s_##name
Lingfeng Yange6556dc2017-01-09 12:04:12 -0800112#define OVERRIDE_CUSTOM(name) this-> name = &s_##name
113#define OVERRIDEWITH(name, target) do { \
114 m_##target##_enc = this-> target; \
115 this-> target = &s_##name; \
116} while(0)
117#define OVERRIDEOES(name) OVERRIDEWITH(name, name##OES)
bohu56bf82f2014-10-17 15:35:48 -0700118
David 'Digit' Turner3afd44b2014-10-30 18:15:04 +0100119 OVERRIDE(glFlush);
120 OVERRIDE(glPixelStorei);
121 OVERRIDE(glGetString);
122 OVERRIDE(glBindBuffer);
123 OVERRIDE(glBufferData);
124 OVERRIDE(glBufferSubData);
125 OVERRIDE(glDeleteBuffers);
126 OVERRIDE(glDrawArrays);
127 OVERRIDE(glDrawElements);
Lingfeng Yang09545912019-01-30 09:22:38 -0800128 OVERRIDE(glDrawArraysNullAEMU);
129 OVERRIDE(glDrawElementsNullAEMU);
David 'Digit' Turner3afd44b2014-10-30 18:15:04 +0100130 OVERRIDE(glGetIntegerv);
131 OVERRIDE(glGetFloatv);
132 OVERRIDE(glGetBooleanv);
133 OVERRIDE(glVertexAttribPointer);
134 OVERRIDE(glEnableVertexAttribArray);
135 OVERRIDE(glDisableVertexAttribArray);
136 OVERRIDE(glGetVertexAttribiv);
137 OVERRIDE(glGetVertexAttribfv);
138 OVERRIDE(glGetVertexAttribPointerv);
keunyoungb85b2752013-03-08 12:28:03 -0800139
Bo Hu73568cd2015-01-20 16:29:50 -0800140 this->glShaderBinary = &s_glShaderBinary;
David 'Digit' Turner3afd44b2014-10-30 18:15:04 +0100141 this->glShaderSource = &s_glShaderSource;
142 this->glFinish = &s_glFinish;
keunyoungb85b2752013-03-08 12:28:03 -0800143
David 'Digit' Turner3afd44b2014-10-30 18:15:04 +0100144 OVERRIDE(glGetError);
145 OVERRIDE(glLinkProgram);
146 OVERRIDE(glDeleteProgram);
147 OVERRIDE(glGetUniformiv);
148 OVERRIDE(glGetUniformfv);
149 OVERRIDE(glCreateProgram);
150 OVERRIDE(glCreateShader);
151 OVERRIDE(glDeleteShader);
152 OVERRIDE(glAttachShader);
153 OVERRIDE(glDetachShader);
154 OVERRIDE(glGetAttachedShaders);
155 OVERRIDE(glGetShaderSource);
156 OVERRIDE(glGetShaderInfoLog);
157 OVERRIDE(glGetProgramInfoLog);
158
159 OVERRIDE(glGetUniformLocation);
160 OVERRIDE(glUseProgram);
161
162 OVERRIDE(glUniform1f);
163 OVERRIDE(glUniform1fv);
164 OVERRIDE(glUniform1i);
165 OVERRIDE(glUniform1iv);
166 OVERRIDE(glUniform2f);
167 OVERRIDE(glUniform2fv);
168 OVERRIDE(glUniform2i);
169 OVERRIDE(glUniform2iv);
170 OVERRIDE(glUniform3f);
171 OVERRIDE(glUniform3fv);
172 OVERRIDE(glUniform3i);
173 OVERRIDE(glUniform3iv);
174 OVERRIDE(glUniform4f);
175 OVERRIDE(glUniform4fv);
176 OVERRIDE(glUniform4i);
177 OVERRIDE(glUniform4iv);
178 OVERRIDE(glUniformMatrix2fv);
179 OVERRIDE(glUniformMatrix3fv);
180 OVERRIDE(glUniformMatrix4fv);
181
182 OVERRIDE(glActiveTexture);
183 OVERRIDE(glBindTexture);
184 OVERRIDE(glDeleteTextures);
185 OVERRIDE(glGetTexParameterfv);
186 OVERRIDE(glGetTexParameteriv);
187 OVERRIDE(glTexParameterf);
188 OVERRIDE(glTexParameterfv);
189 OVERRIDE(glTexParameteri);
190 OVERRIDE(glTexParameteriv);
bohu26a92982014-11-25 16:50:37 -0800191 OVERRIDE(glTexImage2D);
Yahan Zhou2a208292016-06-22 15:36:04 -0700192 OVERRIDE(glTexSubImage2D);
Lingfeng Yange00ec9d2016-09-16 08:54:03 -0700193 OVERRIDE(glCopyTexImage2D);
Lingfeng Yang57cb41b2016-04-08 14:42:34 -0700194
195 OVERRIDE(glGenRenderbuffers);
196 OVERRIDE(glDeleteRenderbuffers);
197 OVERRIDE(glBindRenderbuffer);
Lingfeng Yang69066602016-04-12 09:29:11 -0700198 OVERRIDE(glRenderbufferStorage);
Lingfeng Yang57cb41b2016-04-08 14:42:34 -0700199 OVERRIDE(glFramebufferRenderbuffer);
200
201 OVERRIDE(glGenFramebuffers);
202 OVERRIDE(glDeleteFramebuffers);
203 OVERRIDE(glBindFramebuffer);
204 OVERRIDE(glFramebufferTexture2D);
205 OVERRIDE(glFramebufferTexture3DOES);
206 OVERRIDE(glGetFramebufferAttachmentParameteriv);
Lingfeng Yang69066602016-04-12 09:29:11 -0700207
208 OVERRIDE(glCheckFramebufferStatus);
Lingfeng Yang46153ab2017-01-09 13:37:22 -0800209
210 OVERRIDE(glGenVertexArrays);
211 OVERRIDE(glDeleteVertexArrays);
212 OVERRIDE(glBindVertexArray);
213 OVERRIDEOES(glGenVertexArrays);
214 OVERRIDEOES(glDeleteVertexArrays);
215 OVERRIDEOES(glBindVertexArray);
216
Lingfeng Yangfb3d2bb2017-09-07 15:02:04 -0700217 OVERRIDE_CUSTOM(glMapBufferOES);
218 OVERRIDE_CUSTOM(glUnmapBufferOES);
Lingfeng Yang46153ab2017-01-09 13:37:22 -0800219 OVERRIDE_CUSTOM(glMapBufferRange);
220 OVERRIDE_CUSTOM(glUnmapBuffer);
221 OVERRIDE_CUSTOM(glFlushMappedBufferRange);
222
223 OVERRIDE(glCompressedTexImage2D);
224 OVERRIDE(glCompressedTexSubImage2D);
225
226 OVERRIDE(glBindBufferRange);
227 OVERRIDE(glBindBufferBase);
228
229 OVERRIDE(glCopyBufferSubData);
230
231 OVERRIDE(glGetBufferParameteriv);
232 OVERRIDE(glGetBufferParameteri64v);
233 OVERRIDE(glGetBufferPointerv);
234
235 OVERRIDE_CUSTOM(glGetUniformIndices);
236
237 OVERRIDE(glUniform1ui);
238 OVERRIDE(glUniform2ui);
239 OVERRIDE(glUniform3ui);
240 OVERRIDE(glUniform4ui);
241 OVERRIDE(glUniform1uiv);
242 OVERRIDE(glUniform2uiv);
243 OVERRIDE(glUniform3uiv);
244 OVERRIDE(glUniform4uiv);
245 OVERRIDE(glUniformMatrix2x3fv);
246 OVERRIDE(glUniformMatrix3x2fv);
247 OVERRIDE(glUniformMatrix2x4fv);
248 OVERRIDE(glUniformMatrix4x2fv);
249 OVERRIDE(glUniformMatrix3x4fv);
250 OVERRIDE(glUniformMatrix4x3fv);
251
252 OVERRIDE(glGetUniformuiv);
253 OVERRIDE(glGetActiveUniformBlockiv);
254
255 OVERRIDE(glGetVertexAttribIiv);
256 OVERRIDE(glGetVertexAttribIuiv);
257
258 OVERRIDE_CUSTOM(glVertexAttribIPointer);
259
260 OVERRIDE(glVertexAttribDivisor);
261
262 OVERRIDE(glRenderbufferStorageMultisample);
263 OVERRIDE(glDrawBuffers);
264 OVERRIDE(glReadBuffer);
265 OVERRIDE(glFramebufferTextureLayer);
266 OVERRIDE(glTexStorage2D);
267
268 OVERRIDE_CUSTOM(glTransformFeedbackVaryings);
269 OVERRIDE(glBeginTransformFeedback);
270 OVERRIDE(glEndTransformFeedback);
271 OVERRIDE(glPauseTransformFeedback);
272 OVERRIDE(glResumeTransformFeedback);
273
274 OVERRIDE(glTexImage3D);
275 OVERRIDE(glTexSubImage3D);
276 OVERRIDE(glTexStorage3D);
277 OVERRIDE(glCompressedTexImage3D);
278 OVERRIDE(glCompressedTexSubImage3D);
279
280 OVERRIDE(glDrawArraysInstanced);
281 OVERRIDE_CUSTOM(glDrawElementsInstanced);
282 OVERRIDE_CUSTOM(glDrawRangeElements);
283
284 OVERRIDE_CUSTOM(glGetStringi);
285 OVERRIDE(glGetProgramBinary);
286 OVERRIDE(glReadPixels);
287
288 OVERRIDE(glEnable);
289 OVERRIDE(glDisable);
290 OVERRIDE(glClearBufferiv);
291 OVERRIDE(glClearBufferuiv);
292 OVERRIDE(glClearBufferfv);
293 OVERRIDE(glBlitFramebuffer);
294 OVERRIDE_CUSTOM(glGetInternalformativ);
295
296 OVERRIDE(glGenerateMipmap);
297
298 OVERRIDE(glBindSampler);
299
Lingfeng Yangf000ab42017-01-11 18:31:38 -0800300 OVERRIDE_CUSTOM(glFenceSync);
301 OVERRIDE_CUSTOM(glClientWaitSync);
302 OVERRIDE_CUSTOM(glWaitSync);
303 OVERRIDE_CUSTOM(glDeleteSync);
304 OVERRIDE_CUSTOM(glIsSync);
305 OVERRIDE_CUSTOM(glGetSynciv);
Lingfeng Yang46153ab2017-01-09 13:37:22 -0800306
307 OVERRIDE(glGetIntegeri_v);
308 OVERRIDE(glGetInteger64i_v);
Lingfeng Yang80a36332017-07-09 10:58:07 -0700309 OVERRIDE(glGetInteger64v);
310 OVERRIDE(glGetBooleani_v);
Lingfeng Yang46153ab2017-01-09 13:37:22 -0800311
312 OVERRIDE(glGetShaderiv);
313
Lingfeng Yangd3ae1062017-01-18 11:42:04 -0800314 OVERRIDE(glActiveShaderProgram);
Lingfeng Yang46153ab2017-01-09 13:37:22 -0800315 OVERRIDE_CUSTOM(glCreateShaderProgramv);
316 OVERRIDE(glProgramUniform1f);
317 OVERRIDE(glProgramUniform1fv);
318 OVERRIDE(glProgramUniform1i);
319 OVERRIDE(glProgramUniform1iv);
320 OVERRIDE(glProgramUniform1ui);
321 OVERRIDE(glProgramUniform1uiv);
322 OVERRIDE(glProgramUniform2f);
323 OVERRIDE(glProgramUniform2fv);
324 OVERRIDE(glProgramUniform2i);
325 OVERRIDE(glProgramUniform2iv);
326 OVERRIDE(glProgramUniform2ui);
327 OVERRIDE(glProgramUniform2uiv);
328 OVERRIDE(glProgramUniform3f);
329 OVERRIDE(glProgramUniform3fv);
330 OVERRIDE(glProgramUniform3i);
331 OVERRIDE(glProgramUniform3iv);
332 OVERRIDE(glProgramUniform3ui);
333 OVERRIDE(glProgramUniform3uiv);
334 OVERRIDE(glProgramUniform4f);
335 OVERRIDE(glProgramUniform4fv);
336 OVERRIDE(glProgramUniform4i);
337 OVERRIDE(glProgramUniform4iv);
338 OVERRIDE(glProgramUniform4ui);
339 OVERRIDE(glProgramUniform4uiv);
340 OVERRIDE(glProgramUniformMatrix2fv);
341 OVERRIDE(glProgramUniformMatrix2x3fv);
342 OVERRIDE(glProgramUniformMatrix2x4fv);
343 OVERRIDE(glProgramUniformMatrix3fv);
344 OVERRIDE(glProgramUniformMatrix3x2fv);
345 OVERRIDE(glProgramUniformMatrix3x4fv);
346 OVERRIDE(glProgramUniformMatrix4fv);
347 OVERRIDE(glProgramUniformMatrix4x2fv);
348 OVERRIDE(glProgramUniformMatrix4x3fv);
349
Lingfeng Yangd3ae1062017-01-18 11:42:04 -0800350 OVERRIDE(glProgramParameteri);
Lingfeng Yang46153ab2017-01-09 13:37:22 -0800351 OVERRIDE(glUseProgramStages);
352 OVERRIDE(glBindProgramPipeline);
353
Lingfeng Yangd3ae1062017-01-18 11:42:04 -0800354 OVERRIDE(glGetProgramResourceiv);
355 OVERRIDE(glGetProgramResourceIndex);
356 OVERRIDE(glGetProgramResourceLocation);
357 OVERRIDE(glGetProgramResourceName);
358 OVERRIDE(glGetProgramPipelineInfoLog);
359
Lingfeng Yang46153ab2017-01-09 13:37:22 -0800360 OVERRIDE(glVertexAttribFormat);
361 OVERRIDE(glVertexAttribIFormat);
362 OVERRIDE(glVertexBindingDivisor);
363 OVERRIDE(glVertexAttribBinding);
364 OVERRIDE(glBindVertexBuffer);
365
366 OVERRIDE_CUSTOM(glDrawArraysIndirect);
367 OVERRIDE_CUSTOM(glDrawElementsIndirect);
368
369 OVERRIDE(glTexStorage2DMultisample);
Yahan Zhou72944ba2019-01-02 15:43:46 -0800370
371 OVERRIDE_CUSTOM(glGetGraphicsResetStatusEXT);
372 OVERRIDE_CUSTOM(glReadnPixelsEXT);
373 OVERRIDE_CUSTOM(glGetnUniformfvEXT);
374 OVERRIDE_CUSTOM(glGetnUniformivEXT);
keunyoungb85b2752013-03-08 12:28:03 -0800375}
376
377GL2Encoder::~GL2Encoder()
378{
379 delete m_compressedTextureFormats;
380}
381
382GLenum GL2Encoder::s_glGetError(void * self)
383{
384 GL2Encoder *ctx = (GL2Encoder *)self;
385 GLenum err = ctx->getError();
386 if(err != GL_NO_ERROR) {
Lingfeng Yang80a36332017-07-09 10:58:07 -0700387 ctx->m_glGetError_enc(ctx); // also clear host error
keunyoungb85b2752013-03-08 12:28:03 -0800388 ctx->setError(GL_NO_ERROR);
389 return err;
390 }
391
Lingfeng Yange980c7a2018-01-12 14:50:18 -0800392 if (ctx->m_noHostError) {
393 return GL_NO_ERROR;
394 } else {
395 return ctx->m_glGetError_enc(self);
396 }
Lingfeng Yang80a36332017-07-09 10:58:07 -0700397}
Yahan Zhouae30fe82016-08-10 21:15:45 +0000398
Lingfeng Yang80a36332017-07-09 10:58:07 -0700399class GL2Encoder::ErrorUpdater {
400public:
401 ErrorUpdater(GL2Encoder* ctx) :
402 mCtx(ctx),
403 guest_error(ctx->getError()),
404 host_error(ctx->m_glGetError_enc(ctx)) {
405 // Preserve any existing GL error in the guest:
406 // OpenGL ES 3.0.5 spec:
407 // The command enum GetError( void ); is used to obtain error information.
408 // Each detectable error is assigned a numeric code. When an error is
409 // detected, a flag is set and the code is recorded. Further errors, if
410 // they occur, do not affect this recorded code. When GetError is called,
411 // the code is returned and the flag is cleared, so that a further error
412 // will again record its code. If a call to GetError returns NO_ERROR, then
413 // there has been no detectable error since the last call to GetError (or
414 // since the GL was initialized).
415 if (guest_error == GL_NO_ERROR) {
416 guest_error = host_error;
417 }
418 }
419
420 GLenum getHostErrorAndUpdate() {
421 host_error = mCtx->m_glGetError_enc(mCtx);
422 if (guest_error == GL_NO_ERROR) {
423 guest_error = host_error;
424 }
425 return host_error;
426 }
427
428 void updateGuestErrorState() {
429 mCtx->setError(guest_error);
430 }
431
432private:
433 GL2Encoder* mCtx;
434 GLenum guest_error;
435 GLenum host_error;
436};
437
438template<class T>
439class GL2Encoder::ScopedQueryUpdate {
440public:
441 ScopedQueryUpdate(GL2Encoder* ctx, uint32_t bytes, T* target) :
442 mCtx(ctx),
443 mBuf(bytes, 0),
444 mTarget(target),
445 mErrorUpdater(ctx) {
446 }
447 T* hostStagingBuffer() {
448 return (T*)&mBuf[0];
449 }
450 ~ScopedQueryUpdate() {
451 GLint hostError = mErrorUpdater.getHostErrorAndUpdate();
Lingfeng Yang72ecf472018-06-11 14:20:14 -0700452 if (hostError == GL_NO_ERROR && mTarget) {
Lingfeng Yang80a36332017-07-09 10:58:07 -0700453 memcpy(mTarget, &mBuf[0], mBuf.size());
454 }
455 mErrorUpdater.updateGuestErrorState();
456 }
457private:
458 GL2Encoder* mCtx;
459 std::vector<char> mBuf;
460 T* mTarget;
461 ErrorUpdater mErrorUpdater;
462};
463
464void GL2Encoder::safe_glGetBooleanv(GLenum param, GLboolean* val) {
465 ScopedQueryUpdate<GLboolean> query(this, glUtilsParamSize(param) * sizeof(GLboolean), val);
466 m_glGetBooleanv_enc(this, param, query.hostStagingBuffer());
467}
468
469void GL2Encoder::safe_glGetFloatv(GLenum param, GLfloat* val) {
470 ScopedQueryUpdate<GLfloat> query(this, glUtilsParamSize(param) * sizeof(GLfloat), val);
471 m_glGetFloatv_enc(this, param, query.hostStagingBuffer());
472}
473
474void GL2Encoder::safe_glGetIntegerv(GLenum param, GLint* val) {
475 ScopedQueryUpdate<GLint> query(this, glUtilsParamSize(param) * sizeof(GLint), val);
476 m_glGetIntegerv_enc(this, param, query.hostStagingBuffer());
477}
478
479void GL2Encoder::safe_glGetInteger64v(GLenum param, GLint64* val) {
480 ScopedQueryUpdate<GLint64> query(this, glUtilsParamSize(param) * sizeof(GLint64), val);
481 m_glGetInteger64v_enc(this, param, query.hostStagingBuffer());
482}
483
484void GL2Encoder::safe_glGetIntegeri_v(GLenum param, GLuint index, GLint* val) {
485 ScopedQueryUpdate<GLint> query(this, sizeof(GLint), val);
486 m_glGetIntegeri_v_enc(this, param, index, query.hostStagingBuffer());
487}
488
489void GL2Encoder::safe_glGetInteger64i_v(GLenum param, GLuint index, GLint64* val) {
490 ScopedQueryUpdate<GLint64> query(this, sizeof(GLint64), val);
491 m_glGetInteger64i_v_enc(this, param, index, query.hostStagingBuffer());
492}
493
494void GL2Encoder::safe_glGetBooleani_v(GLenum param, GLuint index, GLboolean* val) {
495 ScopedQueryUpdate<GLboolean> query(this, sizeof(GLboolean), val);
496 m_glGetBooleani_v_enc(this, param, index, query.hostStagingBuffer());
keunyoungb85b2752013-03-08 12:28:03 -0800497}
498
499void GL2Encoder::s_glFlush(void *self)
500{
501 GL2Encoder *ctx = (GL2Encoder *) self;
502 ctx->m_glFlush_enc(self);
503 ctx->m_stream->flush();
504}
505
506const GLubyte *GL2Encoder::s_glGetString(void *self, GLenum name)
507{
Lingfeng Yang46153ab2017-01-09 13:37:22 -0800508 GL2Encoder *ctx = (GL2Encoder *)self;
David 'Digit' Turnere01d5f42014-10-30 21:32:28 +0100509
keunyoungb85b2752013-03-08 12:28:03 -0800510 GLubyte *retval = (GLubyte *) "";
Lingfeng Yang46153ab2017-01-09 13:37:22 -0800511 RET_AND_SET_ERROR_IF(
512 name != GL_VENDOR &&
513 name != GL_RENDERER &&
514 name != GL_VERSION &&
515 name != GL_EXTENSIONS,
516 GL_INVALID_ENUM,
517 retval);
keunyoungb85b2752013-03-08 12:28:03 -0800518 switch(name) {
519 case GL_VENDOR:
520 retval = gVendorString;
521 break;
522 case GL_RENDERER:
523 retval = gRendererString;
524 break;
525 case GL_VERSION:
526 retval = gVersionString;
527 break;
528 case GL_EXTENSIONS:
529 retval = gExtensionsString;
530 break;
531 }
532 return retval;
533}
534
535void GL2Encoder::s_glPixelStorei(void *self, GLenum param, GLint value)
536{
537 GL2Encoder *ctx = (GL2Encoder *)self;
Lingfeng Yang46153ab2017-01-09 13:37:22 -0800538 SET_ERROR_IF(!GLESv2Validation::pixelStoreParam(ctx, param), GL_INVALID_ENUM);
539 SET_ERROR_IF(!GLESv2Validation::pixelStoreValue(param, value), GL_INVALID_VALUE);
keunyoungb85b2752013-03-08 12:28:03 -0800540 ctx->m_glPixelStorei_enc(ctx, param, value);
541 assert(ctx->m_state != NULL);
542 ctx->m_state->setPixelStore(param, value);
543}
keunyoungb85b2752013-03-08 12:28:03 -0800544void GL2Encoder::s_glBindBuffer(void *self, GLenum target, GLuint id)
545{
546 GL2Encoder *ctx = (GL2Encoder *) self;
547 assert(ctx->m_state != NULL);
Lingfeng Yang554a5152019-02-21 20:20:48 -0800548 SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM);
549
Lingfeng Yang2c3a0da2019-03-07 20:43:53 -0800550 bool nop = ctx->m_state->isNonIndexedBindNoOp(target, id);
Lingfeng Yang554a5152019-02-21 20:20:48 -0800551
552 if (nop) return;
553
keunyoungb85b2752013-03-08 12:28:03 -0800554 ctx->m_state->bindBuffer(target, id);
Lingfeng Yangd3ae1062017-01-18 11:42:04 -0800555 ctx->m_state->addBuffer(id);
Lingfeng Yang554a5152019-02-21 20:20:48 -0800556 ctx->m_glBindBuffer_enc(ctx, target, id);
557 ctx->m_state->setLastEncodedBufferBind(target, id);
558}
559
560void GL2Encoder::doBindBufferEncodeCached(GLenum target, GLuint id) {
561 bool encode = id != m_state->getLastEncodedBufferBind(target);
562
563 if (encode) {
564 m_glBindBuffer_enc(this, target, id);
565 }
566
567 m_state->setLastEncodedBufferBind(target, id);
keunyoungb85b2752013-03-08 12:28:03 -0800568}
569
570void GL2Encoder::s_glBufferData(void * self, GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage)
571{
572 GL2Encoder *ctx = (GL2Encoder *) self;
Lingfeng Yang46153ab2017-01-09 13:37:22 -0800573 SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM);
keunyoungb85b2752013-03-08 12:28:03 -0800574 GLuint bufferId = ctx->m_state->getBuffer(target);
575 SET_ERROR_IF(bufferId==0, GL_INVALID_OPERATION);
576 SET_ERROR_IF(size<0, GL_INVALID_VALUE);
577
Roman Kiryanovfb903d62018-09-19 13:38:53 -0700578 ctx->m_shared->updateBufferData(bufferId, size, data);
Lingfeng Yang46153ab2017-01-09 13:37:22 -0800579 ctx->m_shared->setBufferUsage(bufferId, usage);
keunyoungb85b2752013-03-08 12:28:03 -0800580 ctx->m_glBufferData_enc(self, target, size, data, usage);
581}
582
583void GL2Encoder::s_glBufferSubData(void * self, GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data)
584{
585 GL2Encoder *ctx = (GL2Encoder *) self;
Lingfeng Yang46153ab2017-01-09 13:37:22 -0800586 SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM);
keunyoungb85b2752013-03-08 12:28:03 -0800587 GLuint bufferId = ctx->m_state->getBuffer(target);
588 SET_ERROR_IF(bufferId==0, GL_INVALID_OPERATION);
Lingfeng Yang46153ab2017-01-09 13:37:22 -0800589 SET_ERROR_IF(ctx->isBufferTargetMapped(target), GL_INVALID_OPERATION);
keunyoungb85b2752013-03-08 12:28:03 -0800590
Roman Kiryanovfb903d62018-09-19 13:38:53 -0700591 GLenum res = ctx->m_shared->subUpdateBufferData(bufferId, offset, size, data);
keunyoungb85b2752013-03-08 12:28:03 -0800592 SET_ERROR_IF(res, res);
593
594 ctx->m_glBufferSubData_enc(self, target, offset, size, data);
595}
596
Lingfeng Yangd3ae1062017-01-18 11:42:04 -0800597void GL2Encoder::s_glGenBuffers(void* self, GLsizei n, GLuint* buffers) {
598 GL2Encoder *ctx = (GL2Encoder *) self;
599 SET_ERROR_IF(n<0, GL_INVALID_VALUE);
600 ctx->m_glGenBuffers_enc(self, n, buffers);
601 for (int i = 0; i < n; i++) {
602 ctx->m_state->addBuffer(buffers[i]);
603 }
604}
605
keunyoungb85b2752013-03-08 12:28:03 -0800606void GL2Encoder::s_glDeleteBuffers(void * self, GLsizei n, const GLuint * buffers)
607{
608 GL2Encoder *ctx = (GL2Encoder *) self;
609 SET_ERROR_IF(n<0, GL_INVALID_VALUE);
610 for (int i=0; i<n; i++) {
Lingfeng Yang46153ab2017-01-09 13:37:22 -0800611 // Technically if the buffer is mapped, we should unmap it, but we won't
612 // use it anymore after this :)
keunyoungb85b2752013-03-08 12:28:03 -0800613 ctx->m_shared->deleteBufferData(buffers[i]);
bohub0f0cdf2014-11-06 18:08:07 -0800614 ctx->m_state->unBindBuffer(buffers[i]);
Lingfeng Yangd3ae1062017-01-18 11:42:04 -0800615 ctx->m_state->removeBuffer(buffers[i]);
keunyoungb85b2752013-03-08 12:28:03 -0800616 ctx->m_glDeleteBuffers_enc(self,1,&buffers[i]);
617 }
618}
619
Evan Birenbaumd51386b2016-04-13 12:53:09 -0700620static bool isValidVertexAttribIndex(void *self, GLuint indx)
621{
Lingfeng Yang07289902017-01-27 12:26:19 -0800622 GL2Encoder *ctx = (GL2Encoder *)self;
Evan Birenbaumd51386b2016-04-13 12:53:09 -0700623 GLint maxIndex;
624 ctx->glGetIntegerv(self, GL_MAX_VERTEX_ATTRIBS, &maxIndex);
625 return indx < maxIndex;
626}
627
Lingfeng Yang07289902017-01-27 12:26:19 -0800628#define VALIDATE_VERTEX_ATTRIB_INDEX(index) \
629 SET_ERROR_WITH_MESSAGE_IF( \
630 !isValidVertexAttribIndex(self, index), GL_INVALID_VALUE, \
631 GLESv2Validation::vertexAttribIndexRangeErrorMsg, (ctx, index)); \
632
David 'Digit' Turner02fdb692014-10-30 18:07:56 +0100633void GL2Encoder::s_glVertexAttribPointer(void *self, GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid * ptr)
keunyoungb85b2752013-03-08 12:28:03 -0800634{
635 GL2Encoder *ctx = (GL2Encoder *)self;
636 assert(ctx->m_state != NULL);
Lingfeng Yang07289902017-01-27 12:26:19 -0800637 VALIDATE_VERTEX_ATTRIB_INDEX(indx);
Evan Birenbaumd51386b2016-04-13 12:53:09 -0700638 SET_ERROR_IF((size < 1 || size > 4), GL_INVALID_VALUE);
Lingfeng Yang46153ab2017-01-09 13:37:22 -0800639 SET_ERROR_IF(!GLESv2Validation::vertexAttribType(ctx, type), GL_INVALID_ENUM);
Evan Birenbaumd51386b2016-04-13 12:53:09 -0700640 SET_ERROR_IF(stride < 0, GL_INVALID_VALUE);
Lingfeng Yang46153ab2017-01-09 13:37:22 -0800641 SET_ERROR_IF((type == GL_INT_2_10_10_10_REV ||
642 type == GL_UNSIGNED_INT_2_10_10_10_REV) &&
643 size != 4,
644 GL_INVALID_OPERATION);
645 ctx->m_state->setVertexAttribBinding(indx, indx);
646 ctx->m_state->setVertexAttribFormat(indx, size, type, normalized, 0, false);
647
648 GLsizei effectiveStride = stride;
649 if (stride == 0) {
Lingfeng Yang554a5152019-02-21 20:20:48 -0800650 effectiveStride = glSizeof(type) * size;
Lingfeng Yang46153ab2017-01-09 13:37:22 -0800651 switch (type) {
652 case GL_INT_2_10_10_10_REV:
653 case GL_UNSIGNED_INT_2_10_10_10_REV:
654 effectiveStride /= 4;
655 break;
656 default:
657 break;
658 }
659 }
660
661 ctx->m_state->bindIndexedBuffer(0, indx, ctx->m_state->currentArrayVbo(), (uintptr_t)ptr, 0, stride, effectiveStride);
662
Lingfeng Yangfe2a31d2016-12-02 08:02:15 -0800663 if (ctx->m_state->currentArrayVbo() != 0) {
664 ctx->glVertexAttribPointerOffset(ctx, indx, size, type, normalized, stride, (uintptr_t)ptr);
665 } else {
Lingfeng Yang46153ab2017-01-09 13:37:22 -0800666 SET_ERROR_IF(ctx->m_state->currentVertexArrayObject() != 0 && ptr, GL_INVALID_OPERATION);
667 // wait for client-array handler
Lingfeng Yangfe2a31d2016-12-02 08:02:15 -0800668 }
keunyoungb85b2752013-03-08 12:28:03 -0800669}
670
671void GL2Encoder::s_glGetIntegerv(void *self, GLenum param, GLint *ptr)
672{
673 GL2Encoder *ctx = (GL2Encoder *) self;
keunyoungb85b2752013-03-08 12:28:03 -0800674 GLClientState* state = ctx->m_state;
675
676 switch (param) {
Lingfeng Yanga16eb2e2018-02-23 11:26:53 -0800677 case GL_NUM_EXTENSIONS:
678 *ptr = (int)ctx->m_currExtensionsArray.size();
679 break;
Lingfeng Yang46153ab2017-01-09 13:37:22 -0800680 case GL_MAJOR_VERSION:
Lingfeng Yang324c8452017-02-17 09:56:26 -0800681 *ptr = ctx->m_deviceMajorVersion;
Lingfeng Yang46153ab2017-01-09 13:37:22 -0800682 break;
683 case GL_MINOR_VERSION:
Lingfeng Yang324c8452017-02-17 09:56:26 -0800684 *ptr = ctx->m_deviceMinorVersion;
Lingfeng Yang46153ab2017-01-09 13:37:22 -0800685 break;
keunyoungb85b2752013-03-08 12:28:03 -0800686 case GL_NUM_SHADER_BINARY_FORMATS:
687 *ptr = 0;
688 break;
689 case GL_SHADER_BINARY_FORMATS:
690 // do nothing
691 break;
692
693 case GL_COMPRESSED_TEXTURE_FORMATS: {
694 GLint *compressedTextureFormats = ctx->getCompressedTextureFormats();
695 if (ctx->m_num_compressedTextureFormats > 0 &&
696 compressedTextureFormats != NULL) {
697 memcpy(ptr, compressedTextureFormats,
698 ctx->m_num_compressedTextureFormats * sizeof(GLint));
699 }
700 break;
701 }
702
703 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
Lingfeng Yang48685bb2018-10-19 06:44:20 -0700704 if (ctx->m_max_combinedTextureImageUnits != 0) {
705 *ptr = ctx->m_max_combinedTextureImageUnits;
706 } else {
707 ctx->safe_glGetIntegerv(param, ptr);
708 ctx->m_max_combinedTextureImageUnits = *ptr;
709 }
710 break;
keunyoungb85b2752013-03-08 12:28:03 -0800711 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
Lingfeng Yanga1edab62018-10-19 07:53:49 -0700712 if (ctx->m_max_vertexTextureImageUnits != 0) {
713 *ptr = ctx->m_max_vertexTextureImageUnits;
714 } else {
715 ctx->safe_glGetIntegerv(param, ptr);
716 ctx->m_max_vertexTextureImageUnits = *ptr;
717 }
keunyoungb85b2752013-03-08 12:28:03 -0800718 break;
Lingfeng Yanga1edab62018-10-19 07:53:49 -0700719 case GL_MAX_TEXTURE_IMAGE_UNITS:
720 if (ctx->m_max_textureImageUnits != 0) {
721 *ptr = ctx->m_max_textureImageUnits;
722 } else {
723 ctx->safe_glGetIntegerv(param, ptr);
724 ctx->m_max_textureImageUnits = *ptr;
725 }
726 break;
keunyoungb85b2752013-03-08 12:28:03 -0800727 case GL_TEXTURE_BINDING_2D:
Lingfeng Yang83de3d12018-10-17 10:57:53 -0700728 SET_ERROR_IF(!state, GL_INVALID_OPERATION);
keunyoungb85b2752013-03-08 12:28:03 -0800729 *ptr = state->getBoundTexture(GL_TEXTURE_2D);
730 break;
731 case GL_TEXTURE_BINDING_EXTERNAL_OES:
Lingfeng Yang83de3d12018-10-17 10:57:53 -0700732 SET_ERROR_IF(!state, GL_INVALID_OPERATION);
keunyoungb85b2752013-03-08 12:28:03 -0800733 *ptr = state->getBoundTexture(GL_TEXTURE_EXTERNAL_OES);
734 break;
735
Lingfeng Yangb0176982016-03-01 21:27:49 -0800736 case GL_MAX_VERTEX_ATTRIBS:
Lingfeng Yang83de3d12018-10-17 10:57:53 -0700737 SET_ERROR_IF(!state, GL_INVALID_OPERATION);
738 if (!state->getClientStateParameter<GLint>(param, ptr)) {
Lingfeng Yang80a36332017-07-09 10:58:07 -0700739 ctx->safe_glGetIntegerv(param, ptr);
Lingfeng Yang83de3d12018-10-17 10:57:53 -0700740 state->setMaxVertexAttribs(*ptr);
Yahan Zhoua5c36842016-06-01 12:49:39 -0700741 }
742 break;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -0800743 case GL_MAX_VERTEX_ATTRIB_STRIDE:
744 if (ctx->m_max_vertexAttribStride != 0) {
745 *ptr = ctx->m_max_vertexAttribStride;
746 } else {
Lingfeng Yang80a36332017-07-09 10:58:07 -0700747 ctx->safe_glGetIntegerv(param, ptr);
Lingfeng Yangd3ae1062017-01-18 11:42:04 -0800748 ctx->m_max_vertexAttribStride = *ptr;
749 }
750 break;
Lizhe Liue41f4ef2015-05-27 11:13:23 +0800751 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
752 if (ctx->m_max_cubeMapTextureSize != 0) {
753 *ptr = ctx->m_max_cubeMapTextureSize;
754 } else {
Lingfeng Yang80a36332017-07-09 10:58:07 -0700755 ctx->safe_glGetIntegerv(param, ptr);
Lizhe Liue41f4ef2015-05-27 11:13:23 +0800756 ctx->m_max_cubeMapTextureSize = *ptr;
757 }
758 break;
759 case GL_MAX_RENDERBUFFER_SIZE:
760 if (ctx->m_max_renderBufferSize != 0) {
761 *ptr = ctx->m_max_renderBufferSize;
762 } else {
Lingfeng Yang80a36332017-07-09 10:58:07 -0700763 ctx->safe_glGetIntegerv(param, ptr);
Lizhe Liue41f4ef2015-05-27 11:13:23 +0800764 ctx->m_max_renderBufferSize = *ptr;
765 }
766 break;
767 case GL_MAX_TEXTURE_SIZE:
768 if (ctx->m_max_textureSize != 0) {
769 *ptr = ctx->m_max_textureSize;
770 } else {
Lingfeng Yang80a36332017-07-09 10:58:07 -0700771 ctx->safe_glGetIntegerv(param, ptr);
Lizhe Liue41f4ef2015-05-27 11:13:23 +0800772 ctx->m_max_textureSize = *ptr;
Lingfeng Yangb0176982016-03-01 21:27:49 -0800773 }
774 break;
Lingfeng Yang46153ab2017-01-09 13:37:22 -0800775 case GL_MAX_3D_TEXTURE_SIZE:
776 if (ctx->m_max_3d_textureSize != 0) {
777 *ptr = ctx->m_max_3d_textureSize;
778 } else {
Lingfeng Yang80a36332017-07-09 10:58:07 -0700779 ctx->safe_glGetIntegerv(param, ptr);
Lingfeng Yang46153ab2017-01-09 13:37:22 -0800780 ctx->m_max_3d_textureSize = *ptr;
781 }
782 break;
783 case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
784 if (ctx->m_ssbo_offset_align != 0) {
785 *ptr = ctx->m_ssbo_offset_align;
786 } else {
Lingfeng Yang80a36332017-07-09 10:58:07 -0700787 ctx->safe_glGetIntegerv(param, ptr);
Lingfeng Yang46153ab2017-01-09 13:37:22 -0800788 ctx->m_ssbo_offset_align = *ptr;
789 }
790 break;
791 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
792 if (ctx->m_ubo_offset_align != 0) {
793 *ptr = ctx->m_ubo_offset_align;
794 } else {
Lingfeng Yang80a36332017-07-09 10:58:07 -0700795 ctx->safe_glGetIntegerv(param, ptr);
Lingfeng Yang46153ab2017-01-09 13:37:22 -0800796 ctx->m_ubo_offset_align = *ptr;
797 }
798 break;
799 // Desktop OpenGL can allow a mindboggling # samples per pixel (such as 64).
800 // Limit to 4 (spec minimum) to keep dEQP tests from timing out.
801 case GL_MAX_SAMPLES:
Lingfeng Yangd3ae1062017-01-18 11:42:04 -0800802 case GL_MAX_COLOR_TEXTURE_SAMPLES:
803 case GL_MAX_INTEGER_SAMPLES:
804 case GL_MAX_DEPTH_TEXTURE_SAMPLES:
Lingfeng Yang46153ab2017-01-09 13:37:22 -0800805 *ptr = 4;
806 break;
Lingfeng Yangc9b597b2017-07-08 17:21:03 -0700807 // Checks for version-incompatible enums.
808 // Not allowed in vanilla ES 2.0.
809 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
Lingfeng Yanga1edab62018-10-19 07:53:49 -0700810 SET_ERROR_IF(ctx->majorVersion() < 3, GL_INVALID_ENUM);
811 if (ctx->m_max_transformFeedbackSeparateAttribs != 0) {
812 *ptr = ctx->m_max_transformFeedbackSeparateAttribs;
813 } else {
814 ctx->safe_glGetIntegerv(param, ptr);
815 ctx->m_max_transformFeedbackSeparateAttribs = *ptr;
816 }
817 break;
Lingfeng Yangc9b597b2017-07-08 17:21:03 -0700818 case GL_MAX_UNIFORM_BUFFER_BINDINGS:
819 SET_ERROR_IF(ctx->majorVersion() < 3, GL_INVALID_ENUM);
Lingfeng Yanga1edab62018-10-19 07:53:49 -0700820 if (ctx->m_max_uniformBufferBindings != 0) {
821 *ptr = ctx->m_max_uniformBufferBindings;
822 } else {
823 ctx->safe_glGetIntegerv(param, ptr);
824 ctx->m_max_uniformBufferBindings = *ptr;
825 }
Lingfeng Yangc9b597b2017-07-08 17:21:03 -0700826 break;
827 case GL_MAX_COLOR_ATTACHMENTS:
Lingfeng Yanga1edab62018-10-19 07:53:49 -0700828 SET_ERROR_IF(ctx->majorVersion() < 3 &&
829 !ctx->hasExtension("GL_EXT_draw_buffers"), GL_INVALID_ENUM);
830 if (ctx->m_max_colorAttachments != 0) {
831 *ptr = ctx->m_max_colorAttachments;
832 } else {
833 ctx->safe_glGetIntegerv(param, ptr);
834 ctx->m_max_colorAttachments = *ptr;
835 }
836 break;
Lingfeng Yangc9b597b2017-07-08 17:21:03 -0700837 case GL_MAX_DRAW_BUFFERS:
838 SET_ERROR_IF(ctx->majorVersion() < 3 &&
839 !ctx->hasExtension("GL_EXT_draw_buffers"), GL_INVALID_ENUM);
Lingfeng Yanga1edab62018-10-19 07:53:49 -0700840 if (ctx->m_max_drawBuffers != 0) {
841 *ptr = ctx->m_max_drawBuffers;
842 } else {
843 ctx->safe_glGetIntegerv(param, ptr);
844 ctx->m_max_drawBuffers = *ptr;
845 }
Lingfeng Yangc9b597b2017-07-08 17:21:03 -0700846 break;
847 // Not allowed in ES 3.0.
848 case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
Lingfeng Yanga1edab62018-10-19 07:53:49 -0700849 SET_ERROR_IF(ctx->majorVersion() < 3 ||
850 (ctx->majorVersion() == 3 &&
851 ctx->minorVersion() == 0), GL_INVALID_ENUM);
852 if (ctx->m_max_atomicCounterBufferBindings != 0) {
853 *ptr = ctx->m_max_atomicCounterBufferBindings;
854 } else {
855 ctx->safe_glGetIntegerv(param, ptr);
856 ctx->m_max_atomicCounterBufferBindings = *ptr;
857 }
858 break;
Lingfeng Yangc9b597b2017-07-08 17:21:03 -0700859 case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
Lingfeng Yanga1edab62018-10-19 07:53:49 -0700860 SET_ERROR_IF(ctx->majorVersion() < 3 ||
861 (ctx->majorVersion() == 3 &&
862 ctx->minorVersion() == 0), GL_INVALID_ENUM);
863 if (ctx->m_max_shaderStorageBufferBindings != 0) {
864 *ptr = ctx->m_max_shaderStorageBufferBindings;
865 } else {
866 ctx->safe_glGetIntegerv(param, ptr);
867 ctx->m_max_shaderStorageBufferBindings = *ptr;
868 }
869 break;
Lingfeng Yangc9b597b2017-07-08 17:21:03 -0700870 case GL_MAX_VERTEX_ATTRIB_BINDINGS:
871 SET_ERROR_IF(ctx->majorVersion() < 3 ||
872 (ctx->majorVersion() == 3 &&
873 ctx->minorVersion() == 0), GL_INVALID_ENUM);
Lingfeng Yanga1edab62018-10-19 07:53:49 -0700874 if (ctx->m_max_vertexAttribBindings != 0) {
875 *ptr = ctx->m_max_vertexAttribBindings;
876 } else {
877 ctx->safe_glGetIntegerv(param, ptr);
878 ctx->m_max_vertexAttribBindings = *ptr;
879 }
Lingfeng Yangc9b597b2017-07-08 17:21:03 -0700880 break;
Yahan Zhou72944ba2019-01-02 15:43:46 -0800881 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
882 // BUG: 121414786
883 *ptr = GL_LOSE_CONTEXT_ON_RESET_EXT;
884 break;
keunyoungb85b2752013-03-08 12:28:03 -0800885 default:
Lingfeng Yang83de3d12018-10-17 10:57:53 -0700886 SET_ERROR_IF(!state, GL_INVALID_OPERATION);
887 if (!state->getClientStateParameter<GLint>(param, ptr)) {
Lingfeng Yang80a36332017-07-09 10:58:07 -0700888 ctx->safe_glGetIntegerv(param, ptr);
keunyoungb85b2752013-03-08 12:28:03 -0800889 }
890 break;
891 }
892}
893
894
895void GL2Encoder::s_glGetFloatv(void *self, GLenum param, GLfloat *ptr)
896{
897 GL2Encoder *ctx = (GL2Encoder *)self;
keunyoungb85b2752013-03-08 12:28:03 -0800898 GLClientState* state = ctx->m_state;
899
900 switch (param) {
901 case GL_NUM_SHADER_BINARY_FORMATS:
902 *ptr = 0;
903 break;
904 case GL_SHADER_BINARY_FORMATS:
905 // do nothing
906 break;
907
908 case GL_COMPRESSED_TEXTURE_FORMATS: {
909 GLint *compressedTextureFormats = ctx->getCompressedTextureFormats();
910 if (ctx->m_num_compressedTextureFormats > 0 &&
911 compressedTextureFormats != NULL) {
912 for (int i = 0; i < ctx->m_num_compressedTextureFormats; i++) {
913 ptr[i] = (GLfloat) compressedTextureFormats[i];
914 }
915 }
916 break;
917 }
918
919 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
920 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
921 case GL_MAX_TEXTURE_IMAGE_UNITS:
Lingfeng Yanga1edab62018-10-19 07:53:49 -0700922 case GL_MAX_VERTEX_ATTRIBS:
923 case GL_MAX_VERTEX_ATTRIB_STRIDE:
924 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
925 case GL_MAX_RENDERBUFFER_SIZE:
926 case GL_MAX_TEXTURE_SIZE:
927 case GL_MAX_3D_TEXTURE_SIZE:
928 case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
929 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
930 case GL_MAX_SAMPLES:
931 case GL_MAX_COLOR_TEXTURE_SAMPLES:
932 case GL_MAX_INTEGER_SAMPLES:
933 case GL_MAX_DEPTH_TEXTURE_SAMPLES:
934 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
935 case GL_MAX_UNIFORM_BUFFER_BINDINGS:
936 case GL_MAX_COLOR_ATTACHMENTS:
937 case GL_MAX_DRAW_BUFFERS:
938 case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
939 case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
940 case GL_MAX_VERTEX_ATTRIB_BINDINGS:
keunyoungb85b2752013-03-08 12:28:03 -0800941 case GL_TEXTURE_BINDING_2D:
Lingfeng Yanga1edab62018-10-19 07:53:49 -0700942 case GL_TEXTURE_BINDING_EXTERNAL_OES: {
943 GLint res;
944 s_glGetIntegerv(ctx, param, &res);
945 *ptr = (GLfloat)res;
keunyoungb85b2752013-03-08 12:28:03 -0800946 break;
Lingfeng Yanga1edab62018-10-19 07:53:49 -0700947 }
keunyoungb85b2752013-03-08 12:28:03 -0800948
949 default:
Lingfeng Yang83de3d12018-10-17 10:57:53 -0700950 SET_ERROR_IF(!state, GL_INVALID_OPERATION);
951 if (!state->getClientStateParameter<GLfloat>(param, ptr)) {
Lingfeng Yang80a36332017-07-09 10:58:07 -0700952 ctx->safe_glGetFloatv(param, ptr);
keunyoungb85b2752013-03-08 12:28:03 -0800953 }
954 break;
955 }
956}
957
958
959void GL2Encoder::s_glGetBooleanv(void *self, GLenum param, GLboolean *ptr)
960{
961 GL2Encoder *ctx = (GL2Encoder *)self;
keunyoungb85b2752013-03-08 12:28:03 -0800962 GLClientState* state = ctx->m_state;
963
964 switch (param) {
965 case GL_NUM_SHADER_BINARY_FORMATS:
966 *ptr = GL_FALSE;
967 break;
968 case GL_SHADER_BINARY_FORMATS:
969 // do nothing
970 break;
971
972 case GL_COMPRESSED_TEXTURE_FORMATS: {
973 GLint *compressedTextureFormats = ctx->getCompressedTextureFormats();
974 if (ctx->m_num_compressedTextureFormats > 0 &&
975 compressedTextureFormats != NULL) {
976 for (int i = 0; i < ctx->m_num_compressedTextureFormats; i++) {
977 ptr[i] = compressedTextureFormats[i] != 0 ? GL_TRUE : GL_FALSE;
978 }
979 }
980 break;
981 }
982
Lingfeng Yanga1edab62018-10-19 07:53:49 -0700983 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
984 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
985 case GL_MAX_TEXTURE_IMAGE_UNITS:
986 case GL_MAX_VERTEX_ATTRIBS:
987 case GL_MAX_VERTEX_ATTRIB_STRIDE:
988 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
989 case GL_MAX_RENDERBUFFER_SIZE:
990 case GL_MAX_TEXTURE_SIZE:
991 case GL_MAX_3D_TEXTURE_SIZE:
992 case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
993 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
994 case GL_MAX_SAMPLES:
995 case GL_MAX_COLOR_TEXTURE_SAMPLES:
996 case GL_MAX_INTEGER_SAMPLES:
997 case GL_MAX_DEPTH_TEXTURE_SAMPLES:
998 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
999 case GL_MAX_UNIFORM_BUFFER_BINDINGS:
1000 case GL_MAX_COLOR_ATTACHMENTS:
1001 case GL_MAX_DRAW_BUFFERS:
1002 case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
1003 case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
1004 case GL_MAX_VERTEX_ATTRIB_BINDINGS:
keunyoungb85b2752013-03-08 12:28:03 -08001005 case GL_TEXTURE_BINDING_2D:
Lingfeng Yanga1edab62018-10-19 07:53:49 -07001006 case GL_TEXTURE_BINDING_EXTERNAL_OES: {
1007 GLint res;
1008 s_glGetIntegerv(ctx, param, &res);
1009 *ptr = res == 0 ? GL_FALSE : GL_TRUE;
keunyoungb85b2752013-03-08 12:28:03 -08001010 break;
Lingfeng Yanga1edab62018-10-19 07:53:49 -07001011 }
keunyoungb85b2752013-03-08 12:28:03 -08001012
1013 default:
Lingfeng Yang83de3d12018-10-17 10:57:53 -07001014 SET_ERROR_IF(!state, GL_INVALID_OPERATION);
1015 if (!state->getClientStateParameter<GLboolean>(param, ptr)) {
Lingfeng Yang80a36332017-07-09 10:58:07 -07001016 ctx->safe_glGetBooleanv(param, ptr);
keunyoungb85b2752013-03-08 12:28:03 -08001017 }
bohu05101d22014-11-17 16:28:42 -08001018 *ptr = (*ptr != 0) ? GL_TRUE : GL_FALSE;
keunyoungb85b2752013-03-08 12:28:03 -08001019 break;
1020 }
1021}
1022
1023
1024void GL2Encoder::s_glEnableVertexAttribArray(void *self, GLuint index)
1025{
1026 GL2Encoder *ctx = (GL2Encoder *)self;
1027 assert(ctx->m_state);
Lingfeng Yang07289902017-01-27 12:26:19 -08001028 VALIDATE_VERTEX_ATTRIB_INDEX(index);
Lingfeng Yangfe2a31d2016-12-02 08:02:15 -08001029 ctx->m_glEnableVertexAttribArray_enc(ctx, index);
keunyoungb85b2752013-03-08 12:28:03 -08001030 ctx->m_state->enable(index, 1);
1031}
1032
1033void GL2Encoder::s_glDisableVertexAttribArray(void *self, GLuint index)
1034{
1035 GL2Encoder *ctx = (GL2Encoder *)self;
1036 assert(ctx->m_state);
Lingfeng Yang07289902017-01-27 12:26:19 -08001037 VALIDATE_VERTEX_ATTRIB_INDEX(index);
Lingfeng Yangfe2a31d2016-12-02 08:02:15 -08001038 ctx->m_glDisableVertexAttribArray_enc(ctx, index);
keunyoungb85b2752013-03-08 12:28:03 -08001039 ctx->m_state->enable(index, 0);
1040}
1041
1042
1043void GL2Encoder::s_glGetVertexAttribiv(void *self, GLuint index, GLenum pname, GLint *params)
1044{
1045 GL2Encoder *ctx = (GL2Encoder *)self;
1046 assert(ctx->m_state);
Lingfeng Yang0f508082016-04-08 12:38:35 -07001047 GLint maxIndex;
1048 ctx->glGetIntegerv(self, GL_MAX_VERTEX_ATTRIBS, &maxIndex);
1049 SET_ERROR_IF(!(index < maxIndex), GL_INVALID_VALUE);
keunyoungb85b2752013-03-08 12:28:03 -08001050
1051 if (!ctx->m_state->getVertexAttribParameter<GLint>(index, pname, params)) {
1052 ctx->m_glGetVertexAttribiv_enc(self, index, pname, params);
1053 }
1054}
1055
1056void GL2Encoder::s_glGetVertexAttribfv(void *self, GLuint index, GLenum pname, GLfloat *params)
1057{
1058 GL2Encoder *ctx = (GL2Encoder *)self;
1059 assert(ctx->m_state);
Lingfeng Yang0f508082016-04-08 12:38:35 -07001060 GLint maxIndex;
1061 ctx->glGetIntegerv(self, GL_MAX_VERTEX_ATTRIBS, &maxIndex);
1062 SET_ERROR_IF(!(index < maxIndex), GL_INVALID_VALUE);
keunyoungb85b2752013-03-08 12:28:03 -08001063
1064 if (!ctx->m_state->getVertexAttribParameter<GLfloat>(index, pname, params)) {
1065 ctx->m_glGetVertexAttribfv_enc(self, index, pname, params);
1066 }
1067}
1068
1069void GL2Encoder::s_glGetVertexAttribPointerv(void *self, GLuint index, GLenum pname, GLvoid **pointer)
1070{
1071 GL2Encoder *ctx = (GL2Encoder *)self;
1072 if (ctx->m_state == NULL) return;
Lingfeng Yang5e100432016-04-08 12:46:42 -07001073 GLint maxIndex;
1074 ctx->glGetIntegerv(self, GL_MAX_VERTEX_ATTRIBS, &maxIndex);
1075 SET_ERROR_IF(!(index < maxIndex), GL_INVALID_VALUE);
1076 SET_ERROR_IF(pname != GL_VERTEX_ATTRIB_ARRAY_POINTER, GL_INVALID_ENUM);
David 'Digit' Turnere01d5f42014-10-30 21:32:28 +01001077 (void)pname;
1078
Lingfeng Yang46153ab2017-01-09 13:37:22 -08001079 *pointer = (GLvoid*)(ctx->m_state->getCurrAttributeBindingInfo(index).offset);
keunyoungb85b2752013-03-08 12:28:03 -08001080}
1081
Lingfeng Yang8e2b6e02016-10-14 11:20:45 -07001082void GL2Encoder::calcIndexRange(const void* indices,
1083 GLenum type,
1084 GLsizei count,
1085 int* minIndex_out,
1086 int* maxIndex_out) {
1087 switch(type) {
1088 case GL_BYTE:
1089 case GL_UNSIGNED_BYTE:
1090 GLUtils::minmaxExcept(
1091 (unsigned char *)indices, count,
1092 minIndex_out, maxIndex_out,
Lingfeng Yang46153ab2017-01-09 13:37:22 -08001093 m_primitiveRestartEnabled, GLUtils::primitiveRestartIndex<unsigned char>());
Lingfeng Yang8e2b6e02016-10-14 11:20:45 -07001094 break;
1095 case GL_SHORT:
1096 case GL_UNSIGNED_SHORT:
1097 GLUtils::minmaxExcept(
1098 (unsigned short *)indices, count,
1099 minIndex_out, maxIndex_out,
Lingfeng Yang46153ab2017-01-09 13:37:22 -08001100 m_primitiveRestartEnabled, GLUtils::primitiveRestartIndex<unsigned short>());
Lingfeng Yang8e2b6e02016-10-14 11:20:45 -07001101 break;
1102 case GL_INT:
1103 case GL_UNSIGNED_INT:
1104 GLUtils::minmaxExcept(
1105 (unsigned int *)indices, count,
1106 minIndex_out, maxIndex_out,
Lingfeng Yang46153ab2017-01-09 13:37:22 -08001107 m_primitiveRestartEnabled, GLUtils::primitiveRestartIndex<unsigned int>());
Lingfeng Yang8e2b6e02016-10-14 11:20:45 -07001108 break;
1109 default:
1110 ALOGE("unsupported index buffer type %d\n", type);
1111 }
1112}
1113
1114void* GL2Encoder::recenterIndices(const void* src,
1115 GLenum type,
1116 GLsizei count,
1117 int minIndex) {
1118
1119 void* adjustedIndices = (void*)src;
1120
1121 if (minIndex != 0) {
1122 adjustedIndices = m_fixedBuffer.alloc(glSizeof(type) * count);
1123 switch(type) {
1124 case GL_BYTE:
1125 case GL_UNSIGNED_BYTE:
1126 GLUtils::shiftIndicesExcept(
1127 (unsigned char *)src,
1128 (unsigned char *)adjustedIndices,
1129 count, -minIndex,
1130 m_primitiveRestartEnabled,
1131 (unsigned char)m_primitiveRestartIndex);
1132 break;
1133 case GL_SHORT:
1134 case GL_UNSIGNED_SHORT:
1135 GLUtils::shiftIndicesExcept(
1136 (unsigned short *)src,
1137 (unsigned short *)adjustedIndices,
1138 count, -minIndex,
1139 m_primitiveRestartEnabled,
1140 (unsigned short)m_primitiveRestartIndex);
1141 break;
1142 case GL_INT:
1143 case GL_UNSIGNED_INT:
1144 GLUtils::shiftIndicesExcept(
1145 (unsigned int *)src,
1146 (unsigned int *)adjustedIndices,
1147 count, -minIndex,
1148 m_primitiveRestartEnabled,
1149 (unsigned int)m_primitiveRestartIndex);
1150 break;
1151 default:
1152 ALOGE("unsupported index buffer type %d\n", type);
1153 }
1154 }
1155
1156 return adjustedIndices;
1157}
1158
1159void GL2Encoder::getBufferIndexRange(BufferData* buf,
1160 const void* dataWithOffset,
1161 GLenum type,
Lingfeng Yang1ae9d732016-12-12 16:17:02 -08001162 size_t count,
1163 size_t offset,
Lingfeng Yang8e2b6e02016-10-14 11:20:45 -07001164 int* minIndex_out,
1165 int* maxIndex_out) {
1166
1167 if (buf->m_indexRangeCache.findRange(
Lingfeng Yang1ae9d732016-12-12 16:17:02 -08001168 type, offset, count,
Lingfeng Yang8e2b6e02016-10-14 11:20:45 -07001169 m_primitiveRestartEnabled,
1170 minIndex_out,
1171 maxIndex_out)) {
1172 return;
1173 }
1174
1175 calcIndexRange(dataWithOffset, type, count, minIndex_out, maxIndex_out);
1176
1177 buf->m_indexRangeCache.addRange(
Lingfeng Yang1ae9d732016-12-12 16:17:02 -08001178 type, offset, count, m_primitiveRestartEnabled,
Lingfeng Yang8e2b6e02016-10-14 11:20:45 -07001179 *minIndex_out, *maxIndex_out);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08001180
1181 ALOGV("%s: got range [%u %u] pr? %d", __FUNCTION__, *minIndex_out, *maxIndex_out, m_primitiveRestartEnabled);
Lingfeng Yang8e2b6e02016-10-14 11:20:45 -07001182}
keunyoungb85b2752013-03-08 12:28:03 -08001183
Lingfeng Yangfe2a31d2016-12-02 08:02:15 -08001184// For detecting legacy usage of glVertexAttribPointer
1185void GL2Encoder::getVBOUsage(bool* hasClientArrays, bool* hasVBOs) const {
1186 if (hasClientArrays) *hasClientArrays = false;
1187 if (hasVBOs) *hasVBOs = false;
1188
1189 for (int i = 0; i < m_state->nLocations(); i++) {
Lingfeng Yang46153ab2017-01-09 13:37:22 -08001190 const GLClientState::VertexAttribState& state = m_state->getState(i);
1191 if (state.enabled) {
1192 const GLClientState::BufferBinding& curr_binding = m_state->getCurrAttributeBindingInfo(i);
1193 GLuint bufferObject = curr_binding.buffer;
1194 if (bufferObject == 0 && curr_binding.offset && hasClientArrays) {
Lingfeng Yangfe2a31d2016-12-02 08:02:15 -08001195 *hasClientArrays = true;
1196 }
Lingfeng Yang46153ab2017-01-09 13:37:22 -08001197 if (bufferObject != 0 && hasVBOs) {
Lingfeng Yangfe2a31d2016-12-02 08:02:15 -08001198 *hasVBOs = true;
1199 }
1200 }
1201 }
1202}
1203
Lingfeng Yang46153ab2017-01-09 13:37:22 -08001204void GL2Encoder::sendVertexAttributes(GLint first, GLsizei count, bool hasClientArrays, GLsizei primcount)
keunyoungb85b2752013-03-08 12:28:03 -08001205{
1206 assert(m_state);
1207
Lingfeng Yang554a5152019-02-21 20:20:48 -08001208 m_state->updateEnableDirtyArrayForDraw();
1209
Lingfeng Yang398162b2016-05-26 14:18:33 -07001210 GLuint lastBoundVbo = m_state->currentArrayVbo();
Lingfeng Yang554a5152019-02-21 20:20:48 -08001211 const GLClientState::VAOState& vaoState = m_state->currentVaoState();
keunyoungb85b2752013-03-08 12:28:03 -08001212
Lingfeng Yang554a5152019-02-21 20:20:48 -08001213 for (int k = 0; k < vaoState.numAttributesNeedingUpdateForDraw; k++) {
1214 int i = vaoState.attributesNeedingUpdateForDraw[k];
1215
1216 const GLClientState::VertexAttribState& state = vaoState.attribState[i];
keunyoungb85b2752013-03-08 12:28:03 -08001217
Lingfeng Yang46153ab2017-01-09 13:37:22 -08001218 if (state.enabled) {
1219 const GLClientState::BufferBinding& curr_binding = m_state->getCurrAttributeBindingInfo(i);
1220 GLuint bufferObject = curr_binding.buffer;
1221 if (hasClientArrays && lastBoundVbo != bufferObject) {
Lingfeng Yang554a5152019-02-21 20:20:48 -08001222 doBindBufferEncodeCached(GL_ARRAY_BUFFER, bufferObject);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08001223 lastBoundVbo = bufferObject;
Lingfeng Yang398162b2016-05-26 14:18:33 -07001224 }
keunyoungb85b2752013-03-08 12:28:03 -08001225
Lingfeng Yang46153ab2017-01-09 13:37:22 -08001226 int divisor = curr_binding.divisor;
1227 int stride = curr_binding.stride;
1228 int effectiveStride = curr_binding.effectiveStride;
1229 uintptr_t offset = curr_binding.offset;
Lingfeng Yang4e5446b2017-02-15 08:44:21 -08001230
Lingfeng Yang46153ab2017-01-09 13:37:22 -08001231 int firstIndex = effectiveStride * first;
Lingfeng Yang4e5446b2017-02-15 08:44:21 -08001232 if (firstIndex && divisor && !primcount) {
1233 // If firstIndex != 0 according to effectiveStride * first,
1234 // it needs to be adjusted if a divisor has been specified,
1235 // even if we are not in glDraw***Instanced.
1236 firstIndex = 0;
1237 }
keunyoungb85b2752013-03-08 12:28:03 -08001238
Lingfeng Yang46153ab2017-01-09 13:37:22 -08001239 if (bufferObject == 0) {
1240 unsigned int datalen = state.elementSize * count;
Yahan Zhoufe1820e2018-12-06 17:18:12 -08001241 if (divisor) {
Lingfeng Yang46153ab2017-01-09 13:37:22 -08001242 ALOGV("%s: divisor for att %d: %d, w/ stride %d (effective stride %d) size %d type 0x%x) datalen %u",
1243 __FUNCTION__, i, divisor, state.stride, effectiveStride, state.elementSize, state.type, datalen);
1244 int actual_count = std::max(1, (int)((primcount + divisor - 1) / divisor));
1245 datalen = state.elementSize * actual_count;
1246 ALOGV("%s: actual datalen %u", __FUNCTION__, datalen);
1247 }
1248 if (state.elementSize == 0) {
Yahan Zhou3f2f1b42016-12-01 13:49:44 -08001249 // The vertex attribute array is uninitialized. Abandon it.
1250 ALOGE("a vertex attribute array is uninitialized. Skipping corresponding vertex attribute.");
1251 this->m_glDisableVertexAttribArray_enc(this, i);
1252 continue;
1253 }
Yahan Zhou5507c042016-06-01 17:24:28 -07001254 m_glEnableVertexAttribArray_enc(this, i);
Lingfeng Yang000cf4c2017-01-25 08:09:02 -08001255
1256 if (datalen && (!offset || !((unsigned char*)offset + firstIndex))) {
1257 ALOGD("%s: bad offset / len!!!!!", __FUNCTION__);
1258 continue;
1259 }
Lingfeng Yang46153ab2017-01-09 13:37:22 -08001260 if (state.isInt) {
1261 this->glVertexAttribIPointerDataAEMU(this, i, state.size, state.type, stride, (unsigned char *)offset + firstIndex, datalen);
1262 } else {
1263 this->glVertexAttribPointerData(this, i, state.size, state.type, state.normalized, stride, (unsigned char *)offset + firstIndex, datalen);
1264 }
keunyoungb85b2752013-03-08 12:28:03 -08001265 } else {
Lingfeng Yang46153ab2017-01-09 13:37:22 -08001266 const BufferData* buf = m_shared->getBufferData(bufferObject);
Yahan Zhou5507c042016-06-01 17:24:28 -07001267 // The following expression actually means bufLen = stride*count;
1268 // But the last element doesn't have to fill up the whole stride.
1269 // So it becomes the current form.
Lingfeng Yang5fe99012017-01-18 09:17:09 -08001270 unsigned int bufLen = effectiveStride * (count ? (count - 1) : 0) + state.elementSize;
Yahan Zhoufe1820e2018-12-06 17:18:12 -08001271 if (divisor) {
Lingfeng Yang46153ab2017-01-09 13:37:22 -08001272 int actual_count = std::max(1, (int)((primcount + divisor - 1) / divisor));
Lingfeng Yang5fe99012017-01-18 09:17:09 -08001273 bufLen = effectiveStride * (actual_count ? (actual_count - 1) : 0) + state.elementSize;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08001274 }
Yahan Zhou5507c042016-06-01 17:24:28 -07001275 if (buf && firstIndex >= 0 && firstIndex + bufLen <= buf->m_size) {
Lingfeng Yangfe2a31d2016-12-02 08:02:15 -08001276 if (hasClientArrays) {
1277 m_glEnableVertexAttribArray_enc(this, i);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08001278 if (state.isInt) {
1279 this->glVertexAttribIPointerOffsetAEMU(this, i, state.size, state.type, stride, offset + firstIndex);
1280 } else {
1281 this->glVertexAttribPointerOffset(this, i, state.size, state.type, state.normalized, stride, offset + firstIndex);
1282 }
Lingfeng Yangfe2a31d2016-12-02 08:02:15 -08001283 }
Yahan Zhou5507c042016-06-01 17:24:28 -07001284 } else {
Lingfeng Yang46153ab2017-01-09 13:37:22 -08001285 ALOGE("a vertex attribute index out of boundary is detected. Skipping corresponding vertex attribute. buf=%p", buf);
Lingfeng Yang8d9d6c62017-01-18 09:26:19 -08001286 if (buf) {
1287 ALOGE("Out of bounds vertex attribute info: "
1288 "clientArray? %d attribute %d vbo %u allocedBufferSize %u bufferDataSpecified? %d wantedStart %u wantedEnd %u",
Lingfeng Yangddfb4452018-09-24 17:26:07 -07001289 hasClientArrays, i, bufferObject, (unsigned int)buf->m_size, buf != NULL, firstIndex, firstIndex + bufLen);
Lingfeng Yang8d9d6c62017-01-18 09:26:19 -08001290 }
1291 m_glDisableVertexAttribArray_enc(this, i);
Yahan Zhou5507c042016-06-01 17:24:28 -07001292 }
keunyoungb85b2752013-03-08 12:28:03 -08001293 }
1294 } else {
Lingfeng Yangfe2a31d2016-12-02 08:02:15 -08001295 if (hasClientArrays) {
1296 this->m_glDisableVertexAttribArray_enc(this, i);
1297 }
keunyoungb85b2752013-03-08 12:28:03 -08001298 }
1299 }
Lingfeng Yang398162b2016-05-26 14:18:33 -07001300
Lingfeng Yangfe2a31d2016-12-02 08:02:15 -08001301 if (hasClientArrays && lastBoundVbo != m_state->currentArrayVbo()) {
Lingfeng Yang554a5152019-02-21 20:20:48 -08001302 doBindBufferEncodeCached(GL_ARRAY_BUFFER, m_state->currentArrayVbo());
Lingfeng Yang398162b2016-05-26 14:18:33 -07001303 }
keunyoungb85b2752013-03-08 12:28:03 -08001304}
1305
Lingfeng Yang8e2b6e02016-10-14 11:20:45 -07001306void GL2Encoder::flushDrawCall() {
Lingfeng Yang4d0ffea2019-10-12 16:51:59 -07001307 if (m_drawCallFlushCount % m_drawCallFlushInterval == 0) {
Lingfeng Yang8e2b6e02016-10-14 11:20:45 -07001308 m_stream->flush();
1309 }
1310 m_drawCallFlushCount++;
1311}
1312
Evan Birenbaumd51386b2016-04-13 12:53:09 -07001313static bool isValidDrawMode(GLenum mode)
1314{
1315 bool retval = false;
1316 switch (mode) {
1317 case GL_POINTS:
1318 case GL_LINE_STRIP:
1319 case GL_LINE_LOOP:
1320 case GL_LINES:
1321 case GL_TRIANGLE_STRIP:
1322 case GL_TRIANGLE_FAN:
1323 case GL_TRIANGLES:
1324 retval = true;
1325 }
1326 return retval;
1327}
1328
keunyoungb85b2752013-03-08 12:28:03 -08001329void GL2Encoder::s_glDrawArrays(void *self, GLenum mode, GLint first, GLsizei count)
1330{
1331 GL2Encoder *ctx = (GL2Encoder *)self;
Evan Birenbaumd51386b2016-04-13 12:53:09 -07001332 assert(ctx->m_state != NULL);
1333 SET_ERROR_IF(!isValidDrawMode(mode), GL_INVALID_ENUM);
1334 SET_ERROR_IF(count < 0, GL_INVALID_VALUE);
Yahan Zhoud6217a52016-02-10 16:10:46 -08001335
Lingfeng Yangfe2a31d2016-12-02 08:02:15 -08001336 bool has_client_vertex_arrays = false;
1337 bool has_indirect_arrays = false;
1338 ctx->getVBOUsage(&has_client_vertex_arrays,
1339 &has_indirect_arrays);
1340
1341 if (has_client_vertex_arrays ||
1342 (!has_client_vertex_arrays &&
1343 !has_indirect_arrays)) {
1344 ctx->sendVertexAttributes(first, count, true);
1345 ctx->m_glDrawArrays_enc(ctx, mode, 0, count);
1346 } else {
1347 ctx->sendVertexAttributes(0, count, false);
1348 ctx->m_glDrawArrays_enc(ctx, mode, first, count);
1349 }
keunyoungb85b2752013-03-08 12:28:03 -08001350}
1351
1352
1353void GL2Encoder::s_glDrawElements(void *self, GLenum mode, GLsizei count, GLenum type, const void *indices)
1354{
1355
1356 GL2Encoder *ctx = (GL2Encoder *)self;
1357 assert(ctx->m_state != NULL);
Evan Birenbaumd51386b2016-04-13 12:53:09 -07001358 SET_ERROR_IF(!isValidDrawMode(mode), GL_INVALID_ENUM);
1359 SET_ERROR_IF(count < 0, GL_INVALID_VALUE);
Yahan Zhou4520fc92016-04-20 16:02:10 -07001360 SET_ERROR_IF(!(type == GL_UNSIGNED_BYTE || type == GL_UNSIGNED_SHORT || type == GL_UNSIGNED_INT), GL_INVALID_ENUM);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08001361 SET_ERROR_IF(ctx->m_state->getTransformFeedbackActiveUnpaused(), GL_INVALID_OPERATION);
keunyoungb85b2752013-03-08 12:28:03 -08001362
Lingfeng Yangfe2a31d2016-12-02 08:02:15 -08001363 bool has_client_vertex_arrays = false;
keunyoungb85b2752013-03-08 12:28:03 -08001364 bool has_indirect_arrays = false;
Yahan Zhou5507c042016-06-01 17:24:28 -07001365 GLintptr offset = 0;
keunyoungb85b2752013-03-08 12:28:03 -08001366
Lingfeng Yangfe2a31d2016-12-02 08:02:15 -08001367 ctx->getVBOUsage(&has_client_vertex_arrays, &has_indirect_arrays);
keunyoungb85b2752013-03-08 12:28:03 -08001368
Lingfeng Yangfe2a31d2016-12-02 08:02:15 -08001369 if (!has_client_vertex_arrays && !has_indirect_arrays) {
Lingfeng Yang46153ab2017-01-09 13:37:22 -08001370 // ALOGW("glDrawElements: no vertex arrays / buffers bound to the command\n");
Evan Birenbaum82885a62016-04-28 12:47:57 -07001371 GLenum status = ctx->m_glCheckFramebufferStatus_enc(self, GL_FRAMEBUFFER);
1372 SET_ERROR_IF(status != GL_FRAMEBUFFER_COMPLETE, GL_INVALID_FRAMEBUFFER_OPERATION);
keunyoungb85b2752013-03-08 12:28:03 -08001373 }
1374
Lingfeng Yang8e2b6e02016-10-14 11:20:45 -07001375 BufferData* buf = NULL;
Yahan Zhou5507c042016-06-01 17:24:28 -07001376 int minIndex = 0, maxIndex = 0;
Lingfeng Yang8e2b6e02016-10-14 11:20:45 -07001377
1378 // For validation/immediate index array purposes,
1379 // we need the min/max vertex index of the index array.
1380 // If the VBO != 0, this may not be the first time we have
1381 // used this particular index buffer. getBufferIndexRange
1382 // can more quickly get min/max vertex index by
Lingfeng Yang46153ab2017-01-09 13:37:22 -08001383 // caching previous results.
Lingfeng Yang8e2b6e02016-10-14 11:20:45 -07001384 if (ctx->m_state->currentIndexVbo() != 0) {
1385 buf = ctx->m_shared->getBufferData(ctx->m_state->currentIndexVbo());
1386 offset = (GLintptr)indices;
1387 indices = (void*)((GLintptr)buf->m_fixedBuffer.ptr() + (GLintptr)indices);
1388 ctx->getBufferIndexRange(buf,
1389 indices,
1390 type,
Lingfeng Yang1ae9d732016-12-12 16:17:02 -08001391 (size_t)count,
1392 (size_t)offset,
Lingfeng Yang8e2b6e02016-10-14 11:20:45 -07001393 &minIndex, &maxIndex);
1394 } else {
1395 // In this case, the |indices| field holds a real
1396 // array, so calculate the indices now. They will
1397 // also be needed to know how much data to
1398 // transfer to host.
1399 ctx->calcIndexRange(indices,
1400 type,
1401 count,
1402 &minIndex,
1403 &maxIndex);
Yahan Zhou5507c042016-06-01 17:24:28 -07001404 }
1405
Lingfeng Yang26e629a2018-10-13 20:00:12 -07001406 if (count == 0) return;
1407
keunyoungb85b2752013-03-08 12:28:03 -08001408 bool adjustIndices = true;
1409 if (ctx->m_state->currentIndexVbo() != 0) {
Lingfeng Yangfe2a31d2016-12-02 08:02:15 -08001410 if (!has_client_vertex_arrays) {
1411 ctx->sendVertexAttributes(0, maxIndex + 1, false);
Lingfeng Yang554a5152019-02-21 20:20:48 -08001412 ctx->doBindBufferEncodeCached(GL_ELEMENT_ARRAY_BUFFER, ctx->m_state->currentIndexVbo());
Yahan Zhou5507c042016-06-01 17:24:28 -07001413 ctx->glDrawElementsOffset(ctx, mode, count, type, offset);
Lingfeng Yang8e2b6e02016-10-14 11:20:45 -07001414 ctx->flushDrawCall();
keunyoungb85b2752013-03-08 12:28:03 -08001415 adjustIndices = false;
1416 } else {
Lingfeng Yang554a5152019-02-21 20:20:48 -08001417 ctx->doBindBufferEncodeCached(GL_ELEMENT_ARRAY_BUFFER, 0);
keunyoungb85b2752013-03-08 12:28:03 -08001418 }
1419 }
1420 if (adjustIndices) {
Lingfeng Yang8e2b6e02016-10-14 11:20:45 -07001421 void *adjustedIndices =
1422 ctx->recenterIndices(indices,
1423 type,
1424 count,
1425 minIndex);
keunyoungb85b2752013-03-08 12:28:03 -08001426
keunyoungb85b2752013-03-08 12:28:03 -08001427 if (has_indirect_arrays || 1) {
Lingfeng Yangfe2a31d2016-12-02 08:02:15 -08001428 ctx->sendVertexAttributes(minIndex, maxIndex - minIndex + 1, true);
keunyoungb85b2752013-03-08 12:28:03 -08001429 ctx->glDrawElementsData(ctx, mode, count, type, adjustedIndices,
1430 count * glSizeof(type));
1431 // XXX - OPTIMIZATION (see the other else branch) should be implemented
1432 if(!has_indirect_arrays) {
1433 //ALOGD("unoptimized drawelements !!!\n");
1434 }
1435 } else {
1436 // we are all direct arrays and immidate mode index array -
1437 // rebuild the arrays and the index array;
1438 ALOGE("glDrawElements: direct index & direct buffer data - will be implemented in later versions;\n");
1439 }
1440 }
1441}
1442
Lingfeng Yang09545912019-01-30 09:22:38 -08001443void GL2Encoder::s_glDrawArraysNullAEMU(void *self, GLenum mode, GLint first, GLsizei count)
1444{
1445 GL2Encoder *ctx = (GL2Encoder *)self;
1446 assert(ctx->m_state != NULL);
1447 SET_ERROR_IF(!isValidDrawMode(mode), GL_INVALID_ENUM);
1448 SET_ERROR_IF(count < 0, GL_INVALID_VALUE);
1449
1450 bool has_client_vertex_arrays = false;
1451 bool has_indirect_arrays = false;
1452 ctx->getVBOUsage(&has_client_vertex_arrays,
1453 &has_indirect_arrays);
1454
1455 if (has_client_vertex_arrays ||
1456 (!has_client_vertex_arrays &&
1457 !has_indirect_arrays)) {
1458 ctx->sendVertexAttributes(first, count, true);
1459 ctx->m_glDrawArraysNullAEMU_enc(ctx, mode, 0, count);
1460 } else {
1461 ctx->sendVertexAttributes(0, count, false);
1462 ctx->m_glDrawArraysNullAEMU_enc(ctx, mode, first, count);
1463 }
Lingfeng Yang4d0ffea2019-10-12 16:51:59 -07001464 ctx->flushDrawCall();
Lingfeng Yang09545912019-01-30 09:22:38 -08001465}
1466
1467void GL2Encoder::s_glDrawElementsNullAEMU(void *self, GLenum mode, GLsizei count, GLenum type, const void *indices)
1468{
1469
1470 GL2Encoder *ctx = (GL2Encoder *)self;
1471 assert(ctx->m_state != NULL);
1472 SET_ERROR_IF(!isValidDrawMode(mode), GL_INVALID_ENUM);
1473 SET_ERROR_IF(count < 0, GL_INVALID_VALUE);
1474 SET_ERROR_IF(!(type == GL_UNSIGNED_BYTE || type == GL_UNSIGNED_SHORT || type == GL_UNSIGNED_INT), GL_INVALID_ENUM);
1475 SET_ERROR_IF(ctx->m_state->getTransformFeedbackActiveUnpaused(), GL_INVALID_OPERATION);
1476
1477 bool has_client_vertex_arrays = false;
1478 bool has_indirect_arrays = false;
Lingfeng Yang09545912019-01-30 09:22:38 -08001479 GLintptr offset = 0;
1480
1481 ctx->getVBOUsage(&has_client_vertex_arrays, &has_indirect_arrays);
1482
1483 if (!has_client_vertex_arrays && !has_indirect_arrays) {
1484 // ALOGW("glDrawElements: no vertex arrays / buffers bound to the command\n");
1485 GLenum status = ctx->m_glCheckFramebufferStatus_enc(self, GL_FRAMEBUFFER);
1486 SET_ERROR_IF(status != GL_FRAMEBUFFER_COMPLETE, GL_INVALID_FRAMEBUFFER_OPERATION);
1487 }
1488
1489 BufferData* buf = NULL;
1490 int minIndex = 0, maxIndex = 0;
1491
1492 // For validation/immediate index array purposes,
1493 // we need the min/max vertex index of the index array.
1494 // If the VBO != 0, this may not be the first time we have
1495 // used this particular index buffer. getBufferIndexRange
1496 // can more quickly get min/max vertex index by
1497 // caching previous results.
1498 if (ctx->m_state->currentIndexVbo() != 0) {
1499 buf = ctx->m_shared->getBufferData(ctx->m_state->currentIndexVbo());
1500 offset = (GLintptr)indices;
1501 indices = (void*)((GLintptr)buf->m_fixedBuffer.ptr() + (GLintptr)indices);
1502 ctx->getBufferIndexRange(buf,
1503 indices,
1504 type,
1505 (size_t)count,
1506 (size_t)offset,
1507 &minIndex, &maxIndex);
1508 } else {
1509 // In this case, the |indices| field holds a real
1510 // array, so calculate the indices now. They will
1511 // also be needed to know how much data to
1512 // transfer to host.
1513 ctx->calcIndexRange(indices,
1514 type,
1515 count,
1516 &minIndex,
1517 &maxIndex);
1518 }
1519
1520 if (count == 0) return;
1521
1522 bool adjustIndices = true;
1523 if (ctx->m_state->currentIndexVbo() != 0) {
1524 if (!has_client_vertex_arrays) {
1525 ctx->sendVertexAttributes(0, maxIndex + 1, false);
1526 ctx->m_glBindBuffer_enc(self, GL_ELEMENT_ARRAY_BUFFER, ctx->m_state->currentIndexVbo());
1527 ctx->glDrawElementsOffsetNullAEMU(ctx, mode, count, type, offset);
1528 ctx->flushDrawCall();
1529 adjustIndices = false;
1530 } else {
Lingfeng Yang09545912019-01-30 09:22:38 -08001531 ctx->m_glBindBuffer_enc(self, GL_ELEMENT_ARRAY_BUFFER, 0);
1532 }
1533 }
1534 if (adjustIndices) {
1535 void *adjustedIndices =
1536 ctx->recenterIndices(indices,
1537 type,
1538 count,
1539 minIndex);
1540
1541 if (has_indirect_arrays || 1) {
1542 ctx->sendVertexAttributes(minIndex, maxIndex - minIndex + 1, true);
1543 ctx->glDrawElementsDataNullAEMU(ctx, mode, count, type, adjustedIndices,
1544 count * glSizeof(type));
1545 // XXX - OPTIMIZATION (see the other else branch) should be implemented
1546 if(!has_indirect_arrays) {
1547 //ALOGD("unoptimized drawelements !!!\n");
1548 }
1549 } else {
1550 // we are all direct arrays and immidate mode index array -
1551 // rebuild the arrays and the index array;
1552 ALOGE("glDrawElementsNullAEMU: direct index & direct buffer data - will be implemented in later versions;\n");
1553 }
1554 }
1555}
keunyoungb85b2752013-03-08 12:28:03 -08001556
1557GLint * GL2Encoder::getCompressedTextureFormats()
1558{
1559 if (m_compressedTextureFormats == NULL) {
1560 this->glGetIntegerv(this, GL_NUM_COMPRESSED_TEXTURE_FORMATS,
1561 &m_num_compressedTextureFormats);
1562 if (m_num_compressedTextureFormats > 0) {
1563 // get number of texture formats;
1564 m_compressedTextureFormats = new GLint[m_num_compressedTextureFormats];
1565 this->glGetCompressedTextureFormats(this, m_num_compressedTextureFormats, m_compressedTextureFormats);
1566 }
1567 }
1568 return m_compressedTextureFormats;
1569}
1570
1571// Replace uses of samplerExternalOES with sampler2D, recording the names of
1572// modified shaders in data. Also remove
1573// #extension GL_OES_EGL_image_external : require
1574// statements.
1575//
1576// This implementation assumes the input has already been pre-processed. If not,
1577// a few cases will be mishandled:
1578//
1579// 1. "mySampler" will be incorrectly recorded as being a samplerExternalOES in
1580// the following code:
1581// #if 1
1582// uniform sampler2D mySampler;
1583// #else
1584// uniform samplerExternalOES mySampler;
1585// #endif
1586//
1587// 2. Comments that look like sampler declarations will be incorrectly modified
1588// and recorded:
1589// // samplerExternalOES hahaFooledYou
1590//
1591// 3. However, GLSL ES does not have a concatentation operator, so things like
1592// this (valid in C) are invalid and not a problem:
1593// #define SAMPLER(TYPE, NAME) uniform sampler#TYPE NAME
1594// SAMPLER(ExternalOES, mySampler);
1595//
Lingfeng Yangcc22a7a2018-05-15 12:15:57 -07001596
1597static const char STR_SAMPLER_EXTERNAL_OES[] = "samplerExternalOES";
1598static const char STR_SAMPLER2D_SPACE[] = "sampler2D ";
1599static const char STR_DEFINE[] = "#define";
1600
1601static std::vector<std::string> getSamplerExternalAliases(char* str) {
1602 std::vector<std::string> res;
1603
1604 res.push_back(STR_SAMPLER_EXTERNAL_OES);
1605
1606 // -- capture #define x samplerExternalOES
1607 char* c = str;
1608 while ((c = strstr(c, STR_DEFINE))) {
1609 // Don't push it if samplerExternalOES is not even there.
1610 char* samplerExternalOES_next = strstr(c, STR_SAMPLER_EXTERNAL_OES);
1611 if (!samplerExternalOES_next) break;
1612
1613 bool prevIdent = false;
1614
1615 std::vector<std::string> idents;
1616 std::string curr;
1617
1618 while (*c != '\0') {
1619
1620 if (isspace(*c)) {
1621 if (prevIdent) {
1622 idents.push_back(curr);
1623 curr = "";
1624 }
1625 }
1626
1627 if (*c == '\n' || idents.size() == 3) break;
1628
1629 if (isalpha(*c) || *c == '_') {
1630 curr.push_back(*c);
1631 prevIdent = true;
1632 }
1633
1634 ++c;
1635 }
1636
1637 if (idents.size() != 3) continue;
1638
1639 const std::string& defineLhs = idents[1];
1640 const std::string& defineRhs = idents[2];
1641
1642 if (defineRhs == STR_SAMPLER_EXTERNAL_OES) {
1643 res.push_back(defineLhs);
1644 }
1645
1646 if (*c == '\0') break;
1647 }
1648
1649 return res;
1650}
1651
1652static bool replaceExternalSamplerUniformDefinition(char* str, const std::string& samplerExternalType, ShaderData* data) {
1653 // -- replace "samplerExternalOES" with "sampler2D" and record name
1654 char* c = str;
1655 while ((c = strstr(c, samplerExternalType.c_str()))) {
1656 // Make sure "samplerExternalOES" isn't a substring of a larger token
1657 if (c == str || !isspace(*(c-1))) {
1658 c++;
1659 continue;
1660 }
1661 char* sampler_start = c;
1662 c += samplerExternalType.size();
1663 if (!isspace(*c) && *c != '\0') {
1664 continue;
1665 }
1666
1667 // capture sampler name
1668 while (isspace(*c) && *c != '\0') {
1669 c++;
1670 }
1671 if (!isalpha(*c) && *c != '_') {
1672 // not an identifier
1673 return false;
1674 }
1675 char* name_start = c;
1676 do {
1677 c++;
1678 } while (isalnum(*c) || *c == '_');
Lingfeng Yang44209df2018-09-21 10:04:17 -07001679
1680 size_t len = (size_t)(c - name_start);
Lingfeng Yangcc22a7a2018-05-15 12:15:57 -07001681 data->samplerExternalNames.push_back(
Lingfeng Yang44209df2018-09-21 10:04:17 -07001682 std::string(name_start, len));
Lingfeng Yangcc22a7a2018-05-15 12:15:57 -07001683
1684 // We only need to perform a string replacement for the original
1685 // occurrence of samplerExternalOES if a #define was used.
1686 //
1687 // The important part was to record the name in
1688 // |data->samplerExternalNames|.
1689 if (samplerExternalType == STR_SAMPLER_EXTERNAL_OES) {
1690 memcpy(sampler_start, STR_SAMPLER2D_SPACE, sizeof(STR_SAMPLER2D_SPACE)-1);
1691 }
1692 }
1693
1694 return true;
1695}
1696
keunyoungb85b2752013-03-08 12:28:03 -08001697static bool replaceSamplerExternalWith2D(char* const str, ShaderData* const data)
1698{
1699 static const char STR_HASH_EXTENSION[] = "#extension";
1700 static const char STR_GL_OES_EGL_IMAGE_EXTERNAL[] = "GL_OES_EGL_image_external";
Lingfeng Yang3546c4d2018-04-10 12:34:30 -07001701 static const char STR_GL_OES_EGL_IMAGE_EXTERNAL_ESSL3[] = "GL_OES_EGL_image_external_essl3";
keunyoungb85b2752013-03-08 12:28:03 -08001702
1703 // -- overwrite all "#extension GL_OES_EGL_image_external : xxx" statements
1704 char* c = str;
1705 while ((c = strstr(c, STR_HASH_EXTENSION))) {
1706 char* start = c;
1707 c += sizeof(STR_HASH_EXTENSION)-1;
1708 while (isspace(*c) && *c != '\0') {
1709 c++;
1710 }
Lingfeng Yang3546c4d2018-04-10 12:34:30 -07001711
1712 bool hasBaseImageExternal =
1713 !strncmp(c, STR_GL_OES_EGL_IMAGE_EXTERNAL,
1714 sizeof(STR_GL_OES_EGL_IMAGE_EXTERNAL) - 1);
1715 bool hasEssl3ImageExternal =
1716 !strncmp(c, STR_GL_OES_EGL_IMAGE_EXTERNAL_ESSL3,
1717 sizeof(STR_GL_OES_EGL_IMAGE_EXTERNAL_ESSL3) - 1);
1718
1719 if (hasBaseImageExternal || hasEssl3ImageExternal)
keunyoungb85b2752013-03-08 12:28:03 -08001720 {
1721 // #extension statements are terminated by end of line
1722 c = start;
1723 while (*c != '\0' && *c != '\r' && *c != '\n') {
1724 *c++ = ' ';
1725 }
1726 }
1727 }
1728
Lingfeng Yangcc22a7a2018-05-15 12:15:57 -07001729 std::vector<std::string> samplerExternalAliases =
1730 getSamplerExternalAliases(str);
keunyoungb85b2752013-03-08 12:28:03 -08001731
Lingfeng Yangcc22a7a2018-05-15 12:15:57 -07001732 for (size_t i = 0; i < samplerExternalAliases.size(); i++) {
1733 if (!replaceExternalSamplerUniformDefinition(
1734 str, samplerExternalAliases[i], data))
keunyoungb85b2752013-03-08 12:28:03 -08001735 return false;
keunyoungb85b2752013-03-08 12:28:03 -08001736 }
1737
1738 return true;
1739}
1740
Lingfeng Yangde7eaa72019-08-21 21:47:57 -07001741void GL2Encoder::s_glShaderBinary(void *self, GLsizei, const GLuint *, GLenum, const void*, GLsizei)
Bo Hu73568cd2015-01-20 16:29:50 -08001742{
Bo Hu73568cd2015-01-20 16:29:50 -08001743 // Although it is not supported, need to set proper error code.
Lingfeng Yangde7eaa72019-08-21 21:47:57 -07001744 GL2Encoder* ctx = (GL2Encoder*)self;
Bo Hu73568cd2015-01-20 16:29:50 -08001745 SET_ERROR_IF(1, GL_INVALID_ENUM);
1746}
1747
David 'Digit' Turner02fdb692014-10-30 18:07:56 +01001748void GL2Encoder::s_glShaderSource(void *self, GLuint shader, GLsizei count, const GLchar * const *string, const GLint *length)
keunyoungb85b2752013-03-08 12:28:03 -08001749{
1750 GL2Encoder* ctx = (GL2Encoder*)self;
1751 ShaderData* shaderData = ctx->m_shared->getShaderData(shader);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08001752 SET_ERROR_IF(!ctx->m_shared->isShaderOrProgramObject(shader), GL_INVALID_VALUE);
Tina Zhang7a84f652014-12-04 12:37:30 +08001753 SET_ERROR_IF(!shaderData, GL_INVALID_OPERATION);
1754 SET_ERROR_IF((count<0), GL_INVALID_VALUE);
keunyoungb85b2752013-03-08 12:28:03 -08001755
Lingfeng Yang46153ab2017-01-09 13:37:22 -08001756 // Track original sources---they may be translated in the backend
1757 std::vector<std::string> orig_sources;
1758 for (int i = 0; i < count; i++) {
1759 orig_sources.push_back(std::string((const char*)(string[i])));
1760 }
1761 shaderData->sources = orig_sources;
1762
keunyoungb85b2752013-03-08 12:28:03 -08001763 int len = glUtilsCalcShaderSourceLen((char**)string, (GLint*)length, count);
1764 char *str = new char[len + 1];
1765 glUtilsPackStrings(str, (char**)string, (GLint*)length, count);
1766
1767 // TODO: pre-process str before calling replaceSamplerExternalWith2D().
1768 // Perhaps we can borrow Mesa's pre-processor?
1769
1770 if (!replaceSamplerExternalWith2D(str, shaderData)) {
Adam Buchbinder9ae14692016-05-20 15:25:59 -07001771 delete[] str;
keunyoungb85b2752013-03-08 12:28:03 -08001772 ctx->setError(GL_OUT_OF_MEMORY);
1773 return;
1774 }
keunyoungb85b2752013-03-08 12:28:03 -08001775 ctx->glShaderString(ctx, shader, str, len + 1);
Adam Buchbinder9ae14692016-05-20 15:25:59 -07001776 delete[] str;
keunyoungb85b2752013-03-08 12:28:03 -08001777}
1778
1779void GL2Encoder::s_glFinish(void *self)
1780{
1781 GL2Encoder *ctx = (GL2Encoder *)self;
1782 ctx->glFinishRoundTrip(self);
1783}
1784
1785void GL2Encoder::s_glLinkProgram(void * self, GLuint program)
1786{
1787 GL2Encoder *ctx = (GL2Encoder *)self;
Yahan Zhoub99406c2016-11-22 14:03:56 -08001788 bool isProgram = ctx->m_shared->isProgram(program);
1789 SET_ERROR_IF(!isProgram && !ctx->m_shared->isShader(program), GL_INVALID_VALUE);
1790 SET_ERROR_IF(!isProgram, GL_INVALID_OPERATION);
1791
keunyoungb85b2752013-03-08 12:28:03 -08001792 ctx->m_glLinkProgram_enc(self, program);
1793
1794 GLint linkStatus = 0;
Lingfeng Yang80a36332017-07-09 10:58:07 -07001795 ctx->glGetProgramiv(self, program, GL_LINK_STATUS, &linkStatus);
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08001796 if (!linkStatus) {
keunyoungb85b2752013-03-08 12:28:03 -08001797 return;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08001798 }
keunyoungb85b2752013-03-08 12:28:03 -08001799
1800 //get number of active uniforms in the program
1801 GLint numUniforms=0;
1802 ctx->glGetProgramiv(self, program, GL_ACTIVE_UNIFORMS, &numUniforms);
1803 ctx->m_shared->initProgramData(program,numUniforms);
1804
1805 //get the length of the longest uniform name
1806 GLint maxLength=0;
1807 ctx->glGetProgramiv(self, program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxLength);
1808
1809 GLint size;
1810 GLenum type;
1811 GLchar *name = new GLchar[maxLength+1];
1812 GLint location;
1813 //for each active uniform, get its size and starting location.
1814 for (GLint i=0 ; i<numUniforms ; ++i)
1815 {
1816 ctx->glGetActiveUniform(self, program, i, maxLength, NULL, &size, &type, name);
1817 location = ctx->m_glGetUniformLocation_enc(self, program, name);
1818 ctx->m_shared->setProgramIndexInfo(program, i, location, size, type, name);
1819 }
keunyoungb85b2752013-03-08 12:28:03 -08001820
1821 delete[] name;
1822}
1823
1824void GL2Encoder::s_glDeleteProgram(void *self, GLuint program)
1825{
1826 GL2Encoder *ctx = (GL2Encoder*)self;
1827 ctx->m_glDeleteProgram_enc(self, program);
1828
1829 ctx->m_shared->deleteProgramData(program);
1830}
1831
1832void GL2Encoder::s_glGetUniformiv(void *self, GLuint program, GLint location, GLint* params)
1833{
1834 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08001835 SET_ERROR_IF(!ctx->m_shared->isShaderOrProgramObject(program), GL_INVALID_VALUE);
Lingfeng Yang35b0fda2016-04-08 12:21:13 -07001836 SET_ERROR_IF(!ctx->m_shared->isProgram(program), GL_INVALID_OPERATION);
keunyoungb85b2752013-03-08 12:28:03 -08001837 SET_ERROR_IF(!ctx->m_shared->isProgramInitialized(program), GL_INVALID_OPERATION);
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08001838 GLint hostLoc = location;
keunyoungb85b2752013-03-08 12:28:03 -08001839 SET_ERROR_IF(ctx->m_shared->getProgramUniformType(program,hostLoc)==0, GL_INVALID_OPERATION);
1840 ctx->m_glGetUniformiv_enc(self, program, hostLoc, params);
1841}
1842void GL2Encoder::s_glGetUniformfv(void *self, GLuint program, GLint location, GLfloat* params)
1843{
1844 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08001845 SET_ERROR_IF(!ctx->m_shared->isShaderOrProgramObject(program), GL_INVALID_VALUE);
Lingfeng Yang35b0fda2016-04-08 12:21:13 -07001846 SET_ERROR_IF(!ctx->m_shared->isProgram(program), GL_INVALID_OPERATION);
keunyoungb85b2752013-03-08 12:28:03 -08001847 SET_ERROR_IF(!ctx->m_shared->isProgramInitialized(program), GL_INVALID_OPERATION);
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08001848 GLint hostLoc = location;
keunyoungb85b2752013-03-08 12:28:03 -08001849 SET_ERROR_IF(ctx->m_shared->getProgramUniformType(program,hostLoc)==0, GL_INVALID_OPERATION);
1850 ctx->m_glGetUniformfv_enc(self, program, hostLoc, params);
1851}
1852
1853GLuint GL2Encoder::s_glCreateProgram(void * self)
1854{
1855 GL2Encoder *ctx = (GL2Encoder*)self;
1856 GLuint program = ctx->m_glCreateProgram_enc(self);
1857 if (program!=0)
1858 ctx->m_shared->addProgramData(program);
1859 return program;
1860}
1861
1862GLuint GL2Encoder::s_glCreateShader(void *self, GLenum shaderType)
1863{
1864 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08001865 RET_AND_SET_ERROR_IF(!GLESv2Validation::shaderType(ctx, shaderType), GL_INVALID_ENUM, 0);
keunyoungb85b2752013-03-08 12:28:03 -08001866 GLuint shader = ctx->m_glCreateShader_enc(self, shaderType);
1867 if (shader != 0) {
1868 if (!ctx->m_shared->addShaderData(shader)) {
1869 ctx->m_glDeleteShader_enc(self, shader);
1870 return 0;
1871 }
1872 }
1873 return shader;
1874}
1875
bohu56bf82f2014-10-17 15:35:48 -07001876void GL2Encoder::s_glGetAttachedShaders(void *self, GLuint program, GLsizei maxCount,
1877 GLsizei* count, GLuint* shaders)
1878{
1879 GL2Encoder *ctx = (GL2Encoder*)self;
1880 SET_ERROR_IF(maxCount < 0, GL_INVALID_VALUE);
1881 ctx->m_glGetAttachedShaders_enc(self, program, maxCount, count, shaders);
1882}
1883
1884void GL2Encoder::s_glGetShaderSource(void *self, GLuint shader, GLsizei bufsize,
1885 GLsizei* length, GLchar* source)
1886{
1887 GL2Encoder *ctx = (GL2Encoder*)self;
1888 SET_ERROR_IF(bufsize < 0, GL_INVALID_VALUE);
1889 ctx->m_glGetShaderSource_enc(self, shader, bufsize, length, source);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08001890 ShaderData* shaderData = ctx->m_shared->getShaderData(shader);
1891 if (shaderData) {
1892 std::string returned;
1893 int curr_len = 0;
1894 for (int i = 0; i < shaderData->sources.size(); i++) {
1895 if (curr_len + shaderData->sources[i].size() < bufsize - 1) {
1896 returned += shaderData->sources[i];
1897 } else {
1898 returned += shaderData->sources[i].substr(0, bufsize - 1 - curr_len);
1899 break;
1900 }
1901 }
1902 memcpy(source, returned.substr(0, bufsize - 1).c_str(), bufsize);
1903 }
bohu56bf82f2014-10-17 15:35:48 -07001904}
1905
1906void GL2Encoder::s_glGetShaderInfoLog(void *self, GLuint shader, GLsizei bufsize,
1907 GLsizei* length, GLchar* infolog)
1908{
1909 GL2Encoder *ctx = (GL2Encoder*)self;
1910 SET_ERROR_IF(bufsize < 0, GL_INVALID_VALUE);
1911 ctx->m_glGetShaderInfoLog_enc(self, shader, bufsize, length, infolog);
1912}
1913
1914void GL2Encoder::s_glGetProgramInfoLog(void *self, GLuint program, GLsizei bufsize,
1915 GLsizei* length, GLchar* infolog)
1916{
1917 GL2Encoder *ctx = (GL2Encoder*)self;
1918 SET_ERROR_IF(bufsize < 0, GL_INVALID_VALUE);
1919 ctx->m_glGetProgramInfoLog_enc(self, program, bufsize, length, infolog);
1920}
1921
keunyoungb85b2752013-03-08 12:28:03 -08001922void GL2Encoder::s_glDeleteShader(void *self, GLenum shader)
1923{
1924 GL2Encoder *ctx = (GL2Encoder*)self;
1925 ctx->m_glDeleteShader_enc(self,shader);
1926 ctx->m_shared->unrefShaderData(shader);
1927}
1928
1929void GL2Encoder::s_glAttachShader(void *self, GLuint program, GLuint shader)
1930{
1931 GL2Encoder *ctx = (GL2Encoder*)self;
1932 ctx->m_glAttachShader_enc(self, program, shader);
1933 ctx->m_shared->attachShader(program, shader);
1934}
1935
1936void GL2Encoder::s_glDetachShader(void *self, GLuint program, GLuint shader)
1937{
1938 GL2Encoder *ctx = (GL2Encoder*)self;
1939 ctx->m_glDetachShader_enc(self, program, shader);
1940 ctx->m_shared->detachShader(program, shader);
1941}
1942
Lingfeng Yang46153ab2017-01-09 13:37:22 -08001943int sArrIndexOfUniformExpr(const char* name, int* err) {
1944 *err = 0;
1945 int arrIndex = 0;
1946 int namelen = strlen(name);
1947 if (name[namelen-1] == ']') {
1948 const char *brace = strrchr(name,'[');
1949 if (!brace || sscanf(brace+1,"%d",&arrIndex) != 1) {
1950 *err = 1; return 0;
1951 }
1952 }
1953 return arrIndex;
1954}
1955
keunyoungb85b2752013-03-08 12:28:03 -08001956int GL2Encoder::s_glGetUniformLocation(void *self, GLuint program, const GLchar *name)
1957{
1958 if (!name) return -1;
keunyoungb85b2752013-03-08 12:28:03 -08001959 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08001960 return ctx->m_glGetUniformLocation_enc(self, program, name);
keunyoungb85b2752013-03-08 12:28:03 -08001961}
1962
1963bool GL2Encoder::updateHostTexture2DBinding(GLenum texUnit, GLenum newTarget)
1964{
1965 if (newTarget != GL_TEXTURE_2D && newTarget != GL_TEXTURE_EXTERNAL_OES)
1966 return false;
1967
1968 m_state->setActiveTextureUnit(texUnit);
1969
1970 GLenum oldTarget = m_state->getPriorityEnabledTarget(GL_TEXTURE_2D);
1971 if (newTarget != oldTarget) {
1972 if (newTarget == GL_TEXTURE_EXTERNAL_OES) {
1973 m_state->disableTextureTarget(GL_TEXTURE_2D);
1974 m_state->enableTextureTarget(GL_TEXTURE_EXTERNAL_OES);
1975 } else {
1976 m_state->disableTextureTarget(GL_TEXTURE_EXTERNAL_OES);
1977 m_state->enableTextureTarget(GL_TEXTURE_2D);
1978 }
1979 m_glActiveTexture_enc(this, texUnit);
1980 m_glBindTexture_enc(this, GL_TEXTURE_2D,
1981 m_state->getBoundTexture(newTarget));
1982 return true;
1983 }
1984
1985 return false;
1986}
1987
Lingfeng Yang46153ab2017-01-09 13:37:22 -08001988void GL2Encoder::updateHostTexture2DBindingsFromProgramData(GLuint program) {
1989 GL2Encoder *ctx = this;
keunyoungb85b2752013-03-08 12:28:03 -08001990 GLClientState* state = ctx->m_state;
1991 GLSharedGroupPtr shared = ctx->m_shared;
1992
keunyoungb85b2752013-03-08 12:28:03 -08001993 GLenum origActiveTexture = state->getActiveTextureUnit();
1994 GLenum hostActiveTexture = origActiveTexture;
1995 GLint samplerIdx = -1;
1996 GLint samplerVal;
1997 GLenum samplerTarget;
1998 while ((samplerIdx = shared->getNextSamplerUniform(program, samplerIdx, &samplerVal, &samplerTarget)) != -1) {
1999 if (samplerVal < 0 || samplerVal >= GLClientState::MAX_TEXTURE_UNITS)
2000 continue;
2001 if (ctx->updateHostTexture2DBinding(GL_TEXTURE0 + samplerVal,
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002002 samplerTarget))
keunyoungb85b2752013-03-08 12:28:03 -08002003 {
2004 hostActiveTexture = GL_TEXTURE0 + samplerVal;
2005 }
2006 }
2007 state->setActiveTextureUnit(origActiveTexture);
2008 if (hostActiveTexture != origActiveTexture) {
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002009 ctx->m_glActiveTexture_enc(ctx, origActiveTexture);
keunyoungb85b2752013-03-08 12:28:03 -08002010 }
2011}
2012
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002013void GL2Encoder::s_glUseProgram(void *self, GLuint program)
2014{
2015 GL2Encoder *ctx = (GL2Encoder*)self;
2016 GLSharedGroupPtr shared = ctx->m_shared;
2017
2018 SET_ERROR_IF(program && !shared->isShaderOrProgramObject(program), GL_INVALID_VALUE);
2019 SET_ERROR_IF(program && !shared->isProgram(program), GL_INVALID_OPERATION);
2020
2021 ctx->m_glUseProgram_enc(self, program);
2022 ctx->m_state->setCurrentProgram(program);
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08002023 ctx->m_state->setCurrentShaderProgram(program);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002024
2025 ctx->updateHostTexture2DBindingsFromProgramData(program);
2026}
2027
keunyoungb85b2752013-03-08 12:28:03 -08002028void GL2Encoder::s_glUniform1f(void *self , GLint location, GLfloat x)
2029{
2030 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08002031 GLint hostLoc = location;
keunyoungb85b2752013-03-08 12:28:03 -08002032 ctx->m_glUniform1f_enc(self, hostLoc, x);
2033}
2034
2035void GL2Encoder::s_glUniform1fv(void *self , GLint location, GLsizei count, const GLfloat* v)
2036{
2037 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08002038 GLint hostLoc = location;
keunyoungb85b2752013-03-08 12:28:03 -08002039 ctx->m_glUniform1fv_enc(self, hostLoc, count, v);
2040}
2041
2042void GL2Encoder::s_glUniform1i(void *self , GLint location, GLint x)
2043{
2044 GL2Encoder *ctx = (GL2Encoder*)self;
2045 GLClientState* state = ctx->m_state;
2046 GLSharedGroupPtr shared = ctx->m_shared;
2047
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08002048 GLint hostLoc = location;
keunyoungb85b2752013-03-08 12:28:03 -08002049 ctx->m_glUniform1i_enc(self, hostLoc, x);
2050
2051 GLenum target;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08002052 if (shared->setSamplerUniform(state->currentShaderProgram(), location, x, &target)) {
keunyoungb85b2752013-03-08 12:28:03 -08002053 GLenum origActiveTexture = state->getActiveTextureUnit();
2054 if (ctx->updateHostTexture2DBinding(GL_TEXTURE0 + x, target)) {
2055 ctx->m_glActiveTexture_enc(self, origActiveTexture);
2056 }
2057 state->setActiveTextureUnit(origActiveTexture);
2058 }
2059}
2060
2061void GL2Encoder::s_glUniform1iv(void *self , GLint location, GLsizei count, const GLint* v)
2062{
2063 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08002064 GLint hostLoc = location;
keunyoungb85b2752013-03-08 12:28:03 -08002065 ctx->m_glUniform1iv_enc(self, hostLoc, count, v);
2066}
2067
2068void GL2Encoder::s_glUniform2f(void *self , GLint location, GLfloat x, GLfloat y)
2069{
2070 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08002071 GLint hostLoc = location;
keunyoungb85b2752013-03-08 12:28:03 -08002072 ctx->m_glUniform2f_enc(self, hostLoc, x, y);
2073}
2074
2075void GL2Encoder::s_glUniform2fv(void *self , GLint location, GLsizei count, const GLfloat* v)
2076{
2077 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08002078 GLint hostLoc = location;
keunyoungb85b2752013-03-08 12:28:03 -08002079 ctx->m_glUniform2fv_enc(self, hostLoc, count, v);
2080}
2081
2082void GL2Encoder::s_glUniform2i(void *self , GLint location, GLint x, GLint y)
2083{
2084 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08002085 GLint hostLoc = location;
keunyoungb85b2752013-03-08 12:28:03 -08002086 ctx->m_glUniform2i_enc(self, hostLoc, x, y);
2087}
2088
2089void GL2Encoder::s_glUniform2iv(void *self , GLint location, GLsizei count, const GLint* v)
2090{
2091 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08002092 GLint hostLoc = location;
keunyoungb85b2752013-03-08 12:28:03 -08002093 ctx->m_glUniform2iv_enc(self, hostLoc, count, v);
2094}
2095
2096void GL2Encoder::s_glUniform3f(void *self , GLint location, GLfloat x, GLfloat y, GLfloat z)
2097{
2098 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08002099 GLint hostLoc = location;
keunyoungb85b2752013-03-08 12:28:03 -08002100 ctx->m_glUniform3f_enc(self, hostLoc, x, y, z);
2101}
2102
2103void GL2Encoder::s_glUniform3fv(void *self , GLint location, GLsizei count, const GLfloat* v)
2104{
2105 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08002106 GLint hostLoc = location;
keunyoungb85b2752013-03-08 12:28:03 -08002107 ctx->m_glUniform3fv_enc(self, hostLoc, count, v);
2108}
2109
2110void GL2Encoder::s_glUniform3i(void *self , GLint location, GLint x, GLint y, GLint z)
2111{
2112 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08002113 GLint hostLoc = location;
keunyoungb85b2752013-03-08 12:28:03 -08002114 ctx->m_glUniform3i_enc(self, hostLoc, x, y, z);
2115}
2116
2117void GL2Encoder::s_glUniform3iv(void *self , GLint location, GLsizei count, const GLint* v)
2118{
2119 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08002120 GLint hostLoc = location;
keunyoungb85b2752013-03-08 12:28:03 -08002121 ctx->m_glUniform3iv_enc(self, hostLoc, count, v);
2122}
2123
2124void GL2Encoder::s_glUniform4f(void *self , GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
2125{
2126 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08002127 GLint hostLoc = location;
keunyoungb85b2752013-03-08 12:28:03 -08002128 ctx->m_glUniform4f_enc(self, hostLoc, x, y, z, w);
2129}
2130
2131void GL2Encoder::s_glUniform4fv(void *self , GLint location, GLsizei count, const GLfloat* v)
2132{
2133 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08002134 GLint hostLoc = location;
keunyoungb85b2752013-03-08 12:28:03 -08002135 ctx->m_glUniform4fv_enc(self, hostLoc, count, v);
2136}
2137
2138void GL2Encoder::s_glUniform4i(void *self , GLint location, GLint x, GLint y, GLint z, GLint w)
2139{
2140 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08002141 GLint hostLoc = location;
keunyoungb85b2752013-03-08 12:28:03 -08002142 ctx->m_glUniform4i_enc(self, hostLoc, x, y, z, w);
2143}
2144
2145void GL2Encoder::s_glUniform4iv(void *self , GLint location, GLsizei count, const GLint* v)
2146{
2147 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08002148 GLint hostLoc = location;
keunyoungb85b2752013-03-08 12:28:03 -08002149 ctx->m_glUniform4iv_enc(self, hostLoc, count, v);
2150}
2151
2152void GL2Encoder::s_glUniformMatrix2fv(void *self , GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
2153{
2154 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08002155 GLint hostLoc = location;
keunyoungb85b2752013-03-08 12:28:03 -08002156 ctx->m_glUniformMatrix2fv_enc(self, hostLoc, count, transpose, value);
2157}
2158
2159void GL2Encoder::s_glUniformMatrix3fv(void *self , GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
2160{
2161 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08002162 GLint hostLoc = location;
keunyoungb85b2752013-03-08 12:28:03 -08002163 ctx->m_glUniformMatrix3fv_enc(self, hostLoc, count, transpose, value);
2164}
2165
2166void GL2Encoder::s_glUniformMatrix4fv(void *self , GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
2167{
2168 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08002169 GLint hostLoc = location;
keunyoungb85b2752013-03-08 12:28:03 -08002170 ctx->m_glUniformMatrix4fv_enc(self, hostLoc, count, transpose, value);
2171}
2172
2173void GL2Encoder::s_glActiveTexture(void* self, GLenum texture)
2174{
2175 GL2Encoder* ctx = (GL2Encoder*)self;
2176 GLClientState* state = ctx->m_state;
2177 GLenum err;
2178
2179 SET_ERROR_IF((err = state->setActiveTextureUnit(texture)) != GL_NO_ERROR, err);
2180
2181 ctx->m_glActiveTexture_enc(ctx, texture);
2182}
2183
2184void GL2Encoder::s_glBindTexture(void* self, GLenum target, GLuint texture)
2185{
2186 GL2Encoder* ctx = (GL2Encoder*)self;
2187 GLClientState* state = ctx->m_state;
2188 GLenum err;
2189 GLboolean firstUse;
2190
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002191 SET_ERROR_IF(!GLESv2Validation::textureTarget(ctx, target), GL_INVALID_ENUM);
keunyoungb85b2752013-03-08 12:28:03 -08002192 SET_ERROR_IF((err = state->bindTexture(target, texture, &firstUse)) != GL_NO_ERROR, err);
2193
2194 if (target != GL_TEXTURE_2D && target != GL_TEXTURE_EXTERNAL_OES) {
2195 ctx->m_glBindTexture_enc(ctx, target, texture);
2196 return;
2197 }
2198
2199 GLenum priorityTarget = state->getPriorityEnabledTarget(GL_TEXTURE_2D);
2200
2201 if (target == GL_TEXTURE_EXTERNAL_OES && firstUse) {
2202 ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D, texture);
2203 ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D,
2204 GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2205 ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D,
2206 GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2207 ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D,
2208 GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2209
2210 if (target != priorityTarget) {
2211 ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D,
2212 state->getBoundTexture(GL_TEXTURE_2D));
2213 }
2214 }
2215
2216 if (target == priorityTarget) {
2217 ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D, texture);
2218 }
2219}
2220
2221void GL2Encoder::s_glDeleteTextures(void* self, GLsizei n, const GLuint* textures)
2222{
2223 GL2Encoder* ctx = (GL2Encoder*)self;
2224 GLClientState* state = ctx->m_state;
2225
2226 state->deleteTextures(n, textures);
2227 ctx->m_glDeleteTextures_enc(ctx, n, textures);
2228}
2229
2230void GL2Encoder::s_glGetTexParameterfv(void* self,
2231 GLenum target, GLenum pname, GLfloat* params)
2232{
2233 GL2Encoder* ctx = (GL2Encoder*)self;
keunyoungb85b2752013-03-08 12:28:03 -08002234
2235 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
2236 ctx->override2DTextureTarget(target);
2237 ctx->m_glGetTexParameterfv_enc(ctx, GL_TEXTURE_2D, pname, params);
Lingfeng Yangb5c03d52016-09-07 14:40:03 -07002238 ctx->restore2DTextureTarget(target);
keunyoungb85b2752013-03-08 12:28:03 -08002239 } else {
2240 ctx->m_glGetTexParameterfv_enc(ctx, target, pname, params);
2241 }
2242}
2243
2244void GL2Encoder::s_glGetTexParameteriv(void* self,
2245 GLenum target, GLenum pname, GLint* params)
2246{
2247 GL2Encoder* ctx = (GL2Encoder*)self;
keunyoungb85b2752013-03-08 12:28:03 -08002248
2249 switch (pname) {
2250 case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
2251 *params = 1;
2252 break;
2253
2254 default:
2255 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
2256 ctx->override2DTextureTarget(target);
2257 ctx->m_glGetTexParameteriv_enc(ctx, GL_TEXTURE_2D, pname, params);
Lingfeng Yangb5c03d52016-09-07 14:40:03 -07002258 ctx->restore2DTextureTarget(target);
keunyoungb85b2752013-03-08 12:28:03 -08002259 } else {
2260 ctx->m_glGetTexParameteriv_enc(ctx, target, pname, params);
2261 }
2262 break;
2263 }
2264}
2265
2266static bool isValidTextureExternalParam(GLenum pname, GLenum param)
2267{
2268 switch (pname) {
2269 case GL_TEXTURE_MIN_FILTER:
2270 case GL_TEXTURE_MAG_FILTER:
2271 return param == GL_NEAREST || param == GL_LINEAR;
2272
2273 case GL_TEXTURE_WRAP_S:
2274 case GL_TEXTURE_WRAP_T:
2275 return param == GL_CLAMP_TO_EDGE;
2276
2277 default:
2278 return true;
2279 }
2280}
2281
2282void GL2Encoder::s_glTexParameterf(void* self,
2283 GLenum target, GLenum pname, GLfloat param)
2284{
2285 GL2Encoder* ctx = (GL2Encoder*)self;
keunyoungb85b2752013-03-08 12:28:03 -08002286
2287 SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
2288 !isValidTextureExternalParam(pname, (GLenum)param)),
2289 GL_INVALID_ENUM);
2290
2291 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
2292 ctx->override2DTextureTarget(target);
2293 ctx->m_glTexParameterf_enc(ctx, GL_TEXTURE_2D, pname, param);
Lingfeng Yangb5c03d52016-09-07 14:40:03 -07002294 ctx->restore2DTextureTarget(target);
keunyoungb85b2752013-03-08 12:28:03 -08002295 } else {
2296 ctx->m_glTexParameterf_enc(ctx, target, pname, param);
2297 }
2298}
2299
2300void GL2Encoder::s_glTexParameterfv(void* self,
2301 GLenum target, GLenum pname, const GLfloat* params)
2302{
2303 GL2Encoder* ctx = (GL2Encoder*)self;
keunyoungb85b2752013-03-08 12:28:03 -08002304
2305 SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
2306 !isValidTextureExternalParam(pname, (GLenum)params[0])),
2307 GL_INVALID_ENUM);
2308
2309 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
2310 ctx->override2DTextureTarget(target);
2311 ctx->m_glTexParameterfv_enc(ctx, GL_TEXTURE_2D, pname, params);
Lingfeng Yangb5c03d52016-09-07 14:40:03 -07002312 ctx->restore2DTextureTarget(target);
keunyoungb85b2752013-03-08 12:28:03 -08002313 } else {
2314 ctx->m_glTexParameterfv_enc(ctx, target, pname, params);
2315 }
2316}
2317
2318void GL2Encoder::s_glTexParameteri(void* self,
2319 GLenum target, GLenum pname, GLint param)
2320{
2321 GL2Encoder* ctx = (GL2Encoder*)self;
keunyoungb85b2752013-03-08 12:28:03 -08002322
2323 SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
2324 !isValidTextureExternalParam(pname, (GLenum)param)),
2325 GL_INVALID_ENUM);
2326
2327 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
2328 ctx->override2DTextureTarget(target);
2329 ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D, pname, param);
Lingfeng Yangb5c03d52016-09-07 14:40:03 -07002330 ctx->restore2DTextureTarget(target);
keunyoungb85b2752013-03-08 12:28:03 -08002331 } else {
2332 ctx->m_glTexParameteri_enc(ctx, target, pname, param);
2333 }
2334}
2335
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002336static int ilog2(uint32_t x) {
2337 int p = 0;
2338 while ((1 << p) < x)
2339 p++;
2340 return p;
2341}
2342
bohu26a92982014-11-25 16:50:37 -08002343void GL2Encoder::s_glTexImage2D(void* self, GLenum target, GLint level,
2344 GLint internalformat, GLsizei width, GLsizei height, GLint border,
2345 GLenum format, GLenum type, const GLvoid* pixels)
2346{
2347 GL2Encoder* ctx = (GL2Encoder*)self;
Lingfeng Yang69066602016-04-12 09:29:11 -07002348 GLClientState* state = ctx->m_state;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002349
2350 SET_ERROR_IF(!GLESv2Validation::textureTarget(ctx, target), GL_INVALID_ENUM);
2351 SET_ERROR_IF(!GLESv2Validation::pixelType(ctx, type), GL_INVALID_ENUM);
2352 SET_ERROR_IF(!GLESv2Validation::pixelFormat(ctx, format), GL_INVALID_ENUM);
2353 // If unpack buffer is nonzero, verify unmapped state.
2354 SET_ERROR_IF(ctx->isBufferTargetMapped(GL_PIXEL_UNPACK_BUFFER), GL_INVALID_OPERATION);
2355
2356 GLint max_texture_size;
2357 GLint max_cube_map_texture_size;
2358 ctx->glGetIntegerv(ctx, GL_MAX_TEXTURE_SIZE, &max_texture_size);
2359 ctx->glGetIntegerv(ctx, GL_MAX_CUBE_MAP_TEXTURE_SIZE, &max_cube_map_texture_size);
2360 SET_ERROR_IF(level < 0, GL_INVALID_VALUE);
2361 SET_ERROR_IF(level > ilog2(max_texture_size), GL_INVALID_VALUE);
2362 SET_ERROR_IF((target == GL_TEXTURE_CUBE_MAP) &&
2363 (level > ilog2(max_cube_map_texture_size)), GL_INVALID_VALUE);
2364 SET_ERROR_IF(width < 0 || height < 0, GL_INVALID_VALUE);
2365 SET_ERROR_IF(width > max_texture_size, GL_INVALID_VALUE);
2366 SET_ERROR_IF(height > max_texture_size, GL_INVALID_VALUE);
2367 SET_ERROR_IF(GLESv2Validation::isCubeMapTarget(target) && width > max_cube_map_texture_size, GL_INVALID_VALUE);
2368 SET_ERROR_IF(GLESv2Validation::isCubeMapTarget(target) && height > max_cube_map_texture_size, GL_INVALID_VALUE);
2369 SET_ERROR_IF(border != 0, GL_INVALID_VALUE);
2370 // If unpack buffer is nonzero, verify buffer data fits and is evenly divisible by the type.
2371 SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
2372 ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
2373 (ctx->m_state->pboNeededDataSize(width, height, 1, format, type, 0) >
2374 ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size),
2375 GL_INVALID_OPERATION);
2376 SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
2377 ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
2378 (ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size %
2379 glSizeof(type)),
2380 GL_INVALID_OPERATION);
2381 SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
2382 ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
2383 ((uintptr_t)pixels % glSizeof(type)),
2384 GL_INVALID_OPERATION);
2385 SET_ERROR_IF(state->isBoundTextureImmutableFormat(target), GL_INVALID_OPERATION);
2386
2387 GLenum stateTarget = target;
2388 if (target == GL_TEXTURE_CUBE_MAP_POSITIVE_X ||
2389 target == GL_TEXTURE_CUBE_MAP_POSITIVE_Y ||
2390 target == GL_TEXTURE_CUBE_MAP_POSITIVE_Z ||
2391 target == GL_TEXTURE_CUBE_MAP_NEGATIVE_X ||
2392 target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y ||
2393 target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Z)
2394 stateTarget = GL_TEXTURE_CUBE_MAP;
2395
2396 state->setBoundTextureInternalFormat(stateTarget, internalformat);
2397 state->setBoundTextureFormat(stateTarget, format);
2398 state->setBoundTextureType(stateTarget, type);
2399 state->setBoundTextureDims(stateTarget, level, width, height, 1);
2400
bohu26a92982014-11-25 16:50:37 -08002401 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
2402 ctx->override2DTextureTarget(target);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002403 }
Lingfeng Yang69066602016-04-12 09:29:11 -07002404
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002405 if (ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER)) {
2406 ctx->glTexImage2DOffsetAEMU(
2407 ctx, target, level, internalformat,
2408 width, height, border,
2409 format, type, (uintptr_t)pixels);
bohu26a92982014-11-25 16:50:37 -08002410 } else {
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002411 ctx->m_glTexImage2D_enc(
2412 ctx, target, level, internalformat,
2413 width, height, border,
2414 format, type, pixels);
2415 }
2416
2417 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
2418 ctx->restore2DTextureTarget(target);
bohu26a92982014-11-25 16:50:37 -08002419 }
2420}
2421
Yahan Zhou2a208292016-06-22 15:36:04 -07002422void GL2Encoder::s_glTexSubImage2D(void* self, GLenum target, GLint level,
2423 GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format,
2424 GLenum type, const GLvoid* pixels)
2425{
2426 GL2Encoder* ctx = (GL2Encoder*)self;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002427 GLClientState* state = ctx->m_state;
Lingfeng Yang554a5152019-02-21 20:20:48 -08002428
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002429 SET_ERROR_IF(!GLESv2Validation::textureTarget(ctx, target), GL_INVALID_ENUM);
2430 SET_ERROR_IF(!GLESv2Validation::pixelType(ctx, type), GL_INVALID_ENUM);
2431 SET_ERROR_IF(!GLESv2Validation::pixelFormat(ctx, format), GL_INVALID_ENUM);
2432 // If unpack buffer is nonzero, verify unmapped state.
2433 SET_ERROR_IF(ctx->isBufferTargetMapped(GL_PIXEL_UNPACK_BUFFER), GL_INVALID_OPERATION);
2434
2435 GLint max_texture_size;
2436 GLint max_cube_map_texture_size;
2437 ctx->glGetIntegerv(ctx, GL_MAX_TEXTURE_SIZE, &max_texture_size);
2438 ctx->glGetIntegerv(ctx, GL_MAX_CUBE_MAP_TEXTURE_SIZE, &max_cube_map_texture_size);
2439 SET_ERROR_IF(level < 0, GL_INVALID_VALUE);
2440 SET_ERROR_IF(level > ilog2(max_texture_size), GL_INVALID_VALUE);
2441 SET_ERROR_IF(GLESv2Validation::isCubeMapTarget(target) &&
2442 level > ilog2(max_cube_map_texture_size), GL_INVALID_VALUE);
2443 SET_ERROR_IF(width < 0 || height < 0, GL_INVALID_VALUE);
2444 SET_ERROR_IF(xoffset < 0 || yoffset < 0, GL_INVALID_VALUE);
2445
2446 GLuint tex = state->getBoundTexture(target);
2447 GLsizei neededWidth = xoffset + width;
2448 GLsizei neededHeight = yoffset + height;
2449 GLsizei neededDepth = 1;
2450
2451 if (tex && !state->queryTexEGLImageBacked(tex)) {
2452 SET_ERROR_IF(
2453 (neededWidth > state->queryTexWidth(level, tex) ||
2454 neededHeight > state->queryTexHeight(level, tex) ||
2455 neededDepth > state->queryTexDepth(level, tex)),
2456 GL_INVALID_VALUE);
2457 }
2458
2459 // If unpack buffer is nonzero, verify buffer data fits and is evenly divisible by the type.
2460 SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
2461 ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
2462 (state->pboNeededDataSize(width, height, 1, format, type, 0) >
2463 ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size),
2464 GL_INVALID_OPERATION);
2465 SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
2466 ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
2467 (ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size %
2468 glSizeof(type)),
2469 GL_INVALID_OPERATION);
2470 SET_ERROR_IF(!ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) && !pixels, GL_INVALID_OPERATION);
Yahan Zhou2a208292016-06-22 15:36:04 -07002471
2472 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
2473 ctx->override2DTextureTarget(target);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002474 }
2475
2476 if (ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER)) {
2477 ctx->glTexSubImage2DOffsetAEMU(
2478 ctx, target, level,
2479 xoffset, yoffset, width, height,
2480 format, type, (uintptr_t)pixels);
Yahan Zhou2a208292016-06-22 15:36:04 -07002481 } else {
2482 ctx->m_glTexSubImage2D_enc(ctx, target, level, xoffset, yoffset, width,
2483 height, format, type, pixels);
2484 }
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002485
2486 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
2487 ctx->restore2DTextureTarget(target);
2488 }
Yahan Zhou2a208292016-06-22 15:36:04 -07002489}
bohu26a92982014-11-25 16:50:37 -08002490
Lingfeng Yange00ec9d2016-09-16 08:54:03 -07002491void GL2Encoder::s_glCopyTexImage2D(void* self, GLenum target, GLint level,
2492 GLenum internalformat, GLint x, GLint y,
2493 GLsizei width, GLsizei height, GLint border)
2494{
2495 GL2Encoder* ctx = (GL2Encoder*)self;
2496 GLClientState* state = ctx->m_state;
2497
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002498 SET_ERROR_IF(ctx->glCheckFramebufferStatus(ctx, GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE,
2499 GL_INVALID_FRAMEBUFFER_OPERATION);
Lingfeng Yange00ec9d2016-09-16 08:54:03 -07002500 // This is needed to work around underlying OpenGL drivers
2501 // (such as those feeding some some AMD GPUs) that expect
2502 // positive components of cube maps to be defined _before_
2503 // the negative components (otherwise a segfault occurs).
2504 GLenum extraTarget =
2505 state->copyTexImageLuminanceCubeMapAMDWorkaround
2506 (target, level, internalformat);
2507
2508 if (extraTarget) {
2509 ctx->m_glCopyTexImage2D_enc(ctx, extraTarget, level, internalformat,
2510 x, y, width, height, border);
2511 }
2512
2513 ctx->m_glCopyTexImage2D_enc(ctx, target, level, internalformat,
2514 x, y, width, height, border);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002515
2516 state->setBoundTextureInternalFormat(target, internalformat);
2517 state->setBoundTextureDims(target, level, width, height, 1);
Lingfeng Yange00ec9d2016-09-16 08:54:03 -07002518}
2519
keunyoungb85b2752013-03-08 12:28:03 -08002520void GL2Encoder::s_glTexParameteriv(void* self,
2521 GLenum target, GLenum pname, const GLint* params)
2522{
2523 GL2Encoder* ctx = (GL2Encoder*)self;
keunyoungb85b2752013-03-08 12:28:03 -08002524
2525 SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
2526 !isValidTextureExternalParam(pname, (GLenum)params[0])),
2527 GL_INVALID_ENUM);
2528
2529 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
2530 ctx->override2DTextureTarget(target);
2531 ctx->m_glTexParameteriv_enc(ctx, GL_TEXTURE_2D, pname, params);
Lingfeng Yangb5c03d52016-09-07 14:40:03 -07002532 ctx->restore2DTextureTarget(target);
keunyoungb85b2752013-03-08 12:28:03 -08002533 } else {
2534 ctx->m_glTexParameteriv_enc(ctx, target, pname, params);
2535 }
2536}
2537
Lingfeng Yangb5c03d52016-09-07 14:40:03 -07002538bool GL2Encoder::texture2DNeedsOverride(GLenum target) const {
2539 return (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) &&
2540 target != m_state->getPriorityEnabledTarget(GL_TEXTURE_2D);
2541}
2542
keunyoungb85b2752013-03-08 12:28:03 -08002543void GL2Encoder::override2DTextureTarget(GLenum target)
2544{
Lingfeng Yangb5c03d52016-09-07 14:40:03 -07002545 if (texture2DNeedsOverride(target)) {
2546 m_glBindTexture_enc(this, GL_TEXTURE_2D,
2547 m_state->getBoundTexture(target));
keunyoungb85b2752013-03-08 12:28:03 -08002548 }
2549}
2550
Lingfeng Yangb5c03d52016-09-07 14:40:03 -07002551void GL2Encoder::restore2DTextureTarget(GLenum target)
keunyoungb85b2752013-03-08 12:28:03 -08002552{
Lingfeng Yangb5c03d52016-09-07 14:40:03 -07002553 if (texture2DNeedsOverride(target)) {
Lingfeng Yang5bbf5292017-04-24 18:52:56 -07002554 GLuint priorityEnabledBoundTexture =
Lingfeng Yangb5c03d52016-09-07 14:40:03 -07002555 m_state->getBoundTexture(
Lingfeng Yang5bbf5292017-04-24 18:52:56 -07002556 m_state->getPriorityEnabledTarget(GL_TEXTURE_2D));
2557 GLuint texture2DBoundTexture =
2558 m_state->getBoundTexture(GL_TEXTURE_2D);
2559 if (!priorityEnabledBoundTexture) {
2560 m_glBindTexture_enc(this, GL_TEXTURE_2D, texture2DBoundTexture);
2561 } else {
2562 m_glBindTexture_enc(this, GL_TEXTURE_2D, priorityEnabledBoundTexture);
2563 }
Lingfeng Yangb5c03d52016-09-07 14:40:03 -07002564 }
keunyoungb85b2752013-03-08 12:28:03 -08002565}
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07002566
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002567void GL2Encoder::associateEGLImage(GLenum target, GLeglImageOES eglImage) {
2568 m_state->setBoundEGLImage(target, eglImage);
2569}
2570
2571
2572GLuint GL2Encoder::boundBuffer(GLenum target) const {
2573 return m_state->getBuffer(target);
2574}
2575
2576BufferData* GL2Encoder::getBufferData(GLenum target) const {
2577 GLuint bufferId = m_state->getBuffer(target);
2578 if (!bufferId) return NULL;
2579 return m_shared->getBufferData(bufferId);
2580}
2581
2582BufferData* GL2Encoder::getBufferDataById(GLuint bufferId) const {
2583 if (!bufferId) return NULL;
2584 return m_shared->getBufferData(bufferId);
2585}
2586
2587bool GL2Encoder::isBufferMapped(GLuint buffer) const {
2588 return m_shared->getBufferData(buffer)->m_mapped;
2589}
2590
2591bool GL2Encoder::isBufferTargetMapped(GLenum target) const {
2592 BufferData* buf = getBufferData(target);
2593 if (!buf) return false;
2594 return buf->m_mapped;
2595}
2596
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07002597void GL2Encoder::s_glGenRenderbuffers(void* self,
2598 GLsizei n, GLuint* renderbuffers) {
2599 GL2Encoder* ctx = (GL2Encoder*)self;
2600 GLClientState* state = ctx->m_state;
2601
2602 SET_ERROR_IF(n < 0, GL_INVALID_VALUE);
2603
2604 ctx->m_glGenFramebuffers_enc(self, n, renderbuffers);
2605 state->addRenderbuffers(n, renderbuffers);
2606}
2607
2608void GL2Encoder::s_glDeleteRenderbuffers(void* self,
2609 GLsizei n, const GLuint* renderbuffers) {
2610 GL2Encoder* ctx = (GL2Encoder*)self;
2611 GLClientState* state = ctx->m_state;
2612
2613 SET_ERROR_IF(n < 0, GL_INVALID_VALUE);
2614
2615 ctx->m_glDeleteRenderbuffers_enc(self, n, renderbuffers);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002616
2617 // Nope, lets just leak those for now.
2618 // The spec has an *amazingly* convoluted set of conditions for when
2619 // render buffers are actually deleted:
2620 // glDeleteRenderbuffers deletes the n renderbuffer objects whose names are stored in the array addressed by renderbuffers. Unused names in renderbuffers that have been marked as used for the purposes of glGenRenderbuffers are marked as unused again. The name zero is reserved by the GL and is silently ignored, should it occur in renderbuffers, as are other unused names. Once a renderbuffer object is deleted, its name is again unused and it has no contents. If a renderbuffer that is currently bound to the target GL_RENDERBUFFER is deleted, it is as though glBindRenderbuffer had been executed with a target of GL_RENDERBUFFER and a name of zero.
2621 //
2622 // If a renderbuffer object is attached to one or more attachment points in the currently bound framebuffer, then it as if glFramebufferRenderbuffer had been called, with a renderbuffer of zero for each attachment point to which this image was attached in the currently bound framebuffer. In other words, this renderbuffer object is first detached from all attachment ponits in the currently bound framebuffer. ***Note that the renderbuffer image is specifically not detached from any non-bound framebuffers***
2623 //
2624 // So, just detach this one from the bound FBO, and ignore the rest.
2625 for (int i = 0; i < n; i++) {
2626 state->detachRbo(renderbuffers[i]);
2627 }
2628 // state->removeRenderbuffers(n, renderbuffers);
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07002629}
2630
2631void GL2Encoder::s_glBindRenderbuffer(void* self,
2632 GLenum target, GLuint renderbuffer) {
2633 GL2Encoder* ctx = (GL2Encoder*)self;
2634 GLClientState* state = ctx->m_state;
2635
2636 SET_ERROR_IF((target != GL_RENDERBUFFER),
2637 GL_INVALID_ENUM);
2638
2639 ctx->m_glBindRenderbuffer_enc(self, target, renderbuffer);
2640 state->bindRenderbuffer(target, renderbuffer);
2641}
2642
Lingfeng Yang69066602016-04-12 09:29:11 -07002643void GL2Encoder::s_glRenderbufferStorage(void* self,
2644 GLenum target, GLenum internalformat,
2645 GLsizei width, GLsizei height) {
2646 GL2Encoder* ctx = (GL2Encoder*) self;
2647 GLClientState* state = ctx->m_state;
2648
2649 SET_ERROR_IF(target != GL_RENDERBUFFER, GL_INVALID_ENUM);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002650 SET_ERROR_IF(
2651 !GLESv2Validation::rboFormat(ctx, internalformat),
2652 GL_INVALID_ENUM);
Lingfeng Yang69066602016-04-12 09:29:11 -07002653
2654 state->setBoundRenderbufferFormat(internalformat);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002655 state->setBoundRenderbufferSamples(0);
2656
Lingfeng Yang69066602016-04-12 09:29:11 -07002657 ctx->m_glRenderbufferStorage_enc(self, target, internalformat,
2658 width, height);
2659}
2660
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07002661void GL2Encoder::s_glFramebufferRenderbuffer(void* self,
2662 GLenum target, GLenum attachment,
2663 GLenum renderbuffertarget, GLuint renderbuffer) {
2664 GL2Encoder* ctx = (GL2Encoder*)self;
2665 GLClientState* state = ctx->m_state;
2666
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002667 SET_ERROR_IF(!GLESv2Validation::framebufferTarget(ctx, target), GL_INVALID_ENUM);
2668 SET_ERROR_IF(!GLESv2Validation::framebufferAttachment(ctx, attachment), GL_INVALID_ENUM);
2669 state->attachRbo(target, attachment, renderbuffer);
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07002670
2671 ctx->m_glFramebufferRenderbuffer_enc(self, target, attachment, renderbuffertarget, renderbuffer);
2672}
2673
2674void GL2Encoder::s_glGenFramebuffers(void* self,
2675 GLsizei n, GLuint* framebuffers) {
2676 GL2Encoder* ctx = (GL2Encoder*)self;
2677 GLClientState* state = ctx->m_state;
2678
2679 SET_ERROR_IF(n < 0, GL_INVALID_VALUE);
2680
2681 ctx->m_glGenFramebuffers_enc(self, n, framebuffers);
2682 state->addFramebuffers(n, framebuffers);
2683}
2684
2685void GL2Encoder::s_glDeleteFramebuffers(void* self,
2686 GLsizei n, const GLuint* framebuffers) {
2687 GL2Encoder* ctx = (GL2Encoder*)self;
2688 GLClientState* state = ctx->m_state;
2689
2690 SET_ERROR_IF(n < 0, GL_INVALID_VALUE);
2691
2692 ctx->m_glDeleteFramebuffers_enc(self, n, framebuffers);
2693 state->removeFramebuffers(n, framebuffers);
2694}
2695
2696void GL2Encoder::s_glBindFramebuffer(void* self,
2697 GLenum target, GLuint framebuffer) {
2698 GL2Encoder* ctx = (GL2Encoder*)self;
2699 GLClientState* state = ctx->m_state;
2700
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002701 SET_ERROR_IF(!GLESv2Validation::framebufferTarget(ctx, target), GL_INVALID_ENUM);
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07002702
2703 state->bindFramebuffer(target, framebuffer);
2704
2705 ctx->m_glBindFramebuffer_enc(self, target, framebuffer);
2706}
2707
2708void GL2Encoder::s_glFramebufferTexture2D(void* self,
2709 GLenum target, GLenum attachment,
2710 GLenum textarget, GLuint texture, GLint level) {
2711 GL2Encoder* ctx = (GL2Encoder*)self;
2712 GLClientState* state = ctx->m_state;
2713
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002714 SET_ERROR_IF(!GLESv2Validation::framebufferTarget(ctx, target), GL_INVALID_ENUM);
2715 SET_ERROR_IF(!GLESv2Validation::framebufferAttachment(ctx, attachment), GL_INVALID_ENUM);
2716 state->attachTextureObject(target, attachment, texture);
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07002717
2718 ctx->m_glFramebufferTexture2D_enc(self, target, attachment, textarget, texture, level);
2719}
2720
2721void GL2Encoder::s_glFramebufferTexture3DOES(void* self,
2722 GLenum target, GLenum attachment,
2723 GLenum textarget, GLuint texture, GLint level, GLint zoffset) {
2724 GL2Encoder* ctx = (GL2Encoder*)self;
2725 GLClientState* state = ctx->m_state;
2726
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002727 state->attachTextureObject(target, attachment, texture);
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07002728
2729 ctx->m_glFramebufferTexture3DOES_enc(self, target, attachment, textarget, texture, level, zoffset);
2730}
2731
2732void GL2Encoder::s_glGetFramebufferAttachmentParameteriv(void* self,
2733 GLenum target, GLenum attachment, GLenum pname, GLint* params) {
2734 GL2Encoder* ctx = (GL2Encoder*)self;
2735 const GLClientState* state = ctx->m_state;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002736 SET_ERROR_IF(!GLESv2Validation::framebufferTarget(ctx, target), GL_INVALID_ENUM);
2737 SET_ERROR_IF(pname != GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME &&
2738 pname != GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE &&
2739 !state->attachmentHasObject(target, attachment),
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07002740 GL_INVALID_OPERATION);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002741 SET_ERROR_IF((pname == GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL ||
2742 pname == GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE ||
2743 pname == GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER) &&
2744 (!state->attachmentHasObject(target, attachment) ||
2745 state->getBoundFramebufferAttachmentType(target, attachment) !=
2746 FBO_ATTACHMENT_TEXTURE),
2747 !state->attachmentHasObject(target, attachment) ?
2748 GL_INVALID_OPERATION : GL_INVALID_ENUM);
2749 SET_ERROR_IF(attachment == GL_DEPTH_STENCIL_ATTACHMENT &&
2750 pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME &&
2751 (state->objectOfAttachment(target, GL_DEPTH_ATTACHMENT) !=
2752 state->objectOfAttachment(target, GL_STENCIL_ATTACHMENT)),
2753 GL_INVALID_OPERATION);
2754 SET_ERROR_IF(state->boundFramebuffer(target) &&
2755 (attachment == GL_BACK ||
2756 attachment == GL_FRONT),
2757 GL_INVALID_OPERATION);
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07002758 ctx->m_glGetFramebufferAttachmentParameteriv_enc(self, target, attachment, pname, params);
2759}
Lingfeng Yang69066602016-04-12 09:29:11 -07002760
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002761bool GL2Encoder::isCompleteFbo(GLenum target, const GLClientState* state,
Lingfeng Yang69066602016-04-12 09:29:11 -07002762 GLenum attachment) const {
2763 FboFormatInfo fbo_format_info;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002764 state->getBoundFramebufferFormat(target, attachment, &fbo_format_info);
Lingfeng Yang69066602016-04-12 09:29:11 -07002765
2766 bool res;
2767 switch (fbo_format_info.type) {
2768 case FBO_ATTACHMENT_RENDERBUFFER:
2769 switch (fbo_format_info.rb_format) {
2770 case GL_R16F:
2771 case GL_RG16F:
Lingfeng Yang69066602016-04-12 09:29:11 -07002772 case GL_RGBA16F:
Lingfeng Yang931817b2017-01-27 06:50:56 -08002773 case GL_R32F:
2774 case GL_RG32F:
2775 case GL_RGBA32F:
2776 case GL_R11F_G11F_B10F:
Lingfeng Yangc92685e2017-01-30 20:06:39 -08002777 res = majorVersion() >= 3 && hasExtension("GL_EXT_color_buffer_float");
Lingfeng Yang931817b2017-01-27 06:50:56 -08002778 break;
2779 case GL_RGB16F:
Lingfeng Yangc92685e2017-01-30 20:06:39 -08002780 res = majorVersion() >= 3 && hasExtension("GL_EXT_color_buffer_half_float");
Lingfeng Yang69066602016-04-12 09:29:11 -07002781 break;
2782 case GL_STENCIL_INDEX8:
2783 if (attachment == GL_STENCIL_ATTACHMENT) {
2784 res = true;
2785 } else {
2786 res = false;
2787 }
2788 break;
2789 default:
2790 res = true;
2791 }
2792 break;
2793 case FBO_ATTACHMENT_TEXTURE:
Yahan Zhou68bfd8c2016-05-11 15:06:34 -07002794 switch (fbo_format_info.tex_internalformat) {
Yahan Zhou68bfd8c2016-05-11 15:06:34 -07002795 case GL_R16F:
2796 case GL_RG16F:
2797 case GL_RGBA16F:
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002798 case GL_R32F:
2799 case GL_RG32F:
2800 case GL_RGBA32F:
Lingfeng Yang931817b2017-01-27 06:50:56 -08002801 case GL_R11F_G11F_B10F:
Lingfeng Yangc92685e2017-01-30 20:06:39 -08002802 res = majorVersion() >= 3 && hasExtension("GL_EXT_color_buffer_float");
Lingfeng Yang931817b2017-01-27 06:50:56 -08002803 break;
2804 case GL_RGB16F:
Lingfeng Yangc92685e2017-01-30 20:06:39 -08002805 res = majorVersion() >= 3 && hasExtension("GL_EXT_color_buffer_half_float");
Lingfeng Yang931817b2017-01-27 06:50:56 -08002806 break;
2807 case GL_RED:
2808 case GL_RG:
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002809 case GL_SRGB8:
2810 case GL_RGB32UI:
2811 case GL_RGB16UI:
2812 case GL_RGB8UI:
2813 case GL_RGB32I:
2814 case GL_RGB16I:
2815 case GL_RGB8I:
2816 case GL_R8_SNORM:
2817 case GL_RG8_SNORM:
2818 case GL_RGB8_SNORM:
2819 case GL_RGBA8_SNORM:
Yahan Zhou68bfd8c2016-05-11 15:06:34 -07002820 res = false;
2821 break;
Lingfeng Yang69066602016-04-12 09:29:11 -07002822 // No float/half-float formats allowed for RGB(A)
Yahan Zhou68bfd8c2016-05-11 15:06:34 -07002823 case GL_RGB:
2824 case GL_RGBA:
Lingfeng Yang69066602016-04-12 09:29:11 -07002825 switch (fbo_format_info.tex_type) {
2826 case GL_FLOAT:
2827 case GL_HALF_FLOAT_OES:
Yahan Zhou68bfd8c2016-05-11 15:06:34 -07002828 case GL_UNSIGNED_INT_10F_11F_11F_REV:
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002829 case GL_UNSIGNED_INT_2_10_10_10_REV:
Lingfeng Yang69066602016-04-12 09:29:11 -07002830 res = false;
2831 break;
2832 default:
2833 res = true;
2834 }
Yahan Zhou68bfd8c2016-05-11 15:06:34 -07002835 break;
2836 default:
Lingfeng Yang69066602016-04-12 09:29:11 -07002837 res = true;
2838 }
2839 break;
2840 case FBO_ATTACHMENT_NONE:
2841 res = true;
2842 break;
2843 default:
2844 res = true;
2845 }
2846 return res;
2847}
2848
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002849bool GL2Encoder::checkFramebufferCompleteness(GLenum target, const GLClientState* state) const {
2850 bool res = true;
2851
2852 for (int i = 0; i < state->getMaxColorAttachments(); i++) {
2853 res = res && isCompleteFbo(target, state, glUtilsColorAttachmentName(i));
2854 }
2855
2856 res = res && isCompleteFbo(target, state, GL_DEPTH_ATTACHMENT);
2857 res = res && isCompleteFbo(target, state, GL_STENCIL_ATTACHMENT);
2858
2859 return res;
2860}
2861
Lingfeng Yang69066602016-04-12 09:29:11 -07002862GLenum GL2Encoder::s_glCheckFramebufferStatus(void* self, GLenum target) {
2863 GL2Encoder* ctx = (GL2Encoder*)self;
2864 GLClientState* state = ctx->m_state;
2865
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002866 bool fboCompleteByCodec =
2867 ctx->checkFramebufferCompleteness(target, state);
2868
2869 if (!fboCompleteByCodec) {
2870 state->setCheckFramebufferStatus(target, GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT);
Lingfeng Yang69066602016-04-12 09:29:11 -07002871 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
2872 } else {
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002873 // double check with underlying opengl to avoid craziness.
Lingfeng Yang69066602016-04-12 09:29:11 -07002874 GLenum host_checkstatus = ctx->m_glCheckFramebufferStatus_enc(self, target);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002875 state->setCheckFramebufferStatus(target, host_checkstatus);
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08002876 if (host_checkstatus == GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS) return GL_FRAMEBUFFER_COMPLETE;
Lingfeng Yang69066602016-04-12 09:29:11 -07002877 return host_checkstatus;
2878 }
2879}
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002880
2881void GL2Encoder::s_glGenVertexArrays(void* self, GLsizei n, GLuint* arrays) {
2882 GL2Encoder* ctx = (GL2Encoder*)self;
2883 GLClientState* state = ctx->m_state;
2884 SET_ERROR_IF(n < 0, GL_INVALID_VALUE);
2885
2886 ctx->m_glGenVertexArrays_enc(self, n, arrays);
2887 for (int i = 0; i < n; i++) {
2888 ALOGV("%s: gen vao %u", __FUNCTION__, arrays[i]);
2889 }
2890 state->addVertexArrayObjects(n, arrays);
2891}
2892
2893void GL2Encoder::s_glDeleteVertexArrays(void* self, GLsizei n, const GLuint* arrays) {
2894 GL2Encoder* ctx = (GL2Encoder*)self;
2895 GLClientState* state = ctx->m_state;
2896 SET_ERROR_IF(n < 0, GL_INVALID_VALUE);
2897
2898 ctx->m_glDeleteVertexArrays_enc(self, n, arrays);
2899 for (int i = 0; i < n; i++) {
2900 ALOGV("%s: delete vao %u", __FUNCTION__, arrays[i]);
2901 }
2902 state->removeVertexArrayObjects(n, arrays);
2903}
2904
2905void GL2Encoder::s_glBindVertexArray(void* self, GLuint array) {
2906 ALOGV("%s: call. array=%u\n", __FUNCTION__, array);
2907 GL2Encoder* ctx = (GL2Encoder*)self;
2908 GLClientState* state = ctx->m_state;
2909 SET_ERROR_IF(!state->isVertexArrayObject(array), GL_INVALID_OPERATION);
2910 ctx->m_glBindVertexArray_enc(self, array);
2911 state->setVertexArrayObject(array);
2912}
2913
Lingfeng Yangfb3d2bb2017-09-07 15:02:04 -07002914void* GL2Encoder::s_glMapBufferOES(void* self, GLenum target, GLenum access) {
2915 GL2Encoder* ctx = (GL2Encoder*)self;
2916
2917 RET_AND_SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM, NULL);
2918
2919 GLuint boundBuffer = ctx->m_state->getBuffer(target);
2920
2921 RET_AND_SET_ERROR_IF(boundBuffer == 0, GL_INVALID_OPERATION, NULL);
2922
2923 BufferData* buf = ctx->m_shared->getBufferData(boundBuffer);
2924 RET_AND_SET_ERROR_IF(!buf, GL_INVALID_VALUE, NULL);
2925
2926 return ctx->glMapBufferRange(ctx, target, 0, buf->m_size, access);
2927}
2928
2929GLboolean GL2Encoder::s_glUnmapBufferOES(void* self, GLenum target) {
2930 GL2Encoder* ctx = (GL2Encoder*)self;
2931
2932 return ctx->glUnmapBuffer(ctx, target);
2933}
2934
Roman Kiryanovbe1c0c22018-10-02 18:07:14 -07002935void* GL2Encoder::s_glMapBufferRangeAEMUImpl(GL2Encoder* ctx, GLenum target,
2936 GLintptr offset, GLsizeiptr length,
2937 GLbitfield access, BufferData* buf) {
2938 char* bits = (char*)buf->m_fixedBuffer.ptr() + offset;
2939
Lingfeng Yang22e361a2019-10-12 07:19:00 -07002940 if ((access & GL_MAP_READ_BIT) ||
2941 ((access & GL_MAP_WRITE_BIT) &&
2942 (!(access & GL_MAP_INVALIDATE_RANGE_BIT) &&
2943 !(access & GL_MAP_INVALIDATE_BUFFER_BIT)))) {
2944 ctx->glMapBufferRangeAEMU(
2945 ctx, target,
2946 offset, length,
2947 access,
2948 bits);
2949 }
Roman Kiryanovbe1c0c22018-10-02 18:07:14 -07002950
2951 return bits;
2952}
2953
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002954void* GL2Encoder::s_glMapBufferRange(void* self, GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access) {
2955 GL2Encoder* ctx = (GL2Encoder*)self;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002956
2957 // begin validation (lots)
Lingfeng Yang554a5152019-02-21 20:20:48 -08002958
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002959 RET_AND_SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM, NULL);
2960
2961 GLuint boundBuffer = ctx->m_state->getBuffer(target);
2962
2963 RET_AND_SET_ERROR_IF(boundBuffer == 0, GL_INVALID_OPERATION, NULL);
2964
2965 BufferData* buf = ctx->m_shared->getBufferData(boundBuffer);
2966 RET_AND_SET_ERROR_IF(!buf, GL_INVALID_VALUE, NULL);
2967
2968 GLsizeiptr bufferDataSize = buf->m_size;
2969
2970 RET_AND_SET_ERROR_IF(offset < 0, GL_INVALID_VALUE, NULL);
2971 RET_AND_SET_ERROR_IF(length < 0, GL_INVALID_VALUE, NULL);
2972 RET_AND_SET_ERROR_IF(offset + length > bufferDataSize, GL_INVALID_VALUE, NULL);
2973 RET_AND_SET_ERROR_IF(access & ~GLESv2Validation::allBufferMapAccessFlags, GL_INVALID_VALUE, NULL);
2974
2975 RET_AND_SET_ERROR_IF(buf->m_mapped, GL_INVALID_OPERATION, NULL);
2976 RET_AND_SET_ERROR_IF(!(access & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)), GL_INVALID_OPERATION, NULL);
2977 RET_AND_SET_ERROR_IF(
2978 (access & GL_MAP_READ_BIT) &&
2979 ((access & GL_MAP_INVALIDATE_RANGE_BIT) ||
2980 (access & GL_MAP_INVALIDATE_BUFFER_BIT) ||
2981 (access & GL_MAP_UNSYNCHRONIZED_BIT) ||
2982 (access & GL_MAP_FLUSH_EXPLICIT_BIT)), GL_INVALID_OPERATION, NULL);
2983
2984 // end validation; actually do stuff now
Lingfeng Yang554a5152019-02-21 20:20:48 -08002985
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002986 buf->m_mapped = true;
2987 buf->m_mappedAccess = access;
2988 buf->m_mappedOffset = offset;
2989 buf->m_mappedLength = length;
2990
Roman Kiryanovbe1c0c22018-10-02 18:07:14 -07002991 if (ctx->hasExtension("ANDROID_EMU_dma_v2")) {
2992 if (buf->dma_buffer.get().size < length) {
2993 goldfish_dma_context region;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002994
Roman Kiryanovbe1c0c22018-10-02 18:07:14 -07002995 const int PAGE_BITS = 12;
2996 GLsizeiptr aligned_length = (length + (1 << PAGE_BITS) - 1) & ~((1 << PAGE_BITS) - 1);
2997
2998 if (goldfish_dma_create_region(aligned_length, &region)) {
2999 buf->dma_buffer.reset(NULL);
3000 return s_glMapBufferRangeAEMUImpl(ctx, target, offset, length, access, buf);
3001 }
3002
3003 if (!goldfish_dma_map(&region)) {
3004 buf->dma_buffer.reset(NULL);
3005 return s_glMapBufferRangeAEMUImpl(ctx, target, offset, length, access, buf);
3006 }
3007
3008 buf->m_guest_paddr = goldfish_dma_guest_paddr(&region);
3009 buf->dma_buffer.reset(&region);
3010 }
3011
3012 ctx->glMapBufferRangeDMA(
3013 ctx, target,
3014 offset, length,
3015 access,
3016 buf->m_guest_paddr);
3017
3018 return reinterpret_cast<void*>(buf->dma_buffer.get().mapped_addr);
3019 } else {
3020 return s_glMapBufferRangeAEMUImpl(ctx, target, offset, length, access, buf);
3021 }
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003022}
3023
3024GLboolean GL2Encoder::s_glUnmapBuffer(void* self, GLenum target) {
3025 GL2Encoder* ctx = (GL2Encoder*)self;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003026
3027 RET_AND_SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM, GL_FALSE);
3028
3029 GLuint boundBuffer = ctx->m_state->getBuffer(target);
3030
3031 RET_AND_SET_ERROR_IF(boundBuffer == 0, GL_INVALID_OPERATION, GL_FALSE);
3032
3033 BufferData* buf = ctx->m_shared->getBufferData(boundBuffer);
3034 RET_AND_SET_ERROR_IF(!buf, GL_INVALID_VALUE, GL_FALSE);
3035 RET_AND_SET_ERROR_IF(!buf->m_mapped, GL_INVALID_OPERATION, GL_FALSE);
3036
Lingfeng Yang423129e2017-01-18 09:23:12 -08003037 if (buf->m_mappedAccess & GL_MAP_WRITE_BIT) {
3038 // invalide index range cache here
3039 if (buf->m_mappedAccess & GL_MAP_INVALIDATE_BUFFER_BIT) {
3040 buf->m_indexRangeCache.invalidateRange(0, buf->m_size);
3041 } else {
3042 buf->m_indexRangeCache.invalidateRange(buf->m_mappedOffset, buf->m_mappedLength);
3043 }
3044 }
3045
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003046 GLboolean host_res = GL_TRUE;
3047
Roman Kiryanovbe1c0c22018-10-02 18:07:14 -07003048 if (buf->dma_buffer.get().mapped_addr) {
3049 memcpy(static_cast<char*>(buf->m_fixedBuffer.ptr()) + buf->m_mappedOffset,
3050 reinterpret_cast<void*>(buf->dma_buffer.get().mapped_addr),
3051 buf->m_mappedLength);
3052
3053 ctx->glUnmapBufferDMA(
Roman Kiryanovdaecd142018-11-14 14:56:27 -08003054 ctx, target,
3055 buf->m_mappedOffset,
3056 buf->m_mappedLength,
3057 buf->m_mappedAccess,
3058 goldfish_dma_guest_paddr(&buf->dma_buffer.get()),
3059 &host_res);
Roman Kiryanovbe1c0c22018-10-02 18:07:14 -07003060 } else {
Lingfeng Yang22e361a2019-10-12 07:19:00 -07003061 if (ctx->m_hasAsyncUnmapBuffer) {
3062 ctx->glUnmapBufferAsyncAEMU(
3063 ctx, target,
3064 buf->m_mappedOffset,
3065 buf->m_mappedLength,
3066 buf->m_mappedAccess,
3067 (void*)((char*)buf->m_fixedBuffer.ptr() + buf->m_mappedOffset),
3068 &host_res);
3069 } else {
3070 if (buf->m_mappedAccess & GL_MAP_WRITE_BIT) {
3071 ctx->glUnmapBufferAEMU(
3072 ctx, target,
3073 buf->m_mappedOffset,
3074 buf->m_mappedLength,
3075 buf->m_mappedAccess,
3076 (void*)((char*)buf->m_fixedBuffer.ptr() + buf->m_mappedOffset),
3077 &host_res);
3078 }
3079 }
Roman Kiryanovbe1c0c22018-10-02 18:07:14 -07003080 }
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003081
3082 buf->m_mapped = false;
3083 buf->m_mappedAccess = 0;
3084 buf->m_mappedOffset = 0;
3085 buf->m_mappedLength = 0;
3086
3087 return host_res;
3088}
3089
3090void GL2Encoder::s_glFlushMappedBufferRange(void* self, GLenum target, GLintptr offset, GLsizeiptr length) {
3091 GL2Encoder* ctx = (GL2Encoder*)self;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003092
3093 SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM);
3094
3095 GLuint boundBuffer = ctx->m_state->getBuffer(target);
3096 SET_ERROR_IF(!boundBuffer, GL_INVALID_OPERATION);
3097
3098 BufferData* buf = ctx->m_shared->getBufferData(boundBuffer);
3099 SET_ERROR_IF(!buf, GL_INVALID_VALUE);
3100 SET_ERROR_IF(!buf->m_mapped, GL_INVALID_OPERATION);
3101 SET_ERROR_IF(!(buf->m_mappedAccess & GL_MAP_FLUSH_EXPLICIT_BIT), GL_INVALID_OPERATION);
3102
3103 SET_ERROR_IF(offset < 0, GL_INVALID_VALUE);
3104 SET_ERROR_IF(length < 0, GL_INVALID_VALUE);
3105 SET_ERROR_IF(offset + length > buf->m_mappedLength, GL_INVALID_VALUE);
3106
3107 GLintptr totalOffset = buf->m_mappedOffset + offset;
Lingfeng Yang423129e2017-01-18 09:23:12 -08003108
3109 buf->m_indexRangeCache.invalidateRange(totalOffset, length);
3110
Lingfeng Yang22e361a2019-10-12 07:19:00 -07003111 if (ctx->m_hasAsyncUnmapBuffer) {
3112 ctx->glFlushMappedBufferRangeAEMU2(
3113 ctx, target,
3114 totalOffset,
3115 length,
3116 buf->m_mappedAccess,
3117 (void*)((char*)buf->m_fixedBuffer.ptr() + totalOffset));
3118 } else {
3119 ctx->glFlushMappedBufferRangeAEMU(
3120 ctx, target,
3121 totalOffset,
3122 length,
3123 buf->m_mappedAccess,
3124 (void*)((char*)buf->m_fixedBuffer.ptr() + totalOffset));
3125 }
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003126}
3127
3128void GL2Encoder::s_glCompressedTexImage2D(void* self, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* data) {
3129 GL2Encoder* ctx = (GL2Encoder*)self;
3130 GLClientState* state = ctx->m_state;
3131
3132 SET_ERROR_IF(!GLESv2Validation::textureTarget(ctx, target), GL_INVALID_ENUM);
3133 // Filter compressed formats support.
3134 SET_ERROR_IF(!GLESv2Validation::supportedCompressedFormat(ctx, internalformat), GL_INVALID_ENUM);
3135 // Verify level <= log2(GL_MAX_TEXTURE_SIZE).
3136 GLint max_texture_size;
3137 GLint max_cube_map_texture_size;
3138 ctx->glGetIntegerv(ctx, GL_MAX_TEXTURE_SIZE, &max_texture_size);
3139 ctx->glGetIntegerv(ctx, GL_MAX_CUBE_MAP_TEXTURE_SIZE, &max_cube_map_texture_size);
3140 SET_ERROR_IF(level < 0, GL_INVALID_VALUE);
3141 SET_ERROR_IF(level > ilog2(max_texture_size), GL_INVALID_VALUE);
3142 SET_ERROR_IF(level > ilog2(max_cube_map_texture_size), GL_INVALID_VALUE);
3143 SET_ERROR_IF(width > max_texture_size, GL_INVALID_VALUE);
3144 SET_ERROR_IF(height > max_texture_size, GL_INVALID_VALUE);
3145 SET_ERROR_IF(border, GL_INVALID_VALUE);
3146 // If unpack buffer is nonzero, verify unmapped state.
3147 SET_ERROR_IF(ctx->isBufferTargetMapped(GL_PIXEL_UNPACK_BUFFER), GL_INVALID_OPERATION);
3148 SET_ERROR_IF(width < 0 || height < 0, GL_INVALID_VALUE);
3149 // If unpack buffer is nonzero, verify buffer data fits.
3150 SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
3151 ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
3152 (imageSize > ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size),
3153 GL_INVALID_OPERATION);
3154 // TODO: Fix:
3155 // If |imageSize| is inconsistent with compressed dimensions.
3156 // SET_ERROR_IF(GLESv2Validation::compressedTexImageSize(internalformat, width, height, 1) != imageSize, GL_INVALID_VALUE);
3157
3158 GLenum stateTarget = target;
3159 if (target == GL_TEXTURE_CUBE_MAP_POSITIVE_X ||
3160 target == GL_TEXTURE_CUBE_MAP_POSITIVE_Y ||
3161 target == GL_TEXTURE_CUBE_MAP_POSITIVE_Z ||
3162 target == GL_TEXTURE_CUBE_MAP_NEGATIVE_X ||
3163 target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y ||
3164 target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Z)
3165 stateTarget = GL_TEXTURE_CUBE_MAP;
3166 state->setBoundTextureInternalFormat(stateTarget, (GLint)internalformat);
3167 state->setBoundTextureDims(stateTarget, level, width, height, 1);
3168
Lingfeng Yanga9fff6a2018-03-02 13:42:51 -08003169 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
3170 ctx->override2DTextureTarget(target);
3171 }
3172
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003173 if (ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER)) {
3174 ctx->glCompressedTexImage2DOffsetAEMU(
3175 ctx, target, level, internalformat,
3176 width, height, border,
3177 imageSize, (uintptr_t)data);
3178 } else {
3179 ctx->m_glCompressedTexImage2D_enc(
3180 ctx, target, level, internalformat,
3181 width, height, border,
3182 imageSize, data);
3183 }
Lingfeng Yanga9fff6a2018-03-02 13:42:51 -08003184
3185 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
3186 ctx->restore2DTextureTarget(target);
3187 }
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003188}
3189
3190void GL2Encoder::s_glCompressedTexSubImage2D(void* self, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* data) {
3191 GL2Encoder* ctx = (GL2Encoder*)self;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003192
3193 SET_ERROR_IF(!GLESv2Validation::textureTarget(ctx, target), GL_INVALID_ENUM);
3194 // If unpack buffer is nonzero, verify unmapped state.
3195 SET_ERROR_IF(ctx->isBufferTargetMapped(GL_PIXEL_UNPACK_BUFFER), GL_INVALID_OPERATION);
3196 GLint max_texture_size;
3197 GLint max_cube_map_texture_size;
3198 ctx->glGetIntegerv(ctx, GL_MAX_TEXTURE_SIZE, &max_texture_size);
3199 ctx->glGetIntegerv(ctx, GL_MAX_CUBE_MAP_TEXTURE_SIZE, &max_cube_map_texture_size);
3200 SET_ERROR_IF(level < 0, GL_INVALID_VALUE);
3201 SET_ERROR_IF(level > ilog2(max_texture_size), GL_INVALID_VALUE);
3202 SET_ERROR_IF(level > ilog2(max_cube_map_texture_size), GL_INVALID_VALUE);
3203 SET_ERROR_IF(width < 0 || height < 0, GL_INVALID_VALUE);
3204 // If unpack buffer is nonzero, verify buffer data fits.
3205 SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
3206 ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
3207 (imageSize > ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size),
3208 GL_INVALID_OPERATION);
3209 SET_ERROR_IF(xoffset < 0 || yoffset < 0, GL_INVALID_VALUE);
3210
Lingfeng Yanga9fff6a2018-03-02 13:42:51 -08003211 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
3212 ctx->override2DTextureTarget(target);
3213 }
3214
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003215 if (ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER)) {
3216 ctx->glCompressedTexSubImage2DOffsetAEMU(
3217 ctx, target, level,
3218 xoffset, yoffset,
3219 width, height, format,
3220 imageSize, (uintptr_t)data);
3221 } else {
3222 ctx->m_glCompressedTexSubImage2D_enc(
3223 ctx, target, level,
3224 xoffset, yoffset,
3225 width, height, format,
3226 imageSize, data);
3227 }
Lingfeng Yanga9fff6a2018-03-02 13:42:51 -08003228
3229 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
3230 ctx->restore2DTextureTarget(target);
3231 }
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003232}
3233
3234void GL2Encoder::s_glBindBufferRange(void* self, GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size) {
3235 GL2Encoder* ctx = (GL2Encoder*)self;
3236 GLClientState* state = ctx->m_state;
3237
3238 SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM);
3239
3240 // Only works with certain targets
3241 SET_ERROR_IF(
3242 !(target == GL_ATOMIC_COUNTER_BUFFER ||
3243 target == GL_SHADER_STORAGE_BUFFER ||
3244 target == GL_TRANSFORM_FEEDBACK_BUFFER ||
3245 target == GL_UNIFORM_BUFFER),
3246 GL_INVALID_ENUM);
3247
3248 // Can't exceed range
3249 SET_ERROR_IF(index < 0 ||
3250 index >= state->getMaxIndexedBufferBindings(target),
3251 GL_INVALID_VALUE);
3252 SET_ERROR_IF(buffer && size <= 0, GL_INVALID_VALUE);
3253 SET_ERROR_IF((target == GL_ATOMIC_COUNTER_BUFFER ||
3254 target == GL_TRANSFORM_FEEDBACK_BUFFER) &&
3255 (size % 4 || offset % 4),
3256 GL_INVALID_VALUE);
3257
3258 GLint ssbo_offset_align, ubo_offset_align;
3259 ctx->s_glGetIntegerv(ctx, GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT, &ssbo_offset_align);
3260 ctx->s_glGetIntegerv(ctx, GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &ubo_offset_align);
3261 SET_ERROR_IF(target == GL_SHADER_STORAGE_BUFFER &&
3262 offset % ssbo_offset_align,
3263 GL_INVALID_VALUE);
3264 SET_ERROR_IF(target == GL_UNIFORM_BUFFER &&
3265 offset % ubo_offset_align,
3266 GL_INVALID_VALUE);
3267
Lingfeng Yang554a5152019-02-21 20:20:48 -08003268 if (ctx->m_state->isIndexedBindNoOp(target, index, buffer, offset, size, 0, 0)) return;
3269
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003270 state->bindBuffer(target, buffer);
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08003271 ctx->m_state->addBuffer(buffer);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003272 state->bindIndexedBuffer(target, index, buffer, offset, size, 0, 0);
Lingfeng Yang554a5152019-02-21 20:20:48 -08003273
3274 ctx->m_glBindBufferRange_enc(ctx, target, index, buffer, offset, size);
3275 ctx->m_state->setLastEncodedBufferBind(target, buffer);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003276}
3277
3278void GL2Encoder::s_glBindBufferBase(void* self, GLenum target, GLuint index, GLuint buffer) {
3279 GL2Encoder* ctx = (GL2Encoder*)self;
3280 GLClientState* state = ctx->m_state;
3281
3282 SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM);
3283
3284 // Only works with certain targets
3285 SET_ERROR_IF(
3286 !(target == GL_ATOMIC_COUNTER_BUFFER ||
3287 target == GL_SHADER_STORAGE_BUFFER ||
3288 target == GL_TRANSFORM_FEEDBACK_BUFFER ||
3289 target == GL_UNIFORM_BUFFER),
3290 GL_INVALID_ENUM);
3291 // Can't exceed range
3292 SET_ERROR_IF(index < 0 ||
3293 index >= state->getMaxIndexedBufferBindings(target),
3294 GL_INVALID_VALUE);
3295
Lingfeng Yang554a5152019-02-21 20:20:48 -08003296 BufferData* buf = ctx->getBufferDataById(buffer);
3297 GLsizeiptr size = buf ? buf->m_size : 0;
3298
3299 if (ctx->m_state->isIndexedBindNoOp(target, index, buffer, 0, size, 0, 0)) return;
3300
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003301 state->bindBuffer(target, buffer);
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08003302 ctx->m_state->addBuffer(buffer);
Lingfeng Yang554a5152019-02-21 20:20:48 -08003303
3304 state->bindIndexedBuffer(target, index, buffer, 0, size, 0, 0);
3305
3306 ctx->m_glBindBufferBase_enc(ctx, target, index, buffer);
3307 ctx->m_state->setLastEncodedBufferBind(target, buffer);
3308}
3309
3310void GL2Encoder::doIndexedBufferBindEncodeCached(IndexedBufferBindOp op, GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size, GLintptr stride, GLintptr effectiveStride)
3311{
3312 if (m_state->isIndexedBindNoOp(target, index, buffer, offset, size, stride, effectiveStride)) return;
3313
3314 switch (op) {
3315 case BindBufferBase:
3316 // can emulate with bindBufferRange
3317 case BindBufferRange:
3318 m_glBindBufferRange_enc(this, target, index, buffer, offset, size);
3319 break;
3320 // TODO: other ops
3321 }
3322
3323 m_state->setLastEncodedBufferBind(target, buffer);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003324}
3325
3326void GL2Encoder::s_glCopyBufferSubData(void *self , GLenum readtarget, GLenum writetarget, GLintptr readoffset, GLintptr writeoffset, GLsizeiptr size) {
3327 GL2Encoder* ctx = (GL2Encoder*)self;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003328
3329 SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, readtarget), GL_INVALID_ENUM);
3330 SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, writetarget), GL_INVALID_ENUM);
3331 SET_ERROR_IF((readtarget == GL_ATOMIC_COUNTER_BUFFER ||
3332 readtarget == GL_DISPATCH_INDIRECT_BUFFER ||
3333 readtarget == GL_DRAW_INDIRECT_BUFFER ||
3334 readtarget == GL_SHADER_STORAGE_BUFFER), GL_INVALID_ENUM);
3335 SET_ERROR_IF((writetarget == GL_ATOMIC_COUNTER_BUFFER ||
3336 writetarget == GL_DISPATCH_INDIRECT_BUFFER ||
3337 writetarget == GL_DRAW_INDIRECT_BUFFER ||
3338 writetarget == GL_SHADER_STORAGE_BUFFER), GL_INVALID_ENUM);
3339 SET_ERROR_IF(!ctx->boundBuffer(readtarget), GL_INVALID_OPERATION);
3340 SET_ERROR_IF(!ctx->boundBuffer(writetarget), GL_INVALID_OPERATION);
3341 SET_ERROR_IF(ctx->isBufferTargetMapped(readtarget), GL_INVALID_OPERATION);
3342 SET_ERROR_IF(ctx->isBufferTargetMapped(writetarget), GL_INVALID_OPERATION);
3343 SET_ERROR_IF(readoffset < 0, GL_INVALID_VALUE);
3344 SET_ERROR_IF(writeoffset < 0, GL_INVALID_VALUE);
3345 SET_ERROR_IF(size < 0, GL_INVALID_VALUE);
3346 SET_ERROR_IF(
3347 ctx->getBufferData(readtarget) &&
3348 (readoffset + size > ctx->getBufferData(readtarget)->m_size),
3349 GL_INVALID_VALUE);
3350 SET_ERROR_IF(
3351 ctx->getBufferData(writetarget) &&
3352 (writeoffset + size > ctx->getBufferData(writetarget)->m_size),
3353 GL_INVALID_VALUE);
3354 SET_ERROR_IF(readtarget == writetarget &&
3355 !((writeoffset >= readoffset + size) ||
3356 (readoffset >= writeoffset + size)),
3357 GL_INVALID_VALUE);
3358
3359 ctx->m_glCopyBufferSubData_enc(self, readtarget, writetarget, readoffset, writeoffset, size);
3360}
3361
3362void GL2Encoder::s_glGetBufferParameteriv(void* self, GLenum target, GLenum pname, GLint* params) {
3363 GL2Encoder* ctx = (GL2Encoder*)self;
3364
3365 SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM);
3366 SET_ERROR_IF(
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08003367 target != GL_ARRAY_BUFFER &&
3368 target != GL_ELEMENT_ARRAY_BUFFER &&
3369 target != GL_COPY_READ_BUFFER &&
3370 target != GL_COPY_WRITE_BUFFER &&
3371 target != GL_PIXEL_PACK_BUFFER &&
3372 target != GL_PIXEL_UNPACK_BUFFER &&
3373 target != GL_TRANSFORM_FEEDBACK_BUFFER &&
3374 target != GL_UNIFORM_BUFFER,
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003375 GL_INVALID_ENUM);
3376 SET_ERROR_IF(!GLESv2Validation::bufferParam(ctx, pname), GL_INVALID_ENUM);
3377 SET_ERROR_IF(!ctx->boundBuffer(target), GL_INVALID_OPERATION);
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08003378 SET_ERROR_IF(pname != GL_BUFFER_ACCESS_FLAGS &&
3379 pname != GL_BUFFER_MAPPED &&
3380 pname != GL_BUFFER_SIZE &&
3381 pname != GL_BUFFER_USAGE &&
3382 pname != GL_BUFFER_MAP_LENGTH &&
3383 pname != GL_BUFFER_MAP_OFFSET,
3384 GL_INVALID_ENUM);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003385
3386 if (!params) return;
3387
3388 BufferData* buf = ctx->getBufferData(target);
3389
3390 switch (pname) {
3391 case GL_BUFFER_ACCESS_FLAGS:
3392 *params = buf ? buf->m_mappedAccess : 0;
3393 break;
3394 case GL_BUFFER_MAPPED:
3395 *params = buf ? (buf->m_mapped ? GL_TRUE : GL_FALSE) : GL_FALSE;
3396 break;
3397 case GL_BUFFER_SIZE:
3398 *params = buf ? buf->m_size : 0;
3399 break;
3400 case GL_BUFFER_USAGE:
3401 *params = buf ? buf->m_usage : GL_STATIC_DRAW;
3402 break;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08003403 case GL_BUFFER_MAP_LENGTH:
3404 *params = buf ? buf->m_mappedLength : 0;
3405 break;
3406 case GL_BUFFER_MAP_OFFSET:
3407 *params = buf ? buf->m_mappedOffset : 0;
3408 break;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003409 default:
3410 break;
3411 }
3412}
3413
3414void GL2Encoder::s_glGetBufferParameteri64v(void* self, GLenum target, GLenum pname, GLint64* params) {
3415 GL2Encoder* ctx = (GL2Encoder*)self;
3416
3417 SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM);
3418 SET_ERROR_IF(
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08003419 target != GL_ARRAY_BUFFER &&
3420 target != GL_ELEMENT_ARRAY_BUFFER &&
3421 target != GL_COPY_READ_BUFFER &&
3422 target != GL_COPY_WRITE_BUFFER &&
3423 target != GL_PIXEL_PACK_BUFFER &&
3424 target != GL_PIXEL_UNPACK_BUFFER &&
3425 target != GL_TRANSFORM_FEEDBACK_BUFFER &&
3426 target != GL_UNIFORM_BUFFER,
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003427 GL_INVALID_ENUM);
3428 SET_ERROR_IF(!GLESv2Validation::bufferParam(ctx, pname), GL_INVALID_ENUM);
3429 SET_ERROR_IF(!ctx->boundBuffer(target), GL_INVALID_OPERATION);
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08003430 SET_ERROR_IF(pname != GL_BUFFER_ACCESS_FLAGS &&
3431 pname != GL_BUFFER_MAPPED &&
3432 pname != GL_BUFFER_SIZE &&
3433 pname != GL_BUFFER_USAGE &&
3434 pname != GL_BUFFER_MAP_LENGTH &&
3435 pname != GL_BUFFER_MAP_OFFSET,
3436 GL_INVALID_ENUM);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003437
3438 if (!params) return;
3439
3440 BufferData* buf = ctx->getBufferData(target);
3441
3442 switch (pname) {
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08003443 case GL_BUFFER_ACCESS_FLAGS:
3444 *params = buf ? buf->m_mappedAccess : 0;
3445 break;
3446 case GL_BUFFER_MAPPED:
3447 *params = buf ? (buf->m_mapped ? GL_TRUE : GL_FALSE) : GL_FALSE;
3448 break;
3449 case GL_BUFFER_SIZE:
3450 *params = buf ? buf->m_size : 0;
3451 break;
3452 case GL_BUFFER_USAGE:
3453 *params = buf ? buf->m_usage : GL_STATIC_DRAW;
3454 break;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003455 case GL_BUFFER_MAP_LENGTH:
3456 *params = buf ? buf->m_mappedLength : 0;
3457 break;
3458 case GL_BUFFER_MAP_OFFSET:
3459 *params = buf ? buf->m_mappedOffset : 0;
3460 break;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003461 default:
3462 break;
3463 }
3464}
3465
3466void GL2Encoder::s_glGetBufferPointerv(void* self, GLenum target, GLenum pname, GLvoid** params) {
3467 GL2Encoder* ctx = (GL2Encoder*)self;
3468 SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM);
3469 SET_ERROR_IF(
3470 target == GL_ATOMIC_COUNTER_BUFFER ||
3471 target == GL_DISPATCH_INDIRECT_BUFFER ||
3472 target == GL_DRAW_INDIRECT_BUFFER ||
3473 target == GL_SHADER_STORAGE_BUFFER,
3474 GL_INVALID_ENUM);
3475 SET_ERROR_IF(pname != GL_BUFFER_MAP_POINTER, GL_INVALID_ENUM);
3476 SET_ERROR_IF(!ctx->boundBuffer(target), GL_INVALID_OPERATION);
3477 if (!params) return;
3478
3479 BufferData* buf = ctx->getBufferData(target);
3480
3481 if (!buf || !buf->m_mapped) { *params = NULL; return; }
3482
3483 *params = (GLvoid*)((char*)buf->m_fixedBuffer.ptr() + buf->m_mappedOffset);
3484}
3485
3486static const char* const kNameDelimiter = ";";
3487
3488static std::string packVarNames(GLsizei count, const char** names, GLint* err_out) {
3489
3490#define VALIDATE(cond, err) if (cond) { *err_out = err; return packed; } \
3491
3492 std::string packed;
3493 // validate the array of char[]'s
3494 const char* currName;
3495 for (GLsizei i = 0; i < count; i++) {
3496 currName = names[i];
3497 VALIDATE(!currName, GL_INVALID_OPERATION);
3498 // check if has reasonable size
3499 size_t len = strlen(currName);
3500 VALIDATE(!len, GL_INVALID_OPERATION);
3501 // check for our delimiter, which if present
3502 // in the name, means an invalid name anyway.
3503 VALIDATE(strstr(currName, kNameDelimiter),
3504 GL_INVALID_OPERATION);
3505 packed += currName;
3506 packed += ";";
3507 }
3508
3509 *err_out = GL_NO_ERROR;
3510 return packed;
3511}
3512
3513void GL2Encoder::s_glGetUniformIndices(void* self, GLuint program, GLsizei uniformCount, const GLchar ** uniformNames, GLuint* uniformIndices) {
3514 GL2Encoder* ctx = (GL2Encoder*)self;
3515
3516 if (!uniformCount) return;
3517
3518 GLint err = GL_NO_ERROR;
3519 std::string packed = packVarNames(uniformCount, (const char**)uniformNames, &err);
3520 SET_ERROR_IF(err != GL_NO_ERROR, GL_INVALID_OPERATION);
3521
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003522 std::vector<int> arrIndices;
3523 for (size_t i = 0; i < uniformCount; i++) {
3524 int err;
3525 arrIndices.push_back(sArrIndexOfUniformExpr(uniformNames[i], &err));
3526 if (err) {
3527 ALOGE("%s: invalid uniform name %s!", __FUNCTION__, uniformNames[i]);
3528 return;
3529 }
3530 }
3531
3532 ctx->glGetUniformIndicesAEMU(ctx, program, uniformCount, (const GLchar*)&packed[0], packed.size() + 1, uniformIndices);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003533}
3534
3535void GL2Encoder::s_glUniform1ui(void* self, GLint location, GLuint v0) {
3536 GL2Encoder *ctx = (GL2Encoder*)self;
3537 GLClientState* state = ctx->m_state;
3538 GLSharedGroupPtr shared = ctx->m_shared;
3539
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08003540 GLint hostLoc = location;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003541 ctx->m_glUniform1ui_enc(self, hostLoc, v0);
3542
3543 GLenum target;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08003544 if (shared->setSamplerUniform(state->currentShaderProgram(), location, v0, &target)) {
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003545 GLenum origActiveTexture = state->getActiveTextureUnit();
3546 if (ctx->updateHostTexture2DBinding(GL_TEXTURE0 + v0, target)) {
3547 ctx->m_glActiveTexture_enc(self, origActiveTexture);
3548 }
3549 state->setActiveTextureUnit(origActiveTexture);
3550 }
3551}
3552
3553void GL2Encoder::s_glUniform2ui(void* self, GLint location, GLuint v0, GLuint v1) {
3554 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08003555 GLint hostLoc = location;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003556 ctx->m_glUniform2ui_enc(self, hostLoc, v0, v1);
3557}
3558
3559void GL2Encoder::s_glUniform3ui(void* self, GLint location, GLuint v0, GLuint v1, GLuint v2) {
3560 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08003561 GLint hostLoc = location;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003562 ctx->m_glUniform3ui_enc(self, hostLoc, v0, v1, v2);
3563}
3564
3565void GL2Encoder::s_glUniform4ui(void* self, GLint location, GLint v0, GLuint v1, GLuint v2, GLuint v3) {
3566 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08003567 GLint hostLoc = location;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003568 ctx->m_glUniform4ui_enc(self, hostLoc, v0, v1, v2, v3);
3569}
3570
3571void GL2Encoder::s_glUniform1uiv(void* self, GLint location, GLsizei count, const GLuint *value) {
3572 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08003573 GLint hostLoc = location;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003574 ctx->m_glUniform1uiv_enc(self, hostLoc, count, value);
3575}
3576
3577void GL2Encoder::s_glUniform2uiv(void* self, GLint location, GLsizei count, const GLuint *value) {
3578 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08003579 GLint hostLoc = location;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003580 ctx->m_glUniform2uiv_enc(self, hostLoc, count, value);
3581}
3582
3583void GL2Encoder::s_glUniform3uiv(void* self, GLint location, GLsizei count, const GLuint *value) {
3584 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08003585 GLint hostLoc = location;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003586 ctx->m_glUniform3uiv_enc(self, hostLoc, count, value);
3587}
3588
3589void GL2Encoder::s_glUniform4uiv(void* self, GLint location, GLsizei count, const GLuint *value) {
3590 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08003591 GLint hostLoc = location;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003592 ctx->m_glUniform4uiv_enc(self, hostLoc, count, value);
3593}
3594
3595void GL2Encoder::s_glUniformMatrix2x3fv(void* self, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
3596 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08003597 GLint hostLoc = location;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003598 ctx->m_glUniformMatrix2x3fv_enc(self, hostLoc, count, transpose, value);
3599}
3600
3601void GL2Encoder::s_glUniformMatrix3x2fv(void* self, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
3602 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08003603 GLint hostLoc = location;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003604 ctx->m_glUniformMatrix3x2fv_enc(self, hostLoc, count, transpose, value);
3605}
3606
3607void GL2Encoder::s_glUniformMatrix2x4fv(void* self, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
3608 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08003609 GLint hostLoc = location;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003610 ctx->m_glUniformMatrix2x4fv_enc(self, hostLoc, count, transpose, value);
3611}
3612
3613void GL2Encoder::s_glUniformMatrix4x2fv(void* self, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
3614 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08003615 GLint hostLoc = location;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003616 ctx->m_glUniformMatrix4x2fv_enc(self, hostLoc, count, transpose, value);
3617}
3618
3619void GL2Encoder::s_glUniformMatrix3x4fv(void* self, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
3620 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08003621 GLint hostLoc = location;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003622 ctx->m_glUniformMatrix3x4fv_enc(self, hostLoc, count, transpose, value);
3623}
3624
3625void GL2Encoder::s_glUniformMatrix4x3fv(void* self, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
3626 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08003627 GLint hostLoc = location;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003628 ctx->m_glUniformMatrix4x3fv_enc(self, hostLoc, count, transpose, value);
3629}
3630
3631void GL2Encoder::s_glGetUniformuiv(void* self, GLuint program, GLint location, GLuint* params) {
3632 GL2Encoder *ctx = (GL2Encoder*)self;
3633 SET_ERROR_IF(!ctx->m_shared->isShaderOrProgramObject(program), GL_INVALID_VALUE);
3634 SET_ERROR_IF(!ctx->m_shared->isProgram(program), GL_INVALID_OPERATION);
3635 SET_ERROR_IF(!ctx->m_shared->isProgramInitialized(program), GL_INVALID_OPERATION);
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08003636 GLint hostLoc = location;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003637 SET_ERROR_IF(ctx->m_shared->getProgramUniformType(program,hostLoc)==0, GL_INVALID_OPERATION);
3638 ctx->m_glGetUniformuiv_enc(self, program, hostLoc, params);
3639}
3640
3641void GL2Encoder::s_glGetActiveUniformBlockiv(void* self, GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params) {
3642 GL2Encoder* ctx = (GL2Encoder*)self;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003643
3644 // refresh client state's # active uniforms in this block
3645 if (pname == GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES) {
3646 // TODO if worth it: cache uniform count and other params,
3647 // invalidate on program relinking.
3648 GLint numActiveUniforms;
3649 ctx->m_glGetActiveUniformBlockiv_enc(ctx,
3650 program, uniformBlockIndex,
3651 GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS,
3652 &numActiveUniforms);
3653 ctx->m_state->setNumActiveUniformsInUniformBlock(
3654 program, uniformBlockIndex, numActiveUniforms);
3655 }
3656
3657 ctx->m_glGetActiveUniformBlockiv_enc(ctx,
3658 program, uniformBlockIndex,
3659 pname, params);
3660}
3661
3662void GL2Encoder::s_glGetVertexAttribIiv(void* self, GLuint index, GLenum pname, GLint* params) {
3663 GL2Encoder *ctx = (GL2Encoder *)self;
3664 assert(ctx->m_state);
3665 GLint maxIndex;
3666 ctx->glGetIntegerv(self, GL_MAX_VERTEX_ATTRIBS, &maxIndex);
3667 SET_ERROR_IF(!(index < maxIndex), GL_INVALID_VALUE);
3668
3669 if (!ctx->m_state->getVertexAttribParameter<GLint>(index, pname, params)) {
3670 ctx->m_glGetVertexAttribIiv_enc(self, index, pname, params);
3671 }
3672}
3673
3674void GL2Encoder::s_glGetVertexAttribIuiv(void* self, GLuint index, GLenum pname, GLuint* params) {
3675 GL2Encoder *ctx = (GL2Encoder *)self;
3676 assert(ctx->m_state);
3677 GLint maxIndex;
3678 ctx->glGetIntegerv(self, GL_MAX_VERTEX_ATTRIBS, &maxIndex);
3679 SET_ERROR_IF(!(index < maxIndex), GL_INVALID_VALUE);
3680
3681 if (!ctx->m_state->getVertexAttribParameter<GLuint>(index, pname, params)) {
3682 ctx->m_glGetVertexAttribIuiv_enc(self, index, pname, params);
3683 }
3684}
3685
3686void GL2Encoder::s_glVertexAttribIPointer(void* self, GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid* pointer) {
3687 GL2Encoder *ctx = (GL2Encoder *)self;
3688 assert(ctx->m_state != NULL);
Lingfeng Yang07289902017-01-27 12:26:19 -08003689 VALIDATE_VERTEX_ATTRIB_INDEX(index);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003690 SET_ERROR_IF((size < 1 || size > 4), GL_INVALID_VALUE);
3691 SET_ERROR_IF(
3692 !(type == GL_BYTE ||
3693 type == GL_UNSIGNED_BYTE ||
3694 type == GL_SHORT ||
3695 type == GL_UNSIGNED_SHORT ||
3696 type == GL_INT ||
3697 type == GL_UNSIGNED_INT),
3698 GL_INVALID_ENUM);
3699 SET_ERROR_IF(stride < 0, GL_INVALID_VALUE);
3700
3701 ctx->m_state->setVertexAttribBinding(index, index);
3702 ctx->m_state->setVertexAttribFormat(index, size, type, false, 0, true);
3703 GLsizei effectiveStride = stride;
3704 if (stride == 0) {
Lingfeng Yang554a5152019-02-21 20:20:48 -08003705 effectiveStride = glSizeof(type) * size;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003706 }
3707 ctx->m_state->bindIndexedBuffer(0, index, ctx->m_state->currentArrayVbo(), (uintptr_t)pointer, 0, stride, effectiveStride);
3708
3709 if (ctx->m_state->currentArrayVbo() != 0) {
3710 ctx->glVertexAttribIPointerOffsetAEMU(ctx, index, size, type, stride, (uintptr_t)pointer);
3711 } else {
3712 SET_ERROR_IF(ctx->m_state->currentVertexArrayObject() != 0 && pointer, GL_INVALID_OPERATION);
3713 // wait for client-array handler
3714 }
3715}
3716
3717void GL2Encoder::s_glVertexAttribDivisor(void* self, GLuint index, GLuint divisor) {
3718 GL2Encoder *ctx = (GL2Encoder *)self;
3719 assert(ctx->m_state != NULL);
Lingfeng Yang07289902017-01-27 12:26:19 -08003720 VALIDATE_VERTEX_ATTRIB_INDEX(index);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003721 ctx->m_state->setVertexAttribBinding(index, index);
3722 ctx->m_state->setVertexBindingDivisor(index, divisor);
3723 ctx->m_glVertexAttribDivisor_enc(ctx, index, divisor);
3724}
3725
3726void GL2Encoder::s_glRenderbufferStorageMultisample(void* self,
3727 GLenum target, GLsizei samples, GLenum internalformat,
3728 GLsizei width, GLsizei height) {
3729 GL2Encoder *ctx = (GL2Encoder *)self;
3730 GLClientState* state = ctx->m_state;
3731
3732 SET_ERROR_IF(target != GL_RENDERBUFFER, GL_INVALID_ENUM);
3733 SET_ERROR_IF(!GLESv2Validation::rboFormat(ctx, internalformat), GL_INVALID_ENUM);
3734
3735 GLint max_samples;
3736 ctx->s_glGetInternalformativ(ctx, target, internalformat, GL_SAMPLES, 1, &max_samples);
3737 SET_ERROR_IF(samples > max_samples, GL_INVALID_OPERATION);
3738
3739 state->setBoundRenderbufferFormat(internalformat);
3740 state->setBoundRenderbufferSamples(samples);
3741 ctx->m_glRenderbufferStorageMultisample_enc(
3742 self, target, samples, internalformat, width, height);
3743}
3744
3745void GL2Encoder::s_glDrawBuffers(void* self, GLsizei n, const GLenum* bufs) {
3746 GL2Encoder* ctx = (GL2Encoder*)self;
3747 SET_ERROR_IF(!ctx->m_state->boundFramebuffer(GL_DRAW_FRAMEBUFFER) && n > 1, GL_INVALID_OPERATION);
3748 SET_ERROR_IF(n < 0 || n > ctx->m_state->getMaxDrawBuffers(), GL_INVALID_VALUE);
3749 for (int i = 0; i < n; i++) {
3750 SET_ERROR_IF(
3751 bufs[i] != GL_NONE &&
3752 bufs[i] != GL_BACK &&
3753 glUtilsColorAttachmentIndex(bufs[i]) == -1,
3754 GL_INVALID_ENUM);
3755 SET_ERROR_IF(
3756 !ctx->m_state->boundFramebuffer(GL_DRAW_FRAMEBUFFER) &&
3757 glUtilsColorAttachmentIndex(bufs[i]) != -1,
3758 GL_INVALID_OPERATION);
3759 SET_ERROR_IF(
3760 ctx->m_state->boundFramebuffer(GL_DRAW_FRAMEBUFFER) &&
3761 ((glUtilsColorAttachmentIndex(bufs[i]) != -1 &&
3762 glUtilsColorAttachmentIndex(bufs[i]) != i) ||
3763 (glUtilsColorAttachmentIndex(bufs[i]) == -1 &&
3764 bufs[i] != GL_NONE)),
3765 GL_INVALID_OPERATION);
3766 }
3767
3768 ctx->m_glDrawBuffers_enc(ctx, n, bufs);
3769}
3770
3771void GL2Encoder::s_glReadBuffer(void* self, GLenum src) {
3772 GL2Encoder* ctx = (GL2Encoder*)self;
3773
3774 SET_ERROR_IF(
3775 glUtilsColorAttachmentIndex(src) != -1 &&
3776 (glUtilsColorAttachmentIndex(src) >=
3777 ctx->m_state->getMaxColorAttachments()),
3778 GL_INVALID_OPERATION);
3779 SET_ERROR_IF(
3780 src != GL_NONE &&
3781 src != GL_BACK &&
3782 src > GL_COLOR_ATTACHMENT0 &&
3783 src < GL_DEPTH_ATTACHMENT &&
3784 (src - GL_COLOR_ATTACHMENT0) >
3785 ctx->m_state->getMaxColorAttachments(),
3786 GL_INVALID_OPERATION);
3787 SET_ERROR_IF(
3788 src != GL_NONE &&
3789 src != GL_BACK &&
3790 glUtilsColorAttachmentIndex(src) == -1,
3791 GL_INVALID_ENUM);
3792 SET_ERROR_IF(
3793 !ctx->m_state->boundFramebuffer(GL_READ_FRAMEBUFFER) &&
3794 src != GL_NONE &&
3795 src != GL_BACK,
3796 GL_INVALID_OPERATION);
3797 SET_ERROR_IF(
3798 ctx->m_state->boundFramebuffer(GL_READ_FRAMEBUFFER) &&
3799 src != GL_NONE &&
3800 glUtilsColorAttachmentIndex(src) == -1,
3801 GL_INVALID_OPERATION);
3802
3803 ctx->m_glReadBuffer_enc(ctx, src);
3804}
3805
3806void GL2Encoder::s_glFramebufferTextureLayer(void* self, GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) {
3807 GL2Encoder* ctx = (GL2Encoder*)self;
3808 GLClientState* state = ctx->m_state;
3809
3810 SET_ERROR_IF(!GLESv2Validation::framebufferTarget(ctx, target), GL_INVALID_ENUM);
3811 SET_ERROR_IF(!GLESv2Validation::framebufferAttachment(ctx, attachment), GL_INVALID_ENUM);
3812 GLenum lastBoundTarget = state->queryTexLastBoundTarget(texture);
3813 SET_ERROR_IF(lastBoundTarget != GL_TEXTURE_2D_ARRAY &&
3814 lastBoundTarget != GL_TEXTURE_3D,
3815 GL_INVALID_OPERATION);
3816 state->attachTextureObject(target, attachment, texture);
3817
3818 GLint max3DTextureSize;
3819 ctx->glGetIntegerv(ctx, GL_MAX_3D_TEXTURE_SIZE, &max3DTextureSize);
3820 SET_ERROR_IF(
3821 layer >= max3DTextureSize,
3822 GL_INVALID_VALUE);
3823
3824 ctx->m_glFramebufferTextureLayer_enc(self, target, attachment, texture, level, layer);
3825}
3826
3827void GL2Encoder::s_glTexStorage2D(void* self, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) {
3828 GL2Encoder* ctx = (GL2Encoder*)self;
3829 GLClientState* state = ctx->m_state;
3830
3831 SET_ERROR_IF(
3832 target != GL_TEXTURE_2D &&
3833 target != GL_TEXTURE_CUBE_MAP,
3834 GL_INVALID_ENUM);
3835 SET_ERROR_IF(!GLESv2Validation::pixelInternalFormat(internalformat), GL_INVALID_ENUM);
3836 SET_ERROR_IF(!state->getBoundTexture(target), GL_INVALID_OPERATION);
3837 SET_ERROR_IF(levels < 1 || width < 1 || height < 1, GL_INVALID_VALUE);
3838 SET_ERROR_IF(levels > ilog2((uint32_t)std::max(width, height)) + 1,
3839 GL_INVALID_OPERATION);
3840 SET_ERROR_IF(state->isBoundTextureImmutableFormat(target), GL_INVALID_OPERATION);
3841
3842 state->setBoundTextureInternalFormat(target, internalformat);
3843 state->setBoundTextureDims(target, -1, width, height, 1);
3844 state->setBoundTextureImmutableFormat(target);
Lingfeng Yanga9fff6a2018-03-02 13:42:51 -08003845
3846 if (target == GL_TEXTURE_2D) {
3847 ctx->override2DTextureTarget(target);
3848 }
3849
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003850 ctx->m_glTexStorage2D_enc(ctx, target, levels, internalformat, width, height);
Lingfeng Yanga9fff6a2018-03-02 13:42:51 -08003851
3852 if (target == GL_TEXTURE_2D) {
3853 ctx->restore2DTextureTarget(target);
3854 }
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003855}
3856
3857void GL2Encoder::s_glTransformFeedbackVaryings(void* self, GLuint program, GLsizei count, const char** varyings, GLenum bufferMode) {
3858 GL2Encoder* ctx = (GL2Encoder*)self;
3859
3860 SET_ERROR_IF(!ctx->m_shared->isProgram(program), GL_INVALID_VALUE);
3861
3862 GLint maxCount = 0;
3863 ctx->glGetIntegerv(ctx, GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, &maxCount);
3864
3865 SET_ERROR_IF(
3866 bufferMode == GL_SEPARATE_ATTRIBS &&
3867 maxCount < count,
3868 GL_INVALID_VALUE);
3869 SET_ERROR_IF(
3870 bufferMode != GL_INTERLEAVED_ATTRIBS &&
3871 bufferMode != GL_SEPARATE_ATTRIBS,
3872 GL_INVALID_ENUM);
3873
3874 if (!count) return;
3875
3876 GLint err = GL_NO_ERROR;
3877 std::string packed = packVarNames(count, varyings, &err);
3878 SET_ERROR_IF(err != GL_NO_ERROR, GL_INVALID_OPERATION);
3879
3880 ctx->glTransformFeedbackVaryingsAEMU(ctx, program, count, (const char*)&packed[0], packed.size() + 1, bufferMode);
3881}
3882
3883void GL2Encoder::s_glBeginTransformFeedback(void* self, GLenum primitiveMode) {
3884 GL2Encoder* ctx = (GL2Encoder*)self;
3885 GLClientState* state = ctx->m_state;
3886 ctx->m_glBeginTransformFeedback_enc(ctx, primitiveMode);
3887 state->setTransformFeedbackActiveUnpaused(true);
3888}
3889
3890void GL2Encoder::s_glEndTransformFeedback(void* self) {
3891 GL2Encoder* ctx = (GL2Encoder*)self;
3892 GLClientState* state = ctx->m_state;
3893 ctx->m_glEndTransformFeedback_enc(ctx);
3894 state->setTransformFeedbackActiveUnpaused(false);
3895}
3896
3897void GL2Encoder::s_glPauseTransformFeedback(void* self) {
3898 GL2Encoder* ctx = (GL2Encoder*)self;
3899 GLClientState* state = ctx->m_state;
3900 ctx->m_glPauseTransformFeedback_enc(ctx);
3901 state->setTransformFeedbackActiveUnpaused(false);
3902}
3903
3904void GL2Encoder::s_glResumeTransformFeedback(void* self) {
3905 GL2Encoder* ctx = (GL2Encoder*)self;
3906 GLClientState* state = ctx->m_state;
3907 ctx->m_glResumeTransformFeedback_enc(ctx);
3908 state->setTransformFeedbackActiveUnpaused(true);
3909}
3910
3911void GL2Encoder::s_glTexImage3D(void* self, GLenum target, GLint level, GLint internalFormat,
3912 GLsizei width, GLsizei height, GLsizei depth,
3913 GLint border, GLenum format, GLenum type, const GLvoid* data) {
3914 GL2Encoder* ctx = (GL2Encoder*)self;
3915 GLClientState* state = ctx->m_state;
3916
3917 SET_ERROR_IF(target != GL_TEXTURE_3D &&
3918 target != GL_TEXTURE_2D_ARRAY,
3919 GL_INVALID_ENUM);
3920 SET_ERROR_IF(!GLESv2Validation::pixelType(ctx, type), GL_INVALID_ENUM);
3921 SET_ERROR_IF(!GLESv2Validation::pixelFormat(ctx, format), GL_INVALID_ENUM);
3922
3923 // If unpack buffer is nonzero, verify unmapped state.
3924 SET_ERROR_IF(ctx->isBufferTargetMapped(GL_PIXEL_UNPACK_BUFFER), GL_INVALID_OPERATION);
3925
3926 GLint max_texture_size;
3927 GLint max_3d_texture_size;
3928 ctx->glGetIntegerv(ctx, GL_MAX_TEXTURE_SIZE, &max_texture_size);
3929 ctx->glGetIntegerv(ctx, GL_MAX_3D_TEXTURE_SIZE, &max_3d_texture_size);
3930 SET_ERROR_IF(level < 0, GL_INVALID_VALUE);
3931 SET_ERROR_IF(level > ilog2(max_texture_size), GL_INVALID_VALUE);
3932 SET_ERROR_IF(level > ilog2(max_3d_texture_size), GL_INVALID_VALUE);
3933
3934 SET_ERROR_IF(width < 0 || height < 0 || depth < 0, GL_INVALID_VALUE);
Lingfeng Yang730870f2019-10-31 17:45:27 -07003935 SET_ERROR_IF(width > max_texture_size, GL_INVALID_VALUE);
3936 SET_ERROR_IF(height > max_texture_size, GL_INVALID_VALUE);
3937 SET_ERROR_IF(depth > max_texture_size, GL_INVALID_VALUE);
3938 SET_ERROR_IF(width > max_3d_texture_size, GL_INVALID_VALUE);
3939 SET_ERROR_IF(height > max_3d_texture_size, GL_INVALID_VALUE);
3940 SET_ERROR_IF(depth > max_3d_texture_size, GL_INVALID_VALUE);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003941 SET_ERROR_IF(border != 0, GL_INVALID_VALUE);
3942 // If unpack buffer is nonzero, verify buffer data fits and is evenly divisible by the type.
3943 SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
3944 ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
3945 (ctx->m_state->pboNeededDataSize(width, height, depth, format, type, 0) >
3946 ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size),
3947 GL_INVALID_OPERATION);
3948 SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
3949 ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
3950 (ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size %
3951 glSizeof(type)),
3952 GL_INVALID_OPERATION);
3953 SET_ERROR_IF(state->isBoundTextureImmutableFormat(target), GL_INVALID_OPERATION);
3954
3955 state->setBoundTextureInternalFormat(target, internalFormat);
3956 state->setBoundTextureFormat(target, format);
3957 state->setBoundTextureType(target, type);
3958 state->setBoundTextureDims(target, level, width, height, depth);
3959
3960 if (ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER)) {
3961 ctx->glTexImage3DOffsetAEMU(
3962 ctx, target, level, internalFormat,
3963 width, height, depth,
3964 border, format, type, (uintptr_t)data);
3965 } else {
3966 ctx->m_glTexImage3D_enc(ctx,
3967 target, level, internalFormat,
3968 width, height, depth,
3969 border, format, type, data);
3970 }
3971}
3972
3973void GL2Encoder::s_glTexSubImage3D(void* self, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* data) {
3974 GL2Encoder* ctx = (GL2Encoder*)self;
3975 GLClientState* state = ctx->m_state;
3976
3977 SET_ERROR_IF(target != GL_TEXTURE_3D &&
3978 target != GL_TEXTURE_2D_ARRAY,
3979 GL_INVALID_ENUM);
3980 SET_ERROR_IF(!GLESv2Validation::pixelType(ctx, type), GL_INVALID_ENUM);
3981 SET_ERROR_IF(!GLESv2Validation::pixelFormat(ctx, format), GL_INVALID_ENUM);
3982 // If unpack buffer is nonzero, verify unmapped state.
3983 SET_ERROR_IF(ctx->isBufferTargetMapped(GL_PIXEL_UNPACK_BUFFER), GL_INVALID_OPERATION);
3984 GLint max_texture_size;
3985 GLint max_3d_texture_size;
3986 ctx->glGetIntegerv(ctx, GL_MAX_TEXTURE_SIZE, &max_texture_size);
3987 ctx->glGetIntegerv(ctx, GL_MAX_3D_TEXTURE_SIZE, &max_3d_texture_size);
3988 SET_ERROR_IF(level < 0, GL_INVALID_VALUE);
3989 SET_ERROR_IF(level > ilog2(max_texture_size), GL_INVALID_VALUE);
3990 SET_ERROR_IF(level > ilog2(max_3d_texture_size), GL_INVALID_VALUE);
3991 SET_ERROR_IF(width < 0 || height < 0 || depth < 0, GL_INVALID_VALUE);
3992 SET_ERROR_IF(xoffset < 0 || yoffset < 0 || zoffset < 0, GL_INVALID_VALUE);
3993 GLuint tex = state->getBoundTexture(target);
3994 GLsizei neededWidth = xoffset + width;
3995 GLsizei neededHeight = yoffset + height;
3996 GLsizei neededDepth = zoffset + depth;
3997
3998 SET_ERROR_IF(tex &&
3999 (neededWidth > state->queryTexWidth(level, tex) ||
4000 neededHeight > state->queryTexHeight(level, tex) ||
4001 neededDepth > state->queryTexDepth(level, tex)),
4002 GL_INVALID_VALUE);
4003 // If unpack buffer is nonzero, verify buffer data fits and is evenly divisible by the type.
4004 SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
4005 ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
4006 (ctx->m_state->pboNeededDataSize(width, height, depth, format, type, 0) >
4007 ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size),
4008 GL_INVALID_OPERATION);
4009 SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
4010 ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
4011 (ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size %
4012 glSizeof(type)),
4013 GL_INVALID_OPERATION);
4014 SET_ERROR_IF(!ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) && !data, GL_INVALID_OPERATION);
4015 SET_ERROR_IF(xoffset < 0 || yoffset < 0 || zoffset < 0, GL_INVALID_VALUE);
4016
4017 if (ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER)) {
4018 ctx->glTexSubImage3DOffsetAEMU(ctx,
4019 target, level,
4020 xoffset, yoffset, zoffset,
4021 width, height, depth,
4022 format, type, (uintptr_t)data);
4023 } else {
4024 ctx->m_glTexSubImage3D_enc(ctx,
4025 target, level,
4026 xoffset, yoffset, zoffset,
4027 width, height, depth,
4028 format, type, data);
4029 }
4030}
4031
4032void GL2Encoder::s_glCompressedTexImage3D(void* self, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data) {
4033 GL2Encoder* ctx = (GL2Encoder*)self;
4034 GLClientState* state = ctx->m_state;
4035
4036 // Filter compressed formats support.
4037 SET_ERROR_IF(!GLESv2Validation::supportedCompressedFormat(ctx, internalformat), GL_INVALID_ENUM);
4038 // If unpack buffer is nonzero, verify unmapped state.
4039 SET_ERROR_IF(ctx->isBufferTargetMapped(GL_PIXEL_UNPACK_BUFFER), GL_INVALID_OPERATION);
4040 SET_ERROR_IF(width < 0 || height < 0 || depth < 0, GL_INVALID_VALUE);
4041 SET_ERROR_IF(border, GL_INVALID_VALUE);
4042 // If unpack buffer is nonzero, verify buffer data fits.
4043 SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
4044 ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
4045 (imageSize > ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size),
4046 GL_INVALID_OPERATION);
4047 // TODO: Fix:
4048 // If |imageSize| is too small for compressed dimensions.
4049 // SET_ERROR_IF(GLESv2Validation::compressedTexImageSize(internalformat, width, height, depth) > imageSize, GL_INVALID_VALUE);
4050 state->setBoundTextureInternalFormat(target, (GLint)internalformat);
4051 state->setBoundTextureDims(target, level, width, height, depth);
4052
4053 if (ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER)) {
4054 ctx->glCompressedTexImage3DOffsetAEMU(
4055 ctx, target, level, internalformat,
4056 width, height, depth, border,
4057 imageSize, (uintptr_t)data);
4058 } else {
4059 ctx->m_glCompressedTexImage3D_enc(
4060 ctx, target, level, internalformat,
4061 width, height, depth, border,
4062 imageSize, data);
4063 }
4064}
4065
4066void GL2Encoder::s_glCompressedTexSubImage3D(void* self, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data) {
4067 GL2Encoder* ctx = (GL2Encoder*)self;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004068
4069 SET_ERROR_IF(!GLESv2Validation::textureTarget(ctx, target), GL_INVALID_ENUM);
4070 // If unpack buffer is nonzero, verify unmapped state.
4071 SET_ERROR_IF(ctx->isBufferTargetMapped(GL_PIXEL_UNPACK_BUFFER), GL_INVALID_OPERATION);
4072 SET_ERROR_IF(width < 0 || height < 0 || depth < 0, GL_INVALID_VALUE);
4073 // If unpack buffer is nonzero, verify buffer data fits.
4074 SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
4075 ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
4076 (imageSize > ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size),
4077 GL_INVALID_OPERATION);
4078 SET_ERROR_IF(xoffset < 0 || yoffset < 0 || zoffset < 0, GL_INVALID_VALUE);
4079
4080 if (ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER)) {
4081 ctx->glCompressedTexSubImage3DOffsetAEMU(
4082 ctx, target, level,
4083 xoffset, yoffset, zoffset,
4084 width, height, depth,
4085 format, imageSize, (uintptr_t)data);
4086 } else {
4087 ctx->m_glCompressedTexSubImage3D_enc(
4088 ctx, target, level,
4089 xoffset, yoffset, zoffset,
4090 width, height, depth,
4091 format, imageSize, data);
4092
4093 }
4094}
4095
4096void GL2Encoder::s_glTexStorage3D(void* self, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) {
4097 GL2Encoder* ctx = (GL2Encoder*)self;
4098 GLClientState* state = ctx->m_state;
4099 SET_ERROR_IF(target != GL_TEXTURE_3D &&
4100 target != GL_TEXTURE_2D_ARRAY,
4101 GL_INVALID_ENUM);
4102 SET_ERROR_IF(!GLESv2Validation::pixelInternalFormat(internalformat), GL_INVALID_ENUM);
4103 SET_ERROR_IF(!state->getBoundTexture(target), GL_INVALID_OPERATION);
4104 SET_ERROR_IF(levels < 1 || width < 1 || height < 1, GL_INVALID_VALUE);
4105 SET_ERROR_IF(target == GL_TEXTURE_3D && (levels > ilog2((uint32_t)std::max(width, std::max(height, depth))) + 1),
4106 GL_INVALID_OPERATION);
4107 SET_ERROR_IF(target == GL_TEXTURE_2D_ARRAY && (levels > ilog2((uint32_t)std::max(width, height)) + 1),
4108 GL_INVALID_OPERATION);
4109 SET_ERROR_IF(state->isBoundTextureImmutableFormat(target), GL_INVALID_OPERATION);
4110
4111 state->setBoundTextureInternalFormat(target, internalformat);
4112 state->setBoundTextureDims(target, -1, width, height, depth);
4113 state->setBoundTextureImmutableFormat(target);
4114 ctx->m_glTexStorage3D_enc(ctx, target, levels, internalformat, width, height, depth);
4115 state->setBoundTextureImmutableFormat(target);
4116}
4117
4118void GL2Encoder::s_glDrawArraysInstanced(void* self, GLenum mode, GLint first, GLsizei count, GLsizei primcount) {
4119 GL2Encoder *ctx = (GL2Encoder *)self;
4120 assert(ctx->m_state != NULL);
4121 SET_ERROR_IF(!isValidDrawMode(mode), GL_INVALID_ENUM);
4122 SET_ERROR_IF(count < 0, GL_INVALID_VALUE);
4123
4124 bool has_client_vertex_arrays = false;
4125 bool has_indirect_arrays = false;
4126 ctx->getVBOUsage(&has_client_vertex_arrays,
4127 &has_indirect_arrays);
4128
4129 if (has_client_vertex_arrays ||
4130 (!has_client_vertex_arrays &&
4131 !has_indirect_arrays)) {
4132 ctx->sendVertexAttributes(first, count, true, primcount);
4133 ctx->m_glDrawArraysInstanced_enc(ctx, mode, 0, count, primcount);
4134 } else {
4135 ctx->sendVertexAttributes(0, count, false, primcount);
4136 ctx->m_glDrawArraysInstanced_enc(ctx, mode, first, count, primcount);
4137 }
4138 ctx->m_stream->flush();
4139}
4140
4141void GL2Encoder::s_glDrawElementsInstanced(void* self, GLenum mode, GLsizei count, GLenum type, const void* indices, GLsizei primcount)
4142{
4143
4144 GL2Encoder *ctx = (GL2Encoder *)self;
4145 assert(ctx->m_state != NULL);
4146 SET_ERROR_IF(!isValidDrawMode(mode), GL_INVALID_ENUM);
4147 SET_ERROR_IF(count < 0, GL_INVALID_VALUE);
4148 SET_ERROR_IF(!(type == GL_UNSIGNED_BYTE || type == GL_UNSIGNED_SHORT || type == GL_UNSIGNED_INT), GL_INVALID_ENUM);
4149 SET_ERROR_IF(ctx->m_state->getTransformFeedbackActiveUnpaused(), GL_INVALID_OPERATION);
4150
4151 bool has_client_vertex_arrays = false;
4152 bool has_indirect_arrays = false;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004153 GLintptr offset = 0;
4154
4155 ctx->getVBOUsage(&has_client_vertex_arrays, &has_indirect_arrays);
4156
4157 if (!has_client_vertex_arrays && !has_indirect_arrays) {
4158 // ALOGW("glDrawElements: no vertex arrays / buffers bound to the command\n");
4159 GLenum status = ctx->m_glCheckFramebufferStatus_enc(self, GL_FRAMEBUFFER);
4160 SET_ERROR_IF(status != GL_FRAMEBUFFER_COMPLETE, GL_INVALID_FRAMEBUFFER_OPERATION);
4161 }
4162
4163 BufferData* buf = NULL;
4164 int minIndex = 0, maxIndex = 0;
4165
4166 // For validation/immediate index array purposes,
4167 // we need the min/max vertex index of the index array.
4168 // If the VBO != 0, this may not be the first time we have
4169 // used this particular index buffer. getBufferIndexRange
4170 // can more quickly get min/max vertex index by
4171 // caching previous results.
4172 if (ctx->m_state->currentIndexVbo() != 0) {
4173 buf = ctx->m_shared->getBufferData(ctx->m_state->currentIndexVbo());
4174 offset = (GLintptr)indices;
4175 indices = (void*)((GLintptr)buf->m_fixedBuffer.ptr() + (GLintptr)indices);
4176 ctx->getBufferIndexRange(buf,
4177 indices,
4178 type,
4179 (size_t)count,
4180 (size_t)offset,
4181 &minIndex, &maxIndex);
4182 } else {
4183 // In this case, the |indices| field holds a real
4184 // array, so calculate the indices now. They will
4185 // also be needed to know how much data to
4186 // transfer to host.
4187 ctx->calcIndexRange(indices,
4188 type,
4189 count,
4190 &minIndex,
4191 &maxIndex);
4192 }
4193
Lingfeng Yang26e629a2018-10-13 20:00:12 -07004194 if (count == 0) return;
4195
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004196 bool adjustIndices = true;
4197 if (ctx->m_state->currentIndexVbo() != 0) {
4198 if (!has_client_vertex_arrays) {
4199 ctx->sendVertexAttributes(0, maxIndex + 1, false, primcount);
Lingfeng Yang554a5152019-02-21 20:20:48 -08004200 ctx->doBindBufferEncodeCached(GL_ELEMENT_ARRAY_BUFFER, ctx->m_state->currentIndexVbo());
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004201 ctx->glDrawElementsInstancedOffsetAEMU(ctx, mode, count, type, offset, primcount);
4202 ctx->flushDrawCall();
4203 adjustIndices = false;
4204 } else {
Lingfeng Yang554a5152019-02-21 20:20:48 -08004205 ctx->doBindBufferEncodeCached(GL_ELEMENT_ARRAY_BUFFER, 0);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004206 }
4207 }
4208 if (adjustIndices) {
4209 void *adjustedIndices =
4210 ctx->recenterIndices(indices,
4211 type,
4212 count,
4213 minIndex);
4214
4215 if (has_indirect_arrays || 1) {
4216 ctx->sendVertexAttributes(minIndex, maxIndex - minIndex + 1, true, primcount);
4217 ctx->glDrawElementsInstancedDataAEMU(ctx, mode, count, type, adjustedIndices, primcount, count * glSizeof(type));
4218 ctx->m_stream->flush();
4219 // XXX - OPTIMIZATION (see the other else branch) should be implemented
4220 if(!has_indirect_arrays) {
4221 //ALOGD("unoptimized drawelements !!!\n");
4222 }
4223 } else {
4224 // we are all direct arrays and immidate mode index array -
4225 // rebuild the arrays and the index array;
4226 ALOGE("glDrawElements: direct index & direct buffer data - will be implemented in later versions;\n");
4227 }
4228 }
4229}
4230
4231void GL2Encoder::s_glDrawRangeElements(void* self, GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void* indices)
4232{
4233
4234 GL2Encoder *ctx = (GL2Encoder *)self;
4235 assert(ctx->m_state != NULL);
4236 SET_ERROR_IF(!isValidDrawMode(mode), GL_INVALID_ENUM);
4237 SET_ERROR_IF(end < start, GL_INVALID_VALUE);
4238 SET_ERROR_IF(count < 0, GL_INVALID_VALUE);
4239 SET_ERROR_IF(!(type == GL_UNSIGNED_BYTE || type == GL_UNSIGNED_SHORT || type == GL_UNSIGNED_INT), GL_INVALID_ENUM);
4240 SET_ERROR_IF(ctx->m_state->getTransformFeedbackActiveUnpaused(), GL_INVALID_OPERATION);
4241
4242 bool has_client_vertex_arrays = false;
4243 bool has_indirect_arrays = false;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004244 GLintptr offset = 0;
4245
4246 ctx->getVBOUsage(&has_client_vertex_arrays, &has_indirect_arrays);
4247
4248 if (!has_client_vertex_arrays && !has_indirect_arrays) {
4249 // ALOGW("glDrawElements: no vertex arrays / buffers bound to the command\n");
4250 GLenum status = ctx->m_glCheckFramebufferStatus_enc(self, GL_FRAMEBUFFER);
4251 SET_ERROR_IF(status != GL_FRAMEBUFFER_COMPLETE, GL_INVALID_FRAMEBUFFER_OPERATION);
4252 }
4253
4254 BufferData* buf = NULL;
4255 int minIndex = 0, maxIndex = 0;
4256
4257 // For validation/immediate index array purposes,
4258 // we need the min/max vertex index of the index array.
4259 // If the VBO != 0, this may not be the first time we have
4260 // used this particular index buffer. getBufferIndexRange
4261 // can more quickly get min/max vertex index by
4262 // caching previous results.
4263 if (ctx->m_state->currentIndexVbo() != 0) {
4264 buf = ctx->m_shared->getBufferData(ctx->m_state->currentIndexVbo());
Lingfeng Yang2c3a0da2019-03-07 20:43:53 -08004265 ALOGV("%s: current index vbo: %p len %zu count %zu\n", __func__, buf, (size_t)buf->m_fixedBuffer.len(), (size_t)count);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004266 offset = (GLintptr)indices;
Lingfeng Yang2c3a0da2019-03-07 20:43:53 -08004267 void* oldIndices = (void*)indices;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004268 indices = (void*)((GLintptr)buf->m_fixedBuffer.ptr() + (GLintptr)indices);
Lingfeng Yang2c3a0da2019-03-07 20:43:53 -08004269 ALOGV("%s: indices arg: %p buffer start: %p indices: %p\n", __func__,
4270 (void*)(uintptr_t)(oldIndices),
4271 buf->m_fixedBuffer.ptr(),
4272 indices);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004273 ctx->getBufferIndexRange(buf,
4274 indices,
4275 type,
4276 (size_t)count,
4277 (size_t)offset,
4278 &minIndex, &maxIndex);
4279 } else {
4280 // In this case, the |indices| field holds a real
4281 // array, so calculate the indices now. They will
4282 // also be needed to know how much data to
4283 // transfer to host.
4284 ctx->calcIndexRange(indices,
4285 type,
4286 count,
4287 &minIndex,
4288 &maxIndex);
4289 }
4290
Lingfeng Yang26e629a2018-10-13 20:00:12 -07004291 if (count == 0) return;
4292
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004293 bool adjustIndices = true;
4294 if (ctx->m_state->currentIndexVbo() != 0) {
4295 if (!has_client_vertex_arrays) {
4296 ctx->sendVertexAttributes(0, maxIndex + 1, false);
Lingfeng Yang554a5152019-02-21 20:20:48 -08004297 ctx->doBindBufferEncodeCached(GL_ELEMENT_ARRAY_BUFFER, ctx->m_state->currentIndexVbo());
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004298 ctx->glDrawElementsOffset(ctx, mode, count, type, offset);
4299 ctx->flushDrawCall();
4300 adjustIndices = false;
4301 } else {
Lingfeng Yang554a5152019-02-21 20:20:48 -08004302 ctx->doBindBufferEncodeCached(GL_ELEMENT_ARRAY_BUFFER, 0);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004303 }
4304 }
4305 if (adjustIndices) {
4306 void *adjustedIndices =
4307 ctx->recenterIndices(indices,
4308 type,
4309 count,
4310 minIndex);
4311
4312 if (has_indirect_arrays || 1) {
4313 ctx->sendVertexAttributes(minIndex, maxIndex - minIndex + 1, true);
4314 ctx->glDrawElementsData(ctx, mode, count, type, adjustedIndices, count * glSizeof(type));
4315 ctx->m_stream->flush();
4316 // XXX - OPTIMIZATION (see the other else branch) should be implemented
4317 if(!has_indirect_arrays) {
4318 //ALOGD("unoptimized drawelements !!!\n");
4319 }
4320 } else {
4321 // we are all direct arrays and immidate mode index array -
4322 // rebuild the arrays and the index array;
4323 ALOGE("glDrawElements: direct index & direct buffer data - will be implemented in later versions;\n");
4324 }
4325 }
4326}
4327
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004328const GLubyte* GL2Encoder::s_glGetStringi(void* self, GLenum name, GLuint index) {
4329 GL2Encoder *ctx = (GL2Encoder *)self;
Lingfeng Yanga16eb2e2018-02-23 11:26:53 -08004330 const GLubyte *retval = (GLubyte *) "";
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004331
4332 RET_AND_SET_ERROR_IF(
4333 name != GL_VENDOR &&
4334 name != GL_RENDERER &&
4335 name != GL_VERSION &&
4336 name != GL_EXTENSIONS,
4337 GL_INVALID_ENUM,
4338 retval);
4339
4340 RET_AND_SET_ERROR_IF(
Lingfeng Yang44209df2018-09-21 10:04:17 -07004341 (name == GL_VENDOR ||
4342 name == GL_RENDERER ||
4343 name == GL_VERSION) &&
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004344 index != 0,
4345 GL_INVALID_VALUE,
4346 retval);
4347
Lingfeng Yanga16eb2e2018-02-23 11:26:53 -08004348 RET_AND_SET_ERROR_IF(
4349 name == GL_EXTENSIONS &&
4350 index >= ctx->m_currExtensionsArray.size(),
4351 GL_INVALID_VALUE,
4352 retval);
4353
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004354 switch (name) {
4355 case GL_VENDOR:
4356 retval = gVendorString;
4357 break;
4358 case GL_RENDERER:
4359 retval = gRendererString;
4360 break;
4361 case GL_VERSION:
4362 retval = gVersionString;
4363 break;
4364 case GL_EXTENSIONS:
Lingfeng Yanga16eb2e2018-02-23 11:26:53 -08004365 retval = (const GLubyte*)(ctx->m_currExtensionsArray[index].c_str());
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004366 break;
4367 }
4368
4369 return retval;
4370}
4371
4372void GL2Encoder::s_glGetProgramBinary(void* self, GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, void* binary) {
4373 GL2Encoder *ctx = (GL2Encoder *)self;
4374
4375 SET_ERROR_IF(!ctx->m_shared->isProgram(program), GL_INVALID_OPERATION);
4376
4377 GLint linkStatus = 0;
4378 ctx->glGetProgramiv(self, program, GL_LINK_STATUS, &linkStatus);
4379 GLint properLength = 0;
4380 ctx->glGetProgramiv(self, program, GL_PROGRAM_BINARY_LENGTH, &properLength);
4381
4382 SET_ERROR_IF(!linkStatus, GL_INVALID_OPERATION);
4383 SET_ERROR_IF(bufSize < properLength, GL_INVALID_OPERATION);
4384
4385 ctx->m_glGetProgramBinary_enc(ctx, program, bufSize, length, binaryFormat, binary);
4386}
4387
4388void GL2Encoder::s_glReadPixels(void* self, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels) {
4389 GL2Encoder *ctx = (GL2Encoder *)self;
4390
4391 SET_ERROR_IF(!GLESv2Validation::readPixelsFormat(format), GL_INVALID_ENUM);
4392 SET_ERROR_IF(!GLESv2Validation::readPixelsType(type), GL_INVALID_ENUM);
4393 SET_ERROR_IF(width < 0 || height < 0, GL_INVALID_VALUE);
4394 SET_ERROR_IF(ctx->isBufferTargetMapped(GL_PIXEL_PACK_BUFFER), GL_INVALID_OPERATION);
4395 SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_PACK_BUFFER) &&
4396 ctx->getBufferData(GL_PIXEL_PACK_BUFFER) &&
4397 (ctx->m_state->pboNeededDataSize(width, height, 1, format, type, 1) >
4398 ctx->getBufferData(GL_PIXEL_PACK_BUFFER)->m_size),
4399 GL_INVALID_OPERATION);
4400 /*
4401GL_INVALID_OPERATION is generated if the readbuffer of the currently bound framebuffer is a fixed point normalized surface and format and type are neither GL_RGBA and GL_UNSIGNED_BYTE, respectively, nor the format/type pair returned by querying GL_IMPLEMENTATION_COLOR_READ_FORMAT and GL_IMPLEMENTATION_COLOR_READ_TYPE.
4402
4403GL_INVALID_OPERATION is generated if the readbuffer of the currently bound framebuffer is a floating point surface and format and type are neither GL_RGBA and GL_FLOAT, respectively, nor the format/type pair returned by querying GL_IMPLEMENTATION_COLOR_READ_FORMAT and GL_IMPLEMENTATION_COLOR_READ_TYPE.
4404
4405GL_INVALID_OPERATION is generated if the readbuffer of the currently bound framebuffer is a signed integer surface and format and type are neither GL_RGBA_INTEGER and GL_INT, respectively, nor the format/type pair returned by querying GL_IMPLEMENTATION_COLOR_READ_FORMAT and GL_IMPLEMENTATION_COLOR_READ_TYPE.
4406
4407GL_INVALID_OPERATION is generated if the readbuffer of the currently bound framebuffer is an unsigned integer surface and format and type are neither GL_RGBA_INTEGER and GL_UNSIGNED_INT, respectively, nor the format/type pair returned by querying GL_IMPLEMENTATION_COLOR_READ_FORMAT and GL_IMPLEMENTATION_COLOR_READ_TYPE.
4408*/
4409
4410 FboFormatInfo fbo_format_info;
4411 ctx->m_state->getBoundFramebufferFormat(
4412 GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, &fbo_format_info);
4413 SET_ERROR_IF(
4414 fbo_format_info.type == FBO_ATTACHMENT_TEXTURE &&
4415 !GLESv2Validation::readPixelsFboFormatMatch(
4416 format, type, fbo_format_info.tex_type),
4417 GL_INVALID_OPERATION);
4418
4419 if (ctx->boundBuffer(GL_PIXEL_PACK_BUFFER)) {
4420 ctx->glReadPixelsOffsetAEMU(
4421 ctx, x, y, width, height,
4422 format, type, (uintptr_t)pixels);
4423 } else {
4424 ctx->m_glReadPixels_enc(
4425 ctx, x, y, width, height,
4426 format, type, pixels);
4427 }
4428}
4429
4430// Track enabled state for some things like:
4431// - Primitive restart
4432void GL2Encoder::s_glEnable(void* self, GLenum what) {
4433 GL2Encoder *ctx = (GL2Encoder *)self;
4434
4435 switch (what) {
4436 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
4437 ctx->m_primitiveRestartEnabled = true;
4438 break;
4439 }
4440
4441 ctx->m_glEnable_enc(ctx, what);
4442}
4443
4444void GL2Encoder::s_glDisable(void* self, GLenum what) {
4445 GL2Encoder *ctx = (GL2Encoder *)self;
4446
4447 switch (what) {
4448 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
4449 ctx->m_primitiveRestartEnabled = false;
4450 break;
4451 }
4452
4453 ctx->m_glDisable_enc(ctx, what);
4454}
4455
4456void GL2Encoder::s_glClearBufferiv(void* self, GLenum buffer, GLint drawBuffer, const GLint * value) {
4457 GL2Encoder *ctx = (GL2Encoder *)self;
4458
4459 SET_ERROR_IF(buffer == GL_DEPTH || buffer == GL_DEPTH_STENCIL, GL_INVALID_ENUM);
4460
4461 ctx->m_glClearBufferiv_enc(ctx, buffer, drawBuffer, value);
4462}
4463
4464void GL2Encoder::s_glClearBufferuiv(void* self, GLenum buffer, GLint drawBuffer, const GLuint * value) {
4465 GL2Encoder *ctx = (GL2Encoder *)self;
4466
4467 SET_ERROR_IF(buffer == GL_DEPTH || buffer == GL_STENCIL || buffer == GL_DEPTH_STENCIL, GL_INVALID_ENUM);
4468
4469 ctx->m_glClearBufferuiv_enc(ctx, buffer, drawBuffer, value);
4470}
4471
4472void GL2Encoder::s_glClearBufferfv(void* self, GLenum buffer, GLint drawBuffer, const GLfloat * value) {
4473 GL2Encoder *ctx = (GL2Encoder *)self;
4474
4475 SET_ERROR_IF(buffer == GL_STENCIL || buffer == GL_DEPTH_STENCIL, GL_INVALID_ENUM);
4476
4477 ctx->m_glClearBufferfv_enc(ctx, buffer, drawBuffer, value);
4478}
4479
4480void GL2Encoder::s_glBlitFramebuffer(void* self, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) {
4481 GL2Encoder *ctx = (GL2Encoder *)self;
4482 GLClientState* state = ctx->m_state;
4483
Lingfeng Yangb678c362019-06-05 08:00:21 -07004484 bool validateColor = mask & GL_COLOR_BUFFER_BIT;
4485 bool validateDepth = mask & GL_DEPTH_BUFFER_BIT;
4486 bool validateStencil = mask & GL_STENCIL_BUFFER_BIT;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004487
4488 FboFormatInfo read_fbo_format_info;
4489 FboFormatInfo draw_fbo_format_info;
4490 if (validateColor) {
4491 state->getBoundFramebufferFormat(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, &read_fbo_format_info);
4492 state->getBoundFramebufferFormat(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, &draw_fbo_format_info);
4493
4494 if (read_fbo_format_info.type == FBO_ATTACHMENT_TEXTURE &&
4495 draw_fbo_format_info.type == FBO_ATTACHMENT_TEXTURE) {
4496 SET_ERROR_IF(
4497 state->boundFramebuffer(GL_READ_FRAMEBUFFER) &&
4498 state->boundFramebuffer(GL_DRAW_FRAMEBUFFER) &&
4499 !GLESv2Validation::blitFramebufferFormat(
4500 read_fbo_format_info.tex_type,
4501 draw_fbo_format_info.tex_type),
4502 GL_INVALID_OPERATION);
4503 }
4504 }
4505
4506 if (validateDepth) {
4507 state->getBoundFramebufferFormat(GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, &read_fbo_format_info);
4508 state->getBoundFramebufferFormat(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, &draw_fbo_format_info);
4509
4510 if (read_fbo_format_info.type == FBO_ATTACHMENT_RENDERBUFFER &&
4511 draw_fbo_format_info.type == FBO_ATTACHMENT_RENDERBUFFER) {
4512 SET_ERROR_IF(
4513 state->boundFramebuffer(GL_READ_FRAMEBUFFER) &&
4514 state->boundFramebuffer(GL_DRAW_FRAMEBUFFER) &&
4515 !GLESv2Validation::blitFramebufferFormat(
4516 read_fbo_format_info.rb_format,
4517 draw_fbo_format_info.rb_format),
4518 GL_INVALID_OPERATION);
4519 }
4520 }
4521
4522 if (validateStencil) {
4523 state->getBoundFramebufferFormat(GL_READ_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, &read_fbo_format_info);
4524 state->getBoundFramebufferFormat(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, &draw_fbo_format_info);
4525
4526 if (read_fbo_format_info.type == FBO_ATTACHMENT_RENDERBUFFER &&
4527 draw_fbo_format_info.type == FBO_ATTACHMENT_RENDERBUFFER) {
4528 SET_ERROR_IF(
4529 state->boundFramebuffer(GL_READ_FRAMEBUFFER) &&
4530 state->boundFramebuffer(GL_DRAW_FRAMEBUFFER) &&
4531 !GLESv2Validation::blitFramebufferFormat(
4532 read_fbo_format_info.rb_format,
4533 draw_fbo_format_info.rb_format),
4534 GL_INVALID_OPERATION);
4535 }
4536 }
4537
4538 state->getBoundFramebufferFormat(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, &draw_fbo_format_info);
4539 SET_ERROR_IF(
4540 draw_fbo_format_info.type == FBO_ATTACHMENT_RENDERBUFFER &&
4541 draw_fbo_format_info.rb_multisamples > 0,
4542 GL_INVALID_OPERATION);
4543 SET_ERROR_IF(
4544 draw_fbo_format_info.type == FBO_ATTACHMENT_TEXTURE &&
4545 draw_fbo_format_info.tex_multisamples > 0,
4546 GL_INVALID_OPERATION);
4547
4548 state->getBoundFramebufferFormat(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, &read_fbo_format_info);
4549 SET_ERROR_IF(
4550 read_fbo_format_info.type == FBO_ATTACHMENT_RENDERBUFFER &&
4551 read_fbo_format_info.rb_multisamples > 0 &&
4552 draw_fbo_format_info.type == FBO_ATTACHMENT_RENDERBUFFER &&
4553 state->boundFramebuffer(GL_READ_FRAMEBUFFER) &&
4554 state->boundFramebuffer(GL_DRAW_FRAMEBUFFER) &&
4555 (read_fbo_format_info.rb_format !=
4556 draw_fbo_format_info.rb_format),
4557 GL_INVALID_OPERATION);
4558 SET_ERROR_IF(
4559 read_fbo_format_info.type == FBO_ATTACHMENT_RENDERBUFFER &&
4560 read_fbo_format_info.rb_multisamples > 0 &&
4561 draw_fbo_format_info.type == FBO_ATTACHMENT_RENDERBUFFER &&
4562 (srcX0 != dstX0 || srcY0 != dstY0 ||
4563 srcX1 != dstX1 || srcY1 != dstY1),
4564 GL_INVALID_OPERATION);
4565
4566 ctx->m_glBlitFramebuffer_enc(ctx,
4567 srcX0, srcY0, srcX1, srcY1,
4568 dstX0, dstY0, dstX1, dstY1,
4569 mask, filter);
4570}
4571
4572void GL2Encoder::s_glGetInternalformativ(void* self, GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params) {
4573 GL2Encoder *ctx = (GL2Encoder *)self;
4574
4575 SET_ERROR_IF(pname != GL_NUM_SAMPLE_COUNTS &&
4576 pname != GL_SAMPLES,
4577 GL_INVALID_ENUM);
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08004578 SET_ERROR_IF(!GLESv2Validation::internalFormatTarget(ctx, target), GL_INVALID_ENUM);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004579 SET_ERROR_IF(!GLESv2Validation::unsizedFormat(internalformat) &&
Lingfeng Yang931817b2017-01-27 06:50:56 -08004580 !GLESv2Validation::colorRenderableFormat(ctx, internalformat) &&
4581 !GLESv2Validation::depthRenderableFormat(ctx, internalformat) &&
4582 !GLESv2Validation::stencilRenderableFormat(ctx, internalformat),
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004583 GL_INVALID_ENUM);
4584 SET_ERROR_IF(bufSize < 0, GL_INVALID_VALUE);
4585
4586 if (bufSize < 1) return;
4587
4588 // Desktop OpenGL can allow a mindboggling # samples per pixel (such as 64).
4589 // Limit to 4 (spec minimum) to keep dEQP tests from timing out.
4590 switch (pname) {
4591 case GL_NUM_SAMPLE_COUNTS:
4592 *params = 3;
4593 break;
4594 case GL_SAMPLES:
4595 params[0] = 4;
4596 if (bufSize > 1) params[1] = 2;
4597 if (bufSize > 2) params[2] = 1;
4598 break;
4599 default:
4600 break;
4601 }
4602}
4603
4604void GL2Encoder::s_glGenerateMipmap(void* self, GLenum target) {
4605 GL2Encoder *ctx = (GL2Encoder *)self;
4606 GLClientState* state = ctx->m_state;
4607
4608 SET_ERROR_IF(target != GL_TEXTURE_2D &&
4609 target != GL_TEXTURE_3D &&
Yahan Zhou53c64582018-04-16 15:46:17 -07004610 target != GL_TEXTURE_CUBE_MAP &&
4611 target != GL_TEXTURE_2D_ARRAY,
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004612 GL_INVALID_ENUM);
4613
4614 GLuint tex = state->getBoundTexture(target);
4615 GLenum internalformat = state->queryTexInternalFormat(tex);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004616
4617 SET_ERROR_IF(tex && GLESv2Validation::isCompressedFormat(internalformat),
4618 GL_INVALID_OPERATION);
4619 SET_ERROR_IF(tex &&
4620 !GLESv2Validation::unsizedFormat(internalformat) &&
Lingfeng Yang931817b2017-01-27 06:50:56 -08004621 !(GLESv2Validation::colorRenderableFormat(ctx, internalformat) &&
4622 GLESv2Validation::filterableTexFormat(ctx, internalformat)),
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004623 GL_INVALID_OPERATION);
4624
Lingfeng Yanga9fff6a2018-03-02 13:42:51 -08004625 if (target == GL_TEXTURE_2D) {
4626 ctx->override2DTextureTarget(target);
4627 }
4628
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004629 ctx->m_glGenerateMipmap_enc(ctx, target);
Lingfeng Yanga9fff6a2018-03-02 13:42:51 -08004630
4631 if (target == GL_TEXTURE_2D) {
4632 ctx->restore2DTextureTarget(target);
4633 }
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004634}
4635
4636void GL2Encoder::s_glBindSampler(void* self, GLuint unit, GLuint sampler) {
4637 GL2Encoder *ctx = (GL2Encoder *)self;
4638 GLint maxCombinedUnits;
4639 ctx->glGetIntegerv(ctx, GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxCombinedUnits);
4640 SET_ERROR_IF(unit >= maxCombinedUnits, GL_INVALID_VALUE);
4641
Lingfeng Yang554a5152019-02-21 20:20:48 -08004642 ctx->doSamplerBindEncodeCached(unit, sampler);
4643}
4644
4645void GL2Encoder::doSamplerBindEncodeCached(GLuint unit, GLuint sampler) {
4646 if (m_state->isSamplerBindNoOp(unit, sampler)) return;
4647 m_glBindSampler_enc(this, unit, sampler);
4648 m_state->bindSampler(unit, sampler);
4649}
4650
4651void GL2Encoder::s_glDeleteSamplers(void* self, GLsizei n, const GLuint* samplers) {
4652 GL2Encoder *ctx = (GL2Encoder *)self;
4653 ctx->m_state->onDeleteSamplers(n, samplers);
4654 ctx->m_glDeleteSamplers_enc(ctx, n, samplers);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004655}
4656
Lingfeng Yangf000ab42017-01-11 18:31:38 -08004657GLsync GL2Encoder::s_glFenceSync(void* self, GLenum condition, GLbitfield flags) {
4658 GL2Encoder *ctx = (GL2Encoder *)self;
4659 uint64_t syncHandle = ctx->glFenceSyncAEMU(ctx, condition, flags);
4660 return (GLsync)(uintptr_t)syncHandle;
4661}
4662
4663GLenum GL2Encoder::s_glClientWaitSync(void* self, GLsync wait_on, GLbitfield flags, GLuint64 timeout) {
4664 GL2Encoder *ctx = (GL2Encoder *)self;
4665 return ctx->glClientWaitSyncAEMU(ctx, (uint64_t)(uintptr_t)wait_on, flags, timeout);
4666}
4667
4668void GL2Encoder::s_glWaitSync(void* self, GLsync wait_on, GLbitfield flags, GLuint64 timeout) {
4669 GL2Encoder *ctx = (GL2Encoder *)self;
4670 ctx->glWaitSyncAEMU(ctx, (uint64_t)(uintptr_t)wait_on, flags, timeout);
4671}
4672
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004673void GL2Encoder::s_glDeleteSync(void* self, GLsync sync) {
4674 GL2Encoder *ctx = (GL2Encoder *)self;
4675
4676 if (!sync) return;
4677
Lingfeng Yangf000ab42017-01-11 18:31:38 -08004678 ctx->glDeleteSyncAEMU(ctx, (uint64_t)(uintptr_t)sync);
4679}
4680
4681GLboolean GL2Encoder::s_glIsSync(void* self, GLsync sync) {
4682 GL2Encoder *ctx = (GL2Encoder *)self;
4683 return ctx->glIsSyncAEMU(ctx, (uint64_t)(uintptr_t)sync);
4684}
4685
4686void GL2Encoder::s_glGetSynciv(void* self, GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values) {
4687 GL2Encoder *ctx = (GL2Encoder *)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08004688
4689 SET_ERROR_IF(bufSize < 0, GL_INVALID_VALUE);
4690
Lingfeng Yangf000ab42017-01-11 18:31:38 -08004691 return ctx->glGetSyncivAEMU(ctx, (uint64_t)(uintptr_t)sync, pname, bufSize, length, values);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004692}
4693
4694#define LIMIT_CASE(target, lim) \
4695 case target: \
4696 ctx->glGetIntegerv(ctx, lim, &limit); \
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08004697 SET_ERROR_IF(index < 0 || index >= limit, GL_INVALID_VALUE); \
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004698 break; \
4699
4700void GL2Encoder::s_glGetIntegeri_v(void* self, GLenum target, GLuint index, GLint* params) {
4701 GL2Encoder *ctx = (GL2Encoder *)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08004702 GLClientState* state = ctx->m_state;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004703
4704 GLint limit;
4705
4706 switch (target) {
4707 LIMIT_CASE(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS)
4708 LIMIT_CASE(GL_UNIFORM_BUFFER_BINDING, GL_MAX_UNIFORM_BUFFER_BINDINGS)
4709 LIMIT_CASE(GL_ATOMIC_COUNTER_BUFFER_BINDING, GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS)
4710 LIMIT_CASE(GL_SHADER_STORAGE_BUFFER_BINDING, GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS)
4711 default:
4712 break;
4713 }
4714
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08004715 const GLClientState::VertexAttribBindingVector& currBindings =
4716 state->currentVertexBufferBindings();
4717
4718 switch (target) {
4719 case GL_VERTEX_BINDING_DIVISOR:
4720 case GL_VERTEX_BINDING_OFFSET:
4721 case GL_VERTEX_BINDING_STRIDE:
4722 case GL_VERTEX_BINDING_BUFFER:
4723 SET_ERROR_IF(index < 0 || index > currBindings.size(), GL_INVALID_VALUE);
4724 break;
4725 default:
4726 break;
4727 }
4728
4729 switch (target) {
4730 case GL_VERTEX_BINDING_DIVISOR:
4731 *params = currBindings[index].divisor;
4732 return;
4733 case GL_VERTEX_BINDING_OFFSET:
4734 *params = currBindings[index].offset;
4735 return;
4736 case GL_VERTEX_BINDING_STRIDE:
4737 *params = currBindings[index].effectiveStride;
4738 return;
4739 case GL_VERTEX_BINDING_BUFFER:
4740 *params = currBindings[index].buffer;
4741 return;
4742 default:
4743 break;
4744 }
4745
Lingfeng Yang80a36332017-07-09 10:58:07 -07004746 ctx->safe_glGetIntegeri_v(target, index, params);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004747}
4748
4749void GL2Encoder::s_glGetInteger64i_v(void* self, GLenum target, GLuint index, GLint64* params) {
4750 GL2Encoder *ctx = (GL2Encoder *)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08004751 GLClientState* state = ctx->m_state;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004752
4753 GLint limit;
4754
4755 switch (target) {
4756 LIMIT_CASE(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS)
4757 LIMIT_CASE(GL_UNIFORM_BUFFER_BINDING, GL_MAX_UNIFORM_BUFFER_BINDINGS)
4758 LIMIT_CASE(GL_ATOMIC_COUNTER_BUFFER_BINDING, GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS)
4759 LIMIT_CASE(GL_SHADER_STORAGE_BUFFER_BINDING, GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS)
4760 default:
4761 break;
4762 }
4763
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08004764 const GLClientState::VertexAttribBindingVector& currBindings =
4765 state->currentVertexBufferBindings();
4766
4767 switch (target) {
4768 case GL_VERTEX_BINDING_DIVISOR:
4769 case GL_VERTEX_BINDING_OFFSET:
4770 case GL_VERTEX_BINDING_STRIDE:
4771 case GL_VERTEX_BINDING_BUFFER:
4772 SET_ERROR_IF(index < 0 || index > currBindings.size(), GL_INVALID_VALUE);
4773 break;
4774 default:
4775 break;
4776 }
4777
4778 switch (target) {
4779 case GL_VERTEX_BINDING_DIVISOR:
4780 *params = currBindings[index].divisor;
4781 return;
4782 case GL_VERTEX_BINDING_OFFSET:
4783 *params = currBindings[index].offset;
4784 return;
4785 case GL_VERTEX_BINDING_STRIDE:
4786 *params = currBindings[index].effectiveStride;
4787 return;
4788 case GL_VERTEX_BINDING_BUFFER:
4789 *params = currBindings[index].buffer;
4790 return;
4791 default:
4792 break;
4793 }
4794
Lingfeng Yang80a36332017-07-09 10:58:07 -07004795 ctx->safe_glGetInteger64i_v(target, index, params);
4796}
4797
4798void GL2Encoder::s_glGetInteger64v(void* self, GLenum param, GLint64* val) {
4799 GL2Encoder *ctx = (GL2Encoder *)self;
4800 ctx->safe_glGetInteger64v(param, val);
4801}
4802
4803void GL2Encoder::s_glGetBooleani_v(void* self, GLenum param, GLuint index, GLboolean* val) {
4804 GL2Encoder *ctx = (GL2Encoder *)self;
4805 ctx->safe_glGetBooleani_v(param, index, val);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004806}
4807
4808void GL2Encoder::s_glGetShaderiv(void* self, GLuint shader, GLenum pname, GLint* params) {
4809 GL2Encoder *ctx = (GL2Encoder *)self;
4810 ctx->m_glGetShaderiv_enc(self, shader, pname, params);
4811 if (pname == GL_SHADER_SOURCE_LENGTH) {
4812 ShaderData* shaderData = ctx->m_shared->getShaderData(shader);
4813 if (shaderData) {
4814 int totalLen = 0;
4815 for (int i = 0; i < shaderData->sources.size(); i++) {
4816 totalLen += shaderData->sources[i].size();
4817 }
4818 if (totalLen != 0) {
4819 *params = totalLen + 1; // account for null terminator
4820 }
4821 }
4822 }
4823}
4824
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08004825void GL2Encoder::s_glActiveShaderProgram(void* self, GLuint pipeline, GLuint program) {
4826 GL2Encoder *ctx = (GL2Encoder*)self;
4827 GLClientState* state = ctx->m_state;
4828 GLSharedGroupPtr shared = ctx->m_shared;
4829
4830 SET_ERROR_IF(!pipeline, GL_INVALID_OPERATION);
4831 SET_ERROR_IF(program && !shared->isShaderOrProgramObject(program), GL_INVALID_VALUE);
4832 SET_ERROR_IF(program && !shared->isProgram(program), GL_INVALID_OPERATION);
4833
4834 ctx->m_glActiveShaderProgram_enc(ctx, pipeline, program);
4835 if (!state->currentProgram()) {
4836 state->setCurrentShaderProgram(program);
4837 }
4838}
4839
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004840GLuint GL2Encoder::s_glCreateShaderProgramv(void* self, GLenum type, GLsizei count, const char** strings) {
4841
4842 GLint* length = NULL;
4843 GL2Encoder* ctx = (GL2Encoder*)self;
4844
4845 int len = glUtilsCalcShaderSourceLen((char**)strings, length, count);
4846 char *str = new char[len + 1];
4847 glUtilsPackStrings(str, (char**)strings, (GLint*)length, count);
Lingfeng Yang554a5152019-02-21 20:20:48 -08004848
4849 // Do GLSharedGroup and location WorkARound-specific initialization
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004850 // Phase 1: create a ShaderData and initialize with replaceSamplerExternalWith2D()
4851 uint32_t spDataId = ctx->m_shared->addNewShaderProgramData();
4852 ShaderProgramData* spData = ctx->m_shared->getShaderProgramDataById(spDataId);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004853
Lingfeng Yang44209df2018-09-21 10:04:17 -07004854 if (!replaceSamplerExternalWith2D(str, &spData->shaderData)) {
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004855 delete [] str;
4856 ctx->setError(GL_OUT_OF_MEMORY);
4857 ctx->m_shared->deleteShaderProgramDataById(spDataId);
4858 return -1;
4859 }
4860
4861 GLuint res = ctx->glCreateShaderProgramvAEMU(ctx, type, count, str, len + 1);
4862 delete [] str;
4863
4864 // Phase 2: do glLinkProgram-related initialization for locationWorkARound
4865 GLint linkStatus = 0;
4866 ctx->glGetProgramiv(self, res, GL_LINK_STATUS ,&linkStatus);
4867 if (!linkStatus) {
4868 ctx->m_shared->deleteShaderProgramDataById(spDataId);
4869 return -1;
4870 }
4871
4872 ctx->m_shared->associateGLShaderProgram(res, spDataId);
4873
4874 GLint numUniforms = 0;
Lingfeng Yang80a36332017-07-09 10:58:07 -07004875 ctx->glGetProgramiv(self, res, GL_ACTIVE_UNIFORMS, &numUniforms);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004876 ctx->m_shared->initShaderProgramData(res, numUniforms);
4877
4878 GLint maxLength=0;
4879 ctx->glGetProgramiv(self, res, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxLength);
4880
4881 GLint size; GLenum uniformType; GLchar* name = new GLchar[maxLength + 1];
4882
4883 for (GLint i = 0; i < numUniforms; ++i) {
4884 ctx->glGetActiveUniform(self, res, i, maxLength, NULL, &size, &uniformType, name);
4885 GLint location = ctx->m_glGetUniformLocation_enc(self, res, name);
4886 ctx->m_shared->setShaderProgramIndexInfo(res, i, location, size, uniformType, name);
4887 }
4888
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004889 delete [] name;
4890
4891 return res;
4892}
4893
4894void GL2Encoder::s_glProgramUniform1f(void* self, GLuint program, GLint location, GLfloat v0)
4895{
4896 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08004897 GLint hostLoc = location;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004898 ctx->m_glProgramUniform1f_enc(self, program, hostLoc, v0);
4899}
4900
4901void GL2Encoder::s_glProgramUniform1fv(void* self, GLuint program, GLint location, GLsizei count, const GLfloat *value)
4902{
4903 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08004904 GLint hostLoc = location;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004905 ctx->m_glProgramUniform1fv_enc(self, program, hostLoc, count, value);
4906}
4907
4908void GL2Encoder::s_glProgramUniform1i(void* self, GLuint program, GLint location, GLint v0)
4909{
4910 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08004911 GLint hostLoc = location;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08004912 ctx->m_glProgramUniform1i_enc(self, program, hostLoc, v0);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004913
4914 GLClientState* state = ctx->m_state;
4915 GLSharedGroupPtr shared = ctx->m_shared;
4916 GLenum target;
4917
4918 if (shared->setSamplerUniform(program, location, v0, &target)) {
4919 GLenum origActiveTexture = state->getActiveTextureUnit();
4920 if (ctx->updateHostTexture2DBinding(GL_TEXTURE0 + v0, target)) {
4921 ctx->m_glActiveTexture_enc(self, origActiveTexture);
4922 }
4923 state->setActiveTextureUnit(origActiveTexture);
4924 }
4925}
4926
4927void GL2Encoder::s_glProgramUniform1iv(void* self, GLuint program, GLint location, GLsizei count, const GLint *value)
4928{
4929 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08004930 GLint hostLoc = location;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004931 ctx->m_glProgramUniform1iv_enc(self, program, hostLoc, count, value);
4932}
4933
4934void GL2Encoder::s_glProgramUniform1ui(void* self, GLuint program, GLint location, GLuint v0)
4935{
4936 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08004937 GLint hostLoc = location;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004938 ctx->m_glProgramUniform1ui_enc(self, program, hostLoc, v0);
4939
4940 GLClientState* state = ctx->m_state;
4941 GLSharedGroupPtr shared = ctx->m_shared;
4942 GLenum target;
4943
4944 if (shared->setSamplerUniform(program, location, v0, &target)) {
4945 GLenum origActiveTexture = state->getActiveTextureUnit();
4946 if (ctx->updateHostTexture2DBinding(GL_TEXTURE0 + v0, target)) {
4947 ctx->m_glActiveTexture_enc(self, origActiveTexture);
4948 }
4949 state->setActiveTextureUnit(origActiveTexture);
4950 }
4951}
4952
4953void GL2Encoder::s_glProgramUniform1uiv(void* self, GLuint program, GLint location, GLsizei count, const GLuint *value)
4954{
4955 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08004956 GLint hostLoc = location;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004957 ctx->m_glProgramUniform1uiv_enc(self, program, hostLoc, count, value);
4958}
4959
4960void GL2Encoder::s_glProgramUniform2f(void* self, GLuint program, GLint location, GLfloat v0, GLfloat v1)
4961{
4962 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08004963 GLint hostLoc = location;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004964 ctx->m_glProgramUniform2f_enc(self, program, hostLoc, v0, v1);
4965}
4966
4967void GL2Encoder::s_glProgramUniform2fv(void* self, GLuint program, GLint location, GLsizei count, const GLfloat *value)
4968{
4969 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08004970 GLint hostLoc = location;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004971 ctx->m_glProgramUniform2fv_enc(self, program, hostLoc, count, value);
4972}
4973
4974void GL2Encoder::s_glProgramUniform2i(void* self, GLuint program, GLint location, GLint v0, GLint v1)
4975{
4976 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08004977 GLint hostLoc = location;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004978 ctx->m_glProgramUniform2i_enc(self, program, hostLoc, v0, v1);
4979}
4980
4981void GL2Encoder::s_glProgramUniform2iv(void* self, GLuint program, GLint location, GLsizei count, const GLint *value)
4982{
4983 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08004984 GLint hostLoc = location;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004985 ctx->m_glProgramUniform2iv_enc(self, program, hostLoc, count, value);
4986}
4987
4988void GL2Encoder::s_glProgramUniform2ui(void* self, GLuint program, GLint location, GLint v0, GLuint v1)
4989{
4990 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08004991 GLint hostLoc = location;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004992 ctx->m_glProgramUniform2ui_enc(self, program, hostLoc, v0, v1);
4993}
4994
4995void GL2Encoder::s_glProgramUniform2uiv(void* self, GLuint program, GLint location, GLsizei count, const GLuint *value)
4996{
4997 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08004998 GLint hostLoc = location;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004999 ctx->m_glProgramUniform2uiv_enc(self, program, hostLoc, count, value);
5000}
5001
5002void GL2Encoder::s_glProgramUniform3f(void* self, GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2)
5003{
5004 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08005005 GLint hostLoc = location;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005006 ctx->m_glProgramUniform3f_enc(self, program, hostLoc, v0, v1, v2);
5007}
5008
5009void GL2Encoder::s_glProgramUniform3fv(void* self, GLuint program, GLint location, GLsizei count, const GLfloat *value)
5010{
5011 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08005012 GLint hostLoc = location;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005013 ctx->m_glProgramUniform3fv_enc(self, program, hostLoc, count, value);
5014}
5015
5016void GL2Encoder::s_glProgramUniform3i(void* self, GLuint program, GLint location, GLint v0, GLint v1, GLint v2)
5017{
5018 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08005019 GLint hostLoc = location;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005020 ctx->m_glProgramUniform3i_enc(self, program, hostLoc, v0, v1, v2);
5021}
5022
5023void GL2Encoder::s_glProgramUniform3iv(void* self, GLuint program, GLint location, GLsizei count, const GLint *value)
5024{
5025 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08005026 GLint hostLoc = location;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005027 ctx->m_glProgramUniform3iv_enc(self, program, hostLoc, count, value);
5028}
5029
5030void GL2Encoder::s_glProgramUniform3ui(void* self, GLuint program, GLint location, GLint v0, GLint v1, GLuint v2)
5031{
5032 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08005033 GLint hostLoc = location;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005034 ctx->m_glProgramUniform3ui_enc(self, program, hostLoc, v0, v1, v2);
5035}
5036
5037void GL2Encoder::s_glProgramUniform3uiv(void* self, GLuint program, GLint location, GLsizei count, const GLuint *value)
5038{
5039 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08005040 GLint hostLoc = location;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005041 ctx->m_glProgramUniform3uiv_enc(self, program, hostLoc, count, value);
5042}
5043
5044void GL2Encoder::s_glProgramUniform4f(void* self, GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3)
5045{
5046 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08005047 GLint hostLoc = location;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005048 ctx->m_glProgramUniform4f_enc(self, program, hostLoc, v0, v1, v2, v3);
5049}
5050
5051void GL2Encoder::s_glProgramUniform4fv(void* self, GLuint program, GLint location, GLsizei count, const GLfloat *value)
5052{
5053 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08005054 GLint hostLoc = location;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005055 ctx->m_glProgramUniform4fv_enc(self, program, hostLoc, count, value);
5056}
5057
5058void GL2Encoder::s_glProgramUniform4i(void* self, GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3)
5059{
5060 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08005061 GLint hostLoc = location;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005062 ctx->m_glProgramUniform4i_enc(self, program, hostLoc, v0, v1, v2, v3);
5063}
5064
5065void GL2Encoder::s_glProgramUniform4iv(void* self, GLuint program, GLint location, GLsizei count, const GLint *value)
5066{
5067 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08005068 GLint hostLoc = location;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005069 ctx->m_glProgramUniform4iv_enc(self, program, hostLoc, count, value);
5070}
5071
5072void GL2Encoder::s_glProgramUniform4ui(void* self, GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLuint v3)
5073{
5074 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08005075 GLint hostLoc = location;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005076 ctx->m_glProgramUniform4ui_enc(self, program, hostLoc, v0, v1, v2, v3);
5077}
5078
5079void GL2Encoder::s_glProgramUniform4uiv(void* self, GLuint program, GLint location, GLsizei count, const GLuint *value)
5080{
5081 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08005082 GLint hostLoc = location;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005083 ctx->m_glProgramUniform4uiv_enc(self, program, hostLoc, count, value);
5084}
5085
5086void GL2Encoder::s_glProgramUniformMatrix2fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
5087{
5088 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08005089 GLint hostLoc = location;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005090 ctx->m_glProgramUniformMatrix2fv_enc(self, program, hostLoc, count, transpose, value);
5091}
5092
5093void GL2Encoder::s_glProgramUniformMatrix2x3fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
5094{
5095 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08005096 GLint hostLoc = location;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005097 ctx->m_glProgramUniformMatrix2x3fv_enc(self, program, hostLoc, count, transpose, value);
5098}
5099
5100void GL2Encoder::s_glProgramUniformMatrix2x4fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
5101{
5102 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08005103 GLint hostLoc = location;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005104 ctx->m_glProgramUniformMatrix2x4fv_enc(self, program, hostLoc, count, transpose, value);
5105}
5106
5107void GL2Encoder::s_glProgramUniformMatrix3fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
5108{
5109 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08005110 GLint hostLoc = location;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005111 ctx->m_glProgramUniformMatrix3fv_enc(self, program, hostLoc, count, transpose, value);
5112}
5113
5114void GL2Encoder::s_glProgramUniformMatrix3x2fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
5115{
5116 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08005117 GLint hostLoc = location;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005118 ctx->m_glProgramUniformMatrix3x2fv_enc(self, program, hostLoc, count, transpose, value);
5119}
5120
5121void GL2Encoder::s_glProgramUniformMatrix3x4fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
5122{
5123 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08005124 GLint hostLoc = location;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005125 ctx->m_glProgramUniformMatrix3x4fv_enc(self, program, hostLoc, count, transpose, value);
5126}
5127
5128void GL2Encoder::s_glProgramUniformMatrix4fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
5129{
5130 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08005131 GLint hostLoc = location;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005132 ctx->m_glProgramUniformMatrix4fv_enc(self, program, hostLoc, count, transpose, value);
5133}
5134
5135void GL2Encoder::s_glProgramUniformMatrix4x2fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
5136{
5137 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08005138 GLint hostLoc = location;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005139 ctx->m_glProgramUniformMatrix4x2fv_enc(self, program, hostLoc, count, transpose, value);
5140}
5141
5142void GL2Encoder::s_glProgramUniformMatrix4x3fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
5143{
5144 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang0b85afd2019-11-04 08:50:19 -08005145 GLint hostLoc = location;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005146 ctx->m_glProgramUniformMatrix4x3fv_enc(self, program, hostLoc, count, transpose, value);
5147}
5148
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08005149void GL2Encoder::s_glProgramParameteri(void* self, GLuint program, GLenum pname, GLint value) {
5150 GL2Encoder* ctx = (GL2Encoder*)self;
5151 ctx->m_glProgramParameteri_enc(self, program, pname, value);
5152}
5153
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005154void GL2Encoder::s_glUseProgramStages(void *self, GLuint pipeline, GLbitfield stages, GLuint program)
5155{
5156 GL2Encoder *ctx = (GL2Encoder*)self;
5157 GLClientState* state = ctx->m_state;
5158 GLSharedGroupPtr shared = ctx->m_shared;
5159
5160 SET_ERROR_IF(!pipeline, GL_INVALID_OPERATION);
5161 SET_ERROR_IF(program && !shared->isShaderOrProgramObject(program), GL_INVALID_VALUE);
5162 SET_ERROR_IF(program && !shared->isProgram(program), GL_INVALID_OPERATION);
5163
5164 ctx->m_glUseProgramStages_enc(self, pipeline, stages, program);
5165 state->associateProgramWithPipeline(program, pipeline);
5166
5167 // There is an active non-separable shader program in effect; no need to update external/2D bindings.
5168 if (state->currentProgram()) {
5169 return;
5170 }
5171
5172 // Otherwise, update host texture 2D bindings.
5173 ctx->updateHostTexture2DBindingsFromProgramData(program);
5174}
5175
5176void GL2Encoder::s_glBindProgramPipeline(void* self, GLuint pipeline)
5177{
5178 GL2Encoder *ctx = (GL2Encoder*)self;
5179 GLClientState* state = ctx->m_state;
5180
5181 ctx->m_glBindProgramPipeline_enc(self, pipeline);
5182
5183 // There is an active non-separable shader program in effect; no need to update external/2D bindings.
5184 if (!pipeline || state->currentProgram()) {
5185 return;
5186 }
5187
5188 GLClientState::ProgramPipelineIterator it = state->programPipelineBegin();
5189 for (; it != state->programPipelineEnd(); ++it) {
5190 if (it->second == pipeline) {
5191 ctx->updateHostTexture2DBindingsFromProgramData(it->first);
5192 }
5193 }
5194}
5195
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08005196void GL2Encoder::s_glGetProgramResourceiv(void* self, GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum * props, GLsizei bufSize, GLsizei * length, GLint * params) {
5197 GL2Encoder *ctx = (GL2Encoder*)self;
5198 SET_ERROR_IF(bufSize < 0, GL_INVALID_VALUE);
5199 if (bufSize == 0) {
5200 if (length) *length = 0;
5201 return;
5202 }
5203
5204 // Avoid modifying |name| if |*length| < bufSize.
5205 GLint* intermediate = new GLint[bufSize];
5206 GLsizei* myLength = length ? length : new GLsizei;
5207 bool needFreeLength = length == NULL;
5208
5209 ctx->m_glGetProgramResourceiv_enc(self, program, programInterface, index, propCount, props, bufSize, myLength, intermediate);
5210 GLsizei writtenInts = *myLength;
5211 memcpy(params, intermediate, writtenInts * sizeof(GLint));
5212
5213 delete [] intermediate;
5214 if (needFreeLength)
5215 delete myLength;
5216}
5217
5218GLuint GL2Encoder::s_glGetProgramResourceIndex(void* self, GLuint program, GLenum programInterface, const char* name) {
5219 GL2Encoder *ctx = (GL2Encoder*)self;
5220 return ctx->m_glGetProgramResourceIndex_enc(self, program, programInterface, name);
5221}
5222
5223GLint GL2Encoder::s_glGetProgramResourceLocation(void* self, GLuint program, GLenum programInterface, const char* name) {
5224 GL2Encoder *ctx = (GL2Encoder*)self;
5225 return ctx->m_glGetProgramResourceLocation_enc(self, program, programInterface, name);
5226}
5227
5228void GL2Encoder::s_glGetProgramResourceName(void* self, GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei* length, char* name) {
5229 GL2Encoder *ctx = (GL2Encoder*)self;
5230 SET_ERROR_IF(bufSize < 0, GL_INVALID_VALUE);
5231 if (bufSize == 0) {
5232 if (length) *length = 0;
5233 return;
5234 }
5235
5236 // Avoid modifying |name| if |*length| < bufSize.
5237 char* intermediate = new char[bufSize];
5238 GLsizei* myLength = length ? length : new GLsizei;
5239 bool needFreeLength = length == NULL;
5240
5241 ctx->m_glGetProgramResourceName_enc(self, program, programInterface, index, bufSize, myLength, intermediate);
5242 GLsizei writtenStrLen = *myLength;
5243 memcpy(name, intermediate, writtenStrLen + 1);
5244
5245 delete [] intermediate;
5246 if (needFreeLength)
5247 delete myLength;
5248}
5249
5250void GL2Encoder::s_glGetProgramPipelineInfoLog(void* self, GLuint pipeline, GLsizei bufSize, GLsizei* length, GLchar* infoLog) {
5251 GL2Encoder *ctx = (GL2Encoder*)self;
5252 SET_ERROR_IF(bufSize < 0, GL_INVALID_VALUE);
5253 if (bufSize == 0) {
5254 if (length) *length = 0;
5255 return;
5256 }
5257
5258 // Avoid modifying |infoLog| if |*length| < bufSize.
5259 GLchar* intermediate = new GLchar[bufSize];
5260 GLsizei* myLength = length ? length : new GLsizei;
5261 bool needFreeLength = length == NULL;
5262
5263 ctx->m_glGetProgramPipelineInfoLog_enc(self, pipeline, bufSize, myLength, intermediate);
5264 GLsizei writtenStrLen = *myLength;
5265 memcpy(infoLog, intermediate, writtenStrLen + 1);
5266
5267 delete [] intermediate;
5268 if (needFreeLength)
5269 delete myLength;
5270}
5271
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005272void GL2Encoder::s_glVertexAttribFormat(void* self, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset) {
5273 GL2Encoder *ctx = (GL2Encoder*)self;
5274 GLClientState* state = ctx->m_state;
5275
Lingfeng Yang07289902017-01-27 12:26:19 -08005276 VALIDATE_VERTEX_ATTRIB_INDEX(attribindex);
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08005277 SET_ERROR_IF(!state->currentVertexArrayObject(), GL_INVALID_OPERATION);
5278
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005279 state->setVertexAttribFormat(attribindex, size, type, normalized, relativeoffset, false);
5280 ctx->m_glVertexAttribFormat_enc(ctx, attribindex, size, type, normalized, relativeoffset);
5281}
5282
5283void GL2Encoder::s_glVertexAttribIFormat(void* self, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset) {
5284 GL2Encoder *ctx = (GL2Encoder*)self;
5285 GLClientState* state = ctx->m_state;
5286
Lingfeng Yang07289902017-01-27 12:26:19 -08005287 VALIDATE_VERTEX_ATTRIB_INDEX(attribindex);
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08005288 SET_ERROR_IF(!state->currentVertexArrayObject(), GL_INVALID_OPERATION);
5289
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005290 state->setVertexAttribFormat(attribindex, size, type, GL_FALSE, relativeoffset, true);
5291 ctx->m_glVertexAttribIFormat_enc(ctx, attribindex, size, type, relativeoffset);
5292}
5293
5294void GL2Encoder::s_glVertexBindingDivisor(void* self, GLuint bindingindex, GLuint divisor) {
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005295 GL2Encoder *ctx = (GL2Encoder*)self;
5296 GLClientState* state = ctx->m_state;
5297
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08005298 SET_ERROR_IF(!state->currentVertexArrayObject(), GL_INVALID_OPERATION);
5299
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005300 state->setVertexBindingDivisor(bindingindex, divisor);
5301 ctx->m_glVertexBindingDivisor_enc(ctx, bindingindex, divisor);
5302}
5303
5304void GL2Encoder::s_glVertexAttribBinding(void* self, GLuint attribindex, GLuint bindingindex) {
5305 GL2Encoder *ctx = (GL2Encoder*)self;
5306 GLClientState* state = ctx->m_state;
Lingfeng Yang07289902017-01-27 12:26:19 -08005307 VALIDATE_VERTEX_ATTRIB_INDEX(attribindex);
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08005308 SET_ERROR_IF(!state->currentVertexArrayObject(), GL_INVALID_OPERATION);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005309
5310 state->setVertexAttribBinding(attribindex, bindingindex);
5311 ctx->m_glVertexAttribBinding_enc(ctx, attribindex, bindingindex);
5312}
5313
5314void GL2Encoder::s_glBindVertexBuffer(void* self, GLuint bindingindex, GLuint buffer, GLintptr offset, GLintptr stride) {
5315 GL2Encoder *ctx = (GL2Encoder*)self;
5316 GLClientState* state = ctx->m_state;
5317
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08005318 SET_ERROR_IF(offset < 0, GL_INVALID_VALUE);
5319
5320 GLint maxStride;
5321 ctx->glGetIntegerv(ctx, GL_MAX_VERTEX_ATTRIB_STRIDE, &maxStride);
5322 SET_ERROR_IF(stride < 0 || stride > maxStride, GL_INVALID_VALUE);
5323
5324 SET_ERROR_IF(!state->currentVertexArrayObject(), GL_INVALID_OPERATION);
5325
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005326 state->bindIndexedBuffer(0, bindingindex, buffer, offset, 0, stride, stride);
5327 ctx->m_glBindVertexBuffer_enc(ctx, bindingindex, buffer, offset, stride);
5328}
5329
5330void GL2Encoder::s_glDrawArraysIndirect(void* self, GLenum mode, const void* indirect) {
5331 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08005332 GLClientState* state = ctx->m_state;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005333
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08005334 bool hasClientArrays = false;
5335 ctx->getVBOUsage(&hasClientArrays, NULL);
5336
5337 SET_ERROR_IF(hasClientArrays, GL_INVALID_OPERATION);
5338 SET_ERROR_IF(!state->currentVertexArrayObject(), GL_INVALID_OPERATION);
5339 SET_ERROR_IF(!ctx->boundBuffer(GL_DRAW_INDIRECT_BUFFER), GL_INVALID_OPERATION);
5340
5341 GLuint indirectStructSize = glUtilsIndirectStructSize(INDIRECT_COMMAND_DRAWARRAYS);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005342 if (ctx->boundBuffer(GL_DRAW_INDIRECT_BUFFER)) {
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08005343 // BufferData* buf = ctx->getBufferData(target);
5344 // if (buf) {
5345 // SET_ERROR_IF((GLuint)(uintptr_t)indirect + indirectStructSize > buf->m_size, GL_INVALID_VALUE);
5346 // }
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005347 ctx->glDrawArraysIndirectOffsetAEMU(ctx, mode, (uintptr_t)indirect);
5348 } else {
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08005349 // Client command structs are technically allowed in desktop OpenGL, but not in ES.
5350 // This is purely for debug/dev purposes.
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005351 ctx->glDrawArraysIndirectDataAEMU(ctx, mode, indirect, indirectStructSize);
5352 }
5353}
5354
5355void GL2Encoder::s_glDrawElementsIndirect(void* self, GLenum mode, GLenum type, const void* indirect) {
5356 GL2Encoder *ctx = (GL2Encoder*)self;
5357
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08005358 GLClientState* state = ctx->m_state;
5359
5360 bool hasClientArrays = false;
5361 ctx->getVBOUsage(&hasClientArrays, NULL);
5362
5363 SET_ERROR_IF(hasClientArrays, GL_INVALID_OPERATION);
5364 SET_ERROR_IF(!state->currentVertexArrayObject(), GL_INVALID_OPERATION);
5365 SET_ERROR_IF(!ctx->boundBuffer(GL_DRAW_INDIRECT_BUFFER), GL_INVALID_OPERATION);
5366
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005367 SET_ERROR_IF(ctx->m_state->getTransformFeedbackActiveUnpaused(), GL_INVALID_OPERATION);
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08005368
5369 GLuint indirectStructSize = glUtilsIndirectStructSize(INDIRECT_COMMAND_DRAWELEMENTS);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005370 if (ctx->boundBuffer(GL_DRAW_INDIRECT_BUFFER)) {
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08005371 // BufferData* buf = ctx->getBufferData(target);
5372 // if (buf) {
5373 // SET_ERROR_IF((GLuint)(uintptr_t)indirect + indirectStructSize > buf->m_size, GL_INVALID_VALUE);
5374 // }
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005375 ctx->glDrawElementsIndirectOffsetAEMU(ctx, mode, type, (uintptr_t)indirect);
5376 } else {
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08005377 // Client command structs are technically allowed in desktop OpenGL, but not in ES.
5378 // This is purely for debug/dev purposes.
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005379 ctx->glDrawElementsIndirectDataAEMU(ctx, mode, type, indirect, indirectStructSize);
5380 }
5381
5382}
5383
5384void GL2Encoder::s_glTexStorage2DMultisample(void* self, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations) {
5385 GL2Encoder *ctx = (GL2Encoder*)self;
5386 GLClientState* state = ctx->m_state;
5387
5388 SET_ERROR_IF(target != GL_TEXTURE_2D_MULTISAMPLE, GL_INVALID_ENUM);
5389 SET_ERROR_IF(!GLESv2Validation::pixelInternalFormat(internalformat), GL_INVALID_ENUM);
5390 SET_ERROR_IF(!state->getBoundTexture(target), GL_INVALID_OPERATION);
5391 SET_ERROR_IF(width < 1 || height < 1, GL_INVALID_VALUE);
5392 SET_ERROR_IF(state->isBoundTextureImmutableFormat(target), GL_INVALID_OPERATION);
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08005393 GLint max_samples;
5394 ctx->s_glGetInternalformativ(ctx, target, internalformat, GL_SAMPLES, 1, &max_samples);
5395 SET_ERROR_IF(samples > max_samples, GL_INVALID_OPERATION);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005396
5397 state->setBoundTextureInternalFormat(target, internalformat);
5398 state->setBoundTextureDims(target, 0, width, height, 1);
5399 state->setBoundTextureImmutableFormat(target);
5400 state->setBoundTextureSamples(target, samples);
5401
5402 ctx->m_glTexStorage2DMultisample_enc(ctx, target, samples, internalformat, width, height, fixedsamplelocations);
5403}
5404
Yahan Zhou72944ba2019-01-02 15:43:46 -08005405GLenum GL2Encoder::s_glGetGraphicsResetStatusEXT(void* self) {
5406 (void)self;
5407 return GL_NO_ERROR;
5408}
5409
5410void GL2Encoder::s_glReadnPixelsEXT(void* self, GLint x, GLint y, GLsizei width,
5411 GLsizei height, GLenum format, GLenum type, GLsizei bufSize,
5412 GLvoid* pixels) {
5413 GL2Encoder *ctx = (GL2Encoder*)self;
5414 SET_ERROR_IF(bufSize < glesv2_enc::pixelDataSize(self, width, height, format,
5415 type, 1), GL_INVALID_OPERATION);
5416 s_glReadPixels(self, x, y, width, height, format, type, pixels);
5417}
5418
5419void GL2Encoder::s_glGetnUniformfvEXT(void *self, GLuint program, GLint location,
5420 GLsizei bufSize, GLfloat* params) {
5421 GL2Encoder *ctx = (GL2Encoder*)self;
5422 SET_ERROR_IF(bufSize < glSizeof(glesv2_enc::uniformType(self, program,
5423 location)), GL_INVALID_OPERATION);
5424 s_glGetUniformfv(self, program, location, params);
5425}
5426
5427void GL2Encoder::s_glGetnUniformivEXT(void *self, GLuint program, GLint location,
5428 GLsizei bufSize, GLint* params) {
5429 GL2Encoder *ctx = (GL2Encoder*)self;
5430 SET_ERROR_IF(bufSize < glSizeof(glesv2_enc::uniformType(self, program,
5431 location)), GL_INVALID_OPERATION);
5432 s_glGetUniformiv(self, program, location, params);
5433}