blob: 2a7ccdcf8a547fc157b7bb42cdb0af9f71948364 [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 }
1820 ctx->m_shared->setupLocationShiftWAR(program);
1821
1822 delete[] name;
1823}
1824
1825void GL2Encoder::s_glDeleteProgram(void *self, GLuint program)
1826{
1827 GL2Encoder *ctx = (GL2Encoder*)self;
1828 ctx->m_glDeleteProgram_enc(self, program);
1829
1830 ctx->m_shared->deleteProgramData(program);
1831}
1832
1833void GL2Encoder::s_glGetUniformiv(void *self, GLuint program, GLint location, GLint* params)
1834{
1835 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08001836 SET_ERROR_IF(!ctx->m_shared->isShaderOrProgramObject(program), GL_INVALID_VALUE);
Lingfeng Yang35b0fda2016-04-08 12:21:13 -07001837 SET_ERROR_IF(!ctx->m_shared->isProgram(program), GL_INVALID_OPERATION);
keunyoungb85b2752013-03-08 12:28:03 -08001838 SET_ERROR_IF(!ctx->m_shared->isProgramInitialized(program), GL_INVALID_OPERATION);
1839 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
1840 SET_ERROR_IF(ctx->m_shared->getProgramUniformType(program,hostLoc)==0, GL_INVALID_OPERATION);
1841 ctx->m_glGetUniformiv_enc(self, program, hostLoc, params);
1842}
1843void GL2Encoder::s_glGetUniformfv(void *self, GLuint program, GLint location, GLfloat* params)
1844{
1845 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08001846 SET_ERROR_IF(!ctx->m_shared->isShaderOrProgramObject(program), GL_INVALID_VALUE);
Lingfeng Yang35b0fda2016-04-08 12:21:13 -07001847 SET_ERROR_IF(!ctx->m_shared->isProgram(program), GL_INVALID_OPERATION);
keunyoungb85b2752013-03-08 12:28:03 -08001848 SET_ERROR_IF(!ctx->m_shared->isProgramInitialized(program), GL_INVALID_OPERATION);
1849 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program,location);
1850 SET_ERROR_IF(ctx->m_shared->getProgramUniformType(program,hostLoc)==0, GL_INVALID_OPERATION);
1851 ctx->m_glGetUniformfv_enc(self, program, hostLoc, params);
1852}
1853
1854GLuint GL2Encoder::s_glCreateProgram(void * self)
1855{
1856 GL2Encoder *ctx = (GL2Encoder*)self;
1857 GLuint program = ctx->m_glCreateProgram_enc(self);
1858 if (program!=0)
1859 ctx->m_shared->addProgramData(program);
1860 return program;
1861}
1862
1863GLuint GL2Encoder::s_glCreateShader(void *self, GLenum shaderType)
1864{
1865 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08001866 RET_AND_SET_ERROR_IF(!GLESv2Validation::shaderType(ctx, shaderType), GL_INVALID_ENUM, 0);
keunyoungb85b2752013-03-08 12:28:03 -08001867 GLuint shader = ctx->m_glCreateShader_enc(self, shaderType);
1868 if (shader != 0) {
1869 if (!ctx->m_shared->addShaderData(shader)) {
1870 ctx->m_glDeleteShader_enc(self, shader);
1871 return 0;
1872 }
1873 }
1874 return shader;
1875}
1876
bohu56bf82f2014-10-17 15:35:48 -07001877void GL2Encoder::s_glGetAttachedShaders(void *self, GLuint program, GLsizei maxCount,
1878 GLsizei* count, GLuint* shaders)
1879{
1880 GL2Encoder *ctx = (GL2Encoder*)self;
1881 SET_ERROR_IF(maxCount < 0, GL_INVALID_VALUE);
1882 ctx->m_glGetAttachedShaders_enc(self, program, maxCount, count, shaders);
1883}
1884
1885void GL2Encoder::s_glGetShaderSource(void *self, GLuint shader, GLsizei bufsize,
1886 GLsizei* length, GLchar* source)
1887{
1888 GL2Encoder *ctx = (GL2Encoder*)self;
1889 SET_ERROR_IF(bufsize < 0, GL_INVALID_VALUE);
1890 ctx->m_glGetShaderSource_enc(self, shader, bufsize, length, source);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08001891 ShaderData* shaderData = ctx->m_shared->getShaderData(shader);
1892 if (shaderData) {
1893 std::string returned;
1894 int curr_len = 0;
1895 for (int i = 0; i < shaderData->sources.size(); i++) {
1896 if (curr_len + shaderData->sources[i].size() < bufsize - 1) {
1897 returned += shaderData->sources[i];
1898 } else {
1899 returned += shaderData->sources[i].substr(0, bufsize - 1 - curr_len);
1900 break;
1901 }
1902 }
1903 memcpy(source, returned.substr(0, bufsize - 1).c_str(), bufsize);
1904 }
bohu56bf82f2014-10-17 15:35:48 -07001905}
1906
1907void GL2Encoder::s_glGetShaderInfoLog(void *self, GLuint shader, GLsizei bufsize,
1908 GLsizei* length, GLchar* infolog)
1909{
1910 GL2Encoder *ctx = (GL2Encoder*)self;
1911 SET_ERROR_IF(bufsize < 0, GL_INVALID_VALUE);
1912 ctx->m_glGetShaderInfoLog_enc(self, shader, bufsize, length, infolog);
1913}
1914
1915void GL2Encoder::s_glGetProgramInfoLog(void *self, GLuint program, GLsizei bufsize,
1916 GLsizei* length, GLchar* infolog)
1917{
1918 GL2Encoder *ctx = (GL2Encoder*)self;
1919 SET_ERROR_IF(bufsize < 0, GL_INVALID_VALUE);
1920 ctx->m_glGetProgramInfoLog_enc(self, program, bufsize, length, infolog);
1921}
1922
keunyoungb85b2752013-03-08 12:28:03 -08001923void GL2Encoder::s_glDeleteShader(void *self, GLenum shader)
1924{
1925 GL2Encoder *ctx = (GL2Encoder*)self;
1926 ctx->m_glDeleteShader_enc(self,shader);
1927 ctx->m_shared->unrefShaderData(shader);
1928}
1929
1930void GL2Encoder::s_glAttachShader(void *self, GLuint program, GLuint shader)
1931{
1932 GL2Encoder *ctx = (GL2Encoder*)self;
1933 ctx->m_glAttachShader_enc(self, program, shader);
1934 ctx->m_shared->attachShader(program, shader);
1935}
1936
1937void GL2Encoder::s_glDetachShader(void *self, GLuint program, GLuint shader)
1938{
1939 GL2Encoder *ctx = (GL2Encoder*)self;
1940 ctx->m_glDetachShader_enc(self, program, shader);
1941 ctx->m_shared->detachShader(program, shader);
1942}
1943
Lingfeng Yang46153ab2017-01-09 13:37:22 -08001944int sArrIndexOfUniformExpr(const char* name, int* err) {
1945 *err = 0;
1946 int arrIndex = 0;
1947 int namelen = strlen(name);
1948 if (name[namelen-1] == ']') {
1949 const char *brace = strrchr(name,'[');
1950 if (!brace || sscanf(brace+1,"%d",&arrIndex) != 1) {
1951 *err = 1; return 0;
1952 }
1953 }
1954 return arrIndex;
1955}
1956
keunyoungb85b2752013-03-08 12:28:03 -08001957int GL2Encoder::s_glGetUniformLocation(void *self, GLuint program, const GLchar *name)
1958{
1959 if (!name) return -1;
1960
1961 GL2Encoder *ctx = (GL2Encoder*)self;
1962
1963 // if we need the uniform location WAR
1964 // parse array index from the end of the name string
1965 int arrIndex = 0;
1966 bool needLocationWAR = ctx->m_shared->needUniformLocationWAR(program);
1967 if (needLocationWAR) {
Lingfeng Yang46153ab2017-01-09 13:37:22 -08001968 int err;
1969 arrIndex = sArrIndexOfUniformExpr(name, &err);
1970 if (err) return -1;
keunyoungb85b2752013-03-08 12:28:03 -08001971 }
1972
1973 int hostLoc = ctx->m_glGetUniformLocation_enc(self, program, name);
1974 if (hostLoc >= 0 && needLocationWAR) {
1975 return ctx->m_shared->locationWARHostToApp(program, hostLoc, arrIndex);
1976 }
1977 return hostLoc;
1978}
1979
1980bool GL2Encoder::updateHostTexture2DBinding(GLenum texUnit, GLenum newTarget)
1981{
1982 if (newTarget != GL_TEXTURE_2D && newTarget != GL_TEXTURE_EXTERNAL_OES)
1983 return false;
1984
1985 m_state->setActiveTextureUnit(texUnit);
1986
1987 GLenum oldTarget = m_state->getPriorityEnabledTarget(GL_TEXTURE_2D);
1988 if (newTarget != oldTarget) {
1989 if (newTarget == GL_TEXTURE_EXTERNAL_OES) {
1990 m_state->disableTextureTarget(GL_TEXTURE_2D);
1991 m_state->enableTextureTarget(GL_TEXTURE_EXTERNAL_OES);
1992 } else {
1993 m_state->disableTextureTarget(GL_TEXTURE_EXTERNAL_OES);
1994 m_state->enableTextureTarget(GL_TEXTURE_2D);
1995 }
1996 m_glActiveTexture_enc(this, texUnit);
1997 m_glBindTexture_enc(this, GL_TEXTURE_2D,
1998 m_state->getBoundTexture(newTarget));
1999 return true;
2000 }
2001
2002 return false;
2003}
2004
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002005void GL2Encoder::updateHostTexture2DBindingsFromProgramData(GLuint program) {
2006 GL2Encoder *ctx = this;
keunyoungb85b2752013-03-08 12:28:03 -08002007 GLClientState* state = ctx->m_state;
2008 GLSharedGroupPtr shared = ctx->m_shared;
2009
keunyoungb85b2752013-03-08 12:28:03 -08002010 GLenum origActiveTexture = state->getActiveTextureUnit();
2011 GLenum hostActiveTexture = origActiveTexture;
2012 GLint samplerIdx = -1;
2013 GLint samplerVal;
2014 GLenum samplerTarget;
2015 while ((samplerIdx = shared->getNextSamplerUniform(program, samplerIdx, &samplerVal, &samplerTarget)) != -1) {
2016 if (samplerVal < 0 || samplerVal >= GLClientState::MAX_TEXTURE_UNITS)
2017 continue;
2018 if (ctx->updateHostTexture2DBinding(GL_TEXTURE0 + samplerVal,
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002019 samplerTarget))
keunyoungb85b2752013-03-08 12:28:03 -08002020 {
2021 hostActiveTexture = GL_TEXTURE0 + samplerVal;
2022 }
2023 }
2024 state->setActiveTextureUnit(origActiveTexture);
2025 if (hostActiveTexture != origActiveTexture) {
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002026 ctx->m_glActiveTexture_enc(ctx, origActiveTexture);
keunyoungb85b2752013-03-08 12:28:03 -08002027 }
2028}
2029
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002030void GL2Encoder::s_glUseProgram(void *self, GLuint program)
2031{
2032 GL2Encoder *ctx = (GL2Encoder*)self;
2033 GLSharedGroupPtr shared = ctx->m_shared;
2034
2035 SET_ERROR_IF(program && !shared->isShaderOrProgramObject(program), GL_INVALID_VALUE);
2036 SET_ERROR_IF(program && !shared->isProgram(program), GL_INVALID_OPERATION);
2037
2038 ctx->m_glUseProgram_enc(self, program);
2039 ctx->m_state->setCurrentProgram(program);
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08002040 ctx->m_state->setCurrentShaderProgram(program);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002041
2042 ctx->updateHostTexture2DBindingsFromProgramData(program);
2043}
2044
keunyoungb85b2752013-03-08 12:28:03 -08002045void GL2Encoder::s_glUniform1f(void *self , GLint location, GLfloat x)
2046{
2047 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08002048 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
keunyoungb85b2752013-03-08 12:28:03 -08002049 ctx->m_glUniform1f_enc(self, hostLoc, x);
2050}
2051
2052void GL2Encoder::s_glUniform1fv(void *self , GLint location, GLsizei count, const GLfloat* v)
2053{
2054 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08002055 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
keunyoungb85b2752013-03-08 12:28:03 -08002056 ctx->m_glUniform1fv_enc(self, hostLoc, count, v);
2057}
2058
2059void GL2Encoder::s_glUniform1i(void *self , GLint location, GLint x)
2060{
2061 GL2Encoder *ctx = (GL2Encoder*)self;
2062 GLClientState* state = ctx->m_state;
2063 GLSharedGroupPtr shared = ctx->m_shared;
2064
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08002065 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
keunyoungb85b2752013-03-08 12:28:03 -08002066 ctx->m_glUniform1i_enc(self, hostLoc, x);
2067
2068 GLenum target;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08002069 if (shared->setSamplerUniform(state->currentShaderProgram(), location, x, &target)) {
keunyoungb85b2752013-03-08 12:28:03 -08002070 GLenum origActiveTexture = state->getActiveTextureUnit();
2071 if (ctx->updateHostTexture2DBinding(GL_TEXTURE0 + x, target)) {
2072 ctx->m_glActiveTexture_enc(self, origActiveTexture);
2073 }
2074 state->setActiveTextureUnit(origActiveTexture);
2075 }
2076}
2077
2078void GL2Encoder::s_glUniform1iv(void *self , GLint location, GLsizei count, const GLint* v)
2079{
2080 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08002081 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
keunyoungb85b2752013-03-08 12:28:03 -08002082 ctx->m_glUniform1iv_enc(self, hostLoc, count, v);
2083}
2084
2085void GL2Encoder::s_glUniform2f(void *self , GLint location, GLfloat x, GLfloat y)
2086{
2087 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08002088 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
keunyoungb85b2752013-03-08 12:28:03 -08002089 ctx->m_glUniform2f_enc(self, hostLoc, x, y);
2090}
2091
2092void GL2Encoder::s_glUniform2fv(void *self , GLint location, GLsizei count, const GLfloat* v)
2093{
2094 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08002095 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
keunyoungb85b2752013-03-08 12:28:03 -08002096 ctx->m_glUniform2fv_enc(self, hostLoc, count, v);
2097}
2098
2099void GL2Encoder::s_glUniform2i(void *self , GLint location, GLint x, GLint y)
2100{
2101 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08002102 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
keunyoungb85b2752013-03-08 12:28:03 -08002103 ctx->m_glUniform2i_enc(self, hostLoc, x, y);
2104}
2105
2106void GL2Encoder::s_glUniform2iv(void *self , GLint location, GLsizei count, const GLint* v)
2107{
2108 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08002109 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
keunyoungb85b2752013-03-08 12:28:03 -08002110 ctx->m_glUniform2iv_enc(self, hostLoc, count, v);
2111}
2112
2113void GL2Encoder::s_glUniform3f(void *self , GLint location, GLfloat x, GLfloat y, GLfloat z)
2114{
2115 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08002116 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
keunyoungb85b2752013-03-08 12:28:03 -08002117 ctx->m_glUniform3f_enc(self, hostLoc, x, y, z);
2118}
2119
2120void GL2Encoder::s_glUniform3fv(void *self , GLint location, GLsizei count, const GLfloat* v)
2121{
2122 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08002123 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
keunyoungb85b2752013-03-08 12:28:03 -08002124 ctx->m_glUniform3fv_enc(self, hostLoc, count, v);
2125}
2126
2127void GL2Encoder::s_glUniform3i(void *self , GLint location, GLint x, GLint y, GLint z)
2128{
2129 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08002130 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
keunyoungb85b2752013-03-08 12:28:03 -08002131 ctx->m_glUniform3i_enc(self, hostLoc, x, y, z);
2132}
2133
2134void GL2Encoder::s_glUniform3iv(void *self , GLint location, GLsizei count, const GLint* v)
2135{
2136 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08002137 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
keunyoungb85b2752013-03-08 12:28:03 -08002138 ctx->m_glUniform3iv_enc(self, hostLoc, count, v);
2139}
2140
2141void GL2Encoder::s_glUniform4f(void *self , GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
2142{
2143 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08002144 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
keunyoungb85b2752013-03-08 12:28:03 -08002145 ctx->m_glUniform4f_enc(self, hostLoc, x, y, z, w);
2146}
2147
2148void GL2Encoder::s_glUniform4fv(void *self , GLint location, GLsizei count, const GLfloat* v)
2149{
2150 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08002151 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
keunyoungb85b2752013-03-08 12:28:03 -08002152 ctx->m_glUniform4fv_enc(self, hostLoc, count, v);
2153}
2154
2155void GL2Encoder::s_glUniform4i(void *self , GLint location, GLint x, GLint y, GLint z, GLint w)
2156{
2157 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08002158 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
keunyoungb85b2752013-03-08 12:28:03 -08002159 ctx->m_glUniform4i_enc(self, hostLoc, x, y, z, w);
2160}
2161
2162void GL2Encoder::s_glUniform4iv(void *self , GLint location, GLsizei count, const GLint* v)
2163{
2164 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08002165 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
keunyoungb85b2752013-03-08 12:28:03 -08002166 ctx->m_glUniform4iv_enc(self, hostLoc, count, v);
2167}
2168
2169void GL2Encoder::s_glUniformMatrix2fv(void *self , GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
2170{
2171 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08002172 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
keunyoungb85b2752013-03-08 12:28:03 -08002173 ctx->m_glUniformMatrix2fv_enc(self, hostLoc, count, transpose, value);
2174}
2175
2176void GL2Encoder::s_glUniformMatrix3fv(void *self , GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
2177{
2178 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08002179 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
keunyoungb85b2752013-03-08 12:28:03 -08002180 ctx->m_glUniformMatrix3fv_enc(self, hostLoc, count, transpose, value);
2181}
2182
2183void GL2Encoder::s_glUniformMatrix4fv(void *self , GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
2184{
2185 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08002186 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
keunyoungb85b2752013-03-08 12:28:03 -08002187 ctx->m_glUniformMatrix4fv_enc(self, hostLoc, count, transpose, value);
2188}
2189
2190void GL2Encoder::s_glActiveTexture(void* self, GLenum texture)
2191{
2192 GL2Encoder* ctx = (GL2Encoder*)self;
2193 GLClientState* state = ctx->m_state;
2194 GLenum err;
2195
2196 SET_ERROR_IF((err = state->setActiveTextureUnit(texture)) != GL_NO_ERROR, err);
2197
2198 ctx->m_glActiveTexture_enc(ctx, texture);
2199}
2200
2201void GL2Encoder::s_glBindTexture(void* self, GLenum target, GLuint texture)
2202{
2203 GL2Encoder* ctx = (GL2Encoder*)self;
2204 GLClientState* state = ctx->m_state;
2205 GLenum err;
2206 GLboolean firstUse;
2207
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002208 SET_ERROR_IF(!GLESv2Validation::textureTarget(ctx, target), GL_INVALID_ENUM);
keunyoungb85b2752013-03-08 12:28:03 -08002209 SET_ERROR_IF((err = state->bindTexture(target, texture, &firstUse)) != GL_NO_ERROR, err);
2210
2211 if (target != GL_TEXTURE_2D && target != GL_TEXTURE_EXTERNAL_OES) {
2212 ctx->m_glBindTexture_enc(ctx, target, texture);
2213 return;
2214 }
2215
2216 GLenum priorityTarget = state->getPriorityEnabledTarget(GL_TEXTURE_2D);
2217
2218 if (target == GL_TEXTURE_EXTERNAL_OES && firstUse) {
2219 ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D, texture);
2220 ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D,
2221 GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2222 ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D,
2223 GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2224 ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D,
2225 GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2226
2227 if (target != priorityTarget) {
2228 ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D,
2229 state->getBoundTexture(GL_TEXTURE_2D));
2230 }
2231 }
2232
2233 if (target == priorityTarget) {
2234 ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D, texture);
2235 }
2236}
2237
2238void GL2Encoder::s_glDeleteTextures(void* self, GLsizei n, const GLuint* textures)
2239{
2240 GL2Encoder* ctx = (GL2Encoder*)self;
2241 GLClientState* state = ctx->m_state;
2242
2243 state->deleteTextures(n, textures);
2244 ctx->m_glDeleteTextures_enc(ctx, n, textures);
2245}
2246
2247void GL2Encoder::s_glGetTexParameterfv(void* self,
2248 GLenum target, GLenum pname, GLfloat* params)
2249{
2250 GL2Encoder* ctx = (GL2Encoder*)self;
keunyoungb85b2752013-03-08 12:28:03 -08002251
2252 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
2253 ctx->override2DTextureTarget(target);
2254 ctx->m_glGetTexParameterfv_enc(ctx, GL_TEXTURE_2D, pname, params);
Lingfeng Yangb5c03d52016-09-07 14:40:03 -07002255 ctx->restore2DTextureTarget(target);
keunyoungb85b2752013-03-08 12:28:03 -08002256 } else {
2257 ctx->m_glGetTexParameterfv_enc(ctx, target, pname, params);
2258 }
2259}
2260
2261void GL2Encoder::s_glGetTexParameteriv(void* self,
2262 GLenum target, GLenum pname, GLint* params)
2263{
2264 GL2Encoder* ctx = (GL2Encoder*)self;
keunyoungb85b2752013-03-08 12:28:03 -08002265
2266 switch (pname) {
2267 case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
2268 *params = 1;
2269 break;
2270
2271 default:
2272 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
2273 ctx->override2DTextureTarget(target);
2274 ctx->m_glGetTexParameteriv_enc(ctx, GL_TEXTURE_2D, pname, params);
Lingfeng Yangb5c03d52016-09-07 14:40:03 -07002275 ctx->restore2DTextureTarget(target);
keunyoungb85b2752013-03-08 12:28:03 -08002276 } else {
2277 ctx->m_glGetTexParameteriv_enc(ctx, target, pname, params);
2278 }
2279 break;
2280 }
2281}
2282
2283static bool isValidTextureExternalParam(GLenum pname, GLenum param)
2284{
2285 switch (pname) {
2286 case GL_TEXTURE_MIN_FILTER:
2287 case GL_TEXTURE_MAG_FILTER:
2288 return param == GL_NEAREST || param == GL_LINEAR;
2289
2290 case GL_TEXTURE_WRAP_S:
2291 case GL_TEXTURE_WRAP_T:
2292 return param == GL_CLAMP_TO_EDGE;
2293
2294 default:
2295 return true;
2296 }
2297}
2298
2299void GL2Encoder::s_glTexParameterf(void* self,
2300 GLenum target, GLenum pname, GLfloat param)
2301{
2302 GL2Encoder* ctx = (GL2Encoder*)self;
keunyoungb85b2752013-03-08 12:28:03 -08002303
2304 SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
2305 !isValidTextureExternalParam(pname, (GLenum)param)),
2306 GL_INVALID_ENUM);
2307
2308 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
2309 ctx->override2DTextureTarget(target);
2310 ctx->m_glTexParameterf_enc(ctx, GL_TEXTURE_2D, pname, param);
Lingfeng Yangb5c03d52016-09-07 14:40:03 -07002311 ctx->restore2DTextureTarget(target);
keunyoungb85b2752013-03-08 12:28:03 -08002312 } else {
2313 ctx->m_glTexParameterf_enc(ctx, target, pname, param);
2314 }
2315}
2316
2317void GL2Encoder::s_glTexParameterfv(void* self,
2318 GLenum target, GLenum pname, const GLfloat* params)
2319{
2320 GL2Encoder* ctx = (GL2Encoder*)self;
keunyoungb85b2752013-03-08 12:28:03 -08002321
2322 SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
2323 !isValidTextureExternalParam(pname, (GLenum)params[0])),
2324 GL_INVALID_ENUM);
2325
2326 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
2327 ctx->override2DTextureTarget(target);
2328 ctx->m_glTexParameterfv_enc(ctx, GL_TEXTURE_2D, pname, params);
Lingfeng Yangb5c03d52016-09-07 14:40:03 -07002329 ctx->restore2DTextureTarget(target);
keunyoungb85b2752013-03-08 12:28:03 -08002330 } else {
2331 ctx->m_glTexParameterfv_enc(ctx, target, pname, params);
2332 }
2333}
2334
2335void GL2Encoder::s_glTexParameteri(void* self,
2336 GLenum target, GLenum pname, GLint param)
2337{
2338 GL2Encoder* ctx = (GL2Encoder*)self;
keunyoungb85b2752013-03-08 12:28:03 -08002339
2340 SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
2341 !isValidTextureExternalParam(pname, (GLenum)param)),
2342 GL_INVALID_ENUM);
2343
2344 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
2345 ctx->override2DTextureTarget(target);
2346 ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D, pname, param);
Lingfeng Yangb5c03d52016-09-07 14:40:03 -07002347 ctx->restore2DTextureTarget(target);
keunyoungb85b2752013-03-08 12:28:03 -08002348 } else {
2349 ctx->m_glTexParameteri_enc(ctx, target, pname, param);
2350 }
2351}
2352
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002353static int ilog2(uint32_t x) {
2354 int p = 0;
2355 while ((1 << p) < x)
2356 p++;
2357 return p;
2358}
2359
bohu26a92982014-11-25 16:50:37 -08002360void GL2Encoder::s_glTexImage2D(void* self, GLenum target, GLint level,
2361 GLint internalformat, GLsizei width, GLsizei height, GLint border,
2362 GLenum format, GLenum type, const GLvoid* pixels)
2363{
2364 GL2Encoder* ctx = (GL2Encoder*)self;
Lingfeng Yang69066602016-04-12 09:29:11 -07002365 GLClientState* state = ctx->m_state;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002366
2367 SET_ERROR_IF(!GLESv2Validation::textureTarget(ctx, target), GL_INVALID_ENUM);
2368 SET_ERROR_IF(!GLESv2Validation::pixelType(ctx, type), GL_INVALID_ENUM);
2369 SET_ERROR_IF(!GLESv2Validation::pixelFormat(ctx, format), GL_INVALID_ENUM);
2370 // If unpack buffer is nonzero, verify unmapped state.
2371 SET_ERROR_IF(ctx->isBufferTargetMapped(GL_PIXEL_UNPACK_BUFFER), GL_INVALID_OPERATION);
2372
2373 GLint max_texture_size;
2374 GLint max_cube_map_texture_size;
2375 ctx->glGetIntegerv(ctx, GL_MAX_TEXTURE_SIZE, &max_texture_size);
2376 ctx->glGetIntegerv(ctx, GL_MAX_CUBE_MAP_TEXTURE_SIZE, &max_cube_map_texture_size);
2377 SET_ERROR_IF(level < 0, GL_INVALID_VALUE);
2378 SET_ERROR_IF(level > ilog2(max_texture_size), GL_INVALID_VALUE);
2379 SET_ERROR_IF((target == GL_TEXTURE_CUBE_MAP) &&
2380 (level > ilog2(max_cube_map_texture_size)), GL_INVALID_VALUE);
2381 SET_ERROR_IF(width < 0 || height < 0, GL_INVALID_VALUE);
2382 SET_ERROR_IF(width > max_texture_size, GL_INVALID_VALUE);
2383 SET_ERROR_IF(height > max_texture_size, GL_INVALID_VALUE);
2384 SET_ERROR_IF(GLESv2Validation::isCubeMapTarget(target) && width > max_cube_map_texture_size, GL_INVALID_VALUE);
2385 SET_ERROR_IF(GLESv2Validation::isCubeMapTarget(target) && height > max_cube_map_texture_size, GL_INVALID_VALUE);
2386 SET_ERROR_IF(border != 0, GL_INVALID_VALUE);
2387 // If unpack buffer is nonzero, verify buffer data fits and is evenly divisible by the type.
2388 SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
2389 ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
2390 (ctx->m_state->pboNeededDataSize(width, height, 1, format, type, 0) >
2391 ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size),
2392 GL_INVALID_OPERATION);
2393 SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
2394 ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
2395 (ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size %
2396 glSizeof(type)),
2397 GL_INVALID_OPERATION);
2398 SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
2399 ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
2400 ((uintptr_t)pixels % glSizeof(type)),
2401 GL_INVALID_OPERATION);
2402 SET_ERROR_IF(state->isBoundTextureImmutableFormat(target), GL_INVALID_OPERATION);
2403
2404 GLenum stateTarget = target;
2405 if (target == GL_TEXTURE_CUBE_MAP_POSITIVE_X ||
2406 target == GL_TEXTURE_CUBE_MAP_POSITIVE_Y ||
2407 target == GL_TEXTURE_CUBE_MAP_POSITIVE_Z ||
2408 target == GL_TEXTURE_CUBE_MAP_NEGATIVE_X ||
2409 target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y ||
2410 target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Z)
2411 stateTarget = GL_TEXTURE_CUBE_MAP;
2412
2413 state->setBoundTextureInternalFormat(stateTarget, internalformat);
2414 state->setBoundTextureFormat(stateTarget, format);
2415 state->setBoundTextureType(stateTarget, type);
2416 state->setBoundTextureDims(stateTarget, level, width, height, 1);
2417
bohu26a92982014-11-25 16:50:37 -08002418 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
2419 ctx->override2DTextureTarget(target);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002420 }
Lingfeng Yang69066602016-04-12 09:29:11 -07002421
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002422 if (ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER)) {
2423 ctx->glTexImage2DOffsetAEMU(
2424 ctx, target, level, internalformat,
2425 width, height, border,
2426 format, type, (uintptr_t)pixels);
bohu26a92982014-11-25 16:50:37 -08002427 } else {
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002428 ctx->m_glTexImage2D_enc(
2429 ctx, target, level, internalformat,
2430 width, height, border,
2431 format, type, pixels);
2432 }
2433
2434 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
2435 ctx->restore2DTextureTarget(target);
bohu26a92982014-11-25 16:50:37 -08002436 }
2437}
2438
Yahan Zhou2a208292016-06-22 15:36:04 -07002439void GL2Encoder::s_glTexSubImage2D(void* self, GLenum target, GLint level,
2440 GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format,
2441 GLenum type, const GLvoid* pixels)
2442{
2443 GL2Encoder* ctx = (GL2Encoder*)self;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002444 GLClientState* state = ctx->m_state;
Lingfeng Yang554a5152019-02-21 20:20:48 -08002445
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002446 SET_ERROR_IF(!GLESv2Validation::textureTarget(ctx, target), GL_INVALID_ENUM);
2447 SET_ERROR_IF(!GLESv2Validation::pixelType(ctx, type), GL_INVALID_ENUM);
2448 SET_ERROR_IF(!GLESv2Validation::pixelFormat(ctx, format), GL_INVALID_ENUM);
2449 // If unpack buffer is nonzero, verify unmapped state.
2450 SET_ERROR_IF(ctx->isBufferTargetMapped(GL_PIXEL_UNPACK_BUFFER), GL_INVALID_OPERATION);
2451
2452 GLint max_texture_size;
2453 GLint max_cube_map_texture_size;
2454 ctx->glGetIntegerv(ctx, GL_MAX_TEXTURE_SIZE, &max_texture_size);
2455 ctx->glGetIntegerv(ctx, GL_MAX_CUBE_MAP_TEXTURE_SIZE, &max_cube_map_texture_size);
2456 SET_ERROR_IF(level < 0, GL_INVALID_VALUE);
2457 SET_ERROR_IF(level > ilog2(max_texture_size), GL_INVALID_VALUE);
2458 SET_ERROR_IF(GLESv2Validation::isCubeMapTarget(target) &&
2459 level > ilog2(max_cube_map_texture_size), GL_INVALID_VALUE);
2460 SET_ERROR_IF(width < 0 || height < 0, GL_INVALID_VALUE);
2461 SET_ERROR_IF(xoffset < 0 || yoffset < 0, GL_INVALID_VALUE);
2462
2463 GLuint tex = state->getBoundTexture(target);
2464 GLsizei neededWidth = xoffset + width;
2465 GLsizei neededHeight = yoffset + height;
2466 GLsizei neededDepth = 1;
2467
2468 if (tex && !state->queryTexEGLImageBacked(tex)) {
2469 SET_ERROR_IF(
2470 (neededWidth > state->queryTexWidth(level, tex) ||
2471 neededHeight > state->queryTexHeight(level, tex) ||
2472 neededDepth > state->queryTexDepth(level, tex)),
2473 GL_INVALID_VALUE);
2474 }
2475
2476 // If unpack buffer is nonzero, verify buffer data fits and is evenly divisible by the type.
2477 SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
2478 ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
2479 (state->pboNeededDataSize(width, height, 1, format, type, 0) >
2480 ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size),
2481 GL_INVALID_OPERATION);
2482 SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
2483 ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
2484 (ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size %
2485 glSizeof(type)),
2486 GL_INVALID_OPERATION);
2487 SET_ERROR_IF(!ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) && !pixels, GL_INVALID_OPERATION);
Yahan Zhou2a208292016-06-22 15:36:04 -07002488
2489 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
2490 ctx->override2DTextureTarget(target);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002491 }
2492
2493 if (ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER)) {
2494 ctx->glTexSubImage2DOffsetAEMU(
2495 ctx, target, level,
2496 xoffset, yoffset, width, height,
2497 format, type, (uintptr_t)pixels);
Yahan Zhou2a208292016-06-22 15:36:04 -07002498 } else {
2499 ctx->m_glTexSubImage2D_enc(ctx, target, level, xoffset, yoffset, width,
2500 height, format, type, pixels);
2501 }
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002502
2503 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
2504 ctx->restore2DTextureTarget(target);
2505 }
Yahan Zhou2a208292016-06-22 15:36:04 -07002506}
bohu26a92982014-11-25 16:50:37 -08002507
Lingfeng Yange00ec9d2016-09-16 08:54:03 -07002508void GL2Encoder::s_glCopyTexImage2D(void* self, GLenum target, GLint level,
2509 GLenum internalformat, GLint x, GLint y,
2510 GLsizei width, GLsizei height, GLint border)
2511{
2512 GL2Encoder* ctx = (GL2Encoder*)self;
2513 GLClientState* state = ctx->m_state;
2514
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002515 SET_ERROR_IF(ctx->glCheckFramebufferStatus(ctx, GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE,
2516 GL_INVALID_FRAMEBUFFER_OPERATION);
Lingfeng Yange00ec9d2016-09-16 08:54:03 -07002517 // This is needed to work around underlying OpenGL drivers
2518 // (such as those feeding some some AMD GPUs) that expect
2519 // positive components of cube maps to be defined _before_
2520 // the negative components (otherwise a segfault occurs).
2521 GLenum extraTarget =
2522 state->copyTexImageLuminanceCubeMapAMDWorkaround
2523 (target, level, internalformat);
2524
2525 if (extraTarget) {
2526 ctx->m_glCopyTexImage2D_enc(ctx, extraTarget, level, internalformat,
2527 x, y, width, height, border);
2528 }
2529
2530 ctx->m_glCopyTexImage2D_enc(ctx, target, level, internalformat,
2531 x, y, width, height, border);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002532
2533 state->setBoundTextureInternalFormat(target, internalformat);
2534 state->setBoundTextureDims(target, level, width, height, 1);
Lingfeng Yange00ec9d2016-09-16 08:54:03 -07002535}
2536
keunyoungb85b2752013-03-08 12:28:03 -08002537void GL2Encoder::s_glTexParameteriv(void* self,
2538 GLenum target, GLenum pname, const GLint* params)
2539{
2540 GL2Encoder* ctx = (GL2Encoder*)self;
keunyoungb85b2752013-03-08 12:28:03 -08002541
2542 SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
2543 !isValidTextureExternalParam(pname, (GLenum)params[0])),
2544 GL_INVALID_ENUM);
2545
2546 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
2547 ctx->override2DTextureTarget(target);
2548 ctx->m_glTexParameteriv_enc(ctx, GL_TEXTURE_2D, pname, params);
Lingfeng Yangb5c03d52016-09-07 14:40:03 -07002549 ctx->restore2DTextureTarget(target);
keunyoungb85b2752013-03-08 12:28:03 -08002550 } else {
2551 ctx->m_glTexParameteriv_enc(ctx, target, pname, params);
2552 }
2553}
2554
Lingfeng Yangb5c03d52016-09-07 14:40:03 -07002555bool GL2Encoder::texture2DNeedsOverride(GLenum target) const {
2556 return (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) &&
2557 target != m_state->getPriorityEnabledTarget(GL_TEXTURE_2D);
2558}
2559
keunyoungb85b2752013-03-08 12:28:03 -08002560void GL2Encoder::override2DTextureTarget(GLenum target)
2561{
Lingfeng Yangb5c03d52016-09-07 14:40:03 -07002562 if (texture2DNeedsOverride(target)) {
2563 m_glBindTexture_enc(this, GL_TEXTURE_2D,
2564 m_state->getBoundTexture(target));
keunyoungb85b2752013-03-08 12:28:03 -08002565 }
2566}
2567
Lingfeng Yangb5c03d52016-09-07 14:40:03 -07002568void GL2Encoder::restore2DTextureTarget(GLenum target)
keunyoungb85b2752013-03-08 12:28:03 -08002569{
Lingfeng Yangb5c03d52016-09-07 14:40:03 -07002570 if (texture2DNeedsOverride(target)) {
Lingfeng Yang5bbf5292017-04-24 18:52:56 -07002571 GLuint priorityEnabledBoundTexture =
Lingfeng Yangb5c03d52016-09-07 14:40:03 -07002572 m_state->getBoundTexture(
Lingfeng Yang5bbf5292017-04-24 18:52:56 -07002573 m_state->getPriorityEnabledTarget(GL_TEXTURE_2D));
2574 GLuint texture2DBoundTexture =
2575 m_state->getBoundTexture(GL_TEXTURE_2D);
2576 if (!priorityEnabledBoundTexture) {
2577 m_glBindTexture_enc(this, GL_TEXTURE_2D, texture2DBoundTexture);
2578 } else {
2579 m_glBindTexture_enc(this, GL_TEXTURE_2D, priorityEnabledBoundTexture);
2580 }
Lingfeng Yangb5c03d52016-09-07 14:40:03 -07002581 }
keunyoungb85b2752013-03-08 12:28:03 -08002582}
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07002583
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002584void GL2Encoder::associateEGLImage(GLenum target, GLeglImageOES eglImage) {
2585 m_state->setBoundEGLImage(target, eglImage);
2586}
2587
2588
2589GLuint GL2Encoder::boundBuffer(GLenum target) const {
2590 return m_state->getBuffer(target);
2591}
2592
2593BufferData* GL2Encoder::getBufferData(GLenum target) const {
2594 GLuint bufferId = m_state->getBuffer(target);
2595 if (!bufferId) return NULL;
2596 return m_shared->getBufferData(bufferId);
2597}
2598
2599BufferData* GL2Encoder::getBufferDataById(GLuint bufferId) const {
2600 if (!bufferId) return NULL;
2601 return m_shared->getBufferData(bufferId);
2602}
2603
2604bool GL2Encoder::isBufferMapped(GLuint buffer) const {
2605 return m_shared->getBufferData(buffer)->m_mapped;
2606}
2607
2608bool GL2Encoder::isBufferTargetMapped(GLenum target) const {
2609 BufferData* buf = getBufferData(target);
2610 if (!buf) return false;
2611 return buf->m_mapped;
2612}
2613
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07002614void GL2Encoder::s_glGenRenderbuffers(void* self,
2615 GLsizei n, GLuint* renderbuffers) {
2616 GL2Encoder* ctx = (GL2Encoder*)self;
2617 GLClientState* state = ctx->m_state;
2618
2619 SET_ERROR_IF(n < 0, GL_INVALID_VALUE);
2620
2621 ctx->m_glGenFramebuffers_enc(self, n, renderbuffers);
2622 state->addRenderbuffers(n, renderbuffers);
2623}
2624
2625void GL2Encoder::s_glDeleteRenderbuffers(void* self,
2626 GLsizei n, const GLuint* renderbuffers) {
2627 GL2Encoder* ctx = (GL2Encoder*)self;
2628 GLClientState* state = ctx->m_state;
2629
2630 SET_ERROR_IF(n < 0, GL_INVALID_VALUE);
2631
2632 ctx->m_glDeleteRenderbuffers_enc(self, n, renderbuffers);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002633
2634 // Nope, lets just leak those for now.
2635 // The spec has an *amazingly* convoluted set of conditions for when
2636 // render buffers are actually deleted:
2637 // 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.
2638 //
2639 // 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***
2640 //
2641 // So, just detach this one from the bound FBO, and ignore the rest.
2642 for (int i = 0; i < n; i++) {
2643 state->detachRbo(renderbuffers[i]);
2644 }
2645 // state->removeRenderbuffers(n, renderbuffers);
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07002646}
2647
2648void GL2Encoder::s_glBindRenderbuffer(void* self,
2649 GLenum target, GLuint renderbuffer) {
2650 GL2Encoder* ctx = (GL2Encoder*)self;
2651 GLClientState* state = ctx->m_state;
2652
2653 SET_ERROR_IF((target != GL_RENDERBUFFER),
2654 GL_INVALID_ENUM);
2655
2656 ctx->m_glBindRenderbuffer_enc(self, target, renderbuffer);
2657 state->bindRenderbuffer(target, renderbuffer);
2658}
2659
Lingfeng Yang69066602016-04-12 09:29:11 -07002660void GL2Encoder::s_glRenderbufferStorage(void* self,
2661 GLenum target, GLenum internalformat,
2662 GLsizei width, GLsizei height) {
2663 GL2Encoder* ctx = (GL2Encoder*) self;
2664 GLClientState* state = ctx->m_state;
2665
2666 SET_ERROR_IF(target != GL_RENDERBUFFER, GL_INVALID_ENUM);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002667 SET_ERROR_IF(
2668 !GLESv2Validation::rboFormat(ctx, internalformat),
2669 GL_INVALID_ENUM);
Lingfeng Yang69066602016-04-12 09:29:11 -07002670
2671 state->setBoundRenderbufferFormat(internalformat);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002672 state->setBoundRenderbufferSamples(0);
2673
Lingfeng Yang69066602016-04-12 09:29:11 -07002674 ctx->m_glRenderbufferStorage_enc(self, target, internalformat,
2675 width, height);
2676}
2677
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07002678void GL2Encoder::s_glFramebufferRenderbuffer(void* self,
2679 GLenum target, GLenum attachment,
2680 GLenum renderbuffertarget, GLuint renderbuffer) {
2681 GL2Encoder* ctx = (GL2Encoder*)self;
2682 GLClientState* state = ctx->m_state;
2683
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002684 SET_ERROR_IF(!GLESv2Validation::framebufferTarget(ctx, target), GL_INVALID_ENUM);
2685 SET_ERROR_IF(!GLESv2Validation::framebufferAttachment(ctx, attachment), GL_INVALID_ENUM);
2686 state->attachRbo(target, attachment, renderbuffer);
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07002687
2688 ctx->m_glFramebufferRenderbuffer_enc(self, target, attachment, renderbuffertarget, renderbuffer);
2689}
2690
2691void GL2Encoder::s_glGenFramebuffers(void* self,
2692 GLsizei n, GLuint* framebuffers) {
2693 GL2Encoder* ctx = (GL2Encoder*)self;
2694 GLClientState* state = ctx->m_state;
2695
2696 SET_ERROR_IF(n < 0, GL_INVALID_VALUE);
2697
2698 ctx->m_glGenFramebuffers_enc(self, n, framebuffers);
2699 state->addFramebuffers(n, framebuffers);
2700}
2701
2702void GL2Encoder::s_glDeleteFramebuffers(void* self,
2703 GLsizei n, const GLuint* framebuffers) {
2704 GL2Encoder* ctx = (GL2Encoder*)self;
2705 GLClientState* state = ctx->m_state;
2706
2707 SET_ERROR_IF(n < 0, GL_INVALID_VALUE);
2708
2709 ctx->m_glDeleteFramebuffers_enc(self, n, framebuffers);
2710 state->removeFramebuffers(n, framebuffers);
2711}
2712
2713void GL2Encoder::s_glBindFramebuffer(void* self,
2714 GLenum target, GLuint framebuffer) {
2715 GL2Encoder* ctx = (GL2Encoder*)self;
2716 GLClientState* state = ctx->m_state;
2717
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002718 SET_ERROR_IF(!GLESv2Validation::framebufferTarget(ctx, target), GL_INVALID_ENUM);
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07002719
2720 state->bindFramebuffer(target, framebuffer);
2721
2722 ctx->m_glBindFramebuffer_enc(self, target, framebuffer);
2723}
2724
2725void GL2Encoder::s_glFramebufferTexture2D(void* self,
2726 GLenum target, GLenum attachment,
2727 GLenum textarget, GLuint texture, GLint level) {
2728 GL2Encoder* ctx = (GL2Encoder*)self;
2729 GLClientState* state = ctx->m_state;
2730
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002731 SET_ERROR_IF(!GLESv2Validation::framebufferTarget(ctx, target), GL_INVALID_ENUM);
2732 SET_ERROR_IF(!GLESv2Validation::framebufferAttachment(ctx, attachment), GL_INVALID_ENUM);
2733 state->attachTextureObject(target, attachment, texture);
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07002734
2735 ctx->m_glFramebufferTexture2D_enc(self, target, attachment, textarget, texture, level);
2736}
2737
2738void GL2Encoder::s_glFramebufferTexture3DOES(void* self,
2739 GLenum target, GLenum attachment,
2740 GLenum textarget, GLuint texture, GLint level, GLint zoffset) {
2741 GL2Encoder* ctx = (GL2Encoder*)self;
2742 GLClientState* state = ctx->m_state;
2743
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002744 state->attachTextureObject(target, attachment, texture);
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07002745
2746 ctx->m_glFramebufferTexture3DOES_enc(self, target, attachment, textarget, texture, level, zoffset);
2747}
2748
2749void GL2Encoder::s_glGetFramebufferAttachmentParameteriv(void* self,
2750 GLenum target, GLenum attachment, GLenum pname, GLint* params) {
2751 GL2Encoder* ctx = (GL2Encoder*)self;
2752 const GLClientState* state = ctx->m_state;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002753 SET_ERROR_IF(!GLESv2Validation::framebufferTarget(ctx, target), GL_INVALID_ENUM);
2754 SET_ERROR_IF(pname != GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME &&
2755 pname != GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE &&
2756 !state->attachmentHasObject(target, attachment),
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07002757 GL_INVALID_OPERATION);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002758 SET_ERROR_IF((pname == GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL ||
2759 pname == GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE ||
2760 pname == GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER) &&
2761 (!state->attachmentHasObject(target, attachment) ||
2762 state->getBoundFramebufferAttachmentType(target, attachment) !=
2763 FBO_ATTACHMENT_TEXTURE),
2764 !state->attachmentHasObject(target, attachment) ?
2765 GL_INVALID_OPERATION : GL_INVALID_ENUM);
2766 SET_ERROR_IF(attachment == GL_DEPTH_STENCIL_ATTACHMENT &&
2767 pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME &&
2768 (state->objectOfAttachment(target, GL_DEPTH_ATTACHMENT) !=
2769 state->objectOfAttachment(target, GL_STENCIL_ATTACHMENT)),
2770 GL_INVALID_OPERATION);
2771 SET_ERROR_IF(state->boundFramebuffer(target) &&
2772 (attachment == GL_BACK ||
2773 attachment == GL_FRONT),
2774 GL_INVALID_OPERATION);
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07002775 ctx->m_glGetFramebufferAttachmentParameteriv_enc(self, target, attachment, pname, params);
2776}
Lingfeng Yang69066602016-04-12 09:29:11 -07002777
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002778bool GL2Encoder::isCompleteFbo(GLenum target, const GLClientState* state,
Lingfeng Yang69066602016-04-12 09:29:11 -07002779 GLenum attachment) const {
2780 FboFormatInfo fbo_format_info;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002781 state->getBoundFramebufferFormat(target, attachment, &fbo_format_info);
Lingfeng Yang69066602016-04-12 09:29:11 -07002782
2783 bool res;
2784 switch (fbo_format_info.type) {
2785 case FBO_ATTACHMENT_RENDERBUFFER:
2786 switch (fbo_format_info.rb_format) {
2787 case GL_R16F:
2788 case GL_RG16F:
Lingfeng Yang69066602016-04-12 09:29:11 -07002789 case GL_RGBA16F:
Lingfeng Yang931817b2017-01-27 06:50:56 -08002790 case GL_R32F:
2791 case GL_RG32F:
2792 case GL_RGBA32F:
2793 case GL_R11F_G11F_B10F:
Lingfeng Yangc92685e2017-01-30 20:06:39 -08002794 res = majorVersion() >= 3 && hasExtension("GL_EXT_color_buffer_float");
Lingfeng Yang931817b2017-01-27 06:50:56 -08002795 break;
2796 case GL_RGB16F:
Lingfeng Yangc92685e2017-01-30 20:06:39 -08002797 res = majorVersion() >= 3 && hasExtension("GL_EXT_color_buffer_half_float");
Lingfeng Yang69066602016-04-12 09:29:11 -07002798 break;
2799 case GL_STENCIL_INDEX8:
2800 if (attachment == GL_STENCIL_ATTACHMENT) {
2801 res = true;
2802 } else {
2803 res = false;
2804 }
2805 break;
2806 default:
2807 res = true;
2808 }
2809 break;
2810 case FBO_ATTACHMENT_TEXTURE:
Yahan Zhou68bfd8c2016-05-11 15:06:34 -07002811 switch (fbo_format_info.tex_internalformat) {
Yahan Zhou68bfd8c2016-05-11 15:06:34 -07002812 case GL_R16F:
2813 case GL_RG16F:
2814 case GL_RGBA16F:
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002815 case GL_R32F:
2816 case GL_RG32F:
2817 case GL_RGBA32F:
Lingfeng Yang931817b2017-01-27 06:50:56 -08002818 case GL_R11F_G11F_B10F:
Lingfeng Yangc92685e2017-01-30 20:06:39 -08002819 res = majorVersion() >= 3 && hasExtension("GL_EXT_color_buffer_float");
Lingfeng Yang931817b2017-01-27 06:50:56 -08002820 break;
2821 case GL_RGB16F:
Lingfeng Yangc92685e2017-01-30 20:06:39 -08002822 res = majorVersion() >= 3 && hasExtension("GL_EXT_color_buffer_half_float");
Lingfeng Yang931817b2017-01-27 06:50:56 -08002823 break;
2824 case GL_RED:
2825 case GL_RG:
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002826 case GL_SRGB8:
2827 case GL_RGB32UI:
2828 case GL_RGB16UI:
2829 case GL_RGB8UI:
2830 case GL_RGB32I:
2831 case GL_RGB16I:
2832 case GL_RGB8I:
2833 case GL_R8_SNORM:
2834 case GL_RG8_SNORM:
2835 case GL_RGB8_SNORM:
2836 case GL_RGBA8_SNORM:
Yahan Zhou68bfd8c2016-05-11 15:06:34 -07002837 res = false;
2838 break;
Lingfeng Yang69066602016-04-12 09:29:11 -07002839 // No float/half-float formats allowed for RGB(A)
Yahan Zhou68bfd8c2016-05-11 15:06:34 -07002840 case GL_RGB:
2841 case GL_RGBA:
Lingfeng Yang69066602016-04-12 09:29:11 -07002842 switch (fbo_format_info.tex_type) {
2843 case GL_FLOAT:
2844 case GL_HALF_FLOAT_OES:
Yahan Zhou68bfd8c2016-05-11 15:06:34 -07002845 case GL_UNSIGNED_INT_10F_11F_11F_REV:
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002846 case GL_UNSIGNED_INT_2_10_10_10_REV:
Lingfeng Yang69066602016-04-12 09:29:11 -07002847 res = false;
2848 break;
2849 default:
2850 res = true;
2851 }
Yahan Zhou68bfd8c2016-05-11 15:06:34 -07002852 break;
2853 default:
Lingfeng Yang69066602016-04-12 09:29:11 -07002854 res = true;
2855 }
2856 break;
2857 case FBO_ATTACHMENT_NONE:
2858 res = true;
2859 break;
2860 default:
2861 res = true;
2862 }
2863 return res;
2864}
2865
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002866bool GL2Encoder::checkFramebufferCompleteness(GLenum target, const GLClientState* state) const {
2867 bool res = true;
2868
2869 for (int i = 0; i < state->getMaxColorAttachments(); i++) {
2870 res = res && isCompleteFbo(target, state, glUtilsColorAttachmentName(i));
2871 }
2872
2873 res = res && isCompleteFbo(target, state, GL_DEPTH_ATTACHMENT);
2874 res = res && isCompleteFbo(target, state, GL_STENCIL_ATTACHMENT);
2875
2876 return res;
2877}
2878
Lingfeng Yang69066602016-04-12 09:29:11 -07002879GLenum GL2Encoder::s_glCheckFramebufferStatus(void* self, GLenum target) {
2880 GL2Encoder* ctx = (GL2Encoder*)self;
2881 GLClientState* state = ctx->m_state;
2882
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002883 bool fboCompleteByCodec =
2884 ctx->checkFramebufferCompleteness(target, state);
2885
2886 if (!fboCompleteByCodec) {
2887 state->setCheckFramebufferStatus(target, GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT);
Lingfeng Yang69066602016-04-12 09:29:11 -07002888 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
2889 } else {
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002890 // double check with underlying opengl to avoid craziness.
Lingfeng Yang69066602016-04-12 09:29:11 -07002891 GLenum host_checkstatus = ctx->m_glCheckFramebufferStatus_enc(self, target);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002892 state->setCheckFramebufferStatus(target, host_checkstatus);
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08002893 if (host_checkstatus == GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS) return GL_FRAMEBUFFER_COMPLETE;
Lingfeng Yang69066602016-04-12 09:29:11 -07002894 return host_checkstatus;
2895 }
2896}
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002897
2898void GL2Encoder::s_glGenVertexArrays(void* self, GLsizei n, GLuint* arrays) {
2899 GL2Encoder* ctx = (GL2Encoder*)self;
2900 GLClientState* state = ctx->m_state;
2901 SET_ERROR_IF(n < 0, GL_INVALID_VALUE);
2902
2903 ctx->m_glGenVertexArrays_enc(self, n, arrays);
2904 for (int i = 0; i < n; i++) {
2905 ALOGV("%s: gen vao %u", __FUNCTION__, arrays[i]);
2906 }
2907 state->addVertexArrayObjects(n, arrays);
2908}
2909
2910void GL2Encoder::s_glDeleteVertexArrays(void* self, GLsizei n, const GLuint* arrays) {
2911 GL2Encoder* ctx = (GL2Encoder*)self;
2912 GLClientState* state = ctx->m_state;
2913 SET_ERROR_IF(n < 0, GL_INVALID_VALUE);
2914
2915 ctx->m_glDeleteVertexArrays_enc(self, n, arrays);
2916 for (int i = 0; i < n; i++) {
2917 ALOGV("%s: delete vao %u", __FUNCTION__, arrays[i]);
2918 }
2919 state->removeVertexArrayObjects(n, arrays);
2920}
2921
2922void GL2Encoder::s_glBindVertexArray(void* self, GLuint array) {
2923 ALOGV("%s: call. array=%u\n", __FUNCTION__, array);
2924 GL2Encoder* ctx = (GL2Encoder*)self;
2925 GLClientState* state = ctx->m_state;
2926 SET_ERROR_IF(!state->isVertexArrayObject(array), GL_INVALID_OPERATION);
2927 ctx->m_glBindVertexArray_enc(self, array);
2928 state->setVertexArrayObject(array);
2929}
2930
Lingfeng Yangfb3d2bb2017-09-07 15:02:04 -07002931void* GL2Encoder::s_glMapBufferOES(void* self, GLenum target, GLenum access) {
2932 GL2Encoder* ctx = (GL2Encoder*)self;
2933
2934 RET_AND_SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM, NULL);
2935
2936 GLuint boundBuffer = ctx->m_state->getBuffer(target);
2937
2938 RET_AND_SET_ERROR_IF(boundBuffer == 0, GL_INVALID_OPERATION, NULL);
2939
2940 BufferData* buf = ctx->m_shared->getBufferData(boundBuffer);
2941 RET_AND_SET_ERROR_IF(!buf, GL_INVALID_VALUE, NULL);
2942
2943 return ctx->glMapBufferRange(ctx, target, 0, buf->m_size, access);
2944}
2945
2946GLboolean GL2Encoder::s_glUnmapBufferOES(void* self, GLenum target) {
2947 GL2Encoder* ctx = (GL2Encoder*)self;
2948
2949 return ctx->glUnmapBuffer(ctx, target);
2950}
2951
Roman Kiryanovbe1c0c22018-10-02 18:07:14 -07002952void* GL2Encoder::s_glMapBufferRangeAEMUImpl(GL2Encoder* ctx, GLenum target,
2953 GLintptr offset, GLsizeiptr length,
2954 GLbitfield access, BufferData* buf) {
2955 char* bits = (char*)buf->m_fixedBuffer.ptr() + offset;
2956
Lingfeng Yang22e361a2019-10-12 07:19:00 -07002957 if ((access & GL_MAP_READ_BIT) ||
2958 ((access & GL_MAP_WRITE_BIT) &&
2959 (!(access & GL_MAP_INVALIDATE_RANGE_BIT) &&
2960 !(access & GL_MAP_INVALIDATE_BUFFER_BIT)))) {
2961 ctx->glMapBufferRangeAEMU(
2962 ctx, target,
2963 offset, length,
2964 access,
2965 bits);
2966 }
Roman Kiryanovbe1c0c22018-10-02 18:07:14 -07002967
2968 return bits;
2969}
2970
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002971void* GL2Encoder::s_glMapBufferRange(void* self, GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access) {
2972 GL2Encoder* ctx = (GL2Encoder*)self;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002973
2974 // begin validation (lots)
Lingfeng Yang554a5152019-02-21 20:20:48 -08002975
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002976 RET_AND_SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM, NULL);
2977
2978 GLuint boundBuffer = ctx->m_state->getBuffer(target);
2979
2980 RET_AND_SET_ERROR_IF(boundBuffer == 0, GL_INVALID_OPERATION, NULL);
2981
2982 BufferData* buf = ctx->m_shared->getBufferData(boundBuffer);
2983 RET_AND_SET_ERROR_IF(!buf, GL_INVALID_VALUE, NULL);
2984
2985 GLsizeiptr bufferDataSize = buf->m_size;
2986
2987 RET_AND_SET_ERROR_IF(offset < 0, GL_INVALID_VALUE, NULL);
2988 RET_AND_SET_ERROR_IF(length < 0, GL_INVALID_VALUE, NULL);
2989 RET_AND_SET_ERROR_IF(offset + length > bufferDataSize, GL_INVALID_VALUE, NULL);
2990 RET_AND_SET_ERROR_IF(access & ~GLESv2Validation::allBufferMapAccessFlags, GL_INVALID_VALUE, NULL);
2991
2992 RET_AND_SET_ERROR_IF(buf->m_mapped, GL_INVALID_OPERATION, NULL);
2993 RET_AND_SET_ERROR_IF(!(access & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)), GL_INVALID_OPERATION, NULL);
2994 RET_AND_SET_ERROR_IF(
2995 (access & GL_MAP_READ_BIT) &&
2996 ((access & GL_MAP_INVALIDATE_RANGE_BIT) ||
2997 (access & GL_MAP_INVALIDATE_BUFFER_BIT) ||
2998 (access & GL_MAP_UNSYNCHRONIZED_BIT) ||
2999 (access & GL_MAP_FLUSH_EXPLICIT_BIT)), GL_INVALID_OPERATION, NULL);
3000
3001 // end validation; actually do stuff now
Lingfeng Yang554a5152019-02-21 20:20:48 -08003002
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003003 buf->m_mapped = true;
3004 buf->m_mappedAccess = access;
3005 buf->m_mappedOffset = offset;
3006 buf->m_mappedLength = length;
3007
Roman Kiryanovbe1c0c22018-10-02 18:07:14 -07003008 if (ctx->hasExtension("ANDROID_EMU_dma_v2")) {
3009 if (buf->dma_buffer.get().size < length) {
3010 goldfish_dma_context region;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003011
Roman Kiryanovbe1c0c22018-10-02 18:07:14 -07003012 const int PAGE_BITS = 12;
3013 GLsizeiptr aligned_length = (length + (1 << PAGE_BITS) - 1) & ~((1 << PAGE_BITS) - 1);
3014
3015 if (goldfish_dma_create_region(aligned_length, &region)) {
3016 buf->dma_buffer.reset(NULL);
3017 return s_glMapBufferRangeAEMUImpl(ctx, target, offset, length, access, buf);
3018 }
3019
3020 if (!goldfish_dma_map(&region)) {
3021 buf->dma_buffer.reset(NULL);
3022 return s_glMapBufferRangeAEMUImpl(ctx, target, offset, length, access, buf);
3023 }
3024
3025 buf->m_guest_paddr = goldfish_dma_guest_paddr(&region);
3026 buf->dma_buffer.reset(&region);
3027 }
3028
3029 ctx->glMapBufferRangeDMA(
3030 ctx, target,
3031 offset, length,
3032 access,
3033 buf->m_guest_paddr);
3034
3035 return reinterpret_cast<void*>(buf->dma_buffer.get().mapped_addr);
3036 } else {
3037 return s_glMapBufferRangeAEMUImpl(ctx, target, offset, length, access, buf);
3038 }
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003039}
3040
3041GLboolean GL2Encoder::s_glUnmapBuffer(void* self, GLenum target) {
3042 GL2Encoder* ctx = (GL2Encoder*)self;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003043
3044 RET_AND_SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM, GL_FALSE);
3045
3046 GLuint boundBuffer = ctx->m_state->getBuffer(target);
3047
3048 RET_AND_SET_ERROR_IF(boundBuffer == 0, GL_INVALID_OPERATION, GL_FALSE);
3049
3050 BufferData* buf = ctx->m_shared->getBufferData(boundBuffer);
3051 RET_AND_SET_ERROR_IF(!buf, GL_INVALID_VALUE, GL_FALSE);
3052 RET_AND_SET_ERROR_IF(!buf->m_mapped, GL_INVALID_OPERATION, GL_FALSE);
3053
Lingfeng Yang423129e2017-01-18 09:23:12 -08003054 if (buf->m_mappedAccess & GL_MAP_WRITE_BIT) {
3055 // invalide index range cache here
3056 if (buf->m_mappedAccess & GL_MAP_INVALIDATE_BUFFER_BIT) {
3057 buf->m_indexRangeCache.invalidateRange(0, buf->m_size);
3058 } else {
3059 buf->m_indexRangeCache.invalidateRange(buf->m_mappedOffset, buf->m_mappedLength);
3060 }
3061 }
3062
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003063 GLboolean host_res = GL_TRUE;
3064
Roman Kiryanovbe1c0c22018-10-02 18:07:14 -07003065 if (buf->dma_buffer.get().mapped_addr) {
3066 memcpy(static_cast<char*>(buf->m_fixedBuffer.ptr()) + buf->m_mappedOffset,
3067 reinterpret_cast<void*>(buf->dma_buffer.get().mapped_addr),
3068 buf->m_mappedLength);
3069
3070 ctx->glUnmapBufferDMA(
Roman Kiryanovdaecd142018-11-14 14:56:27 -08003071 ctx, target,
3072 buf->m_mappedOffset,
3073 buf->m_mappedLength,
3074 buf->m_mappedAccess,
3075 goldfish_dma_guest_paddr(&buf->dma_buffer.get()),
3076 &host_res);
Roman Kiryanovbe1c0c22018-10-02 18:07:14 -07003077 } else {
Lingfeng Yang22e361a2019-10-12 07:19:00 -07003078 if (ctx->m_hasAsyncUnmapBuffer) {
3079 ctx->glUnmapBufferAsyncAEMU(
3080 ctx, target,
3081 buf->m_mappedOffset,
3082 buf->m_mappedLength,
3083 buf->m_mappedAccess,
3084 (void*)((char*)buf->m_fixedBuffer.ptr() + buf->m_mappedOffset),
3085 &host_res);
3086 } else {
3087 if (buf->m_mappedAccess & GL_MAP_WRITE_BIT) {
3088 ctx->glUnmapBufferAEMU(
3089 ctx, target,
3090 buf->m_mappedOffset,
3091 buf->m_mappedLength,
3092 buf->m_mappedAccess,
3093 (void*)((char*)buf->m_fixedBuffer.ptr() + buf->m_mappedOffset),
3094 &host_res);
3095 }
3096 }
Roman Kiryanovbe1c0c22018-10-02 18:07:14 -07003097 }
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003098
3099 buf->m_mapped = false;
3100 buf->m_mappedAccess = 0;
3101 buf->m_mappedOffset = 0;
3102 buf->m_mappedLength = 0;
3103
3104 return host_res;
3105}
3106
3107void GL2Encoder::s_glFlushMappedBufferRange(void* self, GLenum target, GLintptr offset, GLsizeiptr length) {
3108 GL2Encoder* ctx = (GL2Encoder*)self;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003109
3110 SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM);
3111
3112 GLuint boundBuffer = ctx->m_state->getBuffer(target);
3113 SET_ERROR_IF(!boundBuffer, GL_INVALID_OPERATION);
3114
3115 BufferData* buf = ctx->m_shared->getBufferData(boundBuffer);
3116 SET_ERROR_IF(!buf, GL_INVALID_VALUE);
3117 SET_ERROR_IF(!buf->m_mapped, GL_INVALID_OPERATION);
3118 SET_ERROR_IF(!(buf->m_mappedAccess & GL_MAP_FLUSH_EXPLICIT_BIT), GL_INVALID_OPERATION);
3119
3120 SET_ERROR_IF(offset < 0, GL_INVALID_VALUE);
3121 SET_ERROR_IF(length < 0, GL_INVALID_VALUE);
3122 SET_ERROR_IF(offset + length > buf->m_mappedLength, GL_INVALID_VALUE);
3123
3124 GLintptr totalOffset = buf->m_mappedOffset + offset;
Lingfeng Yang423129e2017-01-18 09:23:12 -08003125
3126 buf->m_indexRangeCache.invalidateRange(totalOffset, length);
3127
Lingfeng Yang22e361a2019-10-12 07:19:00 -07003128 if (ctx->m_hasAsyncUnmapBuffer) {
3129 ctx->glFlushMappedBufferRangeAEMU2(
3130 ctx, target,
3131 totalOffset,
3132 length,
3133 buf->m_mappedAccess,
3134 (void*)((char*)buf->m_fixedBuffer.ptr() + totalOffset));
3135 } else {
3136 ctx->glFlushMappedBufferRangeAEMU(
3137 ctx, target,
3138 totalOffset,
3139 length,
3140 buf->m_mappedAccess,
3141 (void*)((char*)buf->m_fixedBuffer.ptr() + totalOffset));
3142 }
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003143}
3144
3145void GL2Encoder::s_glCompressedTexImage2D(void* self, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* data) {
3146 GL2Encoder* ctx = (GL2Encoder*)self;
3147 GLClientState* state = ctx->m_state;
3148
3149 SET_ERROR_IF(!GLESv2Validation::textureTarget(ctx, target), GL_INVALID_ENUM);
3150 // Filter compressed formats support.
3151 SET_ERROR_IF(!GLESv2Validation::supportedCompressedFormat(ctx, internalformat), GL_INVALID_ENUM);
3152 // Verify level <= log2(GL_MAX_TEXTURE_SIZE).
3153 GLint max_texture_size;
3154 GLint max_cube_map_texture_size;
3155 ctx->glGetIntegerv(ctx, GL_MAX_TEXTURE_SIZE, &max_texture_size);
3156 ctx->glGetIntegerv(ctx, GL_MAX_CUBE_MAP_TEXTURE_SIZE, &max_cube_map_texture_size);
3157 SET_ERROR_IF(level < 0, GL_INVALID_VALUE);
3158 SET_ERROR_IF(level > ilog2(max_texture_size), GL_INVALID_VALUE);
3159 SET_ERROR_IF(level > ilog2(max_cube_map_texture_size), GL_INVALID_VALUE);
3160 SET_ERROR_IF(width > max_texture_size, GL_INVALID_VALUE);
3161 SET_ERROR_IF(height > max_texture_size, GL_INVALID_VALUE);
3162 SET_ERROR_IF(border, GL_INVALID_VALUE);
3163 // If unpack buffer is nonzero, verify unmapped state.
3164 SET_ERROR_IF(ctx->isBufferTargetMapped(GL_PIXEL_UNPACK_BUFFER), GL_INVALID_OPERATION);
3165 SET_ERROR_IF(width < 0 || height < 0, GL_INVALID_VALUE);
3166 // If unpack buffer is nonzero, verify buffer data fits.
3167 SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
3168 ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
3169 (imageSize > ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size),
3170 GL_INVALID_OPERATION);
3171 // TODO: Fix:
3172 // If |imageSize| is inconsistent with compressed dimensions.
3173 // SET_ERROR_IF(GLESv2Validation::compressedTexImageSize(internalformat, width, height, 1) != imageSize, GL_INVALID_VALUE);
3174
3175 GLenum stateTarget = target;
3176 if (target == GL_TEXTURE_CUBE_MAP_POSITIVE_X ||
3177 target == GL_TEXTURE_CUBE_MAP_POSITIVE_Y ||
3178 target == GL_TEXTURE_CUBE_MAP_POSITIVE_Z ||
3179 target == GL_TEXTURE_CUBE_MAP_NEGATIVE_X ||
3180 target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y ||
3181 target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Z)
3182 stateTarget = GL_TEXTURE_CUBE_MAP;
3183 state->setBoundTextureInternalFormat(stateTarget, (GLint)internalformat);
3184 state->setBoundTextureDims(stateTarget, level, width, height, 1);
3185
Lingfeng Yanga9fff6a2018-03-02 13:42:51 -08003186 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
3187 ctx->override2DTextureTarget(target);
3188 }
3189
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003190 if (ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER)) {
3191 ctx->glCompressedTexImage2DOffsetAEMU(
3192 ctx, target, level, internalformat,
3193 width, height, border,
3194 imageSize, (uintptr_t)data);
3195 } else {
3196 ctx->m_glCompressedTexImage2D_enc(
3197 ctx, target, level, internalformat,
3198 width, height, border,
3199 imageSize, data);
3200 }
Lingfeng Yanga9fff6a2018-03-02 13:42:51 -08003201
3202 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
3203 ctx->restore2DTextureTarget(target);
3204 }
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003205}
3206
3207void GL2Encoder::s_glCompressedTexSubImage2D(void* self, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* data) {
3208 GL2Encoder* ctx = (GL2Encoder*)self;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003209
3210 SET_ERROR_IF(!GLESv2Validation::textureTarget(ctx, target), GL_INVALID_ENUM);
3211 // If unpack buffer is nonzero, verify unmapped state.
3212 SET_ERROR_IF(ctx->isBufferTargetMapped(GL_PIXEL_UNPACK_BUFFER), GL_INVALID_OPERATION);
3213 GLint max_texture_size;
3214 GLint max_cube_map_texture_size;
3215 ctx->glGetIntegerv(ctx, GL_MAX_TEXTURE_SIZE, &max_texture_size);
3216 ctx->glGetIntegerv(ctx, GL_MAX_CUBE_MAP_TEXTURE_SIZE, &max_cube_map_texture_size);
3217 SET_ERROR_IF(level < 0, GL_INVALID_VALUE);
3218 SET_ERROR_IF(level > ilog2(max_texture_size), GL_INVALID_VALUE);
3219 SET_ERROR_IF(level > ilog2(max_cube_map_texture_size), GL_INVALID_VALUE);
3220 SET_ERROR_IF(width < 0 || height < 0, GL_INVALID_VALUE);
3221 // If unpack buffer is nonzero, verify buffer data fits.
3222 SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
3223 ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
3224 (imageSize > ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size),
3225 GL_INVALID_OPERATION);
3226 SET_ERROR_IF(xoffset < 0 || yoffset < 0, GL_INVALID_VALUE);
3227
Lingfeng Yanga9fff6a2018-03-02 13:42:51 -08003228 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
3229 ctx->override2DTextureTarget(target);
3230 }
3231
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003232 if (ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER)) {
3233 ctx->glCompressedTexSubImage2DOffsetAEMU(
3234 ctx, target, level,
3235 xoffset, yoffset,
3236 width, height, format,
3237 imageSize, (uintptr_t)data);
3238 } else {
3239 ctx->m_glCompressedTexSubImage2D_enc(
3240 ctx, target, level,
3241 xoffset, yoffset,
3242 width, height, format,
3243 imageSize, data);
3244 }
Lingfeng Yanga9fff6a2018-03-02 13:42:51 -08003245
3246 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
3247 ctx->restore2DTextureTarget(target);
3248 }
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003249}
3250
3251void GL2Encoder::s_glBindBufferRange(void* self, GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size) {
3252 GL2Encoder* ctx = (GL2Encoder*)self;
3253 GLClientState* state = ctx->m_state;
3254
3255 SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM);
3256
3257 // Only works with certain targets
3258 SET_ERROR_IF(
3259 !(target == GL_ATOMIC_COUNTER_BUFFER ||
3260 target == GL_SHADER_STORAGE_BUFFER ||
3261 target == GL_TRANSFORM_FEEDBACK_BUFFER ||
3262 target == GL_UNIFORM_BUFFER),
3263 GL_INVALID_ENUM);
3264
3265 // Can't exceed range
3266 SET_ERROR_IF(index < 0 ||
3267 index >= state->getMaxIndexedBufferBindings(target),
3268 GL_INVALID_VALUE);
3269 SET_ERROR_IF(buffer && size <= 0, GL_INVALID_VALUE);
3270 SET_ERROR_IF((target == GL_ATOMIC_COUNTER_BUFFER ||
3271 target == GL_TRANSFORM_FEEDBACK_BUFFER) &&
3272 (size % 4 || offset % 4),
3273 GL_INVALID_VALUE);
3274
3275 GLint ssbo_offset_align, ubo_offset_align;
3276 ctx->s_glGetIntegerv(ctx, GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT, &ssbo_offset_align);
3277 ctx->s_glGetIntegerv(ctx, GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &ubo_offset_align);
3278 SET_ERROR_IF(target == GL_SHADER_STORAGE_BUFFER &&
3279 offset % ssbo_offset_align,
3280 GL_INVALID_VALUE);
3281 SET_ERROR_IF(target == GL_UNIFORM_BUFFER &&
3282 offset % ubo_offset_align,
3283 GL_INVALID_VALUE);
3284
Lingfeng Yang554a5152019-02-21 20:20:48 -08003285 if (ctx->m_state->isIndexedBindNoOp(target, index, buffer, offset, size, 0, 0)) return;
3286
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003287 state->bindBuffer(target, buffer);
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08003288 ctx->m_state->addBuffer(buffer);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003289 state->bindIndexedBuffer(target, index, buffer, offset, size, 0, 0);
Lingfeng Yang554a5152019-02-21 20:20:48 -08003290
3291 ctx->m_glBindBufferRange_enc(ctx, target, index, buffer, offset, size);
3292 ctx->m_state->setLastEncodedBufferBind(target, buffer);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003293}
3294
3295void GL2Encoder::s_glBindBufferBase(void* self, GLenum target, GLuint index, GLuint buffer) {
3296 GL2Encoder* ctx = (GL2Encoder*)self;
3297 GLClientState* state = ctx->m_state;
3298
3299 SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM);
3300
3301 // Only works with certain targets
3302 SET_ERROR_IF(
3303 !(target == GL_ATOMIC_COUNTER_BUFFER ||
3304 target == GL_SHADER_STORAGE_BUFFER ||
3305 target == GL_TRANSFORM_FEEDBACK_BUFFER ||
3306 target == GL_UNIFORM_BUFFER),
3307 GL_INVALID_ENUM);
3308 // Can't exceed range
3309 SET_ERROR_IF(index < 0 ||
3310 index >= state->getMaxIndexedBufferBindings(target),
3311 GL_INVALID_VALUE);
3312
Lingfeng Yang554a5152019-02-21 20:20:48 -08003313 BufferData* buf = ctx->getBufferDataById(buffer);
3314 GLsizeiptr size = buf ? buf->m_size : 0;
3315
3316 if (ctx->m_state->isIndexedBindNoOp(target, index, buffer, 0, size, 0, 0)) return;
3317
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003318 state->bindBuffer(target, buffer);
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08003319 ctx->m_state->addBuffer(buffer);
Lingfeng Yang554a5152019-02-21 20:20:48 -08003320
3321 state->bindIndexedBuffer(target, index, buffer, 0, size, 0, 0);
3322
3323 ctx->m_glBindBufferBase_enc(ctx, target, index, buffer);
3324 ctx->m_state->setLastEncodedBufferBind(target, buffer);
3325}
3326
3327void GL2Encoder::doIndexedBufferBindEncodeCached(IndexedBufferBindOp op, GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size, GLintptr stride, GLintptr effectiveStride)
3328{
3329 if (m_state->isIndexedBindNoOp(target, index, buffer, offset, size, stride, effectiveStride)) return;
3330
3331 switch (op) {
3332 case BindBufferBase:
3333 // can emulate with bindBufferRange
3334 case BindBufferRange:
3335 m_glBindBufferRange_enc(this, target, index, buffer, offset, size);
3336 break;
3337 // TODO: other ops
3338 }
3339
3340 m_state->setLastEncodedBufferBind(target, buffer);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003341}
3342
3343void GL2Encoder::s_glCopyBufferSubData(void *self , GLenum readtarget, GLenum writetarget, GLintptr readoffset, GLintptr writeoffset, GLsizeiptr size) {
3344 GL2Encoder* ctx = (GL2Encoder*)self;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003345
3346 SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, readtarget), GL_INVALID_ENUM);
3347 SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, writetarget), GL_INVALID_ENUM);
3348 SET_ERROR_IF((readtarget == GL_ATOMIC_COUNTER_BUFFER ||
3349 readtarget == GL_DISPATCH_INDIRECT_BUFFER ||
3350 readtarget == GL_DRAW_INDIRECT_BUFFER ||
3351 readtarget == GL_SHADER_STORAGE_BUFFER), GL_INVALID_ENUM);
3352 SET_ERROR_IF((writetarget == GL_ATOMIC_COUNTER_BUFFER ||
3353 writetarget == GL_DISPATCH_INDIRECT_BUFFER ||
3354 writetarget == GL_DRAW_INDIRECT_BUFFER ||
3355 writetarget == GL_SHADER_STORAGE_BUFFER), GL_INVALID_ENUM);
3356 SET_ERROR_IF(!ctx->boundBuffer(readtarget), GL_INVALID_OPERATION);
3357 SET_ERROR_IF(!ctx->boundBuffer(writetarget), GL_INVALID_OPERATION);
3358 SET_ERROR_IF(ctx->isBufferTargetMapped(readtarget), GL_INVALID_OPERATION);
3359 SET_ERROR_IF(ctx->isBufferTargetMapped(writetarget), GL_INVALID_OPERATION);
3360 SET_ERROR_IF(readoffset < 0, GL_INVALID_VALUE);
3361 SET_ERROR_IF(writeoffset < 0, GL_INVALID_VALUE);
3362 SET_ERROR_IF(size < 0, GL_INVALID_VALUE);
3363 SET_ERROR_IF(
3364 ctx->getBufferData(readtarget) &&
3365 (readoffset + size > ctx->getBufferData(readtarget)->m_size),
3366 GL_INVALID_VALUE);
3367 SET_ERROR_IF(
3368 ctx->getBufferData(writetarget) &&
3369 (writeoffset + size > ctx->getBufferData(writetarget)->m_size),
3370 GL_INVALID_VALUE);
3371 SET_ERROR_IF(readtarget == writetarget &&
3372 !((writeoffset >= readoffset + size) ||
3373 (readoffset >= writeoffset + size)),
3374 GL_INVALID_VALUE);
3375
3376 ctx->m_glCopyBufferSubData_enc(self, readtarget, writetarget, readoffset, writeoffset, size);
3377}
3378
3379void GL2Encoder::s_glGetBufferParameteriv(void* self, GLenum target, GLenum pname, GLint* params) {
3380 GL2Encoder* ctx = (GL2Encoder*)self;
3381
3382 SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM);
3383 SET_ERROR_IF(
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08003384 target != GL_ARRAY_BUFFER &&
3385 target != GL_ELEMENT_ARRAY_BUFFER &&
3386 target != GL_COPY_READ_BUFFER &&
3387 target != GL_COPY_WRITE_BUFFER &&
3388 target != GL_PIXEL_PACK_BUFFER &&
3389 target != GL_PIXEL_UNPACK_BUFFER &&
3390 target != GL_TRANSFORM_FEEDBACK_BUFFER &&
3391 target != GL_UNIFORM_BUFFER,
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003392 GL_INVALID_ENUM);
3393 SET_ERROR_IF(!GLESv2Validation::bufferParam(ctx, pname), GL_INVALID_ENUM);
3394 SET_ERROR_IF(!ctx->boundBuffer(target), GL_INVALID_OPERATION);
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08003395 SET_ERROR_IF(pname != GL_BUFFER_ACCESS_FLAGS &&
3396 pname != GL_BUFFER_MAPPED &&
3397 pname != GL_BUFFER_SIZE &&
3398 pname != GL_BUFFER_USAGE &&
3399 pname != GL_BUFFER_MAP_LENGTH &&
3400 pname != GL_BUFFER_MAP_OFFSET,
3401 GL_INVALID_ENUM);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003402
3403 if (!params) return;
3404
3405 BufferData* buf = ctx->getBufferData(target);
3406
3407 switch (pname) {
3408 case GL_BUFFER_ACCESS_FLAGS:
3409 *params = buf ? buf->m_mappedAccess : 0;
3410 break;
3411 case GL_BUFFER_MAPPED:
3412 *params = buf ? (buf->m_mapped ? GL_TRUE : GL_FALSE) : GL_FALSE;
3413 break;
3414 case GL_BUFFER_SIZE:
3415 *params = buf ? buf->m_size : 0;
3416 break;
3417 case GL_BUFFER_USAGE:
3418 *params = buf ? buf->m_usage : GL_STATIC_DRAW;
3419 break;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08003420 case GL_BUFFER_MAP_LENGTH:
3421 *params = buf ? buf->m_mappedLength : 0;
3422 break;
3423 case GL_BUFFER_MAP_OFFSET:
3424 *params = buf ? buf->m_mappedOffset : 0;
3425 break;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003426 default:
3427 break;
3428 }
3429}
3430
3431void GL2Encoder::s_glGetBufferParameteri64v(void* self, GLenum target, GLenum pname, GLint64* params) {
3432 GL2Encoder* ctx = (GL2Encoder*)self;
3433
3434 SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM);
3435 SET_ERROR_IF(
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08003436 target != GL_ARRAY_BUFFER &&
3437 target != GL_ELEMENT_ARRAY_BUFFER &&
3438 target != GL_COPY_READ_BUFFER &&
3439 target != GL_COPY_WRITE_BUFFER &&
3440 target != GL_PIXEL_PACK_BUFFER &&
3441 target != GL_PIXEL_UNPACK_BUFFER &&
3442 target != GL_TRANSFORM_FEEDBACK_BUFFER &&
3443 target != GL_UNIFORM_BUFFER,
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003444 GL_INVALID_ENUM);
3445 SET_ERROR_IF(!GLESv2Validation::bufferParam(ctx, pname), GL_INVALID_ENUM);
3446 SET_ERROR_IF(!ctx->boundBuffer(target), GL_INVALID_OPERATION);
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08003447 SET_ERROR_IF(pname != GL_BUFFER_ACCESS_FLAGS &&
3448 pname != GL_BUFFER_MAPPED &&
3449 pname != GL_BUFFER_SIZE &&
3450 pname != GL_BUFFER_USAGE &&
3451 pname != GL_BUFFER_MAP_LENGTH &&
3452 pname != GL_BUFFER_MAP_OFFSET,
3453 GL_INVALID_ENUM);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003454
3455 if (!params) return;
3456
3457 BufferData* buf = ctx->getBufferData(target);
3458
3459 switch (pname) {
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08003460 case GL_BUFFER_ACCESS_FLAGS:
3461 *params = buf ? buf->m_mappedAccess : 0;
3462 break;
3463 case GL_BUFFER_MAPPED:
3464 *params = buf ? (buf->m_mapped ? GL_TRUE : GL_FALSE) : GL_FALSE;
3465 break;
3466 case GL_BUFFER_SIZE:
3467 *params = buf ? buf->m_size : 0;
3468 break;
3469 case GL_BUFFER_USAGE:
3470 *params = buf ? buf->m_usage : GL_STATIC_DRAW;
3471 break;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003472 case GL_BUFFER_MAP_LENGTH:
3473 *params = buf ? buf->m_mappedLength : 0;
3474 break;
3475 case GL_BUFFER_MAP_OFFSET:
3476 *params = buf ? buf->m_mappedOffset : 0;
3477 break;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003478 default:
3479 break;
3480 }
3481}
3482
3483void GL2Encoder::s_glGetBufferPointerv(void* self, GLenum target, GLenum pname, GLvoid** params) {
3484 GL2Encoder* ctx = (GL2Encoder*)self;
3485 SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM);
3486 SET_ERROR_IF(
3487 target == GL_ATOMIC_COUNTER_BUFFER ||
3488 target == GL_DISPATCH_INDIRECT_BUFFER ||
3489 target == GL_DRAW_INDIRECT_BUFFER ||
3490 target == GL_SHADER_STORAGE_BUFFER,
3491 GL_INVALID_ENUM);
3492 SET_ERROR_IF(pname != GL_BUFFER_MAP_POINTER, GL_INVALID_ENUM);
3493 SET_ERROR_IF(!ctx->boundBuffer(target), GL_INVALID_OPERATION);
3494 if (!params) return;
3495
3496 BufferData* buf = ctx->getBufferData(target);
3497
3498 if (!buf || !buf->m_mapped) { *params = NULL; return; }
3499
3500 *params = (GLvoid*)((char*)buf->m_fixedBuffer.ptr() + buf->m_mappedOffset);
3501}
3502
3503static const char* const kNameDelimiter = ";";
3504
3505static std::string packVarNames(GLsizei count, const char** names, GLint* err_out) {
3506
3507#define VALIDATE(cond, err) if (cond) { *err_out = err; return packed; } \
3508
3509 std::string packed;
3510 // validate the array of char[]'s
3511 const char* currName;
3512 for (GLsizei i = 0; i < count; i++) {
3513 currName = names[i];
3514 VALIDATE(!currName, GL_INVALID_OPERATION);
3515 // check if has reasonable size
3516 size_t len = strlen(currName);
3517 VALIDATE(!len, GL_INVALID_OPERATION);
3518 // check for our delimiter, which if present
3519 // in the name, means an invalid name anyway.
3520 VALIDATE(strstr(currName, kNameDelimiter),
3521 GL_INVALID_OPERATION);
3522 packed += currName;
3523 packed += ";";
3524 }
3525
3526 *err_out = GL_NO_ERROR;
3527 return packed;
3528}
3529
3530void GL2Encoder::s_glGetUniformIndices(void* self, GLuint program, GLsizei uniformCount, const GLchar ** uniformNames, GLuint* uniformIndices) {
3531 GL2Encoder* ctx = (GL2Encoder*)self;
3532
3533 if (!uniformCount) return;
3534
3535 GLint err = GL_NO_ERROR;
3536 std::string packed = packVarNames(uniformCount, (const char**)uniformNames, &err);
3537 SET_ERROR_IF(err != GL_NO_ERROR, GL_INVALID_OPERATION);
3538
3539 bool needLocationWAR = ctx->m_shared->needUniformLocationWAR(program);
3540 std::vector<int> arrIndices;
3541 for (size_t i = 0; i < uniformCount; i++) {
3542 int err;
3543 arrIndices.push_back(sArrIndexOfUniformExpr(uniformNames[i], &err));
3544 if (err) {
3545 ALOGE("%s: invalid uniform name %s!", __FUNCTION__, uniformNames[i]);
3546 return;
3547 }
3548 }
3549
3550 ctx->glGetUniformIndicesAEMU(ctx, program, uniformCount, (const GLchar*)&packed[0], packed.size() + 1, uniformIndices);
3551
3552 for (int i = 0; i < uniformCount; i++) {
3553 if (uniformIndices[i] >= 0 && needLocationWAR) {
3554 uniformIndices[i] =
3555 ctx->m_shared->locationWARHostToApp(program, uniformIndices[i], arrIndices[i]);
3556 }
3557 }
3558}
3559
3560void GL2Encoder::s_glUniform1ui(void* self, GLint location, GLuint v0) {
3561 GL2Encoder *ctx = (GL2Encoder*)self;
3562 GLClientState* state = ctx->m_state;
3563 GLSharedGroupPtr shared = ctx->m_shared;
3564
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08003565 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003566 ctx->m_glUniform1ui_enc(self, hostLoc, v0);
3567
3568 GLenum target;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08003569 if (shared->setSamplerUniform(state->currentShaderProgram(), location, v0, &target)) {
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003570 GLenum origActiveTexture = state->getActiveTextureUnit();
3571 if (ctx->updateHostTexture2DBinding(GL_TEXTURE0 + v0, target)) {
3572 ctx->m_glActiveTexture_enc(self, origActiveTexture);
3573 }
3574 state->setActiveTextureUnit(origActiveTexture);
3575 }
3576}
3577
3578void GL2Encoder::s_glUniform2ui(void* self, GLint location, GLuint v0, GLuint v1) {
3579 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08003580 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003581 ctx->m_glUniform2ui_enc(self, hostLoc, v0, v1);
3582}
3583
3584void GL2Encoder::s_glUniform3ui(void* self, GLint location, GLuint v0, GLuint v1, GLuint v2) {
3585 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08003586 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003587 ctx->m_glUniform3ui_enc(self, hostLoc, v0, v1, v2);
3588}
3589
3590void GL2Encoder::s_glUniform4ui(void* self, GLint location, GLint v0, GLuint v1, GLuint v2, GLuint v3) {
3591 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08003592 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003593 ctx->m_glUniform4ui_enc(self, hostLoc, v0, v1, v2, v3);
3594}
3595
3596void GL2Encoder::s_glUniform1uiv(void* self, GLint location, GLsizei count, const GLuint *value) {
3597 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08003598 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003599 ctx->m_glUniform1uiv_enc(self, hostLoc, count, value);
3600}
3601
3602void GL2Encoder::s_glUniform2uiv(void* self, GLint location, GLsizei count, const GLuint *value) {
3603 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08003604 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003605 ctx->m_glUniform2uiv_enc(self, hostLoc, count, value);
3606}
3607
3608void GL2Encoder::s_glUniform3uiv(void* self, GLint location, GLsizei count, const GLuint *value) {
3609 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08003610 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003611 ctx->m_glUniform3uiv_enc(self, hostLoc, count, value);
3612}
3613
3614void GL2Encoder::s_glUniform4uiv(void* self, GLint location, GLsizei count, const GLuint *value) {
3615 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08003616 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003617 ctx->m_glUniform4uiv_enc(self, hostLoc, count, value);
3618}
3619
3620void GL2Encoder::s_glUniformMatrix2x3fv(void* self, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
3621 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08003622 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003623 ctx->m_glUniformMatrix2x3fv_enc(self, hostLoc, count, transpose, value);
3624}
3625
3626void GL2Encoder::s_glUniformMatrix3x2fv(void* self, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
3627 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08003628 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003629 ctx->m_glUniformMatrix3x2fv_enc(self, hostLoc, count, transpose, value);
3630}
3631
3632void GL2Encoder::s_glUniformMatrix2x4fv(void* self, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
3633 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08003634 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003635 ctx->m_glUniformMatrix2x4fv_enc(self, hostLoc, count, transpose, value);
3636}
3637
3638void GL2Encoder::s_glUniformMatrix4x2fv(void* self, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
3639 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08003640 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003641 ctx->m_glUniformMatrix4x2fv_enc(self, hostLoc, count, transpose, value);
3642}
3643
3644void GL2Encoder::s_glUniformMatrix3x4fv(void* self, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
3645 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08003646 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003647 ctx->m_glUniformMatrix3x4fv_enc(self, hostLoc, count, transpose, value);
3648}
3649
3650void GL2Encoder::s_glUniformMatrix4x3fv(void* self, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
3651 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08003652 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003653 ctx->m_glUniformMatrix4x3fv_enc(self, hostLoc, count, transpose, value);
3654}
3655
3656void GL2Encoder::s_glGetUniformuiv(void* self, GLuint program, GLint location, GLuint* params) {
3657 GL2Encoder *ctx = (GL2Encoder*)self;
3658 SET_ERROR_IF(!ctx->m_shared->isShaderOrProgramObject(program), GL_INVALID_VALUE);
3659 SET_ERROR_IF(!ctx->m_shared->isProgram(program), GL_INVALID_OPERATION);
3660 SET_ERROR_IF(!ctx->m_shared->isProgramInitialized(program), GL_INVALID_OPERATION);
3661 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
3662 SET_ERROR_IF(ctx->m_shared->getProgramUniformType(program,hostLoc)==0, GL_INVALID_OPERATION);
3663 ctx->m_glGetUniformuiv_enc(self, program, hostLoc, params);
3664}
3665
3666void GL2Encoder::s_glGetActiveUniformBlockiv(void* self, GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params) {
3667 GL2Encoder* ctx = (GL2Encoder*)self;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003668
3669 // refresh client state's # active uniforms in this block
3670 if (pname == GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES) {
3671 // TODO if worth it: cache uniform count and other params,
3672 // invalidate on program relinking.
3673 GLint numActiveUniforms;
3674 ctx->m_glGetActiveUniformBlockiv_enc(ctx,
3675 program, uniformBlockIndex,
3676 GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS,
3677 &numActiveUniforms);
3678 ctx->m_state->setNumActiveUniformsInUniformBlock(
3679 program, uniformBlockIndex, numActiveUniforms);
3680 }
3681
3682 ctx->m_glGetActiveUniformBlockiv_enc(ctx,
3683 program, uniformBlockIndex,
3684 pname, params);
3685}
3686
3687void GL2Encoder::s_glGetVertexAttribIiv(void* self, GLuint index, GLenum pname, GLint* params) {
3688 GL2Encoder *ctx = (GL2Encoder *)self;
3689 assert(ctx->m_state);
3690 GLint maxIndex;
3691 ctx->glGetIntegerv(self, GL_MAX_VERTEX_ATTRIBS, &maxIndex);
3692 SET_ERROR_IF(!(index < maxIndex), GL_INVALID_VALUE);
3693
3694 if (!ctx->m_state->getVertexAttribParameter<GLint>(index, pname, params)) {
3695 ctx->m_glGetVertexAttribIiv_enc(self, index, pname, params);
3696 }
3697}
3698
3699void GL2Encoder::s_glGetVertexAttribIuiv(void* self, GLuint index, GLenum pname, GLuint* params) {
3700 GL2Encoder *ctx = (GL2Encoder *)self;
3701 assert(ctx->m_state);
3702 GLint maxIndex;
3703 ctx->glGetIntegerv(self, GL_MAX_VERTEX_ATTRIBS, &maxIndex);
3704 SET_ERROR_IF(!(index < maxIndex), GL_INVALID_VALUE);
3705
3706 if (!ctx->m_state->getVertexAttribParameter<GLuint>(index, pname, params)) {
3707 ctx->m_glGetVertexAttribIuiv_enc(self, index, pname, params);
3708 }
3709}
3710
3711void GL2Encoder::s_glVertexAttribIPointer(void* self, GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid* pointer) {
3712 GL2Encoder *ctx = (GL2Encoder *)self;
3713 assert(ctx->m_state != NULL);
Lingfeng Yang07289902017-01-27 12:26:19 -08003714 VALIDATE_VERTEX_ATTRIB_INDEX(index);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003715 SET_ERROR_IF((size < 1 || size > 4), GL_INVALID_VALUE);
3716 SET_ERROR_IF(
3717 !(type == GL_BYTE ||
3718 type == GL_UNSIGNED_BYTE ||
3719 type == GL_SHORT ||
3720 type == GL_UNSIGNED_SHORT ||
3721 type == GL_INT ||
3722 type == GL_UNSIGNED_INT),
3723 GL_INVALID_ENUM);
3724 SET_ERROR_IF(stride < 0, GL_INVALID_VALUE);
3725
3726 ctx->m_state->setVertexAttribBinding(index, index);
3727 ctx->m_state->setVertexAttribFormat(index, size, type, false, 0, true);
3728 GLsizei effectiveStride = stride;
3729 if (stride == 0) {
Lingfeng Yang554a5152019-02-21 20:20:48 -08003730 effectiveStride = glSizeof(type) * size;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003731 }
3732 ctx->m_state->bindIndexedBuffer(0, index, ctx->m_state->currentArrayVbo(), (uintptr_t)pointer, 0, stride, effectiveStride);
3733
3734 if (ctx->m_state->currentArrayVbo() != 0) {
3735 ctx->glVertexAttribIPointerOffsetAEMU(ctx, index, size, type, stride, (uintptr_t)pointer);
3736 } else {
3737 SET_ERROR_IF(ctx->m_state->currentVertexArrayObject() != 0 && pointer, GL_INVALID_OPERATION);
3738 // wait for client-array handler
3739 }
3740}
3741
3742void GL2Encoder::s_glVertexAttribDivisor(void* self, GLuint index, GLuint divisor) {
3743 GL2Encoder *ctx = (GL2Encoder *)self;
3744 assert(ctx->m_state != NULL);
Lingfeng Yang07289902017-01-27 12:26:19 -08003745 VALIDATE_VERTEX_ATTRIB_INDEX(index);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003746 ctx->m_state->setVertexAttribBinding(index, index);
3747 ctx->m_state->setVertexBindingDivisor(index, divisor);
3748 ctx->m_glVertexAttribDivisor_enc(ctx, index, divisor);
3749}
3750
3751void GL2Encoder::s_glRenderbufferStorageMultisample(void* self,
3752 GLenum target, GLsizei samples, GLenum internalformat,
3753 GLsizei width, GLsizei height) {
3754 GL2Encoder *ctx = (GL2Encoder *)self;
3755 GLClientState* state = ctx->m_state;
3756
3757 SET_ERROR_IF(target != GL_RENDERBUFFER, GL_INVALID_ENUM);
3758 SET_ERROR_IF(!GLESv2Validation::rboFormat(ctx, internalformat), GL_INVALID_ENUM);
3759
3760 GLint max_samples;
3761 ctx->s_glGetInternalformativ(ctx, target, internalformat, GL_SAMPLES, 1, &max_samples);
3762 SET_ERROR_IF(samples > max_samples, GL_INVALID_OPERATION);
3763
3764 state->setBoundRenderbufferFormat(internalformat);
3765 state->setBoundRenderbufferSamples(samples);
3766 ctx->m_glRenderbufferStorageMultisample_enc(
3767 self, target, samples, internalformat, width, height);
3768}
3769
3770void GL2Encoder::s_glDrawBuffers(void* self, GLsizei n, const GLenum* bufs) {
3771 GL2Encoder* ctx = (GL2Encoder*)self;
3772 SET_ERROR_IF(!ctx->m_state->boundFramebuffer(GL_DRAW_FRAMEBUFFER) && n > 1, GL_INVALID_OPERATION);
3773 SET_ERROR_IF(n < 0 || n > ctx->m_state->getMaxDrawBuffers(), GL_INVALID_VALUE);
3774 for (int i = 0; i < n; i++) {
3775 SET_ERROR_IF(
3776 bufs[i] != GL_NONE &&
3777 bufs[i] != GL_BACK &&
3778 glUtilsColorAttachmentIndex(bufs[i]) == -1,
3779 GL_INVALID_ENUM);
3780 SET_ERROR_IF(
3781 !ctx->m_state->boundFramebuffer(GL_DRAW_FRAMEBUFFER) &&
3782 glUtilsColorAttachmentIndex(bufs[i]) != -1,
3783 GL_INVALID_OPERATION);
3784 SET_ERROR_IF(
3785 ctx->m_state->boundFramebuffer(GL_DRAW_FRAMEBUFFER) &&
3786 ((glUtilsColorAttachmentIndex(bufs[i]) != -1 &&
3787 glUtilsColorAttachmentIndex(bufs[i]) != i) ||
3788 (glUtilsColorAttachmentIndex(bufs[i]) == -1 &&
3789 bufs[i] != GL_NONE)),
3790 GL_INVALID_OPERATION);
3791 }
3792
3793 ctx->m_glDrawBuffers_enc(ctx, n, bufs);
3794}
3795
3796void GL2Encoder::s_glReadBuffer(void* self, GLenum src) {
3797 GL2Encoder* ctx = (GL2Encoder*)self;
3798
3799 SET_ERROR_IF(
3800 glUtilsColorAttachmentIndex(src) != -1 &&
3801 (glUtilsColorAttachmentIndex(src) >=
3802 ctx->m_state->getMaxColorAttachments()),
3803 GL_INVALID_OPERATION);
3804 SET_ERROR_IF(
3805 src != GL_NONE &&
3806 src != GL_BACK &&
3807 src > GL_COLOR_ATTACHMENT0 &&
3808 src < GL_DEPTH_ATTACHMENT &&
3809 (src - GL_COLOR_ATTACHMENT0) >
3810 ctx->m_state->getMaxColorAttachments(),
3811 GL_INVALID_OPERATION);
3812 SET_ERROR_IF(
3813 src != GL_NONE &&
3814 src != GL_BACK &&
3815 glUtilsColorAttachmentIndex(src) == -1,
3816 GL_INVALID_ENUM);
3817 SET_ERROR_IF(
3818 !ctx->m_state->boundFramebuffer(GL_READ_FRAMEBUFFER) &&
3819 src != GL_NONE &&
3820 src != GL_BACK,
3821 GL_INVALID_OPERATION);
3822 SET_ERROR_IF(
3823 ctx->m_state->boundFramebuffer(GL_READ_FRAMEBUFFER) &&
3824 src != GL_NONE &&
3825 glUtilsColorAttachmentIndex(src) == -1,
3826 GL_INVALID_OPERATION);
3827
3828 ctx->m_glReadBuffer_enc(ctx, src);
3829}
3830
3831void GL2Encoder::s_glFramebufferTextureLayer(void* self, GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) {
3832 GL2Encoder* ctx = (GL2Encoder*)self;
3833 GLClientState* state = ctx->m_state;
3834
3835 SET_ERROR_IF(!GLESv2Validation::framebufferTarget(ctx, target), GL_INVALID_ENUM);
3836 SET_ERROR_IF(!GLESv2Validation::framebufferAttachment(ctx, attachment), GL_INVALID_ENUM);
3837 GLenum lastBoundTarget = state->queryTexLastBoundTarget(texture);
3838 SET_ERROR_IF(lastBoundTarget != GL_TEXTURE_2D_ARRAY &&
3839 lastBoundTarget != GL_TEXTURE_3D,
3840 GL_INVALID_OPERATION);
3841 state->attachTextureObject(target, attachment, texture);
3842
3843 GLint max3DTextureSize;
3844 ctx->glGetIntegerv(ctx, GL_MAX_3D_TEXTURE_SIZE, &max3DTextureSize);
3845 SET_ERROR_IF(
3846 layer >= max3DTextureSize,
3847 GL_INVALID_VALUE);
3848
3849 ctx->m_glFramebufferTextureLayer_enc(self, target, attachment, texture, level, layer);
3850}
3851
3852void GL2Encoder::s_glTexStorage2D(void* self, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) {
3853 GL2Encoder* ctx = (GL2Encoder*)self;
3854 GLClientState* state = ctx->m_state;
3855
3856 SET_ERROR_IF(
3857 target != GL_TEXTURE_2D &&
3858 target != GL_TEXTURE_CUBE_MAP,
3859 GL_INVALID_ENUM);
3860 SET_ERROR_IF(!GLESv2Validation::pixelInternalFormat(internalformat), GL_INVALID_ENUM);
3861 SET_ERROR_IF(!state->getBoundTexture(target), GL_INVALID_OPERATION);
3862 SET_ERROR_IF(levels < 1 || width < 1 || height < 1, GL_INVALID_VALUE);
3863 SET_ERROR_IF(levels > ilog2((uint32_t)std::max(width, height)) + 1,
3864 GL_INVALID_OPERATION);
3865 SET_ERROR_IF(state->isBoundTextureImmutableFormat(target), GL_INVALID_OPERATION);
3866
3867 state->setBoundTextureInternalFormat(target, internalformat);
3868 state->setBoundTextureDims(target, -1, width, height, 1);
3869 state->setBoundTextureImmutableFormat(target);
Lingfeng Yanga9fff6a2018-03-02 13:42:51 -08003870
3871 if (target == GL_TEXTURE_2D) {
3872 ctx->override2DTextureTarget(target);
3873 }
3874
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003875 ctx->m_glTexStorage2D_enc(ctx, target, levels, internalformat, width, height);
Lingfeng Yanga9fff6a2018-03-02 13:42:51 -08003876
3877 if (target == GL_TEXTURE_2D) {
3878 ctx->restore2DTextureTarget(target);
3879 }
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003880}
3881
3882void GL2Encoder::s_glTransformFeedbackVaryings(void* self, GLuint program, GLsizei count, const char** varyings, GLenum bufferMode) {
3883 GL2Encoder* ctx = (GL2Encoder*)self;
3884
3885 SET_ERROR_IF(!ctx->m_shared->isProgram(program), GL_INVALID_VALUE);
3886
3887 GLint maxCount = 0;
3888 ctx->glGetIntegerv(ctx, GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, &maxCount);
3889
3890 SET_ERROR_IF(
3891 bufferMode == GL_SEPARATE_ATTRIBS &&
3892 maxCount < count,
3893 GL_INVALID_VALUE);
3894 SET_ERROR_IF(
3895 bufferMode != GL_INTERLEAVED_ATTRIBS &&
3896 bufferMode != GL_SEPARATE_ATTRIBS,
3897 GL_INVALID_ENUM);
3898
3899 if (!count) return;
3900
3901 GLint err = GL_NO_ERROR;
3902 std::string packed = packVarNames(count, varyings, &err);
3903 SET_ERROR_IF(err != GL_NO_ERROR, GL_INVALID_OPERATION);
3904
3905 ctx->glTransformFeedbackVaryingsAEMU(ctx, program, count, (const char*)&packed[0], packed.size() + 1, bufferMode);
3906}
3907
3908void GL2Encoder::s_glBeginTransformFeedback(void* self, GLenum primitiveMode) {
3909 GL2Encoder* ctx = (GL2Encoder*)self;
3910 GLClientState* state = ctx->m_state;
3911 ctx->m_glBeginTransformFeedback_enc(ctx, primitiveMode);
3912 state->setTransformFeedbackActiveUnpaused(true);
3913}
3914
3915void GL2Encoder::s_glEndTransformFeedback(void* self) {
3916 GL2Encoder* ctx = (GL2Encoder*)self;
3917 GLClientState* state = ctx->m_state;
3918 ctx->m_glEndTransformFeedback_enc(ctx);
3919 state->setTransformFeedbackActiveUnpaused(false);
3920}
3921
3922void GL2Encoder::s_glPauseTransformFeedback(void* self) {
3923 GL2Encoder* ctx = (GL2Encoder*)self;
3924 GLClientState* state = ctx->m_state;
3925 ctx->m_glPauseTransformFeedback_enc(ctx);
3926 state->setTransformFeedbackActiveUnpaused(false);
3927}
3928
3929void GL2Encoder::s_glResumeTransformFeedback(void* self) {
3930 GL2Encoder* ctx = (GL2Encoder*)self;
3931 GLClientState* state = ctx->m_state;
3932 ctx->m_glResumeTransformFeedback_enc(ctx);
3933 state->setTransformFeedbackActiveUnpaused(true);
3934}
3935
3936void GL2Encoder::s_glTexImage3D(void* self, GLenum target, GLint level, GLint internalFormat,
3937 GLsizei width, GLsizei height, GLsizei depth,
3938 GLint border, GLenum format, GLenum type, const GLvoid* data) {
3939 GL2Encoder* ctx = (GL2Encoder*)self;
3940 GLClientState* state = ctx->m_state;
3941
3942 SET_ERROR_IF(target != GL_TEXTURE_3D &&
3943 target != GL_TEXTURE_2D_ARRAY,
3944 GL_INVALID_ENUM);
3945 SET_ERROR_IF(!GLESv2Validation::pixelType(ctx, type), GL_INVALID_ENUM);
3946 SET_ERROR_IF(!GLESv2Validation::pixelFormat(ctx, format), GL_INVALID_ENUM);
3947
3948 // If unpack buffer is nonzero, verify unmapped state.
3949 SET_ERROR_IF(ctx->isBufferTargetMapped(GL_PIXEL_UNPACK_BUFFER), GL_INVALID_OPERATION);
3950
3951 GLint max_texture_size;
3952 GLint max_3d_texture_size;
3953 ctx->glGetIntegerv(ctx, GL_MAX_TEXTURE_SIZE, &max_texture_size);
3954 ctx->glGetIntegerv(ctx, GL_MAX_3D_TEXTURE_SIZE, &max_3d_texture_size);
3955 SET_ERROR_IF(level < 0, GL_INVALID_VALUE);
3956 SET_ERROR_IF(level > ilog2(max_texture_size), GL_INVALID_VALUE);
3957 SET_ERROR_IF(level > ilog2(max_3d_texture_size), GL_INVALID_VALUE);
3958
3959 SET_ERROR_IF(width < 0 || height < 0 || depth < 0, GL_INVALID_VALUE);
Lingfeng Yang730870f2019-10-31 17:45:27 -07003960 SET_ERROR_IF(width > max_texture_size, GL_INVALID_VALUE);
3961 SET_ERROR_IF(height > max_texture_size, GL_INVALID_VALUE);
3962 SET_ERROR_IF(depth > max_texture_size, GL_INVALID_VALUE);
3963 SET_ERROR_IF(width > max_3d_texture_size, GL_INVALID_VALUE);
3964 SET_ERROR_IF(height > max_3d_texture_size, GL_INVALID_VALUE);
3965 SET_ERROR_IF(depth > max_3d_texture_size, GL_INVALID_VALUE);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003966 SET_ERROR_IF(border != 0, GL_INVALID_VALUE);
3967 // If unpack buffer is nonzero, verify buffer data fits and is evenly divisible by the type.
3968 SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
3969 ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
3970 (ctx->m_state->pboNeededDataSize(width, height, depth, format, type, 0) >
3971 ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size),
3972 GL_INVALID_OPERATION);
3973 SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
3974 ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
3975 (ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size %
3976 glSizeof(type)),
3977 GL_INVALID_OPERATION);
3978 SET_ERROR_IF(state->isBoundTextureImmutableFormat(target), GL_INVALID_OPERATION);
3979
3980 state->setBoundTextureInternalFormat(target, internalFormat);
3981 state->setBoundTextureFormat(target, format);
3982 state->setBoundTextureType(target, type);
3983 state->setBoundTextureDims(target, level, width, height, depth);
3984
3985 if (ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER)) {
3986 ctx->glTexImage3DOffsetAEMU(
3987 ctx, target, level, internalFormat,
3988 width, height, depth,
3989 border, format, type, (uintptr_t)data);
3990 } else {
3991 ctx->m_glTexImage3D_enc(ctx,
3992 target, level, internalFormat,
3993 width, height, depth,
3994 border, format, type, data);
3995 }
3996}
3997
3998void 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) {
3999 GL2Encoder* ctx = (GL2Encoder*)self;
4000 GLClientState* state = ctx->m_state;
4001
4002 SET_ERROR_IF(target != GL_TEXTURE_3D &&
4003 target != GL_TEXTURE_2D_ARRAY,
4004 GL_INVALID_ENUM);
4005 SET_ERROR_IF(!GLESv2Validation::pixelType(ctx, type), GL_INVALID_ENUM);
4006 SET_ERROR_IF(!GLESv2Validation::pixelFormat(ctx, format), GL_INVALID_ENUM);
4007 // If unpack buffer is nonzero, verify unmapped state.
4008 SET_ERROR_IF(ctx->isBufferTargetMapped(GL_PIXEL_UNPACK_BUFFER), GL_INVALID_OPERATION);
4009 GLint max_texture_size;
4010 GLint max_3d_texture_size;
4011 ctx->glGetIntegerv(ctx, GL_MAX_TEXTURE_SIZE, &max_texture_size);
4012 ctx->glGetIntegerv(ctx, GL_MAX_3D_TEXTURE_SIZE, &max_3d_texture_size);
4013 SET_ERROR_IF(level < 0, GL_INVALID_VALUE);
4014 SET_ERROR_IF(level > ilog2(max_texture_size), GL_INVALID_VALUE);
4015 SET_ERROR_IF(level > ilog2(max_3d_texture_size), GL_INVALID_VALUE);
4016 SET_ERROR_IF(width < 0 || height < 0 || depth < 0, GL_INVALID_VALUE);
4017 SET_ERROR_IF(xoffset < 0 || yoffset < 0 || zoffset < 0, GL_INVALID_VALUE);
4018 GLuint tex = state->getBoundTexture(target);
4019 GLsizei neededWidth = xoffset + width;
4020 GLsizei neededHeight = yoffset + height;
4021 GLsizei neededDepth = zoffset + depth;
4022
4023 SET_ERROR_IF(tex &&
4024 (neededWidth > state->queryTexWidth(level, tex) ||
4025 neededHeight > state->queryTexHeight(level, tex) ||
4026 neededDepth > state->queryTexDepth(level, tex)),
4027 GL_INVALID_VALUE);
4028 // If unpack buffer is nonzero, verify buffer data fits and is evenly divisible by the type.
4029 SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
4030 ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
4031 (ctx->m_state->pboNeededDataSize(width, height, depth, format, type, 0) >
4032 ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size),
4033 GL_INVALID_OPERATION);
4034 SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
4035 ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
4036 (ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size %
4037 glSizeof(type)),
4038 GL_INVALID_OPERATION);
4039 SET_ERROR_IF(!ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) && !data, GL_INVALID_OPERATION);
4040 SET_ERROR_IF(xoffset < 0 || yoffset < 0 || zoffset < 0, GL_INVALID_VALUE);
4041
4042 if (ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER)) {
4043 ctx->glTexSubImage3DOffsetAEMU(ctx,
4044 target, level,
4045 xoffset, yoffset, zoffset,
4046 width, height, depth,
4047 format, type, (uintptr_t)data);
4048 } else {
4049 ctx->m_glTexSubImage3D_enc(ctx,
4050 target, level,
4051 xoffset, yoffset, zoffset,
4052 width, height, depth,
4053 format, type, data);
4054 }
4055}
4056
4057void GL2Encoder::s_glCompressedTexImage3D(void* self, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data) {
4058 GL2Encoder* ctx = (GL2Encoder*)self;
4059 GLClientState* state = ctx->m_state;
4060
4061 // Filter compressed formats support.
4062 SET_ERROR_IF(!GLESv2Validation::supportedCompressedFormat(ctx, internalformat), GL_INVALID_ENUM);
4063 // If unpack buffer is nonzero, verify unmapped state.
4064 SET_ERROR_IF(ctx->isBufferTargetMapped(GL_PIXEL_UNPACK_BUFFER), GL_INVALID_OPERATION);
4065 SET_ERROR_IF(width < 0 || height < 0 || depth < 0, GL_INVALID_VALUE);
4066 SET_ERROR_IF(border, GL_INVALID_VALUE);
4067 // If unpack buffer is nonzero, verify buffer data fits.
4068 SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
4069 ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
4070 (imageSize > ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size),
4071 GL_INVALID_OPERATION);
4072 // TODO: Fix:
4073 // If |imageSize| is too small for compressed dimensions.
4074 // SET_ERROR_IF(GLESv2Validation::compressedTexImageSize(internalformat, width, height, depth) > imageSize, GL_INVALID_VALUE);
4075 state->setBoundTextureInternalFormat(target, (GLint)internalformat);
4076 state->setBoundTextureDims(target, level, width, height, depth);
4077
4078 if (ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER)) {
4079 ctx->glCompressedTexImage3DOffsetAEMU(
4080 ctx, target, level, internalformat,
4081 width, height, depth, border,
4082 imageSize, (uintptr_t)data);
4083 } else {
4084 ctx->m_glCompressedTexImage3D_enc(
4085 ctx, target, level, internalformat,
4086 width, height, depth, border,
4087 imageSize, data);
4088 }
4089}
4090
4091void 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) {
4092 GL2Encoder* ctx = (GL2Encoder*)self;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004093
4094 SET_ERROR_IF(!GLESv2Validation::textureTarget(ctx, target), GL_INVALID_ENUM);
4095 // If unpack buffer is nonzero, verify unmapped state.
4096 SET_ERROR_IF(ctx->isBufferTargetMapped(GL_PIXEL_UNPACK_BUFFER), GL_INVALID_OPERATION);
4097 SET_ERROR_IF(width < 0 || height < 0 || depth < 0, GL_INVALID_VALUE);
4098 // If unpack buffer is nonzero, verify buffer data fits.
4099 SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
4100 ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
4101 (imageSize > ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size),
4102 GL_INVALID_OPERATION);
4103 SET_ERROR_IF(xoffset < 0 || yoffset < 0 || zoffset < 0, GL_INVALID_VALUE);
4104
4105 if (ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER)) {
4106 ctx->glCompressedTexSubImage3DOffsetAEMU(
4107 ctx, target, level,
4108 xoffset, yoffset, zoffset,
4109 width, height, depth,
4110 format, imageSize, (uintptr_t)data);
4111 } else {
4112 ctx->m_glCompressedTexSubImage3D_enc(
4113 ctx, target, level,
4114 xoffset, yoffset, zoffset,
4115 width, height, depth,
4116 format, imageSize, data);
4117
4118 }
4119}
4120
4121void GL2Encoder::s_glTexStorage3D(void* self, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) {
4122 GL2Encoder* ctx = (GL2Encoder*)self;
4123 GLClientState* state = ctx->m_state;
4124 SET_ERROR_IF(target != GL_TEXTURE_3D &&
4125 target != GL_TEXTURE_2D_ARRAY,
4126 GL_INVALID_ENUM);
4127 SET_ERROR_IF(!GLESv2Validation::pixelInternalFormat(internalformat), GL_INVALID_ENUM);
4128 SET_ERROR_IF(!state->getBoundTexture(target), GL_INVALID_OPERATION);
4129 SET_ERROR_IF(levels < 1 || width < 1 || height < 1, GL_INVALID_VALUE);
4130 SET_ERROR_IF(target == GL_TEXTURE_3D && (levels > ilog2((uint32_t)std::max(width, std::max(height, depth))) + 1),
4131 GL_INVALID_OPERATION);
4132 SET_ERROR_IF(target == GL_TEXTURE_2D_ARRAY && (levels > ilog2((uint32_t)std::max(width, height)) + 1),
4133 GL_INVALID_OPERATION);
4134 SET_ERROR_IF(state->isBoundTextureImmutableFormat(target), GL_INVALID_OPERATION);
4135
4136 state->setBoundTextureInternalFormat(target, internalformat);
4137 state->setBoundTextureDims(target, -1, width, height, depth);
4138 state->setBoundTextureImmutableFormat(target);
4139 ctx->m_glTexStorage3D_enc(ctx, target, levels, internalformat, width, height, depth);
4140 state->setBoundTextureImmutableFormat(target);
4141}
4142
4143void GL2Encoder::s_glDrawArraysInstanced(void* self, GLenum mode, GLint first, GLsizei count, GLsizei primcount) {
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
4149 bool has_client_vertex_arrays = false;
4150 bool has_indirect_arrays = false;
4151 ctx->getVBOUsage(&has_client_vertex_arrays,
4152 &has_indirect_arrays);
4153
4154 if (has_client_vertex_arrays ||
4155 (!has_client_vertex_arrays &&
4156 !has_indirect_arrays)) {
4157 ctx->sendVertexAttributes(first, count, true, primcount);
4158 ctx->m_glDrawArraysInstanced_enc(ctx, mode, 0, count, primcount);
4159 } else {
4160 ctx->sendVertexAttributes(0, count, false, primcount);
4161 ctx->m_glDrawArraysInstanced_enc(ctx, mode, first, count, primcount);
4162 }
4163 ctx->m_stream->flush();
4164}
4165
4166void GL2Encoder::s_glDrawElementsInstanced(void* self, GLenum mode, GLsizei count, GLenum type, const void* indices, GLsizei primcount)
4167{
4168
4169 GL2Encoder *ctx = (GL2Encoder *)self;
4170 assert(ctx->m_state != NULL);
4171 SET_ERROR_IF(!isValidDrawMode(mode), GL_INVALID_ENUM);
4172 SET_ERROR_IF(count < 0, GL_INVALID_VALUE);
4173 SET_ERROR_IF(!(type == GL_UNSIGNED_BYTE || type == GL_UNSIGNED_SHORT || type == GL_UNSIGNED_INT), GL_INVALID_ENUM);
4174 SET_ERROR_IF(ctx->m_state->getTransformFeedbackActiveUnpaused(), GL_INVALID_OPERATION);
4175
4176 bool has_client_vertex_arrays = false;
4177 bool has_indirect_arrays = false;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004178 GLintptr offset = 0;
4179
4180 ctx->getVBOUsage(&has_client_vertex_arrays, &has_indirect_arrays);
4181
4182 if (!has_client_vertex_arrays && !has_indirect_arrays) {
4183 // ALOGW("glDrawElements: no vertex arrays / buffers bound to the command\n");
4184 GLenum status = ctx->m_glCheckFramebufferStatus_enc(self, GL_FRAMEBUFFER);
4185 SET_ERROR_IF(status != GL_FRAMEBUFFER_COMPLETE, GL_INVALID_FRAMEBUFFER_OPERATION);
4186 }
4187
4188 BufferData* buf = NULL;
4189 int minIndex = 0, maxIndex = 0;
4190
4191 // For validation/immediate index array purposes,
4192 // we need the min/max vertex index of the index array.
4193 // If the VBO != 0, this may not be the first time we have
4194 // used this particular index buffer. getBufferIndexRange
4195 // can more quickly get min/max vertex index by
4196 // caching previous results.
4197 if (ctx->m_state->currentIndexVbo() != 0) {
4198 buf = ctx->m_shared->getBufferData(ctx->m_state->currentIndexVbo());
4199 offset = (GLintptr)indices;
4200 indices = (void*)((GLintptr)buf->m_fixedBuffer.ptr() + (GLintptr)indices);
4201 ctx->getBufferIndexRange(buf,
4202 indices,
4203 type,
4204 (size_t)count,
4205 (size_t)offset,
4206 &minIndex, &maxIndex);
4207 } else {
4208 // In this case, the |indices| field holds a real
4209 // array, so calculate the indices now. They will
4210 // also be needed to know how much data to
4211 // transfer to host.
4212 ctx->calcIndexRange(indices,
4213 type,
4214 count,
4215 &minIndex,
4216 &maxIndex);
4217 }
4218
Lingfeng Yang26e629a2018-10-13 20:00:12 -07004219 if (count == 0) return;
4220
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004221 bool adjustIndices = true;
4222 if (ctx->m_state->currentIndexVbo() != 0) {
4223 if (!has_client_vertex_arrays) {
4224 ctx->sendVertexAttributes(0, maxIndex + 1, false, primcount);
Lingfeng Yang554a5152019-02-21 20:20:48 -08004225 ctx->doBindBufferEncodeCached(GL_ELEMENT_ARRAY_BUFFER, ctx->m_state->currentIndexVbo());
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004226 ctx->glDrawElementsInstancedOffsetAEMU(ctx, mode, count, type, offset, primcount);
4227 ctx->flushDrawCall();
4228 adjustIndices = false;
4229 } else {
Lingfeng Yang554a5152019-02-21 20:20:48 -08004230 ctx->doBindBufferEncodeCached(GL_ELEMENT_ARRAY_BUFFER, 0);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004231 }
4232 }
4233 if (adjustIndices) {
4234 void *adjustedIndices =
4235 ctx->recenterIndices(indices,
4236 type,
4237 count,
4238 minIndex);
4239
4240 if (has_indirect_arrays || 1) {
4241 ctx->sendVertexAttributes(minIndex, maxIndex - minIndex + 1, true, primcount);
4242 ctx->glDrawElementsInstancedDataAEMU(ctx, mode, count, type, adjustedIndices, primcount, count * glSizeof(type));
4243 ctx->m_stream->flush();
4244 // XXX - OPTIMIZATION (see the other else branch) should be implemented
4245 if(!has_indirect_arrays) {
4246 //ALOGD("unoptimized drawelements !!!\n");
4247 }
4248 } else {
4249 // we are all direct arrays and immidate mode index array -
4250 // rebuild the arrays and the index array;
4251 ALOGE("glDrawElements: direct index & direct buffer data - will be implemented in later versions;\n");
4252 }
4253 }
4254}
4255
4256void GL2Encoder::s_glDrawRangeElements(void* self, GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void* indices)
4257{
4258
4259 GL2Encoder *ctx = (GL2Encoder *)self;
4260 assert(ctx->m_state != NULL);
4261 SET_ERROR_IF(!isValidDrawMode(mode), GL_INVALID_ENUM);
4262 SET_ERROR_IF(end < start, GL_INVALID_VALUE);
4263 SET_ERROR_IF(count < 0, GL_INVALID_VALUE);
4264 SET_ERROR_IF(!(type == GL_UNSIGNED_BYTE || type == GL_UNSIGNED_SHORT || type == GL_UNSIGNED_INT), GL_INVALID_ENUM);
4265 SET_ERROR_IF(ctx->m_state->getTransformFeedbackActiveUnpaused(), GL_INVALID_OPERATION);
4266
4267 bool has_client_vertex_arrays = false;
4268 bool has_indirect_arrays = false;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004269 GLintptr offset = 0;
4270
4271 ctx->getVBOUsage(&has_client_vertex_arrays, &has_indirect_arrays);
4272
4273 if (!has_client_vertex_arrays && !has_indirect_arrays) {
4274 // ALOGW("glDrawElements: no vertex arrays / buffers bound to the command\n");
4275 GLenum status = ctx->m_glCheckFramebufferStatus_enc(self, GL_FRAMEBUFFER);
4276 SET_ERROR_IF(status != GL_FRAMEBUFFER_COMPLETE, GL_INVALID_FRAMEBUFFER_OPERATION);
4277 }
4278
4279 BufferData* buf = NULL;
4280 int minIndex = 0, maxIndex = 0;
4281
4282 // For validation/immediate index array purposes,
4283 // we need the min/max vertex index of the index array.
4284 // If the VBO != 0, this may not be the first time we have
4285 // used this particular index buffer. getBufferIndexRange
4286 // can more quickly get min/max vertex index by
4287 // caching previous results.
4288 if (ctx->m_state->currentIndexVbo() != 0) {
4289 buf = ctx->m_shared->getBufferData(ctx->m_state->currentIndexVbo());
Lingfeng Yang2c3a0da2019-03-07 20:43:53 -08004290 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 -08004291 offset = (GLintptr)indices;
Lingfeng Yang2c3a0da2019-03-07 20:43:53 -08004292 void* oldIndices = (void*)indices;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004293 indices = (void*)((GLintptr)buf->m_fixedBuffer.ptr() + (GLintptr)indices);
Lingfeng Yang2c3a0da2019-03-07 20:43:53 -08004294 ALOGV("%s: indices arg: %p buffer start: %p indices: %p\n", __func__,
4295 (void*)(uintptr_t)(oldIndices),
4296 buf->m_fixedBuffer.ptr(),
4297 indices);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004298 ctx->getBufferIndexRange(buf,
4299 indices,
4300 type,
4301 (size_t)count,
4302 (size_t)offset,
4303 &minIndex, &maxIndex);
4304 } else {
4305 // In this case, the |indices| field holds a real
4306 // array, so calculate the indices now. They will
4307 // also be needed to know how much data to
4308 // transfer to host.
4309 ctx->calcIndexRange(indices,
4310 type,
4311 count,
4312 &minIndex,
4313 &maxIndex);
4314 }
4315
Lingfeng Yang26e629a2018-10-13 20:00:12 -07004316 if (count == 0) return;
4317
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004318 bool adjustIndices = true;
4319 if (ctx->m_state->currentIndexVbo() != 0) {
4320 if (!has_client_vertex_arrays) {
4321 ctx->sendVertexAttributes(0, maxIndex + 1, false);
Lingfeng Yang554a5152019-02-21 20:20:48 -08004322 ctx->doBindBufferEncodeCached(GL_ELEMENT_ARRAY_BUFFER, ctx->m_state->currentIndexVbo());
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004323 ctx->glDrawElementsOffset(ctx, mode, count, type, offset);
4324 ctx->flushDrawCall();
4325 adjustIndices = false;
4326 } else {
Lingfeng Yang554a5152019-02-21 20:20:48 -08004327 ctx->doBindBufferEncodeCached(GL_ELEMENT_ARRAY_BUFFER, 0);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004328 }
4329 }
4330 if (adjustIndices) {
4331 void *adjustedIndices =
4332 ctx->recenterIndices(indices,
4333 type,
4334 count,
4335 minIndex);
4336
4337 if (has_indirect_arrays || 1) {
4338 ctx->sendVertexAttributes(minIndex, maxIndex - minIndex + 1, true);
4339 ctx->glDrawElementsData(ctx, mode, count, type, adjustedIndices, count * glSizeof(type));
4340 ctx->m_stream->flush();
4341 // XXX - OPTIMIZATION (see the other else branch) should be implemented
4342 if(!has_indirect_arrays) {
4343 //ALOGD("unoptimized drawelements !!!\n");
4344 }
4345 } else {
4346 // we are all direct arrays and immidate mode index array -
4347 // rebuild the arrays and the index array;
4348 ALOGE("glDrawElements: direct index & direct buffer data - will be implemented in later versions;\n");
4349 }
4350 }
4351}
4352
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004353const GLubyte* GL2Encoder::s_glGetStringi(void* self, GLenum name, GLuint index) {
4354 GL2Encoder *ctx = (GL2Encoder *)self;
Lingfeng Yanga16eb2e2018-02-23 11:26:53 -08004355 const GLubyte *retval = (GLubyte *) "";
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004356
4357 RET_AND_SET_ERROR_IF(
4358 name != GL_VENDOR &&
4359 name != GL_RENDERER &&
4360 name != GL_VERSION &&
4361 name != GL_EXTENSIONS,
4362 GL_INVALID_ENUM,
4363 retval);
4364
4365 RET_AND_SET_ERROR_IF(
Lingfeng Yang44209df2018-09-21 10:04:17 -07004366 (name == GL_VENDOR ||
4367 name == GL_RENDERER ||
4368 name == GL_VERSION) &&
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004369 index != 0,
4370 GL_INVALID_VALUE,
4371 retval);
4372
Lingfeng Yanga16eb2e2018-02-23 11:26:53 -08004373 RET_AND_SET_ERROR_IF(
4374 name == GL_EXTENSIONS &&
4375 index >= ctx->m_currExtensionsArray.size(),
4376 GL_INVALID_VALUE,
4377 retval);
4378
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004379 switch (name) {
4380 case GL_VENDOR:
4381 retval = gVendorString;
4382 break;
4383 case GL_RENDERER:
4384 retval = gRendererString;
4385 break;
4386 case GL_VERSION:
4387 retval = gVersionString;
4388 break;
4389 case GL_EXTENSIONS:
Lingfeng Yanga16eb2e2018-02-23 11:26:53 -08004390 retval = (const GLubyte*)(ctx->m_currExtensionsArray[index].c_str());
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004391 break;
4392 }
4393
4394 return retval;
4395}
4396
4397void GL2Encoder::s_glGetProgramBinary(void* self, GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, void* binary) {
4398 GL2Encoder *ctx = (GL2Encoder *)self;
4399
4400 SET_ERROR_IF(!ctx->m_shared->isProgram(program), GL_INVALID_OPERATION);
4401
4402 GLint linkStatus = 0;
4403 ctx->glGetProgramiv(self, program, GL_LINK_STATUS, &linkStatus);
4404 GLint properLength = 0;
4405 ctx->glGetProgramiv(self, program, GL_PROGRAM_BINARY_LENGTH, &properLength);
4406
4407 SET_ERROR_IF(!linkStatus, GL_INVALID_OPERATION);
4408 SET_ERROR_IF(bufSize < properLength, GL_INVALID_OPERATION);
4409
4410 ctx->m_glGetProgramBinary_enc(ctx, program, bufSize, length, binaryFormat, binary);
4411}
4412
4413void GL2Encoder::s_glReadPixels(void* self, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels) {
4414 GL2Encoder *ctx = (GL2Encoder *)self;
4415
4416 SET_ERROR_IF(!GLESv2Validation::readPixelsFormat(format), GL_INVALID_ENUM);
4417 SET_ERROR_IF(!GLESv2Validation::readPixelsType(type), GL_INVALID_ENUM);
4418 SET_ERROR_IF(width < 0 || height < 0, GL_INVALID_VALUE);
4419 SET_ERROR_IF(ctx->isBufferTargetMapped(GL_PIXEL_PACK_BUFFER), GL_INVALID_OPERATION);
4420 SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_PACK_BUFFER) &&
4421 ctx->getBufferData(GL_PIXEL_PACK_BUFFER) &&
4422 (ctx->m_state->pboNeededDataSize(width, height, 1, format, type, 1) >
4423 ctx->getBufferData(GL_PIXEL_PACK_BUFFER)->m_size),
4424 GL_INVALID_OPERATION);
4425 /*
4426GL_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.
4427
4428GL_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.
4429
4430GL_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.
4431
4432GL_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.
4433*/
4434
4435 FboFormatInfo fbo_format_info;
4436 ctx->m_state->getBoundFramebufferFormat(
4437 GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, &fbo_format_info);
4438 SET_ERROR_IF(
4439 fbo_format_info.type == FBO_ATTACHMENT_TEXTURE &&
4440 !GLESv2Validation::readPixelsFboFormatMatch(
4441 format, type, fbo_format_info.tex_type),
4442 GL_INVALID_OPERATION);
4443
4444 if (ctx->boundBuffer(GL_PIXEL_PACK_BUFFER)) {
4445 ctx->glReadPixelsOffsetAEMU(
4446 ctx, x, y, width, height,
4447 format, type, (uintptr_t)pixels);
4448 } else {
4449 ctx->m_glReadPixels_enc(
4450 ctx, x, y, width, height,
4451 format, type, pixels);
4452 }
4453}
4454
4455// Track enabled state for some things like:
4456// - Primitive restart
4457void GL2Encoder::s_glEnable(void* self, GLenum what) {
4458 GL2Encoder *ctx = (GL2Encoder *)self;
4459
4460 switch (what) {
4461 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
4462 ctx->m_primitiveRestartEnabled = true;
4463 break;
4464 }
4465
4466 ctx->m_glEnable_enc(ctx, what);
4467}
4468
4469void GL2Encoder::s_glDisable(void* self, GLenum what) {
4470 GL2Encoder *ctx = (GL2Encoder *)self;
4471
4472 switch (what) {
4473 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
4474 ctx->m_primitiveRestartEnabled = false;
4475 break;
4476 }
4477
4478 ctx->m_glDisable_enc(ctx, what);
4479}
4480
4481void GL2Encoder::s_glClearBufferiv(void* self, GLenum buffer, GLint drawBuffer, const GLint * value) {
4482 GL2Encoder *ctx = (GL2Encoder *)self;
4483
4484 SET_ERROR_IF(buffer == GL_DEPTH || buffer == GL_DEPTH_STENCIL, GL_INVALID_ENUM);
4485
4486 ctx->m_glClearBufferiv_enc(ctx, buffer, drawBuffer, value);
4487}
4488
4489void GL2Encoder::s_glClearBufferuiv(void* self, GLenum buffer, GLint drawBuffer, const GLuint * value) {
4490 GL2Encoder *ctx = (GL2Encoder *)self;
4491
4492 SET_ERROR_IF(buffer == GL_DEPTH || buffer == GL_STENCIL || buffer == GL_DEPTH_STENCIL, GL_INVALID_ENUM);
4493
4494 ctx->m_glClearBufferuiv_enc(ctx, buffer, drawBuffer, value);
4495}
4496
4497void GL2Encoder::s_glClearBufferfv(void* self, GLenum buffer, GLint drawBuffer, const GLfloat * value) {
4498 GL2Encoder *ctx = (GL2Encoder *)self;
4499
4500 SET_ERROR_IF(buffer == GL_STENCIL || buffer == GL_DEPTH_STENCIL, GL_INVALID_ENUM);
4501
4502 ctx->m_glClearBufferfv_enc(ctx, buffer, drawBuffer, value);
4503}
4504
4505void 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) {
4506 GL2Encoder *ctx = (GL2Encoder *)self;
4507 GLClientState* state = ctx->m_state;
4508
Lingfeng Yangb678c362019-06-05 08:00:21 -07004509 bool validateColor = mask & GL_COLOR_BUFFER_BIT;
4510 bool validateDepth = mask & GL_DEPTH_BUFFER_BIT;
4511 bool validateStencil = mask & GL_STENCIL_BUFFER_BIT;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004512
4513 FboFormatInfo read_fbo_format_info;
4514 FboFormatInfo draw_fbo_format_info;
4515 if (validateColor) {
4516 state->getBoundFramebufferFormat(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, &read_fbo_format_info);
4517 state->getBoundFramebufferFormat(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, &draw_fbo_format_info);
4518
4519 if (read_fbo_format_info.type == FBO_ATTACHMENT_TEXTURE &&
4520 draw_fbo_format_info.type == FBO_ATTACHMENT_TEXTURE) {
4521 SET_ERROR_IF(
4522 state->boundFramebuffer(GL_READ_FRAMEBUFFER) &&
4523 state->boundFramebuffer(GL_DRAW_FRAMEBUFFER) &&
4524 !GLESv2Validation::blitFramebufferFormat(
4525 read_fbo_format_info.tex_type,
4526 draw_fbo_format_info.tex_type),
4527 GL_INVALID_OPERATION);
4528 }
4529 }
4530
4531 if (validateDepth) {
4532 state->getBoundFramebufferFormat(GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, &read_fbo_format_info);
4533 state->getBoundFramebufferFormat(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, &draw_fbo_format_info);
4534
4535 if (read_fbo_format_info.type == FBO_ATTACHMENT_RENDERBUFFER &&
4536 draw_fbo_format_info.type == FBO_ATTACHMENT_RENDERBUFFER) {
4537 SET_ERROR_IF(
4538 state->boundFramebuffer(GL_READ_FRAMEBUFFER) &&
4539 state->boundFramebuffer(GL_DRAW_FRAMEBUFFER) &&
4540 !GLESv2Validation::blitFramebufferFormat(
4541 read_fbo_format_info.rb_format,
4542 draw_fbo_format_info.rb_format),
4543 GL_INVALID_OPERATION);
4544 }
4545 }
4546
4547 if (validateStencil) {
4548 state->getBoundFramebufferFormat(GL_READ_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, &read_fbo_format_info);
4549 state->getBoundFramebufferFormat(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, &draw_fbo_format_info);
4550
4551 if (read_fbo_format_info.type == FBO_ATTACHMENT_RENDERBUFFER &&
4552 draw_fbo_format_info.type == FBO_ATTACHMENT_RENDERBUFFER) {
4553 SET_ERROR_IF(
4554 state->boundFramebuffer(GL_READ_FRAMEBUFFER) &&
4555 state->boundFramebuffer(GL_DRAW_FRAMEBUFFER) &&
4556 !GLESv2Validation::blitFramebufferFormat(
4557 read_fbo_format_info.rb_format,
4558 draw_fbo_format_info.rb_format),
4559 GL_INVALID_OPERATION);
4560 }
4561 }
4562
4563 state->getBoundFramebufferFormat(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, &draw_fbo_format_info);
4564 SET_ERROR_IF(
4565 draw_fbo_format_info.type == FBO_ATTACHMENT_RENDERBUFFER &&
4566 draw_fbo_format_info.rb_multisamples > 0,
4567 GL_INVALID_OPERATION);
4568 SET_ERROR_IF(
4569 draw_fbo_format_info.type == FBO_ATTACHMENT_TEXTURE &&
4570 draw_fbo_format_info.tex_multisamples > 0,
4571 GL_INVALID_OPERATION);
4572
4573 state->getBoundFramebufferFormat(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, &read_fbo_format_info);
4574 SET_ERROR_IF(
4575 read_fbo_format_info.type == FBO_ATTACHMENT_RENDERBUFFER &&
4576 read_fbo_format_info.rb_multisamples > 0 &&
4577 draw_fbo_format_info.type == FBO_ATTACHMENT_RENDERBUFFER &&
4578 state->boundFramebuffer(GL_READ_FRAMEBUFFER) &&
4579 state->boundFramebuffer(GL_DRAW_FRAMEBUFFER) &&
4580 (read_fbo_format_info.rb_format !=
4581 draw_fbo_format_info.rb_format),
4582 GL_INVALID_OPERATION);
4583 SET_ERROR_IF(
4584 read_fbo_format_info.type == FBO_ATTACHMENT_RENDERBUFFER &&
4585 read_fbo_format_info.rb_multisamples > 0 &&
4586 draw_fbo_format_info.type == FBO_ATTACHMENT_RENDERBUFFER &&
4587 (srcX0 != dstX0 || srcY0 != dstY0 ||
4588 srcX1 != dstX1 || srcY1 != dstY1),
4589 GL_INVALID_OPERATION);
4590
4591 ctx->m_glBlitFramebuffer_enc(ctx,
4592 srcX0, srcY0, srcX1, srcY1,
4593 dstX0, dstY0, dstX1, dstY1,
4594 mask, filter);
4595}
4596
4597void GL2Encoder::s_glGetInternalformativ(void* self, GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params) {
4598 GL2Encoder *ctx = (GL2Encoder *)self;
4599
4600 SET_ERROR_IF(pname != GL_NUM_SAMPLE_COUNTS &&
4601 pname != GL_SAMPLES,
4602 GL_INVALID_ENUM);
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08004603 SET_ERROR_IF(!GLESv2Validation::internalFormatTarget(ctx, target), GL_INVALID_ENUM);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004604 SET_ERROR_IF(!GLESv2Validation::unsizedFormat(internalformat) &&
Lingfeng Yang931817b2017-01-27 06:50:56 -08004605 !GLESv2Validation::colorRenderableFormat(ctx, internalformat) &&
4606 !GLESv2Validation::depthRenderableFormat(ctx, internalformat) &&
4607 !GLESv2Validation::stencilRenderableFormat(ctx, internalformat),
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004608 GL_INVALID_ENUM);
4609 SET_ERROR_IF(bufSize < 0, GL_INVALID_VALUE);
4610
4611 if (bufSize < 1) return;
4612
4613 // Desktop OpenGL can allow a mindboggling # samples per pixel (such as 64).
4614 // Limit to 4 (spec minimum) to keep dEQP tests from timing out.
4615 switch (pname) {
4616 case GL_NUM_SAMPLE_COUNTS:
4617 *params = 3;
4618 break;
4619 case GL_SAMPLES:
4620 params[0] = 4;
4621 if (bufSize > 1) params[1] = 2;
4622 if (bufSize > 2) params[2] = 1;
4623 break;
4624 default:
4625 break;
4626 }
4627}
4628
4629void GL2Encoder::s_glGenerateMipmap(void* self, GLenum target) {
4630 GL2Encoder *ctx = (GL2Encoder *)self;
4631 GLClientState* state = ctx->m_state;
4632
4633 SET_ERROR_IF(target != GL_TEXTURE_2D &&
4634 target != GL_TEXTURE_3D &&
Yahan Zhou53c64582018-04-16 15:46:17 -07004635 target != GL_TEXTURE_CUBE_MAP &&
4636 target != GL_TEXTURE_2D_ARRAY,
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004637 GL_INVALID_ENUM);
4638
4639 GLuint tex = state->getBoundTexture(target);
4640 GLenum internalformat = state->queryTexInternalFormat(tex);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004641
4642 SET_ERROR_IF(tex && GLESv2Validation::isCompressedFormat(internalformat),
4643 GL_INVALID_OPERATION);
4644 SET_ERROR_IF(tex &&
4645 !GLESv2Validation::unsizedFormat(internalformat) &&
Lingfeng Yang931817b2017-01-27 06:50:56 -08004646 !(GLESv2Validation::colorRenderableFormat(ctx, internalformat) &&
4647 GLESv2Validation::filterableTexFormat(ctx, internalformat)),
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004648 GL_INVALID_OPERATION);
4649
Lingfeng Yanga9fff6a2018-03-02 13:42:51 -08004650 if (target == GL_TEXTURE_2D) {
4651 ctx->override2DTextureTarget(target);
4652 }
4653
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004654 ctx->m_glGenerateMipmap_enc(ctx, target);
Lingfeng Yanga9fff6a2018-03-02 13:42:51 -08004655
4656 if (target == GL_TEXTURE_2D) {
4657 ctx->restore2DTextureTarget(target);
4658 }
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004659}
4660
4661void GL2Encoder::s_glBindSampler(void* self, GLuint unit, GLuint sampler) {
4662 GL2Encoder *ctx = (GL2Encoder *)self;
4663 GLint maxCombinedUnits;
4664 ctx->glGetIntegerv(ctx, GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxCombinedUnits);
4665 SET_ERROR_IF(unit >= maxCombinedUnits, GL_INVALID_VALUE);
4666
Lingfeng Yang554a5152019-02-21 20:20:48 -08004667 ctx->doSamplerBindEncodeCached(unit, sampler);
4668}
4669
4670void GL2Encoder::doSamplerBindEncodeCached(GLuint unit, GLuint sampler) {
4671 if (m_state->isSamplerBindNoOp(unit, sampler)) return;
4672 m_glBindSampler_enc(this, unit, sampler);
4673 m_state->bindSampler(unit, sampler);
4674}
4675
4676void GL2Encoder::s_glDeleteSamplers(void* self, GLsizei n, const GLuint* samplers) {
4677 GL2Encoder *ctx = (GL2Encoder *)self;
4678 ctx->m_state->onDeleteSamplers(n, samplers);
4679 ctx->m_glDeleteSamplers_enc(ctx, n, samplers);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004680}
4681
Lingfeng Yangf000ab42017-01-11 18:31:38 -08004682GLsync GL2Encoder::s_glFenceSync(void* self, GLenum condition, GLbitfield flags) {
4683 GL2Encoder *ctx = (GL2Encoder *)self;
4684 uint64_t syncHandle = ctx->glFenceSyncAEMU(ctx, condition, flags);
4685 return (GLsync)(uintptr_t)syncHandle;
4686}
4687
4688GLenum GL2Encoder::s_glClientWaitSync(void* self, GLsync wait_on, GLbitfield flags, GLuint64 timeout) {
4689 GL2Encoder *ctx = (GL2Encoder *)self;
4690 return ctx->glClientWaitSyncAEMU(ctx, (uint64_t)(uintptr_t)wait_on, flags, timeout);
4691}
4692
4693void GL2Encoder::s_glWaitSync(void* self, GLsync wait_on, GLbitfield flags, GLuint64 timeout) {
4694 GL2Encoder *ctx = (GL2Encoder *)self;
4695 ctx->glWaitSyncAEMU(ctx, (uint64_t)(uintptr_t)wait_on, flags, timeout);
4696}
4697
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004698void GL2Encoder::s_glDeleteSync(void* self, GLsync sync) {
4699 GL2Encoder *ctx = (GL2Encoder *)self;
4700
4701 if (!sync) return;
4702
Lingfeng Yangf000ab42017-01-11 18:31:38 -08004703 ctx->glDeleteSyncAEMU(ctx, (uint64_t)(uintptr_t)sync);
4704}
4705
4706GLboolean GL2Encoder::s_glIsSync(void* self, GLsync sync) {
4707 GL2Encoder *ctx = (GL2Encoder *)self;
4708 return ctx->glIsSyncAEMU(ctx, (uint64_t)(uintptr_t)sync);
4709}
4710
4711void GL2Encoder::s_glGetSynciv(void* self, GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values) {
4712 GL2Encoder *ctx = (GL2Encoder *)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08004713
4714 SET_ERROR_IF(bufSize < 0, GL_INVALID_VALUE);
4715
Lingfeng Yangf000ab42017-01-11 18:31:38 -08004716 return ctx->glGetSyncivAEMU(ctx, (uint64_t)(uintptr_t)sync, pname, bufSize, length, values);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004717}
4718
4719#define LIMIT_CASE(target, lim) \
4720 case target: \
4721 ctx->glGetIntegerv(ctx, lim, &limit); \
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08004722 SET_ERROR_IF(index < 0 || index >= limit, GL_INVALID_VALUE); \
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004723 break; \
4724
4725void GL2Encoder::s_glGetIntegeri_v(void* self, GLenum target, GLuint index, GLint* params) {
4726 GL2Encoder *ctx = (GL2Encoder *)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08004727 GLClientState* state = ctx->m_state;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004728
4729 GLint limit;
4730
4731 switch (target) {
4732 LIMIT_CASE(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS)
4733 LIMIT_CASE(GL_UNIFORM_BUFFER_BINDING, GL_MAX_UNIFORM_BUFFER_BINDINGS)
4734 LIMIT_CASE(GL_ATOMIC_COUNTER_BUFFER_BINDING, GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS)
4735 LIMIT_CASE(GL_SHADER_STORAGE_BUFFER_BINDING, GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS)
4736 default:
4737 break;
4738 }
4739
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08004740 const GLClientState::VertexAttribBindingVector& currBindings =
4741 state->currentVertexBufferBindings();
4742
4743 switch (target) {
4744 case GL_VERTEX_BINDING_DIVISOR:
4745 case GL_VERTEX_BINDING_OFFSET:
4746 case GL_VERTEX_BINDING_STRIDE:
4747 case GL_VERTEX_BINDING_BUFFER:
4748 SET_ERROR_IF(index < 0 || index > currBindings.size(), GL_INVALID_VALUE);
4749 break;
4750 default:
4751 break;
4752 }
4753
4754 switch (target) {
4755 case GL_VERTEX_BINDING_DIVISOR:
4756 *params = currBindings[index].divisor;
4757 return;
4758 case GL_VERTEX_BINDING_OFFSET:
4759 *params = currBindings[index].offset;
4760 return;
4761 case GL_VERTEX_BINDING_STRIDE:
4762 *params = currBindings[index].effectiveStride;
4763 return;
4764 case GL_VERTEX_BINDING_BUFFER:
4765 *params = currBindings[index].buffer;
4766 return;
4767 default:
4768 break;
4769 }
4770
Lingfeng Yang80a36332017-07-09 10:58:07 -07004771 ctx->safe_glGetIntegeri_v(target, index, params);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004772}
4773
4774void GL2Encoder::s_glGetInteger64i_v(void* self, GLenum target, GLuint index, GLint64* params) {
4775 GL2Encoder *ctx = (GL2Encoder *)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08004776 GLClientState* state = ctx->m_state;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004777
4778 GLint limit;
4779
4780 switch (target) {
4781 LIMIT_CASE(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS)
4782 LIMIT_CASE(GL_UNIFORM_BUFFER_BINDING, GL_MAX_UNIFORM_BUFFER_BINDINGS)
4783 LIMIT_CASE(GL_ATOMIC_COUNTER_BUFFER_BINDING, GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS)
4784 LIMIT_CASE(GL_SHADER_STORAGE_BUFFER_BINDING, GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS)
4785 default:
4786 break;
4787 }
4788
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08004789 const GLClientState::VertexAttribBindingVector& currBindings =
4790 state->currentVertexBufferBindings();
4791
4792 switch (target) {
4793 case GL_VERTEX_BINDING_DIVISOR:
4794 case GL_VERTEX_BINDING_OFFSET:
4795 case GL_VERTEX_BINDING_STRIDE:
4796 case GL_VERTEX_BINDING_BUFFER:
4797 SET_ERROR_IF(index < 0 || index > currBindings.size(), GL_INVALID_VALUE);
4798 break;
4799 default:
4800 break;
4801 }
4802
4803 switch (target) {
4804 case GL_VERTEX_BINDING_DIVISOR:
4805 *params = currBindings[index].divisor;
4806 return;
4807 case GL_VERTEX_BINDING_OFFSET:
4808 *params = currBindings[index].offset;
4809 return;
4810 case GL_VERTEX_BINDING_STRIDE:
4811 *params = currBindings[index].effectiveStride;
4812 return;
4813 case GL_VERTEX_BINDING_BUFFER:
4814 *params = currBindings[index].buffer;
4815 return;
4816 default:
4817 break;
4818 }
4819
Lingfeng Yang80a36332017-07-09 10:58:07 -07004820 ctx->safe_glGetInteger64i_v(target, index, params);
4821}
4822
4823void GL2Encoder::s_glGetInteger64v(void* self, GLenum param, GLint64* val) {
4824 GL2Encoder *ctx = (GL2Encoder *)self;
4825 ctx->safe_glGetInteger64v(param, val);
4826}
4827
4828void GL2Encoder::s_glGetBooleani_v(void* self, GLenum param, GLuint index, GLboolean* val) {
4829 GL2Encoder *ctx = (GL2Encoder *)self;
4830 ctx->safe_glGetBooleani_v(param, index, val);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004831}
4832
4833void GL2Encoder::s_glGetShaderiv(void* self, GLuint shader, GLenum pname, GLint* params) {
4834 GL2Encoder *ctx = (GL2Encoder *)self;
4835 ctx->m_glGetShaderiv_enc(self, shader, pname, params);
4836 if (pname == GL_SHADER_SOURCE_LENGTH) {
4837 ShaderData* shaderData = ctx->m_shared->getShaderData(shader);
4838 if (shaderData) {
4839 int totalLen = 0;
4840 for (int i = 0; i < shaderData->sources.size(); i++) {
4841 totalLen += shaderData->sources[i].size();
4842 }
4843 if (totalLen != 0) {
4844 *params = totalLen + 1; // account for null terminator
4845 }
4846 }
4847 }
4848}
4849
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08004850void GL2Encoder::s_glActiveShaderProgram(void* self, GLuint pipeline, GLuint program) {
4851 GL2Encoder *ctx = (GL2Encoder*)self;
4852 GLClientState* state = ctx->m_state;
4853 GLSharedGroupPtr shared = ctx->m_shared;
4854
4855 SET_ERROR_IF(!pipeline, GL_INVALID_OPERATION);
4856 SET_ERROR_IF(program && !shared->isShaderOrProgramObject(program), GL_INVALID_VALUE);
4857 SET_ERROR_IF(program && !shared->isProgram(program), GL_INVALID_OPERATION);
4858
4859 ctx->m_glActiveShaderProgram_enc(ctx, pipeline, program);
4860 if (!state->currentProgram()) {
4861 state->setCurrentShaderProgram(program);
4862 }
4863}
4864
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004865GLuint GL2Encoder::s_glCreateShaderProgramv(void* self, GLenum type, GLsizei count, const char** strings) {
4866
4867 GLint* length = NULL;
4868 GL2Encoder* ctx = (GL2Encoder*)self;
4869
4870 int len = glUtilsCalcShaderSourceLen((char**)strings, length, count);
4871 char *str = new char[len + 1];
4872 glUtilsPackStrings(str, (char**)strings, (GLint*)length, count);
Lingfeng Yang554a5152019-02-21 20:20:48 -08004873
4874 // Do GLSharedGroup and location WorkARound-specific initialization
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004875 // Phase 1: create a ShaderData and initialize with replaceSamplerExternalWith2D()
4876 uint32_t spDataId = ctx->m_shared->addNewShaderProgramData();
4877 ShaderProgramData* spData = ctx->m_shared->getShaderProgramDataById(spDataId);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004878
Lingfeng Yang44209df2018-09-21 10:04:17 -07004879 if (!replaceSamplerExternalWith2D(str, &spData->shaderData)) {
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004880 delete [] str;
4881 ctx->setError(GL_OUT_OF_MEMORY);
4882 ctx->m_shared->deleteShaderProgramDataById(spDataId);
4883 return -1;
4884 }
4885
4886 GLuint res = ctx->glCreateShaderProgramvAEMU(ctx, type, count, str, len + 1);
4887 delete [] str;
4888
4889 // Phase 2: do glLinkProgram-related initialization for locationWorkARound
4890 GLint linkStatus = 0;
4891 ctx->glGetProgramiv(self, res, GL_LINK_STATUS ,&linkStatus);
4892 if (!linkStatus) {
4893 ctx->m_shared->deleteShaderProgramDataById(spDataId);
4894 return -1;
4895 }
4896
4897 ctx->m_shared->associateGLShaderProgram(res, spDataId);
4898
4899 GLint numUniforms = 0;
Lingfeng Yang80a36332017-07-09 10:58:07 -07004900 ctx->glGetProgramiv(self, res, GL_ACTIVE_UNIFORMS, &numUniforms);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004901 ctx->m_shared->initShaderProgramData(res, numUniforms);
4902
4903 GLint maxLength=0;
4904 ctx->glGetProgramiv(self, res, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxLength);
4905
4906 GLint size; GLenum uniformType; GLchar* name = new GLchar[maxLength + 1];
4907
4908 for (GLint i = 0; i < numUniforms; ++i) {
4909 ctx->glGetActiveUniform(self, res, i, maxLength, NULL, &size, &uniformType, name);
4910 GLint location = ctx->m_glGetUniformLocation_enc(self, res, name);
4911 ctx->m_shared->setShaderProgramIndexInfo(res, i, location, size, uniformType, name);
4912 }
4913
4914 ctx->m_shared->setupShaderProgramLocationShiftWAR(res);
4915
4916 delete [] name;
4917
4918 return res;
4919}
4920
4921void GL2Encoder::s_glProgramUniform1f(void* self, GLuint program, GLint location, GLfloat v0)
4922{
4923 GL2Encoder *ctx = (GL2Encoder*)self;
4924 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
4925 ctx->m_glProgramUniform1f_enc(self, program, hostLoc, v0);
4926}
4927
4928void GL2Encoder::s_glProgramUniform1fv(void* self, GLuint program, GLint location, GLsizei count, const GLfloat *value)
4929{
4930 GL2Encoder *ctx = (GL2Encoder*)self;
4931 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
4932 ctx->m_glProgramUniform1fv_enc(self, program, hostLoc, count, value);
4933}
4934
4935void GL2Encoder::s_glProgramUniform1i(void* self, GLuint program, GLint location, GLint v0)
4936{
4937 GL2Encoder *ctx = (GL2Encoder*)self;
4938 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08004939 ctx->m_glProgramUniform1i_enc(self, program, hostLoc, v0);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004940
4941 GLClientState* state = ctx->m_state;
4942 GLSharedGroupPtr shared = ctx->m_shared;
4943 GLenum target;
4944
4945 if (shared->setSamplerUniform(program, location, v0, &target)) {
4946 GLenum origActiveTexture = state->getActiveTextureUnit();
4947 if (ctx->updateHostTexture2DBinding(GL_TEXTURE0 + v0, target)) {
4948 ctx->m_glActiveTexture_enc(self, origActiveTexture);
4949 }
4950 state->setActiveTextureUnit(origActiveTexture);
4951 }
4952}
4953
4954void GL2Encoder::s_glProgramUniform1iv(void* self, GLuint program, GLint location, GLsizei count, const GLint *value)
4955{
4956 GL2Encoder *ctx = (GL2Encoder*)self;
4957 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
4958 ctx->m_glProgramUniform1iv_enc(self, program, hostLoc, count, value);
4959}
4960
4961void GL2Encoder::s_glProgramUniform1ui(void* self, GLuint program, GLint location, GLuint v0)
4962{
4963 GL2Encoder *ctx = (GL2Encoder*)self;
4964 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
4965 ctx->m_glProgramUniform1ui_enc(self, program, hostLoc, v0);
4966
4967 GLClientState* state = ctx->m_state;
4968 GLSharedGroupPtr shared = ctx->m_shared;
4969 GLenum target;
4970
4971 if (shared->setSamplerUniform(program, location, v0, &target)) {
4972 GLenum origActiveTexture = state->getActiveTextureUnit();
4973 if (ctx->updateHostTexture2DBinding(GL_TEXTURE0 + v0, target)) {
4974 ctx->m_glActiveTexture_enc(self, origActiveTexture);
4975 }
4976 state->setActiveTextureUnit(origActiveTexture);
4977 }
4978}
4979
4980void GL2Encoder::s_glProgramUniform1uiv(void* self, GLuint program, GLint location, GLsizei count, const GLuint *value)
4981{
4982 GL2Encoder *ctx = (GL2Encoder*)self;
4983 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
4984 ctx->m_glProgramUniform1uiv_enc(self, program, hostLoc, count, value);
4985}
4986
4987void GL2Encoder::s_glProgramUniform2f(void* self, GLuint program, GLint location, GLfloat v0, GLfloat v1)
4988{
4989 GL2Encoder *ctx = (GL2Encoder*)self;
4990 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
4991 ctx->m_glProgramUniform2f_enc(self, program, hostLoc, v0, v1);
4992}
4993
4994void GL2Encoder::s_glProgramUniform2fv(void* self, GLuint program, GLint location, GLsizei count, const GLfloat *value)
4995{
4996 GL2Encoder *ctx = (GL2Encoder*)self;
4997 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
4998 ctx->m_glProgramUniform2fv_enc(self, program, hostLoc, count, value);
4999}
5000
5001void GL2Encoder::s_glProgramUniform2i(void* self, GLuint program, GLint location, GLint v0, GLint v1)
5002{
5003 GL2Encoder *ctx = (GL2Encoder*)self;
5004 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
5005 ctx->m_glProgramUniform2i_enc(self, program, hostLoc, v0, v1);
5006}
5007
5008void GL2Encoder::s_glProgramUniform2iv(void* self, GLuint program, GLint location, GLsizei count, const GLint *value)
5009{
5010 GL2Encoder *ctx = (GL2Encoder*)self;
5011 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
5012 ctx->m_glProgramUniform2iv_enc(self, program, hostLoc, count, value);
5013}
5014
5015void GL2Encoder::s_glProgramUniform2ui(void* self, GLuint program, GLint location, GLint v0, GLuint v1)
5016{
5017 GL2Encoder *ctx = (GL2Encoder*)self;
5018 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
5019 ctx->m_glProgramUniform2ui_enc(self, program, hostLoc, v0, v1);
5020}
5021
5022void GL2Encoder::s_glProgramUniform2uiv(void* self, GLuint program, GLint location, GLsizei count, const GLuint *value)
5023{
5024 GL2Encoder *ctx = (GL2Encoder*)self;
5025 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
5026 ctx->m_glProgramUniform2uiv_enc(self, program, hostLoc, count, value);
5027}
5028
5029void GL2Encoder::s_glProgramUniform3f(void* self, GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2)
5030{
5031 GL2Encoder *ctx = (GL2Encoder*)self;
5032 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
5033 ctx->m_glProgramUniform3f_enc(self, program, hostLoc, v0, v1, v2);
5034}
5035
5036void GL2Encoder::s_glProgramUniform3fv(void* self, GLuint program, GLint location, GLsizei count, const GLfloat *value)
5037{
5038 GL2Encoder *ctx = (GL2Encoder*)self;
5039 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
5040 ctx->m_glProgramUniform3fv_enc(self, program, hostLoc, count, value);
5041}
5042
5043void GL2Encoder::s_glProgramUniform3i(void* self, GLuint program, GLint location, GLint v0, GLint v1, GLint v2)
5044{
5045 GL2Encoder *ctx = (GL2Encoder*)self;
5046 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
5047 ctx->m_glProgramUniform3i_enc(self, program, hostLoc, v0, v1, v2);
5048}
5049
5050void GL2Encoder::s_glProgramUniform3iv(void* self, GLuint program, GLint location, GLsizei count, const GLint *value)
5051{
5052 GL2Encoder *ctx = (GL2Encoder*)self;
5053 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
5054 ctx->m_glProgramUniform3iv_enc(self, program, hostLoc, count, value);
5055}
5056
5057void GL2Encoder::s_glProgramUniform3ui(void* self, GLuint program, GLint location, GLint v0, GLint v1, GLuint v2)
5058{
5059 GL2Encoder *ctx = (GL2Encoder*)self;
5060 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
5061 ctx->m_glProgramUniform3ui_enc(self, program, hostLoc, v0, v1, v2);
5062}
5063
5064void GL2Encoder::s_glProgramUniform3uiv(void* self, GLuint program, GLint location, GLsizei count, const GLuint *value)
5065{
5066 GL2Encoder *ctx = (GL2Encoder*)self;
5067 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
5068 ctx->m_glProgramUniform3uiv_enc(self, program, hostLoc, count, value);
5069}
5070
5071void GL2Encoder::s_glProgramUniform4f(void* self, GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3)
5072{
5073 GL2Encoder *ctx = (GL2Encoder*)self;
5074 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
5075 ctx->m_glProgramUniform4f_enc(self, program, hostLoc, v0, v1, v2, v3);
5076}
5077
5078void GL2Encoder::s_glProgramUniform4fv(void* self, GLuint program, GLint location, GLsizei count, const GLfloat *value)
5079{
5080 GL2Encoder *ctx = (GL2Encoder*)self;
5081 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
5082 ctx->m_glProgramUniform4fv_enc(self, program, hostLoc, count, value);
5083}
5084
5085void GL2Encoder::s_glProgramUniform4i(void* self, GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3)
5086{
5087 GL2Encoder *ctx = (GL2Encoder*)self;
5088 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
5089 ctx->m_glProgramUniform4i_enc(self, program, hostLoc, v0, v1, v2, v3);
5090}
5091
5092void GL2Encoder::s_glProgramUniform4iv(void* self, GLuint program, GLint location, GLsizei count, const GLint *value)
5093{
5094 GL2Encoder *ctx = (GL2Encoder*)self;
5095 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
5096 ctx->m_glProgramUniform4iv_enc(self, program, hostLoc, count, value);
5097}
5098
5099void GL2Encoder::s_glProgramUniform4ui(void* self, GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLuint v3)
5100{
5101 GL2Encoder *ctx = (GL2Encoder*)self;
5102 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
5103 ctx->m_glProgramUniform4ui_enc(self, program, hostLoc, v0, v1, v2, v3);
5104}
5105
5106void GL2Encoder::s_glProgramUniform4uiv(void* self, GLuint program, GLint location, GLsizei count, const GLuint *value)
5107{
5108 GL2Encoder *ctx = (GL2Encoder*)self;
5109 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
5110 ctx->m_glProgramUniform4uiv_enc(self, program, hostLoc, count, value);
5111}
5112
5113void GL2Encoder::s_glProgramUniformMatrix2fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
5114{
5115 GL2Encoder *ctx = (GL2Encoder*)self;
5116 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
5117 ctx->m_glProgramUniformMatrix2fv_enc(self, program, hostLoc, count, transpose, value);
5118}
5119
5120void GL2Encoder::s_glProgramUniformMatrix2x3fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
5121{
5122 GL2Encoder *ctx = (GL2Encoder*)self;
5123 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
5124 ctx->m_glProgramUniformMatrix2x3fv_enc(self, program, hostLoc, count, transpose, value);
5125}
5126
5127void GL2Encoder::s_glProgramUniformMatrix2x4fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
5128{
5129 GL2Encoder *ctx = (GL2Encoder*)self;
5130 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
5131 ctx->m_glProgramUniformMatrix2x4fv_enc(self, program, hostLoc, count, transpose, value);
5132}
5133
5134void GL2Encoder::s_glProgramUniformMatrix3fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
5135{
5136 GL2Encoder *ctx = (GL2Encoder*)self;
5137 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
5138 ctx->m_glProgramUniformMatrix3fv_enc(self, program, hostLoc, count, transpose, value);
5139}
5140
5141void GL2Encoder::s_glProgramUniformMatrix3x2fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
5142{
5143 GL2Encoder *ctx = (GL2Encoder*)self;
5144 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
5145 ctx->m_glProgramUniformMatrix3x2fv_enc(self, program, hostLoc, count, transpose, value);
5146}
5147
5148void GL2Encoder::s_glProgramUniformMatrix3x4fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
5149{
5150 GL2Encoder *ctx = (GL2Encoder*)self;
5151 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
5152 ctx->m_glProgramUniformMatrix3x4fv_enc(self, program, hostLoc, count, transpose, value);
5153}
5154
5155void GL2Encoder::s_glProgramUniformMatrix4fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
5156{
5157 GL2Encoder *ctx = (GL2Encoder*)self;
5158 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
5159 ctx->m_glProgramUniformMatrix4fv_enc(self, program, hostLoc, count, transpose, value);
5160}
5161
5162void GL2Encoder::s_glProgramUniformMatrix4x2fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
5163{
5164 GL2Encoder *ctx = (GL2Encoder*)self;
5165 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
5166 ctx->m_glProgramUniformMatrix4x2fv_enc(self, program, hostLoc, count, transpose, value);
5167}
5168
5169void GL2Encoder::s_glProgramUniformMatrix4x3fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
5170{
5171 GL2Encoder *ctx = (GL2Encoder*)self;
5172 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
5173 ctx->m_glProgramUniformMatrix4x3fv_enc(self, program, hostLoc, count, transpose, value);
5174}
5175
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08005176void GL2Encoder::s_glProgramParameteri(void* self, GLuint program, GLenum pname, GLint value) {
5177 GL2Encoder* ctx = (GL2Encoder*)self;
5178 ctx->m_glProgramParameteri_enc(self, program, pname, value);
5179}
5180
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005181void GL2Encoder::s_glUseProgramStages(void *self, GLuint pipeline, GLbitfield stages, GLuint program)
5182{
5183 GL2Encoder *ctx = (GL2Encoder*)self;
5184 GLClientState* state = ctx->m_state;
5185 GLSharedGroupPtr shared = ctx->m_shared;
5186
5187 SET_ERROR_IF(!pipeline, GL_INVALID_OPERATION);
5188 SET_ERROR_IF(program && !shared->isShaderOrProgramObject(program), GL_INVALID_VALUE);
5189 SET_ERROR_IF(program && !shared->isProgram(program), GL_INVALID_OPERATION);
5190
5191 ctx->m_glUseProgramStages_enc(self, pipeline, stages, program);
5192 state->associateProgramWithPipeline(program, pipeline);
5193
5194 // There is an active non-separable shader program in effect; no need to update external/2D bindings.
5195 if (state->currentProgram()) {
5196 return;
5197 }
5198
5199 // Otherwise, update host texture 2D bindings.
5200 ctx->updateHostTexture2DBindingsFromProgramData(program);
5201}
5202
5203void GL2Encoder::s_glBindProgramPipeline(void* self, GLuint pipeline)
5204{
5205 GL2Encoder *ctx = (GL2Encoder*)self;
5206 GLClientState* state = ctx->m_state;
5207
5208 ctx->m_glBindProgramPipeline_enc(self, pipeline);
5209
5210 // There is an active non-separable shader program in effect; no need to update external/2D bindings.
5211 if (!pipeline || state->currentProgram()) {
5212 return;
5213 }
5214
5215 GLClientState::ProgramPipelineIterator it = state->programPipelineBegin();
5216 for (; it != state->programPipelineEnd(); ++it) {
5217 if (it->second == pipeline) {
5218 ctx->updateHostTexture2DBindingsFromProgramData(it->first);
5219 }
5220 }
5221}
5222
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08005223void GL2Encoder::s_glGetProgramResourceiv(void* self, GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum * props, GLsizei bufSize, GLsizei * length, GLint * params) {
5224 GL2Encoder *ctx = (GL2Encoder*)self;
5225 SET_ERROR_IF(bufSize < 0, GL_INVALID_VALUE);
5226 if (bufSize == 0) {
5227 if (length) *length = 0;
5228 return;
5229 }
5230
5231 // Avoid modifying |name| if |*length| < bufSize.
5232 GLint* intermediate = new GLint[bufSize];
5233 GLsizei* myLength = length ? length : new GLsizei;
5234 bool needFreeLength = length == NULL;
5235
5236 ctx->m_glGetProgramResourceiv_enc(self, program, programInterface, index, propCount, props, bufSize, myLength, intermediate);
5237 GLsizei writtenInts = *myLength;
5238 memcpy(params, intermediate, writtenInts * sizeof(GLint));
5239
5240 delete [] intermediate;
5241 if (needFreeLength)
5242 delete myLength;
5243}
5244
5245GLuint GL2Encoder::s_glGetProgramResourceIndex(void* self, GLuint program, GLenum programInterface, const char* name) {
5246 GL2Encoder *ctx = (GL2Encoder*)self;
5247 return ctx->m_glGetProgramResourceIndex_enc(self, program, programInterface, name);
5248}
5249
5250GLint GL2Encoder::s_glGetProgramResourceLocation(void* self, GLuint program, GLenum programInterface, const char* name) {
5251 GL2Encoder *ctx = (GL2Encoder*)self;
5252 return ctx->m_glGetProgramResourceLocation_enc(self, program, programInterface, name);
5253}
5254
5255void GL2Encoder::s_glGetProgramResourceName(void* self, GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei* length, char* name) {
5256 GL2Encoder *ctx = (GL2Encoder*)self;
5257 SET_ERROR_IF(bufSize < 0, GL_INVALID_VALUE);
5258 if (bufSize == 0) {
5259 if (length) *length = 0;
5260 return;
5261 }
5262
5263 // Avoid modifying |name| if |*length| < bufSize.
5264 char* intermediate = new char[bufSize];
5265 GLsizei* myLength = length ? length : new GLsizei;
5266 bool needFreeLength = length == NULL;
5267
5268 ctx->m_glGetProgramResourceName_enc(self, program, programInterface, index, bufSize, myLength, intermediate);
5269 GLsizei writtenStrLen = *myLength;
5270 memcpy(name, intermediate, writtenStrLen + 1);
5271
5272 delete [] intermediate;
5273 if (needFreeLength)
5274 delete myLength;
5275}
5276
5277void GL2Encoder::s_glGetProgramPipelineInfoLog(void* self, GLuint pipeline, GLsizei bufSize, GLsizei* length, GLchar* infoLog) {
5278 GL2Encoder *ctx = (GL2Encoder*)self;
5279 SET_ERROR_IF(bufSize < 0, GL_INVALID_VALUE);
5280 if (bufSize == 0) {
5281 if (length) *length = 0;
5282 return;
5283 }
5284
5285 // Avoid modifying |infoLog| if |*length| < bufSize.
5286 GLchar* intermediate = new GLchar[bufSize];
5287 GLsizei* myLength = length ? length : new GLsizei;
5288 bool needFreeLength = length == NULL;
5289
5290 ctx->m_glGetProgramPipelineInfoLog_enc(self, pipeline, bufSize, myLength, intermediate);
5291 GLsizei writtenStrLen = *myLength;
5292 memcpy(infoLog, intermediate, writtenStrLen + 1);
5293
5294 delete [] intermediate;
5295 if (needFreeLength)
5296 delete myLength;
5297}
5298
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005299void GL2Encoder::s_glVertexAttribFormat(void* self, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset) {
5300 GL2Encoder *ctx = (GL2Encoder*)self;
5301 GLClientState* state = ctx->m_state;
5302
Lingfeng Yang07289902017-01-27 12:26:19 -08005303 VALIDATE_VERTEX_ATTRIB_INDEX(attribindex);
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08005304 SET_ERROR_IF(!state->currentVertexArrayObject(), GL_INVALID_OPERATION);
5305
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005306 state->setVertexAttribFormat(attribindex, size, type, normalized, relativeoffset, false);
5307 ctx->m_glVertexAttribFormat_enc(ctx, attribindex, size, type, normalized, relativeoffset);
5308}
5309
5310void GL2Encoder::s_glVertexAttribIFormat(void* self, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset) {
5311 GL2Encoder *ctx = (GL2Encoder*)self;
5312 GLClientState* state = ctx->m_state;
5313
Lingfeng Yang07289902017-01-27 12:26:19 -08005314 VALIDATE_VERTEX_ATTRIB_INDEX(attribindex);
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08005315 SET_ERROR_IF(!state->currentVertexArrayObject(), GL_INVALID_OPERATION);
5316
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005317 state->setVertexAttribFormat(attribindex, size, type, GL_FALSE, relativeoffset, true);
5318 ctx->m_glVertexAttribIFormat_enc(ctx, attribindex, size, type, relativeoffset);
5319}
5320
5321void GL2Encoder::s_glVertexBindingDivisor(void* self, GLuint bindingindex, GLuint divisor) {
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005322 GL2Encoder *ctx = (GL2Encoder*)self;
5323 GLClientState* state = ctx->m_state;
5324
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08005325 SET_ERROR_IF(!state->currentVertexArrayObject(), GL_INVALID_OPERATION);
5326
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005327 state->setVertexBindingDivisor(bindingindex, divisor);
5328 ctx->m_glVertexBindingDivisor_enc(ctx, bindingindex, divisor);
5329}
5330
5331void GL2Encoder::s_glVertexAttribBinding(void* self, GLuint attribindex, GLuint bindingindex) {
5332 GL2Encoder *ctx = (GL2Encoder*)self;
5333 GLClientState* state = ctx->m_state;
Lingfeng Yang07289902017-01-27 12:26:19 -08005334 VALIDATE_VERTEX_ATTRIB_INDEX(attribindex);
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08005335 SET_ERROR_IF(!state->currentVertexArrayObject(), GL_INVALID_OPERATION);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005336
5337 state->setVertexAttribBinding(attribindex, bindingindex);
5338 ctx->m_glVertexAttribBinding_enc(ctx, attribindex, bindingindex);
5339}
5340
5341void GL2Encoder::s_glBindVertexBuffer(void* self, GLuint bindingindex, GLuint buffer, GLintptr offset, GLintptr stride) {
5342 GL2Encoder *ctx = (GL2Encoder*)self;
5343 GLClientState* state = ctx->m_state;
5344
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08005345 SET_ERROR_IF(offset < 0, GL_INVALID_VALUE);
5346
5347 GLint maxStride;
5348 ctx->glGetIntegerv(ctx, GL_MAX_VERTEX_ATTRIB_STRIDE, &maxStride);
5349 SET_ERROR_IF(stride < 0 || stride > maxStride, GL_INVALID_VALUE);
5350
5351 SET_ERROR_IF(!state->currentVertexArrayObject(), GL_INVALID_OPERATION);
5352
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005353 state->bindIndexedBuffer(0, bindingindex, buffer, offset, 0, stride, stride);
5354 ctx->m_glBindVertexBuffer_enc(ctx, bindingindex, buffer, offset, stride);
5355}
5356
5357void GL2Encoder::s_glDrawArraysIndirect(void* self, GLenum mode, const void* indirect) {
5358 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08005359 GLClientState* state = ctx->m_state;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005360
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08005361 bool hasClientArrays = false;
5362 ctx->getVBOUsage(&hasClientArrays, NULL);
5363
5364 SET_ERROR_IF(hasClientArrays, GL_INVALID_OPERATION);
5365 SET_ERROR_IF(!state->currentVertexArrayObject(), GL_INVALID_OPERATION);
5366 SET_ERROR_IF(!ctx->boundBuffer(GL_DRAW_INDIRECT_BUFFER), GL_INVALID_OPERATION);
5367
5368 GLuint indirectStructSize = glUtilsIndirectStructSize(INDIRECT_COMMAND_DRAWARRAYS);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005369 if (ctx->boundBuffer(GL_DRAW_INDIRECT_BUFFER)) {
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08005370 // BufferData* buf = ctx->getBufferData(target);
5371 // if (buf) {
5372 // SET_ERROR_IF((GLuint)(uintptr_t)indirect + indirectStructSize > buf->m_size, GL_INVALID_VALUE);
5373 // }
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005374 ctx->glDrawArraysIndirectOffsetAEMU(ctx, mode, (uintptr_t)indirect);
5375 } else {
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08005376 // Client command structs are technically allowed in desktop OpenGL, but not in ES.
5377 // This is purely for debug/dev purposes.
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005378 ctx->glDrawArraysIndirectDataAEMU(ctx, mode, indirect, indirectStructSize);
5379 }
5380}
5381
5382void GL2Encoder::s_glDrawElementsIndirect(void* self, GLenum mode, GLenum type, const void* indirect) {
5383 GL2Encoder *ctx = (GL2Encoder*)self;
5384
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08005385 GLClientState* state = ctx->m_state;
5386
5387 bool hasClientArrays = false;
5388 ctx->getVBOUsage(&hasClientArrays, NULL);
5389
5390 SET_ERROR_IF(hasClientArrays, GL_INVALID_OPERATION);
5391 SET_ERROR_IF(!state->currentVertexArrayObject(), GL_INVALID_OPERATION);
5392 SET_ERROR_IF(!ctx->boundBuffer(GL_DRAW_INDIRECT_BUFFER), GL_INVALID_OPERATION);
5393
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005394 SET_ERROR_IF(ctx->m_state->getTransformFeedbackActiveUnpaused(), GL_INVALID_OPERATION);
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08005395
5396 GLuint indirectStructSize = glUtilsIndirectStructSize(INDIRECT_COMMAND_DRAWELEMENTS);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005397 if (ctx->boundBuffer(GL_DRAW_INDIRECT_BUFFER)) {
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08005398 // BufferData* buf = ctx->getBufferData(target);
5399 // if (buf) {
5400 // SET_ERROR_IF((GLuint)(uintptr_t)indirect + indirectStructSize > buf->m_size, GL_INVALID_VALUE);
5401 // }
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005402 ctx->glDrawElementsIndirectOffsetAEMU(ctx, mode, type, (uintptr_t)indirect);
5403 } else {
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08005404 // Client command structs are technically allowed in desktop OpenGL, but not in ES.
5405 // This is purely for debug/dev purposes.
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005406 ctx->glDrawElementsIndirectDataAEMU(ctx, mode, type, indirect, indirectStructSize);
5407 }
5408
5409}
5410
5411void GL2Encoder::s_glTexStorage2DMultisample(void* self, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations) {
5412 GL2Encoder *ctx = (GL2Encoder*)self;
5413 GLClientState* state = ctx->m_state;
5414
5415 SET_ERROR_IF(target != GL_TEXTURE_2D_MULTISAMPLE, GL_INVALID_ENUM);
5416 SET_ERROR_IF(!GLESv2Validation::pixelInternalFormat(internalformat), GL_INVALID_ENUM);
5417 SET_ERROR_IF(!state->getBoundTexture(target), GL_INVALID_OPERATION);
5418 SET_ERROR_IF(width < 1 || height < 1, GL_INVALID_VALUE);
5419 SET_ERROR_IF(state->isBoundTextureImmutableFormat(target), GL_INVALID_OPERATION);
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08005420 GLint max_samples;
5421 ctx->s_glGetInternalformativ(ctx, target, internalformat, GL_SAMPLES, 1, &max_samples);
5422 SET_ERROR_IF(samples > max_samples, GL_INVALID_OPERATION);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005423
5424 state->setBoundTextureInternalFormat(target, internalformat);
5425 state->setBoundTextureDims(target, 0, width, height, 1);
5426 state->setBoundTextureImmutableFormat(target);
5427 state->setBoundTextureSamples(target, samples);
5428
5429 ctx->m_glTexStorage2DMultisample_enc(ctx, target, samples, internalformat, width, height, fixedsamplelocations);
5430}
5431
Yahan Zhou72944ba2019-01-02 15:43:46 -08005432GLenum GL2Encoder::s_glGetGraphicsResetStatusEXT(void* self) {
5433 (void)self;
5434 return GL_NO_ERROR;
5435}
5436
5437void GL2Encoder::s_glReadnPixelsEXT(void* self, GLint x, GLint y, GLsizei width,
5438 GLsizei height, GLenum format, GLenum type, GLsizei bufSize,
5439 GLvoid* pixels) {
5440 GL2Encoder *ctx = (GL2Encoder*)self;
5441 SET_ERROR_IF(bufSize < glesv2_enc::pixelDataSize(self, width, height, format,
5442 type, 1), GL_INVALID_OPERATION);
5443 s_glReadPixels(self, x, y, width, height, format, type, pixels);
5444}
5445
5446void GL2Encoder::s_glGetnUniformfvEXT(void *self, GLuint program, GLint location,
5447 GLsizei bufSize, GLfloat* params) {
5448 GL2Encoder *ctx = (GL2Encoder*)self;
5449 SET_ERROR_IF(bufSize < glSizeof(glesv2_enc::uniformType(self, program,
5450 location)), GL_INVALID_OPERATION);
5451 s_glGetUniformfv(self, program, location, params);
5452}
5453
5454void GL2Encoder::s_glGetnUniformivEXT(void *self, GLuint program, GLint location,
5455 GLsizei bufSize, GLint* params) {
5456 GL2Encoder *ctx = (GL2Encoder*)self;
5457 SET_ERROR_IF(bufSize < glSizeof(glesv2_enc::uniformType(self, program,
5458 location)), GL_INVALID_OPERATION);
5459 s_glGetUniformiv(self, program, location, params);
5460}