blob: 2f906fcdc4487e7f7b0916ed526e3d0b097ba46f [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;
keunyoungb85b2752013-03-08 12:28:03 -080075 m_initialized = false;
Lingfeng Yange980c7a2018-01-12 14:50:18 -080076 m_noHostError = false;
keunyoungb85b2752013-03-08 12:28:03 -080077 m_state = NULL;
78 m_error = GL_NO_ERROR;
Roman Kiryanovdaecd142018-11-14 14:56:27 -080079
keunyoungb85b2752013-03-08 12:28:03 -080080 m_num_compressedTextureFormats = 0;
Lingfeng Yang48685bb2018-10-19 06:44:20 -070081 m_max_combinedTextureImageUnits = 0;
Lingfeng Yanga1edab62018-10-19 07:53:49 -070082 m_max_vertexTextureImageUnits = 0;
83 m_max_textureImageUnits = 0;
Lizhe Liue41f4ef2015-05-27 11:13:23 +080084 m_max_cubeMapTextureSize = 0;
85 m_max_renderBufferSize = 0;
86 m_max_textureSize = 0;
Lingfeng Yang46153ab2017-01-09 13:37:22 -080087 m_max_3d_textureSize = 0;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -080088 m_max_vertexAttribStride = 0;
Lingfeng Yanga1edab62018-10-19 07:53:49 -070089
90 m_max_transformFeedbackSeparateAttribs = 0;
91 m_max_uniformBufferBindings = 0;
92 m_max_colorAttachments = 0;
93 m_max_drawBuffers = 0;
94
95 m_max_atomicCounterBufferBindings = 0;
96 m_max_shaderStorageBufferBindings = 0;
97 m_max_vertexAttribBindings = 0;
98
keunyoungb85b2752013-03-08 12:28:03 -080099 m_compressedTextureFormats = NULL;
David 'Digit' Turner3afd44b2014-10-30 18:15:04 +0100100
Lingfeng Yang46153ab2017-01-09 13:37:22 -0800101 m_ssbo_offset_align = 0;
102 m_ubo_offset_align = 0;
103
Lingfeng Yangde51dfb2016-10-17 22:48:59 -0700104 m_drawCallFlushCount = 0;
105 m_primitiveRestartEnabled = false;
106 m_primitiveRestartIndex = 0;
107
Lingfeng Yang07289902017-01-27 12:26:19 -0800108 // overrides
David 'Digit' Turner3afd44b2014-10-30 18:15:04 +0100109#define OVERRIDE(name) m_##name##_enc = this-> name ; this-> name = &s_##name
Lingfeng Yange6556dc2017-01-09 12:04:12 -0800110#define OVERRIDE_CUSTOM(name) this-> name = &s_##name
111#define OVERRIDEWITH(name, target) do { \
112 m_##target##_enc = this-> target; \
113 this-> target = &s_##name; \
114} while(0)
115#define OVERRIDEOES(name) OVERRIDEWITH(name, name##OES)
bohu56bf82f2014-10-17 15:35:48 -0700116
David 'Digit' Turner3afd44b2014-10-30 18:15:04 +0100117 OVERRIDE(glFlush);
118 OVERRIDE(glPixelStorei);
119 OVERRIDE(glGetString);
120 OVERRIDE(glBindBuffer);
121 OVERRIDE(glBufferData);
122 OVERRIDE(glBufferSubData);
123 OVERRIDE(glDeleteBuffers);
124 OVERRIDE(glDrawArrays);
125 OVERRIDE(glDrawElements);
Lingfeng Yang09545912019-01-30 09:22:38 -0800126 OVERRIDE(glDrawArraysNullAEMU);
127 OVERRIDE(glDrawElementsNullAEMU);
David 'Digit' Turner3afd44b2014-10-30 18:15:04 +0100128 OVERRIDE(glGetIntegerv);
129 OVERRIDE(glGetFloatv);
130 OVERRIDE(glGetBooleanv);
131 OVERRIDE(glVertexAttribPointer);
132 OVERRIDE(glEnableVertexAttribArray);
133 OVERRIDE(glDisableVertexAttribArray);
134 OVERRIDE(glGetVertexAttribiv);
135 OVERRIDE(glGetVertexAttribfv);
136 OVERRIDE(glGetVertexAttribPointerv);
keunyoungb85b2752013-03-08 12:28:03 -0800137
Bo Hu73568cd2015-01-20 16:29:50 -0800138 this->glShaderBinary = &s_glShaderBinary;
David 'Digit' Turner3afd44b2014-10-30 18:15:04 +0100139 this->glShaderSource = &s_glShaderSource;
140 this->glFinish = &s_glFinish;
keunyoungb85b2752013-03-08 12:28:03 -0800141
David 'Digit' Turner3afd44b2014-10-30 18:15:04 +0100142 OVERRIDE(glGetError);
143 OVERRIDE(glLinkProgram);
144 OVERRIDE(glDeleteProgram);
145 OVERRIDE(glGetUniformiv);
146 OVERRIDE(glGetUniformfv);
147 OVERRIDE(glCreateProgram);
148 OVERRIDE(glCreateShader);
149 OVERRIDE(glDeleteShader);
150 OVERRIDE(glAttachShader);
151 OVERRIDE(glDetachShader);
152 OVERRIDE(glGetAttachedShaders);
153 OVERRIDE(glGetShaderSource);
154 OVERRIDE(glGetShaderInfoLog);
155 OVERRIDE(glGetProgramInfoLog);
156
157 OVERRIDE(glGetUniformLocation);
158 OVERRIDE(glUseProgram);
159
160 OVERRIDE(glUniform1f);
161 OVERRIDE(glUniform1fv);
162 OVERRIDE(glUniform1i);
163 OVERRIDE(glUniform1iv);
164 OVERRIDE(glUniform2f);
165 OVERRIDE(glUniform2fv);
166 OVERRIDE(glUniform2i);
167 OVERRIDE(glUniform2iv);
168 OVERRIDE(glUniform3f);
169 OVERRIDE(glUniform3fv);
170 OVERRIDE(glUniform3i);
171 OVERRIDE(glUniform3iv);
172 OVERRIDE(glUniform4f);
173 OVERRIDE(glUniform4fv);
174 OVERRIDE(glUniform4i);
175 OVERRIDE(glUniform4iv);
176 OVERRIDE(glUniformMatrix2fv);
177 OVERRIDE(glUniformMatrix3fv);
178 OVERRIDE(glUniformMatrix4fv);
179
180 OVERRIDE(glActiveTexture);
181 OVERRIDE(glBindTexture);
182 OVERRIDE(glDeleteTextures);
183 OVERRIDE(glGetTexParameterfv);
184 OVERRIDE(glGetTexParameteriv);
185 OVERRIDE(glTexParameterf);
186 OVERRIDE(glTexParameterfv);
187 OVERRIDE(glTexParameteri);
188 OVERRIDE(glTexParameteriv);
bohu26a92982014-11-25 16:50:37 -0800189 OVERRIDE(glTexImage2D);
Yahan Zhou2a208292016-06-22 15:36:04 -0700190 OVERRIDE(glTexSubImage2D);
Lingfeng Yange00ec9d2016-09-16 08:54:03 -0700191 OVERRIDE(glCopyTexImage2D);
Lingfeng Yang57cb41b2016-04-08 14:42:34 -0700192
193 OVERRIDE(glGenRenderbuffers);
194 OVERRIDE(glDeleteRenderbuffers);
195 OVERRIDE(glBindRenderbuffer);
Lingfeng Yang69066602016-04-12 09:29:11 -0700196 OVERRIDE(glRenderbufferStorage);
Lingfeng Yang57cb41b2016-04-08 14:42:34 -0700197 OVERRIDE(glFramebufferRenderbuffer);
198
199 OVERRIDE(glGenFramebuffers);
200 OVERRIDE(glDeleteFramebuffers);
201 OVERRIDE(glBindFramebuffer);
202 OVERRIDE(glFramebufferTexture2D);
203 OVERRIDE(glFramebufferTexture3DOES);
204 OVERRIDE(glGetFramebufferAttachmentParameteriv);
Lingfeng Yang69066602016-04-12 09:29:11 -0700205
206 OVERRIDE(glCheckFramebufferStatus);
Lingfeng Yang46153ab2017-01-09 13:37:22 -0800207
208 OVERRIDE(glGenVertexArrays);
209 OVERRIDE(glDeleteVertexArrays);
210 OVERRIDE(glBindVertexArray);
211 OVERRIDEOES(glGenVertexArrays);
212 OVERRIDEOES(glDeleteVertexArrays);
213 OVERRIDEOES(glBindVertexArray);
214
Lingfeng Yangfb3d2bb2017-09-07 15:02:04 -0700215 OVERRIDE_CUSTOM(glMapBufferOES);
216 OVERRIDE_CUSTOM(glUnmapBufferOES);
Lingfeng Yang46153ab2017-01-09 13:37:22 -0800217 OVERRIDE_CUSTOM(glMapBufferRange);
218 OVERRIDE_CUSTOM(glUnmapBuffer);
219 OVERRIDE_CUSTOM(glFlushMappedBufferRange);
220
221 OVERRIDE(glCompressedTexImage2D);
222 OVERRIDE(glCompressedTexSubImage2D);
223
224 OVERRIDE(glBindBufferRange);
225 OVERRIDE(glBindBufferBase);
226
227 OVERRIDE(glCopyBufferSubData);
228
229 OVERRIDE(glGetBufferParameteriv);
230 OVERRIDE(glGetBufferParameteri64v);
231 OVERRIDE(glGetBufferPointerv);
232
233 OVERRIDE_CUSTOM(glGetUniformIndices);
234
235 OVERRIDE(glUniform1ui);
236 OVERRIDE(glUniform2ui);
237 OVERRIDE(glUniform3ui);
238 OVERRIDE(glUniform4ui);
239 OVERRIDE(glUniform1uiv);
240 OVERRIDE(glUniform2uiv);
241 OVERRIDE(glUniform3uiv);
242 OVERRIDE(glUniform4uiv);
243 OVERRIDE(glUniformMatrix2x3fv);
244 OVERRIDE(glUniformMatrix3x2fv);
245 OVERRIDE(glUniformMatrix2x4fv);
246 OVERRIDE(glUniformMatrix4x2fv);
247 OVERRIDE(glUniformMatrix3x4fv);
248 OVERRIDE(glUniformMatrix4x3fv);
249
250 OVERRIDE(glGetUniformuiv);
251 OVERRIDE(glGetActiveUniformBlockiv);
252
253 OVERRIDE(glGetVertexAttribIiv);
254 OVERRIDE(glGetVertexAttribIuiv);
255
256 OVERRIDE_CUSTOM(glVertexAttribIPointer);
257
258 OVERRIDE(glVertexAttribDivisor);
259
260 OVERRIDE(glRenderbufferStorageMultisample);
261 OVERRIDE(glDrawBuffers);
262 OVERRIDE(glReadBuffer);
263 OVERRIDE(glFramebufferTextureLayer);
264 OVERRIDE(glTexStorage2D);
265
266 OVERRIDE_CUSTOM(glTransformFeedbackVaryings);
267 OVERRIDE(glBeginTransformFeedback);
268 OVERRIDE(glEndTransformFeedback);
269 OVERRIDE(glPauseTransformFeedback);
270 OVERRIDE(glResumeTransformFeedback);
271
272 OVERRIDE(glTexImage3D);
273 OVERRIDE(glTexSubImage3D);
274 OVERRIDE(glTexStorage3D);
275 OVERRIDE(glCompressedTexImage3D);
276 OVERRIDE(glCompressedTexSubImage3D);
277
278 OVERRIDE(glDrawArraysInstanced);
279 OVERRIDE_CUSTOM(glDrawElementsInstanced);
280 OVERRIDE_CUSTOM(glDrawRangeElements);
281
282 OVERRIDE_CUSTOM(glGetStringi);
283 OVERRIDE(glGetProgramBinary);
284 OVERRIDE(glReadPixels);
285
286 OVERRIDE(glEnable);
287 OVERRIDE(glDisable);
288 OVERRIDE(glClearBufferiv);
289 OVERRIDE(glClearBufferuiv);
290 OVERRIDE(glClearBufferfv);
291 OVERRIDE(glBlitFramebuffer);
292 OVERRIDE_CUSTOM(glGetInternalformativ);
293
294 OVERRIDE(glGenerateMipmap);
295
296 OVERRIDE(glBindSampler);
297
Lingfeng Yangf000ab42017-01-11 18:31:38 -0800298 OVERRIDE_CUSTOM(glFenceSync);
299 OVERRIDE_CUSTOM(glClientWaitSync);
300 OVERRIDE_CUSTOM(glWaitSync);
301 OVERRIDE_CUSTOM(glDeleteSync);
302 OVERRIDE_CUSTOM(glIsSync);
303 OVERRIDE_CUSTOM(glGetSynciv);
Lingfeng Yang46153ab2017-01-09 13:37:22 -0800304
305 OVERRIDE(glGetIntegeri_v);
306 OVERRIDE(glGetInteger64i_v);
Lingfeng Yang80a36332017-07-09 10:58:07 -0700307 OVERRIDE(glGetInteger64v);
308 OVERRIDE(glGetBooleani_v);
Lingfeng Yang46153ab2017-01-09 13:37:22 -0800309
310 OVERRIDE(glGetShaderiv);
311
Lingfeng Yangd3ae1062017-01-18 11:42:04 -0800312 OVERRIDE(glActiveShaderProgram);
Lingfeng Yang46153ab2017-01-09 13:37:22 -0800313 OVERRIDE_CUSTOM(glCreateShaderProgramv);
314 OVERRIDE(glProgramUniform1f);
315 OVERRIDE(glProgramUniform1fv);
316 OVERRIDE(glProgramUniform1i);
317 OVERRIDE(glProgramUniform1iv);
318 OVERRIDE(glProgramUniform1ui);
319 OVERRIDE(glProgramUniform1uiv);
320 OVERRIDE(glProgramUniform2f);
321 OVERRIDE(glProgramUniform2fv);
322 OVERRIDE(glProgramUniform2i);
323 OVERRIDE(glProgramUniform2iv);
324 OVERRIDE(glProgramUniform2ui);
325 OVERRIDE(glProgramUniform2uiv);
326 OVERRIDE(glProgramUniform3f);
327 OVERRIDE(glProgramUniform3fv);
328 OVERRIDE(glProgramUniform3i);
329 OVERRIDE(glProgramUniform3iv);
330 OVERRIDE(glProgramUniform3ui);
331 OVERRIDE(glProgramUniform3uiv);
332 OVERRIDE(glProgramUniform4f);
333 OVERRIDE(glProgramUniform4fv);
334 OVERRIDE(glProgramUniform4i);
335 OVERRIDE(glProgramUniform4iv);
336 OVERRIDE(glProgramUniform4ui);
337 OVERRIDE(glProgramUniform4uiv);
338 OVERRIDE(glProgramUniformMatrix2fv);
339 OVERRIDE(glProgramUniformMatrix2x3fv);
340 OVERRIDE(glProgramUniformMatrix2x4fv);
341 OVERRIDE(glProgramUniformMatrix3fv);
342 OVERRIDE(glProgramUniformMatrix3x2fv);
343 OVERRIDE(glProgramUniformMatrix3x4fv);
344 OVERRIDE(glProgramUniformMatrix4fv);
345 OVERRIDE(glProgramUniformMatrix4x2fv);
346 OVERRIDE(glProgramUniformMatrix4x3fv);
347
Lingfeng Yangd3ae1062017-01-18 11:42:04 -0800348 OVERRIDE(glProgramParameteri);
Lingfeng Yang46153ab2017-01-09 13:37:22 -0800349 OVERRIDE(glUseProgramStages);
350 OVERRIDE(glBindProgramPipeline);
351
Lingfeng Yangd3ae1062017-01-18 11:42:04 -0800352 OVERRIDE(glGetProgramResourceiv);
353 OVERRIDE(glGetProgramResourceIndex);
354 OVERRIDE(glGetProgramResourceLocation);
355 OVERRIDE(glGetProgramResourceName);
356 OVERRIDE(glGetProgramPipelineInfoLog);
357
Lingfeng Yang46153ab2017-01-09 13:37:22 -0800358 OVERRIDE(glVertexAttribFormat);
359 OVERRIDE(glVertexAttribIFormat);
360 OVERRIDE(glVertexBindingDivisor);
361 OVERRIDE(glVertexAttribBinding);
362 OVERRIDE(glBindVertexBuffer);
363
364 OVERRIDE_CUSTOM(glDrawArraysIndirect);
365 OVERRIDE_CUSTOM(glDrawElementsIndirect);
366
367 OVERRIDE(glTexStorage2DMultisample);
Yahan Zhou72944ba2019-01-02 15:43:46 -0800368
369 OVERRIDE_CUSTOM(glGetGraphicsResetStatusEXT);
370 OVERRIDE_CUSTOM(glReadnPixelsEXT);
371 OVERRIDE_CUSTOM(glGetnUniformfvEXT);
372 OVERRIDE_CUSTOM(glGetnUniformivEXT);
keunyoungb85b2752013-03-08 12:28:03 -0800373}
374
375GL2Encoder::~GL2Encoder()
376{
377 delete m_compressedTextureFormats;
378}
379
380GLenum GL2Encoder::s_glGetError(void * self)
381{
382 GL2Encoder *ctx = (GL2Encoder *)self;
383 GLenum err = ctx->getError();
384 if(err != GL_NO_ERROR) {
Lingfeng Yang80a36332017-07-09 10:58:07 -0700385 ctx->m_glGetError_enc(ctx); // also clear host error
keunyoungb85b2752013-03-08 12:28:03 -0800386 ctx->setError(GL_NO_ERROR);
387 return err;
388 }
389
Lingfeng Yange980c7a2018-01-12 14:50:18 -0800390 if (ctx->m_noHostError) {
391 return GL_NO_ERROR;
392 } else {
393 return ctx->m_glGetError_enc(self);
394 }
Lingfeng Yang80a36332017-07-09 10:58:07 -0700395}
Yahan Zhouae30fe82016-08-10 21:15:45 +0000396
Lingfeng Yang80a36332017-07-09 10:58:07 -0700397class GL2Encoder::ErrorUpdater {
398public:
399 ErrorUpdater(GL2Encoder* ctx) :
400 mCtx(ctx),
401 guest_error(ctx->getError()),
402 host_error(ctx->m_glGetError_enc(ctx)) {
403 // Preserve any existing GL error in the guest:
404 // OpenGL ES 3.0.5 spec:
405 // The command enum GetError( void ); is used to obtain error information.
406 // Each detectable error is assigned a numeric code. When an error is
407 // detected, a flag is set and the code is recorded. Further errors, if
408 // they occur, do not affect this recorded code. When GetError is called,
409 // the code is returned and the flag is cleared, so that a further error
410 // will again record its code. If a call to GetError returns NO_ERROR, then
411 // there has been no detectable error since the last call to GetError (or
412 // since the GL was initialized).
413 if (guest_error == GL_NO_ERROR) {
414 guest_error = host_error;
415 }
416 }
417
418 GLenum getHostErrorAndUpdate() {
419 host_error = mCtx->m_glGetError_enc(mCtx);
420 if (guest_error == GL_NO_ERROR) {
421 guest_error = host_error;
422 }
423 return host_error;
424 }
425
426 void updateGuestErrorState() {
427 mCtx->setError(guest_error);
428 }
429
430private:
431 GL2Encoder* mCtx;
432 GLenum guest_error;
433 GLenum host_error;
434};
435
436template<class T>
437class GL2Encoder::ScopedQueryUpdate {
438public:
439 ScopedQueryUpdate(GL2Encoder* ctx, uint32_t bytes, T* target) :
440 mCtx(ctx),
441 mBuf(bytes, 0),
442 mTarget(target),
443 mErrorUpdater(ctx) {
444 }
445 T* hostStagingBuffer() {
446 return (T*)&mBuf[0];
447 }
448 ~ScopedQueryUpdate() {
449 GLint hostError = mErrorUpdater.getHostErrorAndUpdate();
Lingfeng Yang72ecf472018-06-11 14:20:14 -0700450 if (hostError == GL_NO_ERROR && mTarget) {
Lingfeng Yang80a36332017-07-09 10:58:07 -0700451 memcpy(mTarget, &mBuf[0], mBuf.size());
452 }
453 mErrorUpdater.updateGuestErrorState();
454 }
455private:
456 GL2Encoder* mCtx;
457 std::vector<char> mBuf;
458 T* mTarget;
459 ErrorUpdater mErrorUpdater;
460};
461
462void GL2Encoder::safe_glGetBooleanv(GLenum param, GLboolean* val) {
463 ScopedQueryUpdate<GLboolean> query(this, glUtilsParamSize(param) * sizeof(GLboolean), val);
464 m_glGetBooleanv_enc(this, param, query.hostStagingBuffer());
465}
466
467void GL2Encoder::safe_glGetFloatv(GLenum param, GLfloat* val) {
468 ScopedQueryUpdate<GLfloat> query(this, glUtilsParamSize(param) * sizeof(GLfloat), val);
469 m_glGetFloatv_enc(this, param, query.hostStagingBuffer());
470}
471
472void GL2Encoder::safe_glGetIntegerv(GLenum param, GLint* val) {
473 ScopedQueryUpdate<GLint> query(this, glUtilsParamSize(param) * sizeof(GLint), val);
474 m_glGetIntegerv_enc(this, param, query.hostStagingBuffer());
475}
476
477void GL2Encoder::safe_glGetInteger64v(GLenum param, GLint64* val) {
478 ScopedQueryUpdate<GLint64> query(this, glUtilsParamSize(param) * sizeof(GLint64), val);
479 m_glGetInteger64v_enc(this, param, query.hostStagingBuffer());
480}
481
482void GL2Encoder::safe_glGetIntegeri_v(GLenum param, GLuint index, GLint* val) {
483 ScopedQueryUpdate<GLint> query(this, sizeof(GLint), val);
484 m_glGetIntegeri_v_enc(this, param, index, query.hostStagingBuffer());
485}
486
487void GL2Encoder::safe_glGetInteger64i_v(GLenum param, GLuint index, GLint64* val) {
488 ScopedQueryUpdate<GLint64> query(this, sizeof(GLint64), val);
489 m_glGetInteger64i_v_enc(this, param, index, query.hostStagingBuffer());
490}
491
492void GL2Encoder::safe_glGetBooleani_v(GLenum param, GLuint index, GLboolean* val) {
493 ScopedQueryUpdate<GLboolean> query(this, sizeof(GLboolean), val);
494 m_glGetBooleani_v_enc(this, param, index, query.hostStagingBuffer());
keunyoungb85b2752013-03-08 12:28:03 -0800495}
496
497void GL2Encoder::s_glFlush(void *self)
498{
499 GL2Encoder *ctx = (GL2Encoder *) self;
500 ctx->m_glFlush_enc(self);
501 ctx->m_stream->flush();
502}
503
504const GLubyte *GL2Encoder::s_glGetString(void *self, GLenum name)
505{
Lingfeng Yang46153ab2017-01-09 13:37:22 -0800506 GL2Encoder *ctx = (GL2Encoder *)self;
David 'Digit' Turnere01d5f42014-10-30 21:32:28 +0100507
keunyoungb85b2752013-03-08 12:28:03 -0800508 GLubyte *retval = (GLubyte *) "";
Lingfeng Yang46153ab2017-01-09 13:37:22 -0800509 RET_AND_SET_ERROR_IF(
510 name != GL_VENDOR &&
511 name != GL_RENDERER &&
512 name != GL_VERSION &&
513 name != GL_EXTENSIONS,
514 GL_INVALID_ENUM,
515 retval);
keunyoungb85b2752013-03-08 12:28:03 -0800516 switch(name) {
517 case GL_VENDOR:
518 retval = gVendorString;
519 break;
520 case GL_RENDERER:
521 retval = gRendererString;
522 break;
523 case GL_VERSION:
524 retval = gVersionString;
525 break;
526 case GL_EXTENSIONS:
527 retval = gExtensionsString;
528 break;
529 }
530 return retval;
531}
532
533void GL2Encoder::s_glPixelStorei(void *self, GLenum param, GLint value)
534{
535 GL2Encoder *ctx = (GL2Encoder *)self;
Lingfeng Yang46153ab2017-01-09 13:37:22 -0800536 SET_ERROR_IF(!GLESv2Validation::pixelStoreParam(ctx, param), GL_INVALID_ENUM);
537 SET_ERROR_IF(!GLESv2Validation::pixelStoreValue(param, value), GL_INVALID_VALUE);
keunyoungb85b2752013-03-08 12:28:03 -0800538 ctx->m_glPixelStorei_enc(ctx, param, value);
539 assert(ctx->m_state != NULL);
540 ctx->m_state->setPixelStore(param, value);
541}
keunyoungb85b2752013-03-08 12:28:03 -0800542void GL2Encoder::s_glBindBuffer(void *self, GLenum target, GLuint id)
543{
544 GL2Encoder *ctx = (GL2Encoder *) self;
545 assert(ctx->m_state != NULL);
Lingfeng Yang554a5152019-02-21 20:20:48 -0800546 SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM);
547
Lingfeng Yang2c3a0da2019-03-07 20:43:53 -0800548 bool nop = ctx->m_state->isNonIndexedBindNoOp(target, id);
Lingfeng Yang554a5152019-02-21 20:20:48 -0800549
550 if (nop) return;
551
keunyoungb85b2752013-03-08 12:28:03 -0800552 ctx->m_state->bindBuffer(target, id);
Lingfeng Yangd3ae1062017-01-18 11:42:04 -0800553 ctx->m_state->addBuffer(id);
Lingfeng Yang554a5152019-02-21 20:20:48 -0800554 ctx->m_glBindBuffer_enc(ctx, target, id);
555 ctx->m_state->setLastEncodedBufferBind(target, id);
556}
557
558void GL2Encoder::doBindBufferEncodeCached(GLenum target, GLuint id) {
559 bool encode = id != m_state->getLastEncodedBufferBind(target);
560
561 if (encode) {
562 m_glBindBuffer_enc(this, target, id);
563 }
564
565 m_state->setLastEncodedBufferBind(target, id);
keunyoungb85b2752013-03-08 12:28:03 -0800566}
567
568void GL2Encoder::s_glBufferData(void * self, GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage)
569{
570 GL2Encoder *ctx = (GL2Encoder *) self;
Lingfeng Yang46153ab2017-01-09 13:37:22 -0800571 SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM);
keunyoungb85b2752013-03-08 12:28:03 -0800572 GLuint bufferId = ctx->m_state->getBuffer(target);
573 SET_ERROR_IF(bufferId==0, GL_INVALID_OPERATION);
574 SET_ERROR_IF(size<0, GL_INVALID_VALUE);
575
Roman Kiryanovfb903d62018-09-19 13:38:53 -0700576 ctx->m_shared->updateBufferData(bufferId, size, data);
Lingfeng Yang46153ab2017-01-09 13:37:22 -0800577 ctx->m_shared->setBufferUsage(bufferId, usage);
keunyoungb85b2752013-03-08 12:28:03 -0800578 ctx->m_glBufferData_enc(self, target, size, data, usage);
579}
580
581void GL2Encoder::s_glBufferSubData(void * self, GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data)
582{
583 GL2Encoder *ctx = (GL2Encoder *) self;
Lingfeng Yang46153ab2017-01-09 13:37:22 -0800584 SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM);
keunyoungb85b2752013-03-08 12:28:03 -0800585 GLuint bufferId = ctx->m_state->getBuffer(target);
586 SET_ERROR_IF(bufferId==0, GL_INVALID_OPERATION);
Lingfeng Yang46153ab2017-01-09 13:37:22 -0800587 SET_ERROR_IF(ctx->isBufferTargetMapped(target), GL_INVALID_OPERATION);
keunyoungb85b2752013-03-08 12:28:03 -0800588
Roman Kiryanovfb903d62018-09-19 13:38:53 -0700589 GLenum res = ctx->m_shared->subUpdateBufferData(bufferId, offset, size, data);
keunyoungb85b2752013-03-08 12:28:03 -0800590 SET_ERROR_IF(res, res);
591
592 ctx->m_glBufferSubData_enc(self, target, offset, size, data);
593}
594
Lingfeng Yangd3ae1062017-01-18 11:42:04 -0800595void GL2Encoder::s_glGenBuffers(void* self, GLsizei n, GLuint* buffers) {
596 GL2Encoder *ctx = (GL2Encoder *) self;
597 SET_ERROR_IF(n<0, GL_INVALID_VALUE);
598 ctx->m_glGenBuffers_enc(self, n, buffers);
599 for (int i = 0; i < n; i++) {
600 ctx->m_state->addBuffer(buffers[i]);
601 }
602}
603
keunyoungb85b2752013-03-08 12:28:03 -0800604void GL2Encoder::s_glDeleteBuffers(void * self, GLsizei n, const GLuint * buffers)
605{
606 GL2Encoder *ctx = (GL2Encoder *) self;
607 SET_ERROR_IF(n<0, GL_INVALID_VALUE);
608 for (int i=0; i<n; i++) {
Lingfeng Yang46153ab2017-01-09 13:37:22 -0800609 // Technically if the buffer is mapped, we should unmap it, but we won't
610 // use it anymore after this :)
keunyoungb85b2752013-03-08 12:28:03 -0800611 ctx->m_shared->deleteBufferData(buffers[i]);
bohub0f0cdf2014-11-06 18:08:07 -0800612 ctx->m_state->unBindBuffer(buffers[i]);
Lingfeng Yangd3ae1062017-01-18 11:42:04 -0800613 ctx->m_state->removeBuffer(buffers[i]);
keunyoungb85b2752013-03-08 12:28:03 -0800614 ctx->m_glDeleteBuffers_enc(self,1,&buffers[i]);
615 }
616}
617
Evan Birenbaumd51386b2016-04-13 12:53:09 -0700618static bool isValidVertexAttribIndex(void *self, GLuint indx)
619{
Lingfeng Yang07289902017-01-27 12:26:19 -0800620 GL2Encoder *ctx = (GL2Encoder *)self;
Evan Birenbaumd51386b2016-04-13 12:53:09 -0700621 GLint maxIndex;
622 ctx->glGetIntegerv(self, GL_MAX_VERTEX_ATTRIBS, &maxIndex);
623 return indx < maxIndex;
624}
625
Lingfeng Yang07289902017-01-27 12:26:19 -0800626#define VALIDATE_VERTEX_ATTRIB_INDEX(index) \
627 SET_ERROR_WITH_MESSAGE_IF( \
628 !isValidVertexAttribIndex(self, index), GL_INVALID_VALUE, \
629 GLESv2Validation::vertexAttribIndexRangeErrorMsg, (ctx, index)); \
630
David 'Digit' Turner02fdb692014-10-30 18:07:56 +0100631void GL2Encoder::s_glVertexAttribPointer(void *self, GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid * ptr)
keunyoungb85b2752013-03-08 12:28:03 -0800632{
633 GL2Encoder *ctx = (GL2Encoder *)self;
634 assert(ctx->m_state != NULL);
Lingfeng Yang07289902017-01-27 12:26:19 -0800635 VALIDATE_VERTEX_ATTRIB_INDEX(indx);
Evan Birenbaumd51386b2016-04-13 12:53:09 -0700636 SET_ERROR_IF((size < 1 || size > 4), GL_INVALID_VALUE);
Lingfeng Yang46153ab2017-01-09 13:37:22 -0800637 SET_ERROR_IF(!GLESv2Validation::vertexAttribType(ctx, type), GL_INVALID_ENUM);
Evan Birenbaumd51386b2016-04-13 12:53:09 -0700638 SET_ERROR_IF(stride < 0, GL_INVALID_VALUE);
Lingfeng Yang46153ab2017-01-09 13:37:22 -0800639 SET_ERROR_IF((type == GL_INT_2_10_10_10_REV ||
640 type == GL_UNSIGNED_INT_2_10_10_10_REV) &&
641 size != 4,
642 GL_INVALID_OPERATION);
643 ctx->m_state->setVertexAttribBinding(indx, indx);
644 ctx->m_state->setVertexAttribFormat(indx, size, type, normalized, 0, false);
645
646 GLsizei effectiveStride = stride;
647 if (stride == 0) {
Lingfeng Yang554a5152019-02-21 20:20:48 -0800648 effectiveStride = glSizeof(type) * size;
Lingfeng Yang46153ab2017-01-09 13:37:22 -0800649 switch (type) {
650 case GL_INT_2_10_10_10_REV:
651 case GL_UNSIGNED_INT_2_10_10_10_REV:
652 effectiveStride /= 4;
653 break;
654 default:
655 break;
656 }
657 }
658
659 ctx->m_state->bindIndexedBuffer(0, indx, ctx->m_state->currentArrayVbo(), (uintptr_t)ptr, 0, stride, effectiveStride);
660
Lingfeng Yangfe2a31d2016-12-02 08:02:15 -0800661 if (ctx->m_state->currentArrayVbo() != 0) {
662 ctx->glVertexAttribPointerOffset(ctx, indx, size, type, normalized, stride, (uintptr_t)ptr);
663 } else {
Lingfeng Yang46153ab2017-01-09 13:37:22 -0800664 SET_ERROR_IF(ctx->m_state->currentVertexArrayObject() != 0 && ptr, GL_INVALID_OPERATION);
665 // wait for client-array handler
Lingfeng Yangfe2a31d2016-12-02 08:02:15 -0800666 }
keunyoungb85b2752013-03-08 12:28:03 -0800667}
668
669void GL2Encoder::s_glGetIntegerv(void *self, GLenum param, GLint *ptr)
670{
671 GL2Encoder *ctx = (GL2Encoder *) self;
keunyoungb85b2752013-03-08 12:28:03 -0800672 GLClientState* state = ctx->m_state;
673
674 switch (param) {
Lingfeng Yanga16eb2e2018-02-23 11:26:53 -0800675 case GL_NUM_EXTENSIONS:
676 *ptr = (int)ctx->m_currExtensionsArray.size();
677 break;
Lingfeng Yang46153ab2017-01-09 13:37:22 -0800678 case GL_MAJOR_VERSION:
Lingfeng Yang324c8452017-02-17 09:56:26 -0800679 *ptr = ctx->m_deviceMajorVersion;
Lingfeng Yang46153ab2017-01-09 13:37:22 -0800680 break;
681 case GL_MINOR_VERSION:
Lingfeng Yang324c8452017-02-17 09:56:26 -0800682 *ptr = ctx->m_deviceMinorVersion;
Lingfeng Yang46153ab2017-01-09 13:37:22 -0800683 break;
keunyoungb85b2752013-03-08 12:28:03 -0800684 case GL_NUM_SHADER_BINARY_FORMATS:
685 *ptr = 0;
686 break;
687 case GL_SHADER_BINARY_FORMATS:
688 // do nothing
689 break;
690
691 case GL_COMPRESSED_TEXTURE_FORMATS: {
692 GLint *compressedTextureFormats = ctx->getCompressedTextureFormats();
693 if (ctx->m_num_compressedTextureFormats > 0 &&
694 compressedTextureFormats != NULL) {
695 memcpy(ptr, compressedTextureFormats,
696 ctx->m_num_compressedTextureFormats * sizeof(GLint));
697 }
698 break;
699 }
700
701 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
Lingfeng Yang48685bb2018-10-19 06:44:20 -0700702 if (ctx->m_max_combinedTextureImageUnits != 0) {
703 *ptr = ctx->m_max_combinedTextureImageUnits;
704 } else {
705 ctx->safe_glGetIntegerv(param, ptr);
706 ctx->m_max_combinedTextureImageUnits = *ptr;
707 }
708 break;
keunyoungb85b2752013-03-08 12:28:03 -0800709 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
Lingfeng Yanga1edab62018-10-19 07:53:49 -0700710 if (ctx->m_max_vertexTextureImageUnits != 0) {
711 *ptr = ctx->m_max_vertexTextureImageUnits;
712 } else {
713 ctx->safe_glGetIntegerv(param, ptr);
714 ctx->m_max_vertexTextureImageUnits = *ptr;
715 }
keunyoungb85b2752013-03-08 12:28:03 -0800716 break;
Lingfeng Yanga1edab62018-10-19 07:53:49 -0700717 case GL_MAX_TEXTURE_IMAGE_UNITS:
718 if (ctx->m_max_textureImageUnits != 0) {
719 *ptr = ctx->m_max_textureImageUnits;
720 } else {
721 ctx->safe_glGetIntegerv(param, ptr);
722 ctx->m_max_textureImageUnits = *ptr;
723 }
724 break;
keunyoungb85b2752013-03-08 12:28:03 -0800725 case GL_TEXTURE_BINDING_2D:
Lingfeng Yang83de3d12018-10-17 10:57:53 -0700726 SET_ERROR_IF(!state, GL_INVALID_OPERATION);
keunyoungb85b2752013-03-08 12:28:03 -0800727 *ptr = state->getBoundTexture(GL_TEXTURE_2D);
728 break;
729 case GL_TEXTURE_BINDING_EXTERNAL_OES:
Lingfeng Yang83de3d12018-10-17 10:57:53 -0700730 SET_ERROR_IF(!state, GL_INVALID_OPERATION);
keunyoungb85b2752013-03-08 12:28:03 -0800731 *ptr = state->getBoundTexture(GL_TEXTURE_EXTERNAL_OES);
732 break;
733
Lingfeng Yangb0176982016-03-01 21:27:49 -0800734 case GL_MAX_VERTEX_ATTRIBS:
Lingfeng Yang83de3d12018-10-17 10:57:53 -0700735 SET_ERROR_IF(!state, GL_INVALID_OPERATION);
736 if (!state->getClientStateParameter<GLint>(param, ptr)) {
Lingfeng Yang80a36332017-07-09 10:58:07 -0700737 ctx->safe_glGetIntegerv(param, ptr);
Lingfeng Yang83de3d12018-10-17 10:57:53 -0700738 state->setMaxVertexAttribs(*ptr);
Yahan Zhoua5c36842016-06-01 12:49:39 -0700739 }
740 break;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -0800741 case GL_MAX_VERTEX_ATTRIB_STRIDE:
742 if (ctx->m_max_vertexAttribStride != 0) {
743 *ptr = ctx->m_max_vertexAttribStride;
744 } else {
Lingfeng Yang80a36332017-07-09 10:58:07 -0700745 ctx->safe_glGetIntegerv(param, ptr);
Lingfeng Yangd3ae1062017-01-18 11:42:04 -0800746 ctx->m_max_vertexAttribStride = *ptr;
747 }
748 break;
Lizhe Liue41f4ef2015-05-27 11:13:23 +0800749 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
750 if (ctx->m_max_cubeMapTextureSize != 0) {
751 *ptr = ctx->m_max_cubeMapTextureSize;
752 } else {
Lingfeng Yang80a36332017-07-09 10:58:07 -0700753 ctx->safe_glGetIntegerv(param, ptr);
Lizhe Liue41f4ef2015-05-27 11:13:23 +0800754 ctx->m_max_cubeMapTextureSize = *ptr;
755 }
756 break;
757 case GL_MAX_RENDERBUFFER_SIZE:
758 if (ctx->m_max_renderBufferSize != 0) {
759 *ptr = ctx->m_max_renderBufferSize;
760 } else {
Lingfeng Yang80a36332017-07-09 10:58:07 -0700761 ctx->safe_glGetIntegerv(param, ptr);
Lizhe Liue41f4ef2015-05-27 11:13:23 +0800762 ctx->m_max_renderBufferSize = *ptr;
763 }
764 break;
765 case GL_MAX_TEXTURE_SIZE:
766 if (ctx->m_max_textureSize != 0) {
767 *ptr = ctx->m_max_textureSize;
768 } else {
Lingfeng Yang80a36332017-07-09 10:58:07 -0700769 ctx->safe_glGetIntegerv(param, ptr);
Lizhe Liue41f4ef2015-05-27 11:13:23 +0800770 ctx->m_max_textureSize = *ptr;
Lingfeng Yangb0176982016-03-01 21:27:49 -0800771 }
772 break;
Lingfeng Yang46153ab2017-01-09 13:37:22 -0800773 case GL_MAX_3D_TEXTURE_SIZE:
774 if (ctx->m_max_3d_textureSize != 0) {
775 *ptr = ctx->m_max_3d_textureSize;
776 } else {
Lingfeng Yang80a36332017-07-09 10:58:07 -0700777 ctx->safe_glGetIntegerv(param, ptr);
Lingfeng Yang46153ab2017-01-09 13:37:22 -0800778 ctx->m_max_3d_textureSize = *ptr;
779 }
780 break;
781 case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
782 if (ctx->m_ssbo_offset_align != 0) {
783 *ptr = ctx->m_ssbo_offset_align;
784 } else {
Lingfeng Yang80a36332017-07-09 10:58:07 -0700785 ctx->safe_glGetIntegerv(param, ptr);
Lingfeng Yang46153ab2017-01-09 13:37:22 -0800786 ctx->m_ssbo_offset_align = *ptr;
787 }
788 break;
789 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
790 if (ctx->m_ubo_offset_align != 0) {
791 *ptr = ctx->m_ubo_offset_align;
792 } else {
Lingfeng Yang80a36332017-07-09 10:58:07 -0700793 ctx->safe_glGetIntegerv(param, ptr);
Lingfeng Yang46153ab2017-01-09 13:37:22 -0800794 ctx->m_ubo_offset_align = *ptr;
795 }
796 break;
797 // Desktop OpenGL can allow a mindboggling # samples per pixel (such as 64).
798 // Limit to 4 (spec minimum) to keep dEQP tests from timing out.
799 case GL_MAX_SAMPLES:
Lingfeng Yangd3ae1062017-01-18 11:42:04 -0800800 case GL_MAX_COLOR_TEXTURE_SAMPLES:
801 case GL_MAX_INTEGER_SAMPLES:
802 case GL_MAX_DEPTH_TEXTURE_SAMPLES:
Lingfeng Yang46153ab2017-01-09 13:37:22 -0800803 *ptr = 4;
804 break;
Lingfeng Yangc9b597b2017-07-08 17:21:03 -0700805 // Checks for version-incompatible enums.
806 // Not allowed in vanilla ES 2.0.
807 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
Lingfeng Yanga1edab62018-10-19 07:53:49 -0700808 SET_ERROR_IF(ctx->majorVersion() < 3, GL_INVALID_ENUM);
809 if (ctx->m_max_transformFeedbackSeparateAttribs != 0) {
810 *ptr = ctx->m_max_transformFeedbackSeparateAttribs;
811 } else {
812 ctx->safe_glGetIntegerv(param, ptr);
813 ctx->m_max_transformFeedbackSeparateAttribs = *ptr;
814 }
815 break;
Lingfeng Yangc9b597b2017-07-08 17:21:03 -0700816 case GL_MAX_UNIFORM_BUFFER_BINDINGS:
817 SET_ERROR_IF(ctx->majorVersion() < 3, GL_INVALID_ENUM);
Lingfeng Yanga1edab62018-10-19 07:53:49 -0700818 if (ctx->m_max_uniformBufferBindings != 0) {
819 *ptr = ctx->m_max_uniformBufferBindings;
820 } else {
821 ctx->safe_glGetIntegerv(param, ptr);
822 ctx->m_max_uniformBufferBindings = *ptr;
823 }
Lingfeng Yangc9b597b2017-07-08 17:21:03 -0700824 break;
825 case GL_MAX_COLOR_ATTACHMENTS:
Lingfeng Yanga1edab62018-10-19 07:53:49 -0700826 SET_ERROR_IF(ctx->majorVersion() < 3 &&
827 !ctx->hasExtension("GL_EXT_draw_buffers"), GL_INVALID_ENUM);
828 if (ctx->m_max_colorAttachments != 0) {
829 *ptr = ctx->m_max_colorAttachments;
830 } else {
831 ctx->safe_glGetIntegerv(param, ptr);
832 ctx->m_max_colorAttachments = *ptr;
833 }
834 break;
Lingfeng Yangc9b597b2017-07-08 17:21:03 -0700835 case GL_MAX_DRAW_BUFFERS:
836 SET_ERROR_IF(ctx->majorVersion() < 3 &&
837 !ctx->hasExtension("GL_EXT_draw_buffers"), GL_INVALID_ENUM);
Lingfeng Yanga1edab62018-10-19 07:53:49 -0700838 if (ctx->m_max_drawBuffers != 0) {
839 *ptr = ctx->m_max_drawBuffers;
840 } else {
841 ctx->safe_glGetIntegerv(param, ptr);
842 ctx->m_max_drawBuffers = *ptr;
843 }
Lingfeng Yangc9b597b2017-07-08 17:21:03 -0700844 break;
845 // Not allowed in ES 3.0.
846 case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
Lingfeng Yanga1edab62018-10-19 07:53:49 -0700847 SET_ERROR_IF(ctx->majorVersion() < 3 ||
848 (ctx->majorVersion() == 3 &&
849 ctx->minorVersion() == 0), GL_INVALID_ENUM);
850 if (ctx->m_max_atomicCounterBufferBindings != 0) {
851 *ptr = ctx->m_max_atomicCounterBufferBindings;
852 } else {
853 ctx->safe_glGetIntegerv(param, ptr);
854 ctx->m_max_atomicCounterBufferBindings = *ptr;
855 }
856 break;
Lingfeng Yangc9b597b2017-07-08 17:21:03 -0700857 case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
Lingfeng Yanga1edab62018-10-19 07:53:49 -0700858 SET_ERROR_IF(ctx->majorVersion() < 3 ||
859 (ctx->majorVersion() == 3 &&
860 ctx->minorVersion() == 0), GL_INVALID_ENUM);
861 if (ctx->m_max_shaderStorageBufferBindings != 0) {
862 *ptr = ctx->m_max_shaderStorageBufferBindings;
863 } else {
864 ctx->safe_glGetIntegerv(param, ptr);
865 ctx->m_max_shaderStorageBufferBindings = *ptr;
866 }
867 break;
Lingfeng Yangc9b597b2017-07-08 17:21:03 -0700868 case GL_MAX_VERTEX_ATTRIB_BINDINGS:
869 SET_ERROR_IF(ctx->majorVersion() < 3 ||
870 (ctx->majorVersion() == 3 &&
871 ctx->minorVersion() == 0), GL_INVALID_ENUM);
Lingfeng Yanga1edab62018-10-19 07:53:49 -0700872 if (ctx->m_max_vertexAttribBindings != 0) {
873 *ptr = ctx->m_max_vertexAttribBindings;
874 } else {
875 ctx->safe_glGetIntegerv(param, ptr);
876 ctx->m_max_vertexAttribBindings = *ptr;
877 }
Lingfeng Yangc9b597b2017-07-08 17:21:03 -0700878 break;
Yahan Zhou72944ba2019-01-02 15:43:46 -0800879 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
880 // BUG: 121414786
881 *ptr = GL_LOSE_CONTEXT_ON_RESET_EXT;
882 break;
keunyoungb85b2752013-03-08 12:28:03 -0800883 default:
Lingfeng Yang83de3d12018-10-17 10:57:53 -0700884 SET_ERROR_IF(!state, GL_INVALID_OPERATION);
885 if (!state->getClientStateParameter<GLint>(param, ptr)) {
Lingfeng Yang80a36332017-07-09 10:58:07 -0700886 ctx->safe_glGetIntegerv(param, ptr);
keunyoungb85b2752013-03-08 12:28:03 -0800887 }
888 break;
889 }
890}
891
892
893void GL2Encoder::s_glGetFloatv(void *self, GLenum param, GLfloat *ptr)
894{
895 GL2Encoder *ctx = (GL2Encoder *)self;
keunyoungb85b2752013-03-08 12:28:03 -0800896 GLClientState* state = ctx->m_state;
897
898 switch (param) {
899 case GL_NUM_SHADER_BINARY_FORMATS:
900 *ptr = 0;
901 break;
902 case GL_SHADER_BINARY_FORMATS:
903 // do nothing
904 break;
905
906 case GL_COMPRESSED_TEXTURE_FORMATS: {
907 GLint *compressedTextureFormats = ctx->getCompressedTextureFormats();
908 if (ctx->m_num_compressedTextureFormats > 0 &&
909 compressedTextureFormats != NULL) {
910 for (int i = 0; i < ctx->m_num_compressedTextureFormats; i++) {
911 ptr[i] = (GLfloat) compressedTextureFormats[i];
912 }
913 }
914 break;
915 }
916
917 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
918 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
919 case GL_MAX_TEXTURE_IMAGE_UNITS:
Lingfeng Yanga1edab62018-10-19 07:53:49 -0700920 case GL_MAX_VERTEX_ATTRIBS:
921 case GL_MAX_VERTEX_ATTRIB_STRIDE:
922 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
923 case GL_MAX_RENDERBUFFER_SIZE:
924 case GL_MAX_TEXTURE_SIZE:
925 case GL_MAX_3D_TEXTURE_SIZE:
926 case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
927 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
928 case GL_MAX_SAMPLES:
929 case GL_MAX_COLOR_TEXTURE_SAMPLES:
930 case GL_MAX_INTEGER_SAMPLES:
931 case GL_MAX_DEPTH_TEXTURE_SAMPLES:
932 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
933 case GL_MAX_UNIFORM_BUFFER_BINDINGS:
934 case GL_MAX_COLOR_ATTACHMENTS:
935 case GL_MAX_DRAW_BUFFERS:
936 case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
937 case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
938 case GL_MAX_VERTEX_ATTRIB_BINDINGS:
keunyoungb85b2752013-03-08 12:28:03 -0800939 case GL_TEXTURE_BINDING_2D:
Lingfeng Yanga1edab62018-10-19 07:53:49 -0700940 case GL_TEXTURE_BINDING_EXTERNAL_OES: {
941 GLint res;
942 s_glGetIntegerv(ctx, param, &res);
943 *ptr = (GLfloat)res;
keunyoungb85b2752013-03-08 12:28:03 -0800944 break;
Lingfeng Yanga1edab62018-10-19 07:53:49 -0700945 }
keunyoungb85b2752013-03-08 12:28:03 -0800946
947 default:
Lingfeng Yang83de3d12018-10-17 10:57:53 -0700948 SET_ERROR_IF(!state, GL_INVALID_OPERATION);
949 if (!state->getClientStateParameter<GLfloat>(param, ptr)) {
Lingfeng Yang80a36332017-07-09 10:58:07 -0700950 ctx->safe_glGetFloatv(param, ptr);
keunyoungb85b2752013-03-08 12:28:03 -0800951 }
952 break;
953 }
954}
955
956
957void GL2Encoder::s_glGetBooleanv(void *self, GLenum param, GLboolean *ptr)
958{
959 GL2Encoder *ctx = (GL2Encoder *)self;
keunyoungb85b2752013-03-08 12:28:03 -0800960 GLClientState* state = ctx->m_state;
961
962 switch (param) {
963 case GL_NUM_SHADER_BINARY_FORMATS:
964 *ptr = GL_FALSE;
965 break;
966 case GL_SHADER_BINARY_FORMATS:
967 // do nothing
968 break;
969
970 case GL_COMPRESSED_TEXTURE_FORMATS: {
971 GLint *compressedTextureFormats = ctx->getCompressedTextureFormats();
972 if (ctx->m_num_compressedTextureFormats > 0 &&
973 compressedTextureFormats != NULL) {
974 for (int i = 0; i < ctx->m_num_compressedTextureFormats; i++) {
975 ptr[i] = compressedTextureFormats[i] != 0 ? GL_TRUE : GL_FALSE;
976 }
977 }
978 break;
979 }
980
Lingfeng Yanga1edab62018-10-19 07:53:49 -0700981 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
982 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
983 case GL_MAX_TEXTURE_IMAGE_UNITS:
984 case GL_MAX_VERTEX_ATTRIBS:
985 case GL_MAX_VERTEX_ATTRIB_STRIDE:
986 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
987 case GL_MAX_RENDERBUFFER_SIZE:
988 case GL_MAX_TEXTURE_SIZE:
989 case GL_MAX_3D_TEXTURE_SIZE:
990 case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
991 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
992 case GL_MAX_SAMPLES:
993 case GL_MAX_COLOR_TEXTURE_SAMPLES:
994 case GL_MAX_INTEGER_SAMPLES:
995 case GL_MAX_DEPTH_TEXTURE_SAMPLES:
996 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
997 case GL_MAX_UNIFORM_BUFFER_BINDINGS:
998 case GL_MAX_COLOR_ATTACHMENTS:
999 case GL_MAX_DRAW_BUFFERS:
1000 case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
1001 case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
1002 case GL_MAX_VERTEX_ATTRIB_BINDINGS:
keunyoungb85b2752013-03-08 12:28:03 -08001003 case GL_TEXTURE_BINDING_2D:
Lingfeng Yanga1edab62018-10-19 07:53:49 -07001004 case GL_TEXTURE_BINDING_EXTERNAL_OES: {
1005 GLint res;
1006 s_glGetIntegerv(ctx, param, &res);
1007 *ptr = res == 0 ? GL_FALSE : GL_TRUE;
keunyoungb85b2752013-03-08 12:28:03 -08001008 break;
Lingfeng Yanga1edab62018-10-19 07:53:49 -07001009 }
keunyoungb85b2752013-03-08 12:28:03 -08001010
1011 default:
Lingfeng Yang83de3d12018-10-17 10:57:53 -07001012 SET_ERROR_IF(!state, GL_INVALID_OPERATION);
1013 if (!state->getClientStateParameter<GLboolean>(param, ptr)) {
Lingfeng Yang80a36332017-07-09 10:58:07 -07001014 ctx->safe_glGetBooleanv(param, ptr);
keunyoungb85b2752013-03-08 12:28:03 -08001015 }
bohu05101d22014-11-17 16:28:42 -08001016 *ptr = (*ptr != 0) ? GL_TRUE : GL_FALSE;
keunyoungb85b2752013-03-08 12:28:03 -08001017 break;
1018 }
1019}
1020
1021
1022void GL2Encoder::s_glEnableVertexAttribArray(void *self, GLuint index)
1023{
1024 GL2Encoder *ctx = (GL2Encoder *)self;
1025 assert(ctx->m_state);
Lingfeng Yang07289902017-01-27 12:26:19 -08001026 VALIDATE_VERTEX_ATTRIB_INDEX(index);
Lingfeng Yangfe2a31d2016-12-02 08:02:15 -08001027 ctx->m_glEnableVertexAttribArray_enc(ctx, index);
keunyoungb85b2752013-03-08 12:28:03 -08001028 ctx->m_state->enable(index, 1);
1029}
1030
1031void GL2Encoder::s_glDisableVertexAttribArray(void *self, GLuint index)
1032{
1033 GL2Encoder *ctx = (GL2Encoder *)self;
1034 assert(ctx->m_state);
Lingfeng Yang07289902017-01-27 12:26:19 -08001035 VALIDATE_VERTEX_ATTRIB_INDEX(index);
Lingfeng Yangfe2a31d2016-12-02 08:02:15 -08001036 ctx->m_glDisableVertexAttribArray_enc(ctx, index);
keunyoungb85b2752013-03-08 12:28:03 -08001037 ctx->m_state->enable(index, 0);
1038}
1039
1040
1041void GL2Encoder::s_glGetVertexAttribiv(void *self, GLuint index, GLenum pname, GLint *params)
1042{
1043 GL2Encoder *ctx = (GL2Encoder *)self;
1044 assert(ctx->m_state);
Lingfeng Yang0f508082016-04-08 12:38:35 -07001045 GLint maxIndex;
1046 ctx->glGetIntegerv(self, GL_MAX_VERTEX_ATTRIBS, &maxIndex);
1047 SET_ERROR_IF(!(index < maxIndex), GL_INVALID_VALUE);
keunyoungb85b2752013-03-08 12:28:03 -08001048
1049 if (!ctx->m_state->getVertexAttribParameter<GLint>(index, pname, params)) {
1050 ctx->m_glGetVertexAttribiv_enc(self, index, pname, params);
1051 }
1052}
1053
1054void GL2Encoder::s_glGetVertexAttribfv(void *self, GLuint index, GLenum pname, GLfloat *params)
1055{
1056 GL2Encoder *ctx = (GL2Encoder *)self;
1057 assert(ctx->m_state);
Lingfeng Yang0f508082016-04-08 12:38:35 -07001058 GLint maxIndex;
1059 ctx->glGetIntegerv(self, GL_MAX_VERTEX_ATTRIBS, &maxIndex);
1060 SET_ERROR_IF(!(index < maxIndex), GL_INVALID_VALUE);
keunyoungb85b2752013-03-08 12:28:03 -08001061
1062 if (!ctx->m_state->getVertexAttribParameter<GLfloat>(index, pname, params)) {
1063 ctx->m_glGetVertexAttribfv_enc(self, index, pname, params);
1064 }
1065}
1066
1067void GL2Encoder::s_glGetVertexAttribPointerv(void *self, GLuint index, GLenum pname, GLvoid **pointer)
1068{
1069 GL2Encoder *ctx = (GL2Encoder *)self;
1070 if (ctx->m_state == NULL) return;
Lingfeng Yang5e100432016-04-08 12:46:42 -07001071 GLint maxIndex;
1072 ctx->glGetIntegerv(self, GL_MAX_VERTEX_ATTRIBS, &maxIndex);
1073 SET_ERROR_IF(!(index < maxIndex), GL_INVALID_VALUE);
1074 SET_ERROR_IF(pname != GL_VERTEX_ATTRIB_ARRAY_POINTER, GL_INVALID_ENUM);
David 'Digit' Turnere01d5f42014-10-30 21:32:28 +01001075 (void)pname;
1076
Lingfeng Yang46153ab2017-01-09 13:37:22 -08001077 *pointer = (GLvoid*)(ctx->m_state->getCurrAttributeBindingInfo(index).offset);
keunyoungb85b2752013-03-08 12:28:03 -08001078}
1079
Lingfeng Yang8e2b6e02016-10-14 11:20:45 -07001080void GL2Encoder::calcIndexRange(const void* indices,
1081 GLenum type,
1082 GLsizei count,
1083 int* minIndex_out,
1084 int* maxIndex_out) {
1085 switch(type) {
1086 case GL_BYTE:
1087 case GL_UNSIGNED_BYTE:
1088 GLUtils::minmaxExcept(
1089 (unsigned char *)indices, count,
1090 minIndex_out, maxIndex_out,
Lingfeng Yang46153ab2017-01-09 13:37:22 -08001091 m_primitiveRestartEnabled, GLUtils::primitiveRestartIndex<unsigned char>());
Lingfeng Yang8e2b6e02016-10-14 11:20:45 -07001092 break;
1093 case GL_SHORT:
1094 case GL_UNSIGNED_SHORT:
1095 GLUtils::minmaxExcept(
1096 (unsigned short *)indices, count,
1097 minIndex_out, maxIndex_out,
Lingfeng Yang46153ab2017-01-09 13:37:22 -08001098 m_primitiveRestartEnabled, GLUtils::primitiveRestartIndex<unsigned short>());
Lingfeng Yang8e2b6e02016-10-14 11:20:45 -07001099 break;
1100 case GL_INT:
1101 case GL_UNSIGNED_INT:
1102 GLUtils::minmaxExcept(
1103 (unsigned int *)indices, count,
1104 minIndex_out, maxIndex_out,
Lingfeng Yang46153ab2017-01-09 13:37:22 -08001105 m_primitiveRestartEnabled, GLUtils::primitiveRestartIndex<unsigned int>());
Lingfeng Yang8e2b6e02016-10-14 11:20:45 -07001106 break;
1107 default:
1108 ALOGE("unsupported index buffer type %d\n", type);
1109 }
1110}
1111
1112void* GL2Encoder::recenterIndices(const void* src,
1113 GLenum type,
1114 GLsizei count,
1115 int minIndex) {
1116
1117 void* adjustedIndices = (void*)src;
1118
1119 if (minIndex != 0) {
1120 adjustedIndices = m_fixedBuffer.alloc(glSizeof(type) * count);
1121 switch(type) {
1122 case GL_BYTE:
1123 case GL_UNSIGNED_BYTE:
1124 GLUtils::shiftIndicesExcept(
1125 (unsigned char *)src,
1126 (unsigned char *)adjustedIndices,
1127 count, -minIndex,
1128 m_primitiveRestartEnabled,
1129 (unsigned char)m_primitiveRestartIndex);
1130 break;
1131 case GL_SHORT:
1132 case GL_UNSIGNED_SHORT:
1133 GLUtils::shiftIndicesExcept(
1134 (unsigned short *)src,
1135 (unsigned short *)adjustedIndices,
1136 count, -minIndex,
1137 m_primitiveRestartEnabled,
1138 (unsigned short)m_primitiveRestartIndex);
1139 break;
1140 case GL_INT:
1141 case GL_UNSIGNED_INT:
1142 GLUtils::shiftIndicesExcept(
1143 (unsigned int *)src,
1144 (unsigned int *)adjustedIndices,
1145 count, -minIndex,
1146 m_primitiveRestartEnabled,
1147 (unsigned int)m_primitiveRestartIndex);
1148 break;
1149 default:
1150 ALOGE("unsupported index buffer type %d\n", type);
1151 }
1152 }
1153
1154 return adjustedIndices;
1155}
1156
1157void GL2Encoder::getBufferIndexRange(BufferData* buf,
1158 const void* dataWithOffset,
1159 GLenum type,
Lingfeng Yang1ae9d732016-12-12 16:17:02 -08001160 size_t count,
1161 size_t offset,
Lingfeng Yang8e2b6e02016-10-14 11:20:45 -07001162 int* minIndex_out,
1163 int* maxIndex_out) {
1164
1165 if (buf->m_indexRangeCache.findRange(
Lingfeng Yang1ae9d732016-12-12 16:17:02 -08001166 type, offset, count,
Lingfeng Yang8e2b6e02016-10-14 11:20:45 -07001167 m_primitiveRestartEnabled,
1168 minIndex_out,
1169 maxIndex_out)) {
1170 return;
1171 }
1172
1173 calcIndexRange(dataWithOffset, type, count, minIndex_out, maxIndex_out);
1174
1175 buf->m_indexRangeCache.addRange(
Lingfeng Yang1ae9d732016-12-12 16:17:02 -08001176 type, offset, count, m_primitiveRestartEnabled,
Lingfeng Yang8e2b6e02016-10-14 11:20:45 -07001177 *minIndex_out, *maxIndex_out);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08001178
1179 ALOGV("%s: got range [%u %u] pr? %d", __FUNCTION__, *minIndex_out, *maxIndex_out, m_primitiveRestartEnabled);
Lingfeng Yang8e2b6e02016-10-14 11:20:45 -07001180}
keunyoungb85b2752013-03-08 12:28:03 -08001181
Lingfeng Yangfe2a31d2016-12-02 08:02:15 -08001182// For detecting legacy usage of glVertexAttribPointer
1183void GL2Encoder::getVBOUsage(bool* hasClientArrays, bool* hasVBOs) const {
1184 if (hasClientArrays) *hasClientArrays = false;
1185 if (hasVBOs) *hasVBOs = false;
1186
1187 for (int i = 0; i < m_state->nLocations(); i++) {
Lingfeng Yang46153ab2017-01-09 13:37:22 -08001188 const GLClientState::VertexAttribState& state = m_state->getState(i);
1189 if (state.enabled) {
1190 const GLClientState::BufferBinding& curr_binding = m_state->getCurrAttributeBindingInfo(i);
1191 GLuint bufferObject = curr_binding.buffer;
1192 if (bufferObject == 0 && curr_binding.offset && hasClientArrays) {
Lingfeng Yangfe2a31d2016-12-02 08:02:15 -08001193 *hasClientArrays = true;
1194 }
Lingfeng Yang46153ab2017-01-09 13:37:22 -08001195 if (bufferObject != 0 && hasVBOs) {
Lingfeng Yangfe2a31d2016-12-02 08:02:15 -08001196 *hasVBOs = true;
1197 }
1198 }
1199 }
1200}
1201
Lingfeng Yang46153ab2017-01-09 13:37:22 -08001202void GL2Encoder::sendVertexAttributes(GLint first, GLsizei count, bool hasClientArrays, GLsizei primcount)
keunyoungb85b2752013-03-08 12:28:03 -08001203{
1204 assert(m_state);
1205
Lingfeng Yang554a5152019-02-21 20:20:48 -08001206 m_state->updateEnableDirtyArrayForDraw();
1207
Lingfeng Yang398162b2016-05-26 14:18:33 -07001208 GLuint lastBoundVbo = m_state->currentArrayVbo();
Lingfeng Yang554a5152019-02-21 20:20:48 -08001209 const GLClientState::VAOState& vaoState = m_state->currentVaoState();
keunyoungb85b2752013-03-08 12:28:03 -08001210
Lingfeng Yang554a5152019-02-21 20:20:48 -08001211 for (int k = 0; k < vaoState.numAttributesNeedingUpdateForDraw; k++) {
1212 int i = vaoState.attributesNeedingUpdateForDraw[k];
1213
1214 const GLClientState::VertexAttribState& state = vaoState.attribState[i];
keunyoungb85b2752013-03-08 12:28:03 -08001215
Lingfeng Yang46153ab2017-01-09 13:37:22 -08001216 if (state.enabled) {
1217 const GLClientState::BufferBinding& curr_binding = m_state->getCurrAttributeBindingInfo(i);
1218 GLuint bufferObject = curr_binding.buffer;
1219 if (hasClientArrays && lastBoundVbo != bufferObject) {
Lingfeng Yang554a5152019-02-21 20:20:48 -08001220 doBindBufferEncodeCached(GL_ARRAY_BUFFER, bufferObject);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08001221 lastBoundVbo = bufferObject;
Lingfeng Yang398162b2016-05-26 14:18:33 -07001222 }
keunyoungb85b2752013-03-08 12:28:03 -08001223
Lingfeng Yang46153ab2017-01-09 13:37:22 -08001224 int divisor = curr_binding.divisor;
1225 int stride = curr_binding.stride;
1226 int effectiveStride = curr_binding.effectiveStride;
1227 uintptr_t offset = curr_binding.offset;
Lingfeng Yang4e5446b2017-02-15 08:44:21 -08001228
Lingfeng Yang46153ab2017-01-09 13:37:22 -08001229 int firstIndex = effectiveStride * first;
Lingfeng Yang4e5446b2017-02-15 08:44:21 -08001230 if (firstIndex && divisor && !primcount) {
1231 // If firstIndex != 0 according to effectiveStride * first,
1232 // it needs to be adjusted if a divisor has been specified,
1233 // even if we are not in glDraw***Instanced.
1234 firstIndex = 0;
1235 }
keunyoungb85b2752013-03-08 12:28:03 -08001236
Lingfeng Yang46153ab2017-01-09 13:37:22 -08001237 if (bufferObject == 0) {
1238 unsigned int datalen = state.elementSize * count;
Yahan Zhoufe1820e2018-12-06 17:18:12 -08001239 if (divisor) {
Lingfeng Yang46153ab2017-01-09 13:37:22 -08001240 ALOGV("%s: divisor for att %d: %d, w/ stride %d (effective stride %d) size %d type 0x%x) datalen %u",
1241 __FUNCTION__, i, divisor, state.stride, effectiveStride, state.elementSize, state.type, datalen);
1242 int actual_count = std::max(1, (int)((primcount + divisor - 1) / divisor));
1243 datalen = state.elementSize * actual_count;
1244 ALOGV("%s: actual datalen %u", __FUNCTION__, datalen);
1245 }
1246 if (state.elementSize == 0) {
Yahan Zhou3f2f1b42016-12-01 13:49:44 -08001247 // The vertex attribute array is uninitialized. Abandon it.
1248 ALOGE("a vertex attribute array is uninitialized. Skipping corresponding vertex attribute.");
1249 this->m_glDisableVertexAttribArray_enc(this, i);
1250 continue;
1251 }
Yahan Zhou5507c042016-06-01 17:24:28 -07001252 m_glEnableVertexAttribArray_enc(this, i);
Lingfeng Yang000cf4c2017-01-25 08:09:02 -08001253
1254 if (datalen && (!offset || !((unsigned char*)offset + firstIndex))) {
1255 ALOGD("%s: bad offset / len!!!!!", __FUNCTION__);
1256 continue;
1257 }
Lingfeng Yang46153ab2017-01-09 13:37:22 -08001258 if (state.isInt) {
1259 this->glVertexAttribIPointerDataAEMU(this, i, state.size, state.type, stride, (unsigned char *)offset + firstIndex, datalen);
1260 } else {
1261 this->glVertexAttribPointerData(this, i, state.size, state.type, state.normalized, stride, (unsigned char *)offset + firstIndex, datalen);
1262 }
keunyoungb85b2752013-03-08 12:28:03 -08001263 } else {
Lingfeng Yang46153ab2017-01-09 13:37:22 -08001264 const BufferData* buf = m_shared->getBufferData(bufferObject);
Yahan Zhou5507c042016-06-01 17:24:28 -07001265 // The following expression actually means bufLen = stride*count;
1266 // But the last element doesn't have to fill up the whole stride.
1267 // So it becomes the current form.
Lingfeng Yang5fe99012017-01-18 09:17:09 -08001268 unsigned int bufLen = effectiveStride * (count ? (count - 1) : 0) + state.elementSize;
Yahan Zhoufe1820e2018-12-06 17:18:12 -08001269 if (divisor) {
Lingfeng Yang46153ab2017-01-09 13:37:22 -08001270 int actual_count = std::max(1, (int)((primcount + divisor - 1) / divisor));
Lingfeng Yang5fe99012017-01-18 09:17:09 -08001271 bufLen = effectiveStride * (actual_count ? (actual_count - 1) : 0) + state.elementSize;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08001272 }
Yahan Zhou5507c042016-06-01 17:24:28 -07001273 if (buf && firstIndex >= 0 && firstIndex + bufLen <= buf->m_size) {
Lingfeng Yangfe2a31d2016-12-02 08:02:15 -08001274 if (hasClientArrays) {
1275 m_glEnableVertexAttribArray_enc(this, i);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08001276 if (state.isInt) {
1277 this->glVertexAttribIPointerOffsetAEMU(this, i, state.size, state.type, stride, offset + firstIndex);
1278 } else {
1279 this->glVertexAttribPointerOffset(this, i, state.size, state.type, state.normalized, stride, offset + firstIndex);
1280 }
Lingfeng Yangfe2a31d2016-12-02 08:02:15 -08001281 }
Yahan Zhou5507c042016-06-01 17:24:28 -07001282 } else {
Lingfeng Yang46153ab2017-01-09 13:37:22 -08001283 ALOGE("a vertex attribute index out of boundary is detected. Skipping corresponding vertex attribute. buf=%p", buf);
Lingfeng Yang8d9d6c62017-01-18 09:26:19 -08001284 if (buf) {
1285 ALOGE("Out of bounds vertex attribute info: "
1286 "clientArray? %d attribute %d vbo %u allocedBufferSize %u bufferDataSpecified? %d wantedStart %u wantedEnd %u",
Lingfeng Yangddfb4452018-09-24 17:26:07 -07001287 hasClientArrays, i, bufferObject, (unsigned int)buf->m_size, buf != NULL, firstIndex, firstIndex + bufLen);
Lingfeng Yang8d9d6c62017-01-18 09:26:19 -08001288 }
1289 m_glDisableVertexAttribArray_enc(this, i);
Yahan Zhou5507c042016-06-01 17:24:28 -07001290 }
keunyoungb85b2752013-03-08 12:28:03 -08001291 }
1292 } else {
Lingfeng Yangfe2a31d2016-12-02 08:02:15 -08001293 if (hasClientArrays) {
1294 this->m_glDisableVertexAttribArray_enc(this, i);
1295 }
keunyoungb85b2752013-03-08 12:28:03 -08001296 }
1297 }
Lingfeng Yang398162b2016-05-26 14:18:33 -07001298
Lingfeng Yangfe2a31d2016-12-02 08:02:15 -08001299 if (hasClientArrays && lastBoundVbo != m_state->currentArrayVbo()) {
Lingfeng Yang554a5152019-02-21 20:20:48 -08001300 doBindBufferEncodeCached(GL_ARRAY_BUFFER, m_state->currentArrayVbo());
Lingfeng Yang398162b2016-05-26 14:18:33 -07001301 }
keunyoungb85b2752013-03-08 12:28:03 -08001302}
1303
Lingfeng Yang8e2b6e02016-10-14 11:20:45 -07001304void GL2Encoder::flushDrawCall() {
Lingfeng Yang1ebb33c2017-01-19 08:04:48 -08001305 // This used to be every other draw call, but
1306 // now that we are using real GPU buffers on host,
1307 // set this to every 200 draw calls
1308 // (tuned on z840 linux NVIDIA Quadro K2200)
1309 if (m_drawCallFlushCount % 200 == 0) {
Lingfeng Yang8e2b6e02016-10-14 11:20:45 -07001310 m_stream->flush();
1311 }
1312 m_drawCallFlushCount++;
1313}
1314
Evan Birenbaumd51386b2016-04-13 12:53:09 -07001315static bool isValidDrawMode(GLenum mode)
1316{
1317 bool retval = false;
1318 switch (mode) {
1319 case GL_POINTS:
1320 case GL_LINE_STRIP:
1321 case GL_LINE_LOOP:
1322 case GL_LINES:
1323 case GL_TRIANGLE_STRIP:
1324 case GL_TRIANGLE_FAN:
1325 case GL_TRIANGLES:
1326 retval = true;
1327 }
1328 return retval;
1329}
1330
keunyoungb85b2752013-03-08 12:28:03 -08001331void GL2Encoder::s_glDrawArrays(void *self, GLenum mode, GLint first, GLsizei count)
1332{
1333 GL2Encoder *ctx = (GL2Encoder *)self;
Evan Birenbaumd51386b2016-04-13 12:53:09 -07001334 assert(ctx->m_state != NULL);
1335 SET_ERROR_IF(!isValidDrawMode(mode), GL_INVALID_ENUM);
1336 SET_ERROR_IF(count < 0, GL_INVALID_VALUE);
Yahan Zhoud6217a52016-02-10 16:10:46 -08001337
Lingfeng Yangfe2a31d2016-12-02 08:02:15 -08001338 bool has_client_vertex_arrays = false;
1339 bool has_indirect_arrays = false;
1340 ctx->getVBOUsage(&has_client_vertex_arrays,
1341 &has_indirect_arrays);
1342
1343 if (has_client_vertex_arrays ||
1344 (!has_client_vertex_arrays &&
1345 !has_indirect_arrays)) {
1346 ctx->sendVertexAttributes(first, count, true);
1347 ctx->m_glDrawArrays_enc(ctx, mode, 0, count);
1348 } else {
1349 ctx->sendVertexAttributes(0, count, false);
1350 ctx->m_glDrawArrays_enc(ctx, mode, first, count);
1351 }
keunyoungb85b2752013-03-08 12:28:03 -08001352}
1353
1354
1355void GL2Encoder::s_glDrawElements(void *self, GLenum mode, GLsizei count, GLenum type, const void *indices)
1356{
1357
1358 GL2Encoder *ctx = (GL2Encoder *)self;
1359 assert(ctx->m_state != NULL);
Evan Birenbaumd51386b2016-04-13 12:53:09 -07001360 SET_ERROR_IF(!isValidDrawMode(mode), GL_INVALID_ENUM);
1361 SET_ERROR_IF(count < 0, GL_INVALID_VALUE);
Yahan Zhou4520fc92016-04-20 16:02:10 -07001362 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 -08001363 SET_ERROR_IF(ctx->m_state->getTransformFeedbackActiveUnpaused(), GL_INVALID_OPERATION);
keunyoungb85b2752013-03-08 12:28:03 -08001364
Lingfeng Yangfe2a31d2016-12-02 08:02:15 -08001365 bool has_client_vertex_arrays = false;
keunyoungb85b2752013-03-08 12:28:03 -08001366 bool has_indirect_arrays = false;
Yahan Zhou5507c042016-06-01 17:24:28 -07001367 GLintptr offset = 0;
keunyoungb85b2752013-03-08 12:28:03 -08001368
Lingfeng Yangfe2a31d2016-12-02 08:02:15 -08001369 ctx->getVBOUsage(&has_client_vertex_arrays, &has_indirect_arrays);
keunyoungb85b2752013-03-08 12:28:03 -08001370
Lingfeng Yangfe2a31d2016-12-02 08:02:15 -08001371 if (!has_client_vertex_arrays && !has_indirect_arrays) {
Lingfeng Yang46153ab2017-01-09 13:37:22 -08001372 // ALOGW("glDrawElements: no vertex arrays / buffers bound to the command\n");
Evan Birenbaum82885a62016-04-28 12:47:57 -07001373 GLenum status = ctx->m_glCheckFramebufferStatus_enc(self, GL_FRAMEBUFFER);
1374 SET_ERROR_IF(status != GL_FRAMEBUFFER_COMPLETE, GL_INVALID_FRAMEBUFFER_OPERATION);
keunyoungb85b2752013-03-08 12:28:03 -08001375 }
1376
Lingfeng Yang8e2b6e02016-10-14 11:20:45 -07001377 BufferData* buf = NULL;
Yahan Zhou5507c042016-06-01 17:24:28 -07001378 int minIndex = 0, maxIndex = 0;
Lingfeng Yang8e2b6e02016-10-14 11:20:45 -07001379
1380 // For validation/immediate index array purposes,
1381 // we need the min/max vertex index of the index array.
1382 // If the VBO != 0, this may not be the first time we have
1383 // used this particular index buffer. getBufferIndexRange
1384 // can more quickly get min/max vertex index by
Lingfeng Yang46153ab2017-01-09 13:37:22 -08001385 // caching previous results.
Lingfeng Yang8e2b6e02016-10-14 11:20:45 -07001386 if (ctx->m_state->currentIndexVbo() != 0) {
1387 buf = ctx->m_shared->getBufferData(ctx->m_state->currentIndexVbo());
1388 offset = (GLintptr)indices;
1389 indices = (void*)((GLintptr)buf->m_fixedBuffer.ptr() + (GLintptr)indices);
1390 ctx->getBufferIndexRange(buf,
1391 indices,
1392 type,
Lingfeng Yang1ae9d732016-12-12 16:17:02 -08001393 (size_t)count,
1394 (size_t)offset,
Lingfeng Yang8e2b6e02016-10-14 11:20:45 -07001395 &minIndex, &maxIndex);
1396 } else {
1397 // In this case, the |indices| field holds a real
1398 // array, so calculate the indices now. They will
1399 // also be needed to know how much data to
1400 // transfer to host.
1401 ctx->calcIndexRange(indices,
1402 type,
1403 count,
1404 &minIndex,
1405 &maxIndex);
Yahan Zhou5507c042016-06-01 17:24:28 -07001406 }
1407
Lingfeng Yang26e629a2018-10-13 20:00:12 -07001408 if (count == 0) return;
1409
keunyoungb85b2752013-03-08 12:28:03 -08001410 bool adjustIndices = true;
1411 if (ctx->m_state->currentIndexVbo() != 0) {
Lingfeng Yangfe2a31d2016-12-02 08:02:15 -08001412 if (!has_client_vertex_arrays) {
1413 ctx->sendVertexAttributes(0, maxIndex + 1, false);
Lingfeng Yang554a5152019-02-21 20:20:48 -08001414 ctx->doBindBufferEncodeCached(GL_ELEMENT_ARRAY_BUFFER, ctx->m_state->currentIndexVbo());
Yahan Zhou5507c042016-06-01 17:24:28 -07001415 ctx->glDrawElementsOffset(ctx, mode, count, type, offset);
Lingfeng Yang8e2b6e02016-10-14 11:20:45 -07001416 ctx->flushDrawCall();
keunyoungb85b2752013-03-08 12:28:03 -08001417 adjustIndices = false;
1418 } else {
Lingfeng Yang554a5152019-02-21 20:20:48 -08001419 ctx->doBindBufferEncodeCached(GL_ELEMENT_ARRAY_BUFFER, 0);
keunyoungb85b2752013-03-08 12:28:03 -08001420 }
1421 }
1422 if (adjustIndices) {
Lingfeng Yang8e2b6e02016-10-14 11:20:45 -07001423 void *adjustedIndices =
1424 ctx->recenterIndices(indices,
1425 type,
1426 count,
1427 minIndex);
keunyoungb85b2752013-03-08 12:28:03 -08001428
keunyoungb85b2752013-03-08 12:28:03 -08001429 if (has_indirect_arrays || 1) {
Lingfeng Yangfe2a31d2016-12-02 08:02:15 -08001430 ctx->sendVertexAttributes(minIndex, maxIndex - minIndex + 1, true);
keunyoungb85b2752013-03-08 12:28:03 -08001431 ctx->glDrawElementsData(ctx, mode, count, type, adjustedIndices,
1432 count * glSizeof(type));
1433 // XXX - OPTIMIZATION (see the other else branch) should be implemented
1434 if(!has_indirect_arrays) {
1435 //ALOGD("unoptimized drawelements !!!\n");
1436 }
1437 } else {
1438 // we are all direct arrays and immidate mode index array -
1439 // rebuild the arrays and the index array;
1440 ALOGE("glDrawElements: direct index & direct buffer data - will be implemented in later versions;\n");
1441 }
1442 }
1443}
1444
Lingfeng Yang09545912019-01-30 09:22:38 -08001445void GL2Encoder::s_glDrawArraysNullAEMU(void *self, GLenum mode, GLint first, GLsizei count)
1446{
1447 GL2Encoder *ctx = (GL2Encoder *)self;
1448 assert(ctx->m_state != NULL);
1449 SET_ERROR_IF(!isValidDrawMode(mode), GL_INVALID_ENUM);
1450 SET_ERROR_IF(count < 0, GL_INVALID_VALUE);
1451
1452 bool has_client_vertex_arrays = false;
1453 bool has_indirect_arrays = false;
1454 ctx->getVBOUsage(&has_client_vertex_arrays,
1455 &has_indirect_arrays);
1456
1457 if (has_client_vertex_arrays ||
1458 (!has_client_vertex_arrays &&
1459 !has_indirect_arrays)) {
1460 ctx->sendVertexAttributes(first, count, true);
1461 ctx->m_glDrawArraysNullAEMU_enc(ctx, mode, 0, count);
1462 } else {
1463 ctx->sendVertexAttributes(0, count, false);
1464 ctx->m_glDrawArraysNullAEMU_enc(ctx, mode, first, count);
1465 }
1466}
1467
1468void GL2Encoder::s_glDrawElementsNullAEMU(void *self, GLenum mode, GLsizei count, GLenum type, const void *indices)
1469{
1470
1471 GL2Encoder *ctx = (GL2Encoder *)self;
1472 assert(ctx->m_state != NULL);
1473 SET_ERROR_IF(!isValidDrawMode(mode), GL_INVALID_ENUM);
1474 SET_ERROR_IF(count < 0, GL_INVALID_VALUE);
1475 SET_ERROR_IF(!(type == GL_UNSIGNED_BYTE || type == GL_UNSIGNED_SHORT || type == GL_UNSIGNED_INT), GL_INVALID_ENUM);
1476 SET_ERROR_IF(ctx->m_state->getTransformFeedbackActiveUnpaused(), GL_INVALID_OPERATION);
1477
1478 bool has_client_vertex_arrays = false;
1479 bool has_indirect_arrays = false;
Lingfeng Yang09545912019-01-30 09:22:38 -08001480 GLintptr offset = 0;
1481
1482 ctx->getVBOUsage(&has_client_vertex_arrays, &has_indirect_arrays);
1483
1484 if (!has_client_vertex_arrays && !has_indirect_arrays) {
1485 // ALOGW("glDrawElements: no vertex arrays / buffers bound to the command\n");
1486 GLenum status = ctx->m_glCheckFramebufferStatus_enc(self, GL_FRAMEBUFFER);
1487 SET_ERROR_IF(status != GL_FRAMEBUFFER_COMPLETE, GL_INVALID_FRAMEBUFFER_OPERATION);
1488 }
1489
1490 BufferData* buf = NULL;
1491 int minIndex = 0, maxIndex = 0;
1492
1493 // For validation/immediate index array purposes,
1494 // we need the min/max vertex index of the index array.
1495 // If the VBO != 0, this may not be the first time we have
1496 // used this particular index buffer. getBufferIndexRange
1497 // can more quickly get min/max vertex index by
1498 // caching previous results.
1499 if (ctx->m_state->currentIndexVbo() != 0) {
1500 buf = ctx->m_shared->getBufferData(ctx->m_state->currentIndexVbo());
1501 offset = (GLintptr)indices;
1502 indices = (void*)((GLintptr)buf->m_fixedBuffer.ptr() + (GLintptr)indices);
1503 ctx->getBufferIndexRange(buf,
1504 indices,
1505 type,
1506 (size_t)count,
1507 (size_t)offset,
1508 &minIndex, &maxIndex);
1509 } else {
1510 // In this case, the |indices| field holds a real
1511 // array, so calculate the indices now. They will
1512 // also be needed to know how much data to
1513 // transfer to host.
1514 ctx->calcIndexRange(indices,
1515 type,
1516 count,
1517 &minIndex,
1518 &maxIndex);
1519 }
1520
1521 if (count == 0) return;
1522
1523 bool adjustIndices = true;
1524 if (ctx->m_state->currentIndexVbo() != 0) {
1525 if (!has_client_vertex_arrays) {
1526 ctx->sendVertexAttributes(0, maxIndex + 1, false);
1527 ctx->m_glBindBuffer_enc(self, GL_ELEMENT_ARRAY_BUFFER, ctx->m_state->currentIndexVbo());
1528 ctx->glDrawElementsOffsetNullAEMU(ctx, mode, count, type, offset);
1529 ctx->flushDrawCall();
1530 adjustIndices = false;
1531 } else {
Lingfeng Yang09545912019-01-30 09:22:38 -08001532 ctx->m_glBindBuffer_enc(self, GL_ELEMENT_ARRAY_BUFFER, 0);
1533 }
1534 }
1535 if (adjustIndices) {
1536 void *adjustedIndices =
1537 ctx->recenterIndices(indices,
1538 type,
1539 count,
1540 minIndex);
1541
1542 if (has_indirect_arrays || 1) {
1543 ctx->sendVertexAttributes(minIndex, maxIndex - minIndex + 1, true);
1544 ctx->glDrawElementsDataNullAEMU(ctx, mode, count, type, adjustedIndices,
1545 count * glSizeof(type));
1546 // XXX - OPTIMIZATION (see the other else branch) should be implemented
1547 if(!has_indirect_arrays) {
1548 //ALOGD("unoptimized drawelements !!!\n");
1549 }
1550 } else {
1551 // we are all direct arrays and immidate mode index array -
1552 // rebuild the arrays and the index array;
1553 ALOGE("glDrawElementsNullAEMU: direct index & direct buffer data - will be implemented in later versions;\n");
1554 }
1555 }
1556}
keunyoungb85b2752013-03-08 12:28:03 -08001557
1558GLint * GL2Encoder::getCompressedTextureFormats()
1559{
1560 if (m_compressedTextureFormats == NULL) {
1561 this->glGetIntegerv(this, GL_NUM_COMPRESSED_TEXTURE_FORMATS,
1562 &m_num_compressedTextureFormats);
1563 if (m_num_compressedTextureFormats > 0) {
1564 // get number of texture formats;
1565 m_compressedTextureFormats = new GLint[m_num_compressedTextureFormats];
1566 this->glGetCompressedTextureFormats(this, m_num_compressedTextureFormats, m_compressedTextureFormats);
1567 }
1568 }
1569 return m_compressedTextureFormats;
1570}
1571
1572// Replace uses of samplerExternalOES with sampler2D, recording the names of
1573// modified shaders in data. Also remove
1574// #extension GL_OES_EGL_image_external : require
1575// statements.
1576//
1577// This implementation assumes the input has already been pre-processed. If not,
1578// a few cases will be mishandled:
1579//
1580// 1. "mySampler" will be incorrectly recorded as being a samplerExternalOES in
1581// the following code:
1582// #if 1
1583// uniform sampler2D mySampler;
1584// #else
1585// uniform samplerExternalOES mySampler;
1586// #endif
1587//
1588// 2. Comments that look like sampler declarations will be incorrectly modified
1589// and recorded:
1590// // samplerExternalOES hahaFooledYou
1591//
1592// 3. However, GLSL ES does not have a concatentation operator, so things like
1593// this (valid in C) are invalid and not a problem:
1594// #define SAMPLER(TYPE, NAME) uniform sampler#TYPE NAME
1595// SAMPLER(ExternalOES, mySampler);
1596//
Lingfeng Yangcc22a7a2018-05-15 12:15:57 -07001597
1598static const char STR_SAMPLER_EXTERNAL_OES[] = "samplerExternalOES";
1599static const char STR_SAMPLER2D_SPACE[] = "sampler2D ";
1600static const char STR_DEFINE[] = "#define";
1601
1602static std::vector<std::string> getSamplerExternalAliases(char* str) {
1603 std::vector<std::string> res;
1604
1605 res.push_back(STR_SAMPLER_EXTERNAL_OES);
1606
1607 // -- capture #define x samplerExternalOES
1608 char* c = str;
1609 while ((c = strstr(c, STR_DEFINE))) {
1610 // Don't push it if samplerExternalOES is not even there.
1611 char* samplerExternalOES_next = strstr(c, STR_SAMPLER_EXTERNAL_OES);
1612 if (!samplerExternalOES_next) break;
1613
1614 bool prevIdent = false;
1615
1616 std::vector<std::string> idents;
1617 std::string curr;
1618
1619 while (*c != '\0') {
1620
1621 if (isspace(*c)) {
1622 if (prevIdent) {
1623 idents.push_back(curr);
1624 curr = "";
1625 }
1626 }
1627
1628 if (*c == '\n' || idents.size() == 3) break;
1629
1630 if (isalpha(*c) || *c == '_') {
1631 curr.push_back(*c);
1632 prevIdent = true;
1633 }
1634
1635 ++c;
1636 }
1637
1638 if (idents.size() != 3) continue;
1639
1640 const std::string& defineLhs = idents[1];
1641 const std::string& defineRhs = idents[2];
1642
1643 if (defineRhs == STR_SAMPLER_EXTERNAL_OES) {
1644 res.push_back(defineLhs);
1645 }
1646
1647 if (*c == '\0') break;
1648 }
1649
1650 return res;
1651}
1652
1653static bool replaceExternalSamplerUniformDefinition(char* str, const std::string& samplerExternalType, ShaderData* data) {
1654 // -- replace "samplerExternalOES" with "sampler2D" and record name
1655 char* c = str;
1656 while ((c = strstr(c, samplerExternalType.c_str()))) {
1657 // Make sure "samplerExternalOES" isn't a substring of a larger token
1658 if (c == str || !isspace(*(c-1))) {
1659 c++;
1660 continue;
1661 }
1662 char* sampler_start = c;
1663 c += samplerExternalType.size();
1664 if (!isspace(*c) && *c != '\0') {
1665 continue;
1666 }
1667
1668 // capture sampler name
1669 while (isspace(*c) && *c != '\0') {
1670 c++;
1671 }
1672 if (!isalpha(*c) && *c != '_') {
1673 // not an identifier
1674 return false;
1675 }
1676 char* name_start = c;
1677 do {
1678 c++;
1679 } while (isalnum(*c) || *c == '_');
Lingfeng Yang44209df2018-09-21 10:04:17 -07001680
1681 size_t len = (size_t)(c - name_start);
Lingfeng Yangcc22a7a2018-05-15 12:15:57 -07001682 data->samplerExternalNames.push_back(
Lingfeng Yang44209df2018-09-21 10:04:17 -07001683 std::string(name_start, len));
Lingfeng Yangcc22a7a2018-05-15 12:15:57 -07001684
1685 // We only need to perform a string replacement for the original
1686 // occurrence of samplerExternalOES if a #define was used.
1687 //
1688 // The important part was to record the name in
1689 // |data->samplerExternalNames|.
1690 if (samplerExternalType == STR_SAMPLER_EXTERNAL_OES) {
1691 memcpy(sampler_start, STR_SAMPLER2D_SPACE, sizeof(STR_SAMPLER2D_SPACE)-1);
1692 }
1693 }
1694
1695 return true;
1696}
1697
keunyoungb85b2752013-03-08 12:28:03 -08001698static bool replaceSamplerExternalWith2D(char* const str, ShaderData* const data)
1699{
1700 static const char STR_HASH_EXTENSION[] = "#extension";
1701 static const char STR_GL_OES_EGL_IMAGE_EXTERNAL[] = "GL_OES_EGL_image_external";
Lingfeng Yang3546c4d2018-04-10 12:34:30 -07001702 static const char STR_GL_OES_EGL_IMAGE_EXTERNAL_ESSL3[] = "GL_OES_EGL_image_external_essl3";
keunyoungb85b2752013-03-08 12:28:03 -08001703
1704 // -- overwrite all "#extension GL_OES_EGL_image_external : xxx" statements
1705 char* c = str;
1706 while ((c = strstr(c, STR_HASH_EXTENSION))) {
1707 char* start = c;
1708 c += sizeof(STR_HASH_EXTENSION)-1;
1709 while (isspace(*c) && *c != '\0') {
1710 c++;
1711 }
Lingfeng Yang3546c4d2018-04-10 12:34:30 -07001712
1713 bool hasBaseImageExternal =
1714 !strncmp(c, STR_GL_OES_EGL_IMAGE_EXTERNAL,
1715 sizeof(STR_GL_OES_EGL_IMAGE_EXTERNAL) - 1);
1716 bool hasEssl3ImageExternal =
1717 !strncmp(c, STR_GL_OES_EGL_IMAGE_EXTERNAL_ESSL3,
1718 sizeof(STR_GL_OES_EGL_IMAGE_EXTERNAL_ESSL3) - 1);
1719
1720 if (hasBaseImageExternal || hasEssl3ImageExternal)
keunyoungb85b2752013-03-08 12:28:03 -08001721 {
1722 // #extension statements are terminated by end of line
1723 c = start;
1724 while (*c != '\0' && *c != '\r' && *c != '\n') {
1725 *c++ = ' ';
1726 }
1727 }
1728 }
1729
Lingfeng Yangcc22a7a2018-05-15 12:15:57 -07001730 std::vector<std::string> samplerExternalAliases =
1731 getSamplerExternalAliases(str);
keunyoungb85b2752013-03-08 12:28:03 -08001732
Lingfeng Yangcc22a7a2018-05-15 12:15:57 -07001733 for (size_t i = 0; i < samplerExternalAliases.size(); i++) {
1734 if (!replaceExternalSamplerUniformDefinition(
1735 str, samplerExternalAliases[i], data))
keunyoungb85b2752013-03-08 12:28:03 -08001736 return false;
keunyoungb85b2752013-03-08 12:28:03 -08001737 }
1738
1739 return true;
1740}
1741
Lingfeng Yangde7eaa72019-08-21 21:47:57 -07001742void GL2Encoder::s_glShaderBinary(void *self, GLsizei, const GLuint *, GLenum, const void*, GLsizei)
Bo Hu73568cd2015-01-20 16:29:50 -08001743{
Bo Hu73568cd2015-01-20 16:29:50 -08001744 // Although it is not supported, need to set proper error code.
Lingfeng Yangde7eaa72019-08-21 21:47:57 -07001745 GL2Encoder* ctx = (GL2Encoder*)self;
Bo Hu73568cd2015-01-20 16:29:50 -08001746 SET_ERROR_IF(1, GL_INVALID_ENUM);
1747}
1748
David 'Digit' Turner02fdb692014-10-30 18:07:56 +01001749void GL2Encoder::s_glShaderSource(void *self, GLuint shader, GLsizei count, const GLchar * const *string, const GLint *length)
keunyoungb85b2752013-03-08 12:28:03 -08001750{
1751 GL2Encoder* ctx = (GL2Encoder*)self;
1752 ShaderData* shaderData = ctx->m_shared->getShaderData(shader);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08001753 SET_ERROR_IF(!ctx->m_shared->isShaderOrProgramObject(shader), GL_INVALID_VALUE);
Tina Zhang7a84f652014-12-04 12:37:30 +08001754 SET_ERROR_IF(!shaderData, GL_INVALID_OPERATION);
1755 SET_ERROR_IF((count<0), GL_INVALID_VALUE);
keunyoungb85b2752013-03-08 12:28:03 -08001756
Lingfeng Yang46153ab2017-01-09 13:37:22 -08001757 // Track original sources---they may be translated in the backend
1758 std::vector<std::string> orig_sources;
1759 for (int i = 0; i < count; i++) {
1760 orig_sources.push_back(std::string((const char*)(string[i])));
1761 }
1762 shaderData->sources = orig_sources;
1763
keunyoungb85b2752013-03-08 12:28:03 -08001764 int len = glUtilsCalcShaderSourceLen((char**)string, (GLint*)length, count);
1765 char *str = new char[len + 1];
1766 glUtilsPackStrings(str, (char**)string, (GLint*)length, count);
1767
1768 // TODO: pre-process str before calling replaceSamplerExternalWith2D().
1769 // Perhaps we can borrow Mesa's pre-processor?
1770
1771 if (!replaceSamplerExternalWith2D(str, shaderData)) {
Adam Buchbinder9ae14692016-05-20 15:25:59 -07001772 delete[] str;
keunyoungb85b2752013-03-08 12:28:03 -08001773 ctx->setError(GL_OUT_OF_MEMORY);
1774 return;
1775 }
keunyoungb85b2752013-03-08 12:28:03 -08001776 ctx->glShaderString(ctx, shader, str, len + 1);
Adam Buchbinder9ae14692016-05-20 15:25:59 -07001777 delete[] str;
keunyoungb85b2752013-03-08 12:28:03 -08001778}
1779
1780void GL2Encoder::s_glFinish(void *self)
1781{
1782 GL2Encoder *ctx = (GL2Encoder *)self;
1783 ctx->glFinishRoundTrip(self);
1784}
1785
1786void GL2Encoder::s_glLinkProgram(void * self, GLuint program)
1787{
1788 GL2Encoder *ctx = (GL2Encoder *)self;
Yahan Zhoub99406c2016-11-22 14:03:56 -08001789 bool isProgram = ctx->m_shared->isProgram(program);
1790 SET_ERROR_IF(!isProgram && !ctx->m_shared->isShader(program), GL_INVALID_VALUE);
1791 SET_ERROR_IF(!isProgram, GL_INVALID_OPERATION);
1792
keunyoungb85b2752013-03-08 12:28:03 -08001793 ctx->m_glLinkProgram_enc(self, program);
1794
1795 GLint linkStatus = 0;
Lingfeng Yang80a36332017-07-09 10:58:07 -07001796 ctx->glGetProgramiv(self, program, GL_LINK_STATUS, &linkStatus);
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08001797 if (!linkStatus) {
keunyoungb85b2752013-03-08 12:28:03 -08001798 return;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08001799 }
keunyoungb85b2752013-03-08 12:28:03 -08001800
1801 //get number of active uniforms in the program
1802 GLint numUniforms=0;
1803 ctx->glGetProgramiv(self, program, GL_ACTIVE_UNIFORMS, &numUniforms);
1804 ctx->m_shared->initProgramData(program,numUniforms);
1805
1806 //get the length of the longest uniform name
1807 GLint maxLength=0;
1808 ctx->glGetProgramiv(self, program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxLength);
1809
1810 GLint size;
1811 GLenum type;
1812 GLchar *name = new GLchar[maxLength+1];
1813 GLint location;
1814 //for each active uniform, get its size and starting location.
1815 for (GLint i=0 ; i<numUniforms ; ++i)
1816 {
1817 ctx->glGetActiveUniform(self, program, i, maxLength, NULL, &size, &type, name);
1818 location = ctx->m_glGetUniformLocation_enc(self, program, name);
1819 ctx->m_shared->setProgramIndexInfo(program, i, location, size, type, name);
1820 }
1821 ctx->m_shared->setupLocationShiftWAR(program);
1822
1823 delete[] name;
1824}
1825
1826void GL2Encoder::s_glDeleteProgram(void *self, GLuint program)
1827{
1828 GL2Encoder *ctx = (GL2Encoder*)self;
1829 ctx->m_glDeleteProgram_enc(self, program);
1830
1831 ctx->m_shared->deleteProgramData(program);
1832}
1833
1834void GL2Encoder::s_glGetUniformiv(void *self, GLuint program, GLint location, GLint* params)
1835{
1836 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08001837 SET_ERROR_IF(!ctx->m_shared->isShaderOrProgramObject(program), GL_INVALID_VALUE);
Lingfeng Yang35b0fda2016-04-08 12:21:13 -07001838 SET_ERROR_IF(!ctx->m_shared->isProgram(program), GL_INVALID_OPERATION);
keunyoungb85b2752013-03-08 12:28:03 -08001839 SET_ERROR_IF(!ctx->m_shared->isProgramInitialized(program), GL_INVALID_OPERATION);
1840 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
1841 SET_ERROR_IF(ctx->m_shared->getProgramUniformType(program,hostLoc)==0, GL_INVALID_OPERATION);
1842 ctx->m_glGetUniformiv_enc(self, program, hostLoc, params);
1843}
1844void GL2Encoder::s_glGetUniformfv(void *self, GLuint program, GLint location, GLfloat* params)
1845{
1846 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08001847 SET_ERROR_IF(!ctx->m_shared->isShaderOrProgramObject(program), GL_INVALID_VALUE);
Lingfeng Yang35b0fda2016-04-08 12:21:13 -07001848 SET_ERROR_IF(!ctx->m_shared->isProgram(program), GL_INVALID_OPERATION);
keunyoungb85b2752013-03-08 12:28:03 -08001849 SET_ERROR_IF(!ctx->m_shared->isProgramInitialized(program), GL_INVALID_OPERATION);
1850 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program,location);
1851 SET_ERROR_IF(ctx->m_shared->getProgramUniformType(program,hostLoc)==0, GL_INVALID_OPERATION);
1852 ctx->m_glGetUniformfv_enc(self, program, hostLoc, params);
1853}
1854
1855GLuint GL2Encoder::s_glCreateProgram(void * self)
1856{
1857 GL2Encoder *ctx = (GL2Encoder*)self;
1858 GLuint program = ctx->m_glCreateProgram_enc(self);
1859 if (program!=0)
1860 ctx->m_shared->addProgramData(program);
1861 return program;
1862}
1863
1864GLuint GL2Encoder::s_glCreateShader(void *self, GLenum shaderType)
1865{
1866 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08001867 RET_AND_SET_ERROR_IF(!GLESv2Validation::shaderType(ctx, shaderType), GL_INVALID_ENUM, 0);
keunyoungb85b2752013-03-08 12:28:03 -08001868 GLuint shader = ctx->m_glCreateShader_enc(self, shaderType);
1869 if (shader != 0) {
1870 if (!ctx->m_shared->addShaderData(shader)) {
1871 ctx->m_glDeleteShader_enc(self, shader);
1872 return 0;
1873 }
1874 }
1875 return shader;
1876}
1877
bohu56bf82f2014-10-17 15:35:48 -07001878void GL2Encoder::s_glGetAttachedShaders(void *self, GLuint program, GLsizei maxCount,
1879 GLsizei* count, GLuint* shaders)
1880{
1881 GL2Encoder *ctx = (GL2Encoder*)self;
1882 SET_ERROR_IF(maxCount < 0, GL_INVALID_VALUE);
1883 ctx->m_glGetAttachedShaders_enc(self, program, maxCount, count, shaders);
1884}
1885
1886void GL2Encoder::s_glGetShaderSource(void *self, GLuint shader, GLsizei bufsize,
1887 GLsizei* length, GLchar* source)
1888{
1889 GL2Encoder *ctx = (GL2Encoder*)self;
1890 SET_ERROR_IF(bufsize < 0, GL_INVALID_VALUE);
1891 ctx->m_glGetShaderSource_enc(self, shader, bufsize, length, source);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08001892 ShaderData* shaderData = ctx->m_shared->getShaderData(shader);
1893 if (shaderData) {
1894 std::string returned;
1895 int curr_len = 0;
1896 for (int i = 0; i < shaderData->sources.size(); i++) {
1897 if (curr_len + shaderData->sources[i].size() < bufsize - 1) {
1898 returned += shaderData->sources[i];
1899 } else {
1900 returned += shaderData->sources[i].substr(0, bufsize - 1 - curr_len);
1901 break;
1902 }
1903 }
1904 memcpy(source, returned.substr(0, bufsize - 1).c_str(), bufsize);
1905 }
bohu56bf82f2014-10-17 15:35:48 -07001906}
1907
1908void GL2Encoder::s_glGetShaderInfoLog(void *self, GLuint shader, GLsizei bufsize,
1909 GLsizei* length, GLchar* infolog)
1910{
1911 GL2Encoder *ctx = (GL2Encoder*)self;
1912 SET_ERROR_IF(bufsize < 0, GL_INVALID_VALUE);
1913 ctx->m_glGetShaderInfoLog_enc(self, shader, bufsize, length, infolog);
1914}
1915
1916void GL2Encoder::s_glGetProgramInfoLog(void *self, GLuint program, GLsizei bufsize,
1917 GLsizei* length, GLchar* infolog)
1918{
1919 GL2Encoder *ctx = (GL2Encoder*)self;
1920 SET_ERROR_IF(bufsize < 0, GL_INVALID_VALUE);
1921 ctx->m_glGetProgramInfoLog_enc(self, program, bufsize, length, infolog);
1922}
1923
keunyoungb85b2752013-03-08 12:28:03 -08001924void GL2Encoder::s_glDeleteShader(void *self, GLenum shader)
1925{
1926 GL2Encoder *ctx = (GL2Encoder*)self;
1927 ctx->m_glDeleteShader_enc(self,shader);
1928 ctx->m_shared->unrefShaderData(shader);
1929}
1930
1931void GL2Encoder::s_glAttachShader(void *self, GLuint program, GLuint shader)
1932{
1933 GL2Encoder *ctx = (GL2Encoder*)self;
1934 ctx->m_glAttachShader_enc(self, program, shader);
1935 ctx->m_shared->attachShader(program, shader);
1936}
1937
1938void GL2Encoder::s_glDetachShader(void *self, GLuint program, GLuint shader)
1939{
1940 GL2Encoder *ctx = (GL2Encoder*)self;
1941 ctx->m_glDetachShader_enc(self, program, shader);
1942 ctx->m_shared->detachShader(program, shader);
1943}
1944
Lingfeng Yang46153ab2017-01-09 13:37:22 -08001945int sArrIndexOfUniformExpr(const char* name, int* err) {
1946 *err = 0;
1947 int arrIndex = 0;
1948 int namelen = strlen(name);
1949 if (name[namelen-1] == ']') {
1950 const char *brace = strrchr(name,'[');
1951 if (!brace || sscanf(brace+1,"%d",&arrIndex) != 1) {
1952 *err = 1; return 0;
1953 }
1954 }
1955 return arrIndex;
1956}
1957
keunyoungb85b2752013-03-08 12:28:03 -08001958int GL2Encoder::s_glGetUniformLocation(void *self, GLuint program, const GLchar *name)
1959{
1960 if (!name) return -1;
1961
1962 GL2Encoder *ctx = (GL2Encoder*)self;
1963
1964 // if we need the uniform location WAR
1965 // parse array index from the end of the name string
1966 int arrIndex = 0;
1967 bool needLocationWAR = ctx->m_shared->needUniformLocationWAR(program);
1968 if (needLocationWAR) {
Lingfeng Yang46153ab2017-01-09 13:37:22 -08001969 int err;
1970 arrIndex = sArrIndexOfUniformExpr(name, &err);
1971 if (err) return -1;
keunyoungb85b2752013-03-08 12:28:03 -08001972 }
1973
1974 int hostLoc = ctx->m_glGetUniformLocation_enc(self, program, name);
1975 if (hostLoc >= 0 && needLocationWAR) {
1976 return ctx->m_shared->locationWARHostToApp(program, hostLoc, arrIndex);
1977 }
1978 return hostLoc;
1979}
1980
1981bool GL2Encoder::updateHostTexture2DBinding(GLenum texUnit, GLenum newTarget)
1982{
1983 if (newTarget != GL_TEXTURE_2D && newTarget != GL_TEXTURE_EXTERNAL_OES)
1984 return false;
1985
1986 m_state->setActiveTextureUnit(texUnit);
1987
1988 GLenum oldTarget = m_state->getPriorityEnabledTarget(GL_TEXTURE_2D);
1989 if (newTarget != oldTarget) {
1990 if (newTarget == GL_TEXTURE_EXTERNAL_OES) {
1991 m_state->disableTextureTarget(GL_TEXTURE_2D);
1992 m_state->enableTextureTarget(GL_TEXTURE_EXTERNAL_OES);
1993 } else {
1994 m_state->disableTextureTarget(GL_TEXTURE_EXTERNAL_OES);
1995 m_state->enableTextureTarget(GL_TEXTURE_2D);
1996 }
1997 m_glActiveTexture_enc(this, texUnit);
1998 m_glBindTexture_enc(this, GL_TEXTURE_2D,
1999 m_state->getBoundTexture(newTarget));
2000 return true;
2001 }
2002
2003 return false;
2004}
2005
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002006void GL2Encoder::updateHostTexture2DBindingsFromProgramData(GLuint program) {
2007 GL2Encoder *ctx = this;
keunyoungb85b2752013-03-08 12:28:03 -08002008 GLClientState* state = ctx->m_state;
2009 GLSharedGroupPtr shared = ctx->m_shared;
2010
keunyoungb85b2752013-03-08 12:28:03 -08002011 GLenum origActiveTexture = state->getActiveTextureUnit();
2012 GLenum hostActiveTexture = origActiveTexture;
2013 GLint samplerIdx = -1;
2014 GLint samplerVal;
2015 GLenum samplerTarget;
2016 while ((samplerIdx = shared->getNextSamplerUniform(program, samplerIdx, &samplerVal, &samplerTarget)) != -1) {
2017 if (samplerVal < 0 || samplerVal >= GLClientState::MAX_TEXTURE_UNITS)
2018 continue;
2019 if (ctx->updateHostTexture2DBinding(GL_TEXTURE0 + samplerVal,
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002020 samplerTarget))
keunyoungb85b2752013-03-08 12:28:03 -08002021 {
2022 hostActiveTexture = GL_TEXTURE0 + samplerVal;
2023 }
2024 }
2025 state->setActiveTextureUnit(origActiveTexture);
2026 if (hostActiveTexture != origActiveTexture) {
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002027 ctx->m_glActiveTexture_enc(ctx, origActiveTexture);
keunyoungb85b2752013-03-08 12:28:03 -08002028 }
2029}
2030
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002031void GL2Encoder::s_glUseProgram(void *self, GLuint program)
2032{
2033 GL2Encoder *ctx = (GL2Encoder*)self;
2034 GLSharedGroupPtr shared = ctx->m_shared;
2035
2036 SET_ERROR_IF(program && !shared->isShaderOrProgramObject(program), GL_INVALID_VALUE);
2037 SET_ERROR_IF(program && !shared->isProgram(program), GL_INVALID_OPERATION);
2038
2039 ctx->m_glUseProgram_enc(self, program);
2040 ctx->m_state->setCurrentProgram(program);
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08002041 ctx->m_state->setCurrentShaderProgram(program);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002042
2043 ctx->updateHostTexture2DBindingsFromProgramData(program);
2044}
2045
keunyoungb85b2752013-03-08 12:28:03 -08002046void GL2Encoder::s_glUniform1f(void *self , GLint location, GLfloat x)
2047{
2048 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08002049 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
keunyoungb85b2752013-03-08 12:28:03 -08002050 ctx->m_glUniform1f_enc(self, hostLoc, x);
2051}
2052
2053void GL2Encoder::s_glUniform1fv(void *self , GLint location, GLsizei count, const GLfloat* v)
2054{
2055 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08002056 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
keunyoungb85b2752013-03-08 12:28:03 -08002057 ctx->m_glUniform1fv_enc(self, hostLoc, count, v);
2058}
2059
2060void GL2Encoder::s_glUniform1i(void *self , GLint location, GLint x)
2061{
2062 GL2Encoder *ctx = (GL2Encoder*)self;
2063 GLClientState* state = ctx->m_state;
2064 GLSharedGroupPtr shared = ctx->m_shared;
2065
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08002066 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
keunyoungb85b2752013-03-08 12:28:03 -08002067 ctx->m_glUniform1i_enc(self, hostLoc, x);
2068
2069 GLenum target;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08002070 if (shared->setSamplerUniform(state->currentShaderProgram(), location, x, &target)) {
keunyoungb85b2752013-03-08 12:28:03 -08002071 GLenum origActiveTexture = state->getActiveTextureUnit();
2072 if (ctx->updateHostTexture2DBinding(GL_TEXTURE0 + x, target)) {
2073 ctx->m_glActiveTexture_enc(self, origActiveTexture);
2074 }
2075 state->setActiveTextureUnit(origActiveTexture);
2076 }
2077}
2078
2079void GL2Encoder::s_glUniform1iv(void *self , GLint location, GLsizei count, const GLint* v)
2080{
2081 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08002082 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
keunyoungb85b2752013-03-08 12:28:03 -08002083 ctx->m_glUniform1iv_enc(self, hostLoc, count, v);
2084}
2085
2086void GL2Encoder::s_glUniform2f(void *self , GLint location, GLfloat x, GLfloat y)
2087{
2088 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08002089 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
keunyoungb85b2752013-03-08 12:28:03 -08002090 ctx->m_glUniform2f_enc(self, hostLoc, x, y);
2091}
2092
2093void GL2Encoder::s_glUniform2fv(void *self , GLint location, GLsizei count, const GLfloat* v)
2094{
2095 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08002096 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
keunyoungb85b2752013-03-08 12:28:03 -08002097 ctx->m_glUniform2fv_enc(self, hostLoc, count, v);
2098}
2099
2100void GL2Encoder::s_glUniform2i(void *self , GLint location, GLint x, GLint y)
2101{
2102 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08002103 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
keunyoungb85b2752013-03-08 12:28:03 -08002104 ctx->m_glUniform2i_enc(self, hostLoc, x, y);
2105}
2106
2107void GL2Encoder::s_glUniform2iv(void *self , GLint location, GLsizei count, const GLint* v)
2108{
2109 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08002110 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
keunyoungb85b2752013-03-08 12:28:03 -08002111 ctx->m_glUniform2iv_enc(self, hostLoc, count, v);
2112}
2113
2114void GL2Encoder::s_glUniform3f(void *self , GLint location, GLfloat x, GLfloat y, GLfloat z)
2115{
2116 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08002117 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
keunyoungb85b2752013-03-08 12:28:03 -08002118 ctx->m_glUniform3f_enc(self, hostLoc, x, y, z);
2119}
2120
2121void GL2Encoder::s_glUniform3fv(void *self , GLint location, GLsizei count, const GLfloat* v)
2122{
2123 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08002124 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
keunyoungb85b2752013-03-08 12:28:03 -08002125 ctx->m_glUniform3fv_enc(self, hostLoc, count, v);
2126}
2127
2128void GL2Encoder::s_glUniform3i(void *self , GLint location, GLint x, GLint y, GLint z)
2129{
2130 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08002131 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
keunyoungb85b2752013-03-08 12:28:03 -08002132 ctx->m_glUniform3i_enc(self, hostLoc, x, y, z);
2133}
2134
2135void GL2Encoder::s_glUniform3iv(void *self , GLint location, GLsizei count, const GLint* v)
2136{
2137 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08002138 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
keunyoungb85b2752013-03-08 12:28:03 -08002139 ctx->m_glUniform3iv_enc(self, hostLoc, count, v);
2140}
2141
2142void GL2Encoder::s_glUniform4f(void *self , GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
2143{
2144 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08002145 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
keunyoungb85b2752013-03-08 12:28:03 -08002146 ctx->m_glUniform4f_enc(self, hostLoc, x, y, z, w);
2147}
2148
2149void GL2Encoder::s_glUniform4fv(void *self , GLint location, GLsizei count, const GLfloat* v)
2150{
2151 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08002152 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
keunyoungb85b2752013-03-08 12:28:03 -08002153 ctx->m_glUniform4fv_enc(self, hostLoc, count, v);
2154}
2155
2156void GL2Encoder::s_glUniform4i(void *self , GLint location, GLint x, GLint y, GLint z, GLint w)
2157{
2158 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08002159 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
keunyoungb85b2752013-03-08 12:28:03 -08002160 ctx->m_glUniform4i_enc(self, hostLoc, x, y, z, w);
2161}
2162
2163void GL2Encoder::s_glUniform4iv(void *self , GLint location, GLsizei count, const GLint* v)
2164{
2165 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08002166 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
keunyoungb85b2752013-03-08 12:28:03 -08002167 ctx->m_glUniform4iv_enc(self, hostLoc, count, v);
2168}
2169
2170void GL2Encoder::s_glUniformMatrix2fv(void *self , GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
2171{
2172 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08002173 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
keunyoungb85b2752013-03-08 12:28:03 -08002174 ctx->m_glUniformMatrix2fv_enc(self, hostLoc, count, transpose, value);
2175}
2176
2177void GL2Encoder::s_glUniformMatrix3fv(void *self , GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
2178{
2179 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08002180 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
keunyoungb85b2752013-03-08 12:28:03 -08002181 ctx->m_glUniformMatrix3fv_enc(self, hostLoc, count, transpose, value);
2182}
2183
2184void GL2Encoder::s_glUniformMatrix4fv(void *self , GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
2185{
2186 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08002187 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
keunyoungb85b2752013-03-08 12:28:03 -08002188 ctx->m_glUniformMatrix4fv_enc(self, hostLoc, count, transpose, value);
2189}
2190
2191void GL2Encoder::s_glActiveTexture(void* self, GLenum texture)
2192{
2193 GL2Encoder* ctx = (GL2Encoder*)self;
2194 GLClientState* state = ctx->m_state;
2195 GLenum err;
2196
2197 SET_ERROR_IF((err = state->setActiveTextureUnit(texture)) != GL_NO_ERROR, err);
2198
2199 ctx->m_glActiveTexture_enc(ctx, texture);
2200}
2201
2202void GL2Encoder::s_glBindTexture(void* self, GLenum target, GLuint texture)
2203{
2204 GL2Encoder* ctx = (GL2Encoder*)self;
2205 GLClientState* state = ctx->m_state;
2206 GLenum err;
2207 GLboolean firstUse;
2208
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002209 SET_ERROR_IF(!GLESv2Validation::textureTarget(ctx, target), GL_INVALID_ENUM);
keunyoungb85b2752013-03-08 12:28:03 -08002210 SET_ERROR_IF((err = state->bindTexture(target, texture, &firstUse)) != GL_NO_ERROR, err);
2211
2212 if (target != GL_TEXTURE_2D && target != GL_TEXTURE_EXTERNAL_OES) {
2213 ctx->m_glBindTexture_enc(ctx, target, texture);
2214 return;
2215 }
2216
2217 GLenum priorityTarget = state->getPriorityEnabledTarget(GL_TEXTURE_2D);
2218
2219 if (target == GL_TEXTURE_EXTERNAL_OES && firstUse) {
2220 ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D, texture);
2221 ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D,
2222 GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2223 ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D,
2224 GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2225 ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D,
2226 GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2227
2228 if (target != priorityTarget) {
2229 ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D,
2230 state->getBoundTexture(GL_TEXTURE_2D));
2231 }
2232 }
2233
2234 if (target == priorityTarget) {
2235 ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D, texture);
2236 }
2237}
2238
2239void GL2Encoder::s_glDeleteTextures(void* self, GLsizei n, const GLuint* textures)
2240{
2241 GL2Encoder* ctx = (GL2Encoder*)self;
2242 GLClientState* state = ctx->m_state;
2243
2244 state->deleteTextures(n, textures);
2245 ctx->m_glDeleteTextures_enc(ctx, n, textures);
2246}
2247
2248void GL2Encoder::s_glGetTexParameterfv(void* self,
2249 GLenum target, GLenum pname, GLfloat* params)
2250{
2251 GL2Encoder* ctx = (GL2Encoder*)self;
keunyoungb85b2752013-03-08 12:28:03 -08002252
2253 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
2254 ctx->override2DTextureTarget(target);
2255 ctx->m_glGetTexParameterfv_enc(ctx, GL_TEXTURE_2D, pname, params);
Lingfeng Yangb5c03d52016-09-07 14:40:03 -07002256 ctx->restore2DTextureTarget(target);
keunyoungb85b2752013-03-08 12:28:03 -08002257 } else {
2258 ctx->m_glGetTexParameterfv_enc(ctx, target, pname, params);
2259 }
2260}
2261
2262void GL2Encoder::s_glGetTexParameteriv(void* self,
2263 GLenum target, GLenum pname, GLint* params)
2264{
2265 GL2Encoder* ctx = (GL2Encoder*)self;
keunyoungb85b2752013-03-08 12:28:03 -08002266
2267 switch (pname) {
2268 case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
2269 *params = 1;
2270 break;
2271
2272 default:
2273 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
2274 ctx->override2DTextureTarget(target);
2275 ctx->m_glGetTexParameteriv_enc(ctx, GL_TEXTURE_2D, pname, params);
Lingfeng Yangb5c03d52016-09-07 14:40:03 -07002276 ctx->restore2DTextureTarget(target);
keunyoungb85b2752013-03-08 12:28:03 -08002277 } else {
2278 ctx->m_glGetTexParameteriv_enc(ctx, target, pname, params);
2279 }
2280 break;
2281 }
2282}
2283
2284static bool isValidTextureExternalParam(GLenum pname, GLenum param)
2285{
2286 switch (pname) {
2287 case GL_TEXTURE_MIN_FILTER:
2288 case GL_TEXTURE_MAG_FILTER:
2289 return param == GL_NEAREST || param == GL_LINEAR;
2290
2291 case GL_TEXTURE_WRAP_S:
2292 case GL_TEXTURE_WRAP_T:
2293 return param == GL_CLAMP_TO_EDGE;
2294
2295 default:
2296 return true;
2297 }
2298}
2299
2300void GL2Encoder::s_glTexParameterf(void* self,
2301 GLenum target, GLenum pname, GLfloat param)
2302{
2303 GL2Encoder* ctx = (GL2Encoder*)self;
keunyoungb85b2752013-03-08 12:28:03 -08002304
2305 SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
2306 !isValidTextureExternalParam(pname, (GLenum)param)),
2307 GL_INVALID_ENUM);
2308
2309 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
2310 ctx->override2DTextureTarget(target);
2311 ctx->m_glTexParameterf_enc(ctx, GL_TEXTURE_2D, pname, param);
Lingfeng Yangb5c03d52016-09-07 14:40:03 -07002312 ctx->restore2DTextureTarget(target);
keunyoungb85b2752013-03-08 12:28:03 -08002313 } else {
2314 ctx->m_glTexParameterf_enc(ctx, target, pname, param);
2315 }
2316}
2317
2318void GL2Encoder::s_glTexParameterfv(void* self,
2319 GLenum target, GLenum pname, const GLfloat* params)
2320{
2321 GL2Encoder* ctx = (GL2Encoder*)self;
keunyoungb85b2752013-03-08 12:28:03 -08002322
2323 SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
2324 !isValidTextureExternalParam(pname, (GLenum)params[0])),
2325 GL_INVALID_ENUM);
2326
2327 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
2328 ctx->override2DTextureTarget(target);
2329 ctx->m_glTexParameterfv_enc(ctx, GL_TEXTURE_2D, pname, params);
Lingfeng Yangb5c03d52016-09-07 14:40:03 -07002330 ctx->restore2DTextureTarget(target);
keunyoungb85b2752013-03-08 12:28:03 -08002331 } else {
2332 ctx->m_glTexParameterfv_enc(ctx, target, pname, params);
2333 }
2334}
2335
2336void GL2Encoder::s_glTexParameteri(void* self,
2337 GLenum target, GLenum pname, GLint param)
2338{
2339 GL2Encoder* ctx = (GL2Encoder*)self;
keunyoungb85b2752013-03-08 12:28:03 -08002340
2341 SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
2342 !isValidTextureExternalParam(pname, (GLenum)param)),
2343 GL_INVALID_ENUM);
2344
2345 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
2346 ctx->override2DTextureTarget(target);
2347 ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D, pname, param);
Lingfeng Yangb5c03d52016-09-07 14:40:03 -07002348 ctx->restore2DTextureTarget(target);
keunyoungb85b2752013-03-08 12:28:03 -08002349 } else {
2350 ctx->m_glTexParameteri_enc(ctx, target, pname, param);
2351 }
2352}
2353
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002354static int ilog2(uint32_t x) {
2355 int p = 0;
2356 while ((1 << p) < x)
2357 p++;
2358 return p;
2359}
2360
bohu26a92982014-11-25 16:50:37 -08002361void GL2Encoder::s_glTexImage2D(void* self, GLenum target, GLint level,
2362 GLint internalformat, GLsizei width, GLsizei height, GLint border,
2363 GLenum format, GLenum type, const GLvoid* pixels)
2364{
2365 GL2Encoder* ctx = (GL2Encoder*)self;
Lingfeng Yang69066602016-04-12 09:29:11 -07002366 GLClientState* state = ctx->m_state;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002367
2368 SET_ERROR_IF(!GLESv2Validation::textureTarget(ctx, target), GL_INVALID_ENUM);
2369 SET_ERROR_IF(!GLESv2Validation::pixelType(ctx, type), GL_INVALID_ENUM);
2370 SET_ERROR_IF(!GLESv2Validation::pixelFormat(ctx, format), GL_INVALID_ENUM);
2371 // If unpack buffer is nonzero, verify unmapped state.
2372 SET_ERROR_IF(ctx->isBufferTargetMapped(GL_PIXEL_UNPACK_BUFFER), GL_INVALID_OPERATION);
2373
2374 GLint max_texture_size;
2375 GLint max_cube_map_texture_size;
2376 ctx->glGetIntegerv(ctx, GL_MAX_TEXTURE_SIZE, &max_texture_size);
2377 ctx->glGetIntegerv(ctx, GL_MAX_CUBE_MAP_TEXTURE_SIZE, &max_cube_map_texture_size);
2378 SET_ERROR_IF(level < 0, GL_INVALID_VALUE);
2379 SET_ERROR_IF(level > ilog2(max_texture_size), GL_INVALID_VALUE);
2380 SET_ERROR_IF((target == GL_TEXTURE_CUBE_MAP) &&
2381 (level > ilog2(max_cube_map_texture_size)), GL_INVALID_VALUE);
2382 SET_ERROR_IF(width < 0 || height < 0, GL_INVALID_VALUE);
2383 SET_ERROR_IF(width > max_texture_size, GL_INVALID_VALUE);
2384 SET_ERROR_IF(height > max_texture_size, GL_INVALID_VALUE);
2385 SET_ERROR_IF(GLESv2Validation::isCubeMapTarget(target) && width > max_cube_map_texture_size, GL_INVALID_VALUE);
2386 SET_ERROR_IF(GLESv2Validation::isCubeMapTarget(target) && height > max_cube_map_texture_size, GL_INVALID_VALUE);
2387 SET_ERROR_IF(border != 0, GL_INVALID_VALUE);
2388 // If unpack buffer is nonzero, verify buffer data fits and is evenly divisible by the type.
2389 SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
2390 ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
2391 (ctx->m_state->pboNeededDataSize(width, height, 1, format, type, 0) >
2392 ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size),
2393 GL_INVALID_OPERATION);
2394 SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
2395 ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
2396 (ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size %
2397 glSizeof(type)),
2398 GL_INVALID_OPERATION);
2399 SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
2400 ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
2401 ((uintptr_t)pixels % glSizeof(type)),
2402 GL_INVALID_OPERATION);
2403 SET_ERROR_IF(state->isBoundTextureImmutableFormat(target), GL_INVALID_OPERATION);
2404
2405 GLenum stateTarget = target;
2406 if (target == GL_TEXTURE_CUBE_MAP_POSITIVE_X ||
2407 target == GL_TEXTURE_CUBE_MAP_POSITIVE_Y ||
2408 target == GL_TEXTURE_CUBE_MAP_POSITIVE_Z ||
2409 target == GL_TEXTURE_CUBE_MAP_NEGATIVE_X ||
2410 target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y ||
2411 target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Z)
2412 stateTarget = GL_TEXTURE_CUBE_MAP;
2413
2414 state->setBoundTextureInternalFormat(stateTarget, internalformat);
2415 state->setBoundTextureFormat(stateTarget, format);
2416 state->setBoundTextureType(stateTarget, type);
2417 state->setBoundTextureDims(stateTarget, level, width, height, 1);
2418
bohu26a92982014-11-25 16:50:37 -08002419 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
2420 ctx->override2DTextureTarget(target);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002421 }
Lingfeng Yang69066602016-04-12 09:29:11 -07002422
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002423 if (ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER)) {
2424 ctx->glTexImage2DOffsetAEMU(
2425 ctx, target, level, internalformat,
2426 width, height, border,
2427 format, type, (uintptr_t)pixels);
bohu26a92982014-11-25 16:50:37 -08002428 } else {
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002429 ctx->m_glTexImage2D_enc(
2430 ctx, target, level, internalformat,
2431 width, height, border,
2432 format, type, pixels);
2433 }
2434
2435 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
2436 ctx->restore2DTextureTarget(target);
bohu26a92982014-11-25 16:50:37 -08002437 }
2438}
2439
Yahan Zhou2a208292016-06-22 15:36:04 -07002440void GL2Encoder::s_glTexSubImage2D(void* self, GLenum target, GLint level,
2441 GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format,
2442 GLenum type, const GLvoid* pixels)
2443{
2444 GL2Encoder* ctx = (GL2Encoder*)self;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002445 GLClientState* state = ctx->m_state;
Lingfeng Yang554a5152019-02-21 20:20:48 -08002446
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002447 SET_ERROR_IF(!GLESv2Validation::textureTarget(ctx, target), GL_INVALID_ENUM);
2448 SET_ERROR_IF(!GLESv2Validation::pixelType(ctx, type), GL_INVALID_ENUM);
2449 SET_ERROR_IF(!GLESv2Validation::pixelFormat(ctx, format), GL_INVALID_ENUM);
2450 // If unpack buffer is nonzero, verify unmapped state.
2451 SET_ERROR_IF(ctx->isBufferTargetMapped(GL_PIXEL_UNPACK_BUFFER), GL_INVALID_OPERATION);
2452
2453 GLint max_texture_size;
2454 GLint max_cube_map_texture_size;
2455 ctx->glGetIntegerv(ctx, GL_MAX_TEXTURE_SIZE, &max_texture_size);
2456 ctx->glGetIntegerv(ctx, GL_MAX_CUBE_MAP_TEXTURE_SIZE, &max_cube_map_texture_size);
2457 SET_ERROR_IF(level < 0, GL_INVALID_VALUE);
2458 SET_ERROR_IF(level > ilog2(max_texture_size), GL_INVALID_VALUE);
2459 SET_ERROR_IF(GLESv2Validation::isCubeMapTarget(target) &&
2460 level > ilog2(max_cube_map_texture_size), GL_INVALID_VALUE);
2461 SET_ERROR_IF(width < 0 || height < 0, GL_INVALID_VALUE);
2462 SET_ERROR_IF(xoffset < 0 || yoffset < 0, GL_INVALID_VALUE);
2463
2464 GLuint tex = state->getBoundTexture(target);
2465 GLsizei neededWidth = xoffset + width;
2466 GLsizei neededHeight = yoffset + height;
2467 GLsizei neededDepth = 1;
2468
2469 if (tex && !state->queryTexEGLImageBacked(tex)) {
2470 SET_ERROR_IF(
2471 (neededWidth > state->queryTexWidth(level, tex) ||
2472 neededHeight > state->queryTexHeight(level, tex) ||
2473 neededDepth > state->queryTexDepth(level, tex)),
2474 GL_INVALID_VALUE);
2475 }
2476
2477 // If unpack buffer is nonzero, verify buffer data fits and is evenly divisible by the type.
2478 SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
2479 ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
2480 (state->pboNeededDataSize(width, height, 1, format, type, 0) >
2481 ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size),
2482 GL_INVALID_OPERATION);
2483 SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
2484 ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
2485 (ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size %
2486 glSizeof(type)),
2487 GL_INVALID_OPERATION);
2488 SET_ERROR_IF(!ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) && !pixels, GL_INVALID_OPERATION);
Yahan Zhou2a208292016-06-22 15:36:04 -07002489
2490 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
2491 ctx->override2DTextureTarget(target);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002492 }
2493
2494 if (ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER)) {
2495 ctx->glTexSubImage2DOffsetAEMU(
2496 ctx, target, level,
2497 xoffset, yoffset, width, height,
2498 format, type, (uintptr_t)pixels);
Yahan Zhou2a208292016-06-22 15:36:04 -07002499 } else {
2500 ctx->m_glTexSubImage2D_enc(ctx, target, level, xoffset, yoffset, width,
2501 height, format, type, pixels);
2502 }
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002503
2504 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
2505 ctx->restore2DTextureTarget(target);
2506 }
Yahan Zhou2a208292016-06-22 15:36:04 -07002507}
bohu26a92982014-11-25 16:50:37 -08002508
Lingfeng Yange00ec9d2016-09-16 08:54:03 -07002509void GL2Encoder::s_glCopyTexImage2D(void* self, GLenum target, GLint level,
2510 GLenum internalformat, GLint x, GLint y,
2511 GLsizei width, GLsizei height, GLint border)
2512{
2513 GL2Encoder* ctx = (GL2Encoder*)self;
2514 GLClientState* state = ctx->m_state;
2515
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002516 SET_ERROR_IF(ctx->glCheckFramebufferStatus(ctx, GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE,
2517 GL_INVALID_FRAMEBUFFER_OPERATION);
Lingfeng Yange00ec9d2016-09-16 08:54:03 -07002518 // This is needed to work around underlying OpenGL drivers
2519 // (such as those feeding some some AMD GPUs) that expect
2520 // positive components of cube maps to be defined _before_
2521 // the negative components (otherwise a segfault occurs).
2522 GLenum extraTarget =
2523 state->copyTexImageLuminanceCubeMapAMDWorkaround
2524 (target, level, internalformat);
2525
2526 if (extraTarget) {
2527 ctx->m_glCopyTexImage2D_enc(ctx, extraTarget, level, internalformat,
2528 x, y, width, height, border);
2529 }
2530
2531 ctx->m_glCopyTexImage2D_enc(ctx, target, level, internalformat,
2532 x, y, width, height, border);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002533
2534 state->setBoundTextureInternalFormat(target, internalformat);
2535 state->setBoundTextureDims(target, level, width, height, 1);
Lingfeng Yange00ec9d2016-09-16 08:54:03 -07002536}
2537
keunyoungb85b2752013-03-08 12:28:03 -08002538void GL2Encoder::s_glTexParameteriv(void* self,
2539 GLenum target, GLenum pname, const GLint* params)
2540{
2541 GL2Encoder* ctx = (GL2Encoder*)self;
keunyoungb85b2752013-03-08 12:28:03 -08002542
2543 SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
2544 !isValidTextureExternalParam(pname, (GLenum)params[0])),
2545 GL_INVALID_ENUM);
2546
2547 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
2548 ctx->override2DTextureTarget(target);
2549 ctx->m_glTexParameteriv_enc(ctx, GL_TEXTURE_2D, pname, params);
Lingfeng Yangb5c03d52016-09-07 14:40:03 -07002550 ctx->restore2DTextureTarget(target);
keunyoungb85b2752013-03-08 12:28:03 -08002551 } else {
2552 ctx->m_glTexParameteriv_enc(ctx, target, pname, params);
2553 }
2554}
2555
Lingfeng Yangb5c03d52016-09-07 14:40:03 -07002556bool GL2Encoder::texture2DNeedsOverride(GLenum target) const {
2557 return (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) &&
2558 target != m_state->getPriorityEnabledTarget(GL_TEXTURE_2D);
2559}
2560
keunyoungb85b2752013-03-08 12:28:03 -08002561void GL2Encoder::override2DTextureTarget(GLenum target)
2562{
Lingfeng Yangb5c03d52016-09-07 14:40:03 -07002563 if (texture2DNeedsOverride(target)) {
2564 m_glBindTexture_enc(this, GL_TEXTURE_2D,
2565 m_state->getBoundTexture(target));
keunyoungb85b2752013-03-08 12:28:03 -08002566 }
2567}
2568
Lingfeng Yangb5c03d52016-09-07 14:40:03 -07002569void GL2Encoder::restore2DTextureTarget(GLenum target)
keunyoungb85b2752013-03-08 12:28:03 -08002570{
Lingfeng Yangb5c03d52016-09-07 14:40:03 -07002571 if (texture2DNeedsOverride(target)) {
Lingfeng Yang5bbf5292017-04-24 18:52:56 -07002572 GLuint priorityEnabledBoundTexture =
Lingfeng Yangb5c03d52016-09-07 14:40:03 -07002573 m_state->getBoundTexture(
Lingfeng Yang5bbf5292017-04-24 18:52:56 -07002574 m_state->getPriorityEnabledTarget(GL_TEXTURE_2D));
2575 GLuint texture2DBoundTexture =
2576 m_state->getBoundTexture(GL_TEXTURE_2D);
2577 if (!priorityEnabledBoundTexture) {
2578 m_glBindTexture_enc(this, GL_TEXTURE_2D, texture2DBoundTexture);
2579 } else {
2580 m_glBindTexture_enc(this, GL_TEXTURE_2D, priorityEnabledBoundTexture);
2581 }
Lingfeng Yangb5c03d52016-09-07 14:40:03 -07002582 }
keunyoungb85b2752013-03-08 12:28:03 -08002583}
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07002584
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002585void GL2Encoder::associateEGLImage(GLenum target, GLeglImageOES eglImage) {
2586 m_state->setBoundEGLImage(target, eglImage);
2587}
2588
2589
2590GLuint GL2Encoder::boundBuffer(GLenum target) const {
2591 return m_state->getBuffer(target);
2592}
2593
2594BufferData* GL2Encoder::getBufferData(GLenum target) const {
2595 GLuint bufferId = m_state->getBuffer(target);
2596 if (!bufferId) return NULL;
2597 return m_shared->getBufferData(bufferId);
2598}
2599
2600BufferData* GL2Encoder::getBufferDataById(GLuint bufferId) const {
2601 if (!bufferId) return NULL;
2602 return m_shared->getBufferData(bufferId);
2603}
2604
2605bool GL2Encoder::isBufferMapped(GLuint buffer) const {
2606 return m_shared->getBufferData(buffer)->m_mapped;
2607}
2608
2609bool GL2Encoder::isBufferTargetMapped(GLenum target) const {
2610 BufferData* buf = getBufferData(target);
2611 if (!buf) return false;
2612 return buf->m_mapped;
2613}
2614
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07002615void GL2Encoder::s_glGenRenderbuffers(void* self,
2616 GLsizei n, GLuint* renderbuffers) {
2617 GL2Encoder* ctx = (GL2Encoder*)self;
2618 GLClientState* state = ctx->m_state;
2619
2620 SET_ERROR_IF(n < 0, GL_INVALID_VALUE);
2621
2622 ctx->m_glGenFramebuffers_enc(self, n, renderbuffers);
2623 state->addRenderbuffers(n, renderbuffers);
2624}
2625
2626void GL2Encoder::s_glDeleteRenderbuffers(void* self,
2627 GLsizei n, const GLuint* renderbuffers) {
2628 GL2Encoder* ctx = (GL2Encoder*)self;
2629 GLClientState* state = ctx->m_state;
2630
2631 SET_ERROR_IF(n < 0, GL_INVALID_VALUE);
2632
2633 ctx->m_glDeleteRenderbuffers_enc(self, n, renderbuffers);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002634
2635 // Nope, lets just leak those for now.
2636 // The spec has an *amazingly* convoluted set of conditions for when
2637 // render buffers are actually deleted:
2638 // 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.
2639 //
2640 // 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***
2641 //
2642 // So, just detach this one from the bound FBO, and ignore the rest.
2643 for (int i = 0; i < n; i++) {
2644 state->detachRbo(renderbuffers[i]);
2645 }
2646 // state->removeRenderbuffers(n, renderbuffers);
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07002647}
2648
2649void GL2Encoder::s_glBindRenderbuffer(void* self,
2650 GLenum target, GLuint renderbuffer) {
2651 GL2Encoder* ctx = (GL2Encoder*)self;
2652 GLClientState* state = ctx->m_state;
2653
2654 SET_ERROR_IF((target != GL_RENDERBUFFER),
2655 GL_INVALID_ENUM);
2656
2657 ctx->m_glBindRenderbuffer_enc(self, target, renderbuffer);
2658 state->bindRenderbuffer(target, renderbuffer);
2659}
2660
Lingfeng Yang69066602016-04-12 09:29:11 -07002661void GL2Encoder::s_glRenderbufferStorage(void* self,
2662 GLenum target, GLenum internalformat,
2663 GLsizei width, GLsizei height) {
2664 GL2Encoder* ctx = (GL2Encoder*) self;
2665 GLClientState* state = ctx->m_state;
2666
2667 SET_ERROR_IF(target != GL_RENDERBUFFER, GL_INVALID_ENUM);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002668 SET_ERROR_IF(
2669 !GLESv2Validation::rboFormat(ctx, internalformat),
2670 GL_INVALID_ENUM);
Lingfeng Yang69066602016-04-12 09:29:11 -07002671
2672 state->setBoundRenderbufferFormat(internalformat);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002673 state->setBoundRenderbufferSamples(0);
2674
Lingfeng Yang69066602016-04-12 09:29:11 -07002675 ctx->m_glRenderbufferStorage_enc(self, target, internalformat,
2676 width, height);
2677}
2678
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07002679void GL2Encoder::s_glFramebufferRenderbuffer(void* self,
2680 GLenum target, GLenum attachment,
2681 GLenum renderbuffertarget, GLuint renderbuffer) {
2682 GL2Encoder* ctx = (GL2Encoder*)self;
2683 GLClientState* state = ctx->m_state;
2684
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002685 SET_ERROR_IF(!GLESv2Validation::framebufferTarget(ctx, target), GL_INVALID_ENUM);
2686 SET_ERROR_IF(!GLESv2Validation::framebufferAttachment(ctx, attachment), GL_INVALID_ENUM);
2687 state->attachRbo(target, attachment, renderbuffer);
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07002688
2689 ctx->m_glFramebufferRenderbuffer_enc(self, target, attachment, renderbuffertarget, renderbuffer);
2690}
2691
2692void GL2Encoder::s_glGenFramebuffers(void* self,
2693 GLsizei n, GLuint* framebuffers) {
2694 GL2Encoder* ctx = (GL2Encoder*)self;
2695 GLClientState* state = ctx->m_state;
2696
2697 SET_ERROR_IF(n < 0, GL_INVALID_VALUE);
2698
2699 ctx->m_glGenFramebuffers_enc(self, n, framebuffers);
2700 state->addFramebuffers(n, framebuffers);
2701}
2702
2703void GL2Encoder::s_glDeleteFramebuffers(void* self,
2704 GLsizei n, const GLuint* framebuffers) {
2705 GL2Encoder* ctx = (GL2Encoder*)self;
2706 GLClientState* state = ctx->m_state;
2707
2708 SET_ERROR_IF(n < 0, GL_INVALID_VALUE);
2709
2710 ctx->m_glDeleteFramebuffers_enc(self, n, framebuffers);
2711 state->removeFramebuffers(n, framebuffers);
2712}
2713
2714void GL2Encoder::s_glBindFramebuffer(void* self,
2715 GLenum target, GLuint framebuffer) {
2716 GL2Encoder* ctx = (GL2Encoder*)self;
2717 GLClientState* state = ctx->m_state;
2718
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002719 SET_ERROR_IF(!GLESv2Validation::framebufferTarget(ctx, target), GL_INVALID_ENUM);
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07002720
2721 state->bindFramebuffer(target, framebuffer);
2722
2723 ctx->m_glBindFramebuffer_enc(self, target, framebuffer);
2724}
2725
2726void GL2Encoder::s_glFramebufferTexture2D(void* self,
2727 GLenum target, GLenum attachment,
2728 GLenum textarget, GLuint texture, GLint level) {
2729 GL2Encoder* ctx = (GL2Encoder*)self;
2730 GLClientState* state = ctx->m_state;
2731
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002732 SET_ERROR_IF(!GLESv2Validation::framebufferTarget(ctx, target), GL_INVALID_ENUM);
2733 SET_ERROR_IF(!GLESv2Validation::framebufferAttachment(ctx, attachment), GL_INVALID_ENUM);
2734 state->attachTextureObject(target, attachment, texture);
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07002735
2736 ctx->m_glFramebufferTexture2D_enc(self, target, attachment, textarget, texture, level);
2737}
2738
2739void GL2Encoder::s_glFramebufferTexture3DOES(void* self,
2740 GLenum target, GLenum attachment,
2741 GLenum textarget, GLuint texture, GLint level, GLint zoffset) {
2742 GL2Encoder* ctx = (GL2Encoder*)self;
2743 GLClientState* state = ctx->m_state;
2744
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002745 state->attachTextureObject(target, attachment, texture);
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07002746
2747 ctx->m_glFramebufferTexture3DOES_enc(self, target, attachment, textarget, texture, level, zoffset);
2748}
2749
2750void GL2Encoder::s_glGetFramebufferAttachmentParameteriv(void* self,
2751 GLenum target, GLenum attachment, GLenum pname, GLint* params) {
2752 GL2Encoder* ctx = (GL2Encoder*)self;
2753 const GLClientState* state = ctx->m_state;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002754 SET_ERROR_IF(!GLESv2Validation::framebufferTarget(ctx, target), GL_INVALID_ENUM);
2755 SET_ERROR_IF(pname != GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME &&
2756 pname != GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE &&
2757 !state->attachmentHasObject(target, attachment),
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07002758 GL_INVALID_OPERATION);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002759 SET_ERROR_IF((pname == GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL ||
2760 pname == GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE ||
2761 pname == GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER) &&
2762 (!state->attachmentHasObject(target, attachment) ||
2763 state->getBoundFramebufferAttachmentType(target, attachment) !=
2764 FBO_ATTACHMENT_TEXTURE),
2765 !state->attachmentHasObject(target, attachment) ?
2766 GL_INVALID_OPERATION : GL_INVALID_ENUM);
2767 SET_ERROR_IF(attachment == GL_DEPTH_STENCIL_ATTACHMENT &&
2768 pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME &&
2769 (state->objectOfAttachment(target, GL_DEPTH_ATTACHMENT) !=
2770 state->objectOfAttachment(target, GL_STENCIL_ATTACHMENT)),
2771 GL_INVALID_OPERATION);
2772 SET_ERROR_IF(state->boundFramebuffer(target) &&
2773 (attachment == GL_BACK ||
2774 attachment == GL_FRONT),
2775 GL_INVALID_OPERATION);
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07002776 ctx->m_glGetFramebufferAttachmentParameteriv_enc(self, target, attachment, pname, params);
2777}
Lingfeng Yang69066602016-04-12 09:29:11 -07002778
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002779bool GL2Encoder::isCompleteFbo(GLenum target, const GLClientState* state,
Lingfeng Yang69066602016-04-12 09:29:11 -07002780 GLenum attachment) const {
2781 FboFormatInfo fbo_format_info;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002782 state->getBoundFramebufferFormat(target, attachment, &fbo_format_info);
Lingfeng Yang69066602016-04-12 09:29:11 -07002783
2784 bool res;
2785 switch (fbo_format_info.type) {
2786 case FBO_ATTACHMENT_RENDERBUFFER:
2787 switch (fbo_format_info.rb_format) {
2788 case GL_R16F:
2789 case GL_RG16F:
Lingfeng Yang69066602016-04-12 09:29:11 -07002790 case GL_RGBA16F:
Lingfeng Yang931817b2017-01-27 06:50:56 -08002791 case GL_R32F:
2792 case GL_RG32F:
2793 case GL_RGBA32F:
2794 case GL_R11F_G11F_B10F:
Lingfeng Yangc92685e2017-01-30 20:06:39 -08002795 res = majorVersion() >= 3 && hasExtension("GL_EXT_color_buffer_float");
Lingfeng Yang931817b2017-01-27 06:50:56 -08002796 break;
2797 case GL_RGB16F:
Lingfeng Yangc92685e2017-01-30 20:06:39 -08002798 res = majorVersion() >= 3 && hasExtension("GL_EXT_color_buffer_half_float");
Lingfeng Yang69066602016-04-12 09:29:11 -07002799 break;
2800 case GL_STENCIL_INDEX8:
2801 if (attachment == GL_STENCIL_ATTACHMENT) {
2802 res = true;
2803 } else {
2804 res = false;
2805 }
2806 break;
2807 default:
2808 res = true;
2809 }
2810 break;
2811 case FBO_ATTACHMENT_TEXTURE:
Yahan Zhou68bfd8c2016-05-11 15:06:34 -07002812 switch (fbo_format_info.tex_internalformat) {
Yahan Zhou68bfd8c2016-05-11 15:06:34 -07002813 case GL_R16F:
2814 case GL_RG16F:
2815 case GL_RGBA16F:
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002816 case GL_R32F:
2817 case GL_RG32F:
2818 case GL_RGBA32F:
Lingfeng Yang931817b2017-01-27 06:50:56 -08002819 case GL_R11F_G11F_B10F:
Lingfeng Yangc92685e2017-01-30 20:06:39 -08002820 res = majorVersion() >= 3 && hasExtension("GL_EXT_color_buffer_float");
Lingfeng Yang931817b2017-01-27 06:50:56 -08002821 break;
2822 case GL_RGB16F:
Lingfeng Yangc92685e2017-01-30 20:06:39 -08002823 res = majorVersion() >= 3 && hasExtension("GL_EXT_color_buffer_half_float");
Lingfeng Yang931817b2017-01-27 06:50:56 -08002824 break;
2825 case GL_RED:
2826 case GL_RG:
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002827 case GL_SRGB8:
2828 case GL_RGB32UI:
2829 case GL_RGB16UI:
2830 case GL_RGB8UI:
2831 case GL_RGB32I:
2832 case GL_RGB16I:
2833 case GL_RGB8I:
2834 case GL_R8_SNORM:
2835 case GL_RG8_SNORM:
2836 case GL_RGB8_SNORM:
2837 case GL_RGBA8_SNORM:
Yahan Zhou68bfd8c2016-05-11 15:06:34 -07002838 res = false;
2839 break;
Lingfeng Yang69066602016-04-12 09:29:11 -07002840 // No float/half-float formats allowed for RGB(A)
Yahan Zhou68bfd8c2016-05-11 15:06:34 -07002841 case GL_RGB:
2842 case GL_RGBA:
Lingfeng Yang69066602016-04-12 09:29:11 -07002843 switch (fbo_format_info.tex_type) {
2844 case GL_FLOAT:
2845 case GL_HALF_FLOAT_OES:
Yahan Zhou68bfd8c2016-05-11 15:06:34 -07002846 case GL_UNSIGNED_INT_10F_11F_11F_REV:
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002847 case GL_UNSIGNED_INT_2_10_10_10_REV:
Lingfeng Yang69066602016-04-12 09:29:11 -07002848 res = false;
2849 break;
2850 default:
2851 res = true;
2852 }
Yahan Zhou68bfd8c2016-05-11 15:06:34 -07002853 break;
2854 default:
Lingfeng Yang69066602016-04-12 09:29:11 -07002855 res = true;
2856 }
2857 break;
2858 case FBO_ATTACHMENT_NONE:
2859 res = true;
2860 break;
2861 default:
2862 res = true;
2863 }
2864 return res;
2865}
2866
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002867bool GL2Encoder::checkFramebufferCompleteness(GLenum target, const GLClientState* state) const {
2868 bool res = true;
2869
2870 for (int i = 0; i < state->getMaxColorAttachments(); i++) {
2871 res = res && isCompleteFbo(target, state, glUtilsColorAttachmentName(i));
2872 }
2873
2874 res = res && isCompleteFbo(target, state, GL_DEPTH_ATTACHMENT);
2875 res = res && isCompleteFbo(target, state, GL_STENCIL_ATTACHMENT);
2876
2877 return res;
2878}
2879
Lingfeng Yang69066602016-04-12 09:29:11 -07002880GLenum GL2Encoder::s_glCheckFramebufferStatus(void* self, GLenum target) {
2881 GL2Encoder* ctx = (GL2Encoder*)self;
2882 GLClientState* state = ctx->m_state;
2883
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002884 bool fboCompleteByCodec =
2885 ctx->checkFramebufferCompleteness(target, state);
2886
2887 if (!fboCompleteByCodec) {
2888 state->setCheckFramebufferStatus(target, GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT);
Lingfeng Yang69066602016-04-12 09:29:11 -07002889 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
2890 } else {
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002891 // double check with underlying opengl to avoid craziness.
Lingfeng Yang69066602016-04-12 09:29:11 -07002892 GLenum host_checkstatus = ctx->m_glCheckFramebufferStatus_enc(self, target);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002893 state->setCheckFramebufferStatus(target, host_checkstatus);
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08002894 if (host_checkstatus == GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS) return GL_FRAMEBUFFER_COMPLETE;
Lingfeng Yang69066602016-04-12 09:29:11 -07002895 return host_checkstatus;
2896 }
2897}
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002898
2899void GL2Encoder::s_glGenVertexArrays(void* self, GLsizei n, GLuint* arrays) {
2900 GL2Encoder* ctx = (GL2Encoder*)self;
2901 GLClientState* state = ctx->m_state;
2902 SET_ERROR_IF(n < 0, GL_INVALID_VALUE);
2903
2904 ctx->m_glGenVertexArrays_enc(self, n, arrays);
2905 for (int i = 0; i < n; i++) {
2906 ALOGV("%s: gen vao %u", __FUNCTION__, arrays[i]);
2907 }
2908 state->addVertexArrayObjects(n, arrays);
2909}
2910
2911void GL2Encoder::s_glDeleteVertexArrays(void* self, GLsizei n, const GLuint* arrays) {
2912 GL2Encoder* ctx = (GL2Encoder*)self;
2913 GLClientState* state = ctx->m_state;
2914 SET_ERROR_IF(n < 0, GL_INVALID_VALUE);
2915
2916 ctx->m_glDeleteVertexArrays_enc(self, n, arrays);
2917 for (int i = 0; i < n; i++) {
2918 ALOGV("%s: delete vao %u", __FUNCTION__, arrays[i]);
2919 }
2920 state->removeVertexArrayObjects(n, arrays);
2921}
2922
2923void GL2Encoder::s_glBindVertexArray(void* self, GLuint array) {
2924 ALOGV("%s: call. array=%u\n", __FUNCTION__, array);
2925 GL2Encoder* ctx = (GL2Encoder*)self;
2926 GLClientState* state = ctx->m_state;
2927 SET_ERROR_IF(!state->isVertexArrayObject(array), GL_INVALID_OPERATION);
2928 ctx->m_glBindVertexArray_enc(self, array);
2929 state->setVertexArrayObject(array);
2930}
2931
Lingfeng Yangfb3d2bb2017-09-07 15:02:04 -07002932void* GL2Encoder::s_glMapBufferOES(void* self, GLenum target, GLenum access) {
2933 GL2Encoder* ctx = (GL2Encoder*)self;
2934
2935 RET_AND_SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM, NULL);
2936
2937 GLuint boundBuffer = ctx->m_state->getBuffer(target);
2938
2939 RET_AND_SET_ERROR_IF(boundBuffer == 0, GL_INVALID_OPERATION, NULL);
2940
2941 BufferData* buf = ctx->m_shared->getBufferData(boundBuffer);
2942 RET_AND_SET_ERROR_IF(!buf, GL_INVALID_VALUE, NULL);
2943
2944 return ctx->glMapBufferRange(ctx, target, 0, buf->m_size, access);
2945}
2946
2947GLboolean GL2Encoder::s_glUnmapBufferOES(void* self, GLenum target) {
2948 GL2Encoder* ctx = (GL2Encoder*)self;
2949
2950 return ctx->glUnmapBuffer(ctx, target);
2951}
2952
Roman Kiryanovbe1c0c22018-10-02 18:07:14 -07002953void* GL2Encoder::s_glMapBufferRangeAEMUImpl(GL2Encoder* ctx, GLenum target,
2954 GLintptr offset, GLsizeiptr length,
2955 GLbitfield access, BufferData* buf) {
2956 char* bits = (char*)buf->m_fixedBuffer.ptr() + offset;
2957
2958 ctx->glMapBufferRangeAEMU(
2959 ctx, target,
2960 offset, length,
2961 access,
2962 bits);
2963
2964 return bits;
2965}
2966
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002967void* GL2Encoder::s_glMapBufferRange(void* self, GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access) {
2968 GL2Encoder* ctx = (GL2Encoder*)self;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002969
2970 // begin validation (lots)
Lingfeng Yang554a5152019-02-21 20:20:48 -08002971
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002972 RET_AND_SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM, NULL);
2973
2974 GLuint boundBuffer = ctx->m_state->getBuffer(target);
2975
2976 RET_AND_SET_ERROR_IF(boundBuffer == 0, GL_INVALID_OPERATION, NULL);
2977
2978 BufferData* buf = ctx->m_shared->getBufferData(boundBuffer);
2979 RET_AND_SET_ERROR_IF(!buf, GL_INVALID_VALUE, NULL);
2980
2981 GLsizeiptr bufferDataSize = buf->m_size;
2982
2983 RET_AND_SET_ERROR_IF(offset < 0, GL_INVALID_VALUE, NULL);
2984 RET_AND_SET_ERROR_IF(length < 0, GL_INVALID_VALUE, NULL);
2985 RET_AND_SET_ERROR_IF(offset + length > bufferDataSize, GL_INVALID_VALUE, NULL);
2986 RET_AND_SET_ERROR_IF(access & ~GLESv2Validation::allBufferMapAccessFlags, GL_INVALID_VALUE, NULL);
2987
2988 RET_AND_SET_ERROR_IF(buf->m_mapped, GL_INVALID_OPERATION, NULL);
2989 RET_AND_SET_ERROR_IF(!(access & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)), GL_INVALID_OPERATION, NULL);
2990 RET_AND_SET_ERROR_IF(
2991 (access & GL_MAP_READ_BIT) &&
2992 ((access & GL_MAP_INVALIDATE_RANGE_BIT) ||
2993 (access & GL_MAP_INVALIDATE_BUFFER_BIT) ||
2994 (access & GL_MAP_UNSYNCHRONIZED_BIT) ||
2995 (access & GL_MAP_FLUSH_EXPLICIT_BIT)), GL_INVALID_OPERATION, NULL);
2996
2997 // end validation; actually do stuff now
Lingfeng Yang554a5152019-02-21 20:20:48 -08002998
Lingfeng Yang46153ab2017-01-09 13:37:22 -08002999 buf->m_mapped = true;
3000 buf->m_mappedAccess = access;
3001 buf->m_mappedOffset = offset;
3002 buf->m_mappedLength = length;
3003
Roman Kiryanovbe1c0c22018-10-02 18:07:14 -07003004 if (ctx->hasExtension("ANDROID_EMU_dma_v2")) {
3005 if (buf->dma_buffer.get().size < length) {
3006 goldfish_dma_context region;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003007
Roman Kiryanovbe1c0c22018-10-02 18:07:14 -07003008 const int PAGE_BITS = 12;
3009 GLsizeiptr aligned_length = (length + (1 << PAGE_BITS) - 1) & ~((1 << PAGE_BITS) - 1);
3010
3011 if (goldfish_dma_create_region(aligned_length, &region)) {
3012 buf->dma_buffer.reset(NULL);
3013 return s_glMapBufferRangeAEMUImpl(ctx, target, offset, length, access, buf);
3014 }
3015
3016 if (!goldfish_dma_map(&region)) {
3017 buf->dma_buffer.reset(NULL);
3018 return s_glMapBufferRangeAEMUImpl(ctx, target, offset, length, access, buf);
3019 }
3020
3021 buf->m_guest_paddr = goldfish_dma_guest_paddr(&region);
3022 buf->dma_buffer.reset(&region);
3023 }
3024
3025 ctx->glMapBufferRangeDMA(
3026 ctx, target,
3027 offset, length,
3028 access,
3029 buf->m_guest_paddr);
3030
3031 return reinterpret_cast<void*>(buf->dma_buffer.get().mapped_addr);
3032 } else {
3033 return s_glMapBufferRangeAEMUImpl(ctx, target, offset, length, access, buf);
3034 }
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003035}
3036
3037GLboolean GL2Encoder::s_glUnmapBuffer(void* self, GLenum target) {
3038 GL2Encoder* ctx = (GL2Encoder*)self;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003039
3040 RET_AND_SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM, GL_FALSE);
3041
3042 GLuint boundBuffer = ctx->m_state->getBuffer(target);
3043
3044 RET_AND_SET_ERROR_IF(boundBuffer == 0, GL_INVALID_OPERATION, GL_FALSE);
3045
3046 BufferData* buf = ctx->m_shared->getBufferData(boundBuffer);
3047 RET_AND_SET_ERROR_IF(!buf, GL_INVALID_VALUE, GL_FALSE);
3048 RET_AND_SET_ERROR_IF(!buf->m_mapped, GL_INVALID_OPERATION, GL_FALSE);
3049
Lingfeng Yang423129e2017-01-18 09:23:12 -08003050 if (buf->m_mappedAccess & GL_MAP_WRITE_BIT) {
3051 // invalide index range cache here
3052 if (buf->m_mappedAccess & GL_MAP_INVALIDATE_BUFFER_BIT) {
3053 buf->m_indexRangeCache.invalidateRange(0, buf->m_size);
3054 } else {
3055 buf->m_indexRangeCache.invalidateRange(buf->m_mappedOffset, buf->m_mappedLength);
3056 }
3057 }
3058
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003059 GLboolean host_res = GL_TRUE;
3060
Roman Kiryanovbe1c0c22018-10-02 18:07:14 -07003061 if (buf->dma_buffer.get().mapped_addr) {
3062 memcpy(static_cast<char*>(buf->m_fixedBuffer.ptr()) + buf->m_mappedOffset,
3063 reinterpret_cast<void*>(buf->dma_buffer.get().mapped_addr),
3064 buf->m_mappedLength);
3065
3066 ctx->glUnmapBufferDMA(
Roman Kiryanovdaecd142018-11-14 14:56:27 -08003067 ctx, target,
3068 buf->m_mappedOffset,
3069 buf->m_mappedLength,
3070 buf->m_mappedAccess,
3071 goldfish_dma_guest_paddr(&buf->dma_buffer.get()),
3072 &host_res);
Roman Kiryanovbe1c0c22018-10-02 18:07:14 -07003073 } else {
3074 ctx->glUnmapBufferAEMU(
3075 ctx, target,
3076 buf->m_mappedOffset,
3077 buf->m_mappedLength,
3078 buf->m_mappedAccess,
3079 (void*)((char*)buf->m_fixedBuffer.ptr() + buf->m_mappedOffset),
3080 &host_res);
3081 }
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003082
3083 buf->m_mapped = false;
3084 buf->m_mappedAccess = 0;
3085 buf->m_mappedOffset = 0;
3086 buf->m_mappedLength = 0;
3087
3088 return host_res;
3089}
3090
3091void GL2Encoder::s_glFlushMappedBufferRange(void* self, GLenum target, GLintptr offset, GLsizeiptr length) {
3092 GL2Encoder* ctx = (GL2Encoder*)self;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003093
3094 SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM);
3095
3096 GLuint boundBuffer = ctx->m_state->getBuffer(target);
3097 SET_ERROR_IF(!boundBuffer, GL_INVALID_OPERATION);
3098
3099 BufferData* buf = ctx->m_shared->getBufferData(boundBuffer);
3100 SET_ERROR_IF(!buf, GL_INVALID_VALUE);
3101 SET_ERROR_IF(!buf->m_mapped, GL_INVALID_OPERATION);
3102 SET_ERROR_IF(!(buf->m_mappedAccess & GL_MAP_FLUSH_EXPLICIT_BIT), GL_INVALID_OPERATION);
3103
3104 SET_ERROR_IF(offset < 0, GL_INVALID_VALUE);
3105 SET_ERROR_IF(length < 0, GL_INVALID_VALUE);
3106 SET_ERROR_IF(offset + length > buf->m_mappedLength, GL_INVALID_VALUE);
3107
3108 GLintptr totalOffset = buf->m_mappedOffset + offset;
Lingfeng Yang423129e2017-01-18 09:23:12 -08003109
3110 buf->m_indexRangeCache.invalidateRange(totalOffset, length);
3111
Roman Kiryanov13211652019-05-22 15:58:16 -07003112 ctx->glFlushMappedBufferRangeAEMU(
3113 ctx, target,
3114 totalOffset,
3115 length,
3116 buf->m_mappedAccess,
3117 (void*)((char*)buf->m_fixedBuffer.ptr() + totalOffset));
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003118}
3119
3120void GL2Encoder::s_glCompressedTexImage2D(void* self, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* data) {
3121 GL2Encoder* ctx = (GL2Encoder*)self;
3122 GLClientState* state = ctx->m_state;
3123
3124 SET_ERROR_IF(!GLESv2Validation::textureTarget(ctx, target), GL_INVALID_ENUM);
3125 // Filter compressed formats support.
3126 SET_ERROR_IF(!GLESv2Validation::supportedCompressedFormat(ctx, internalformat), GL_INVALID_ENUM);
3127 // Verify level <= log2(GL_MAX_TEXTURE_SIZE).
3128 GLint max_texture_size;
3129 GLint max_cube_map_texture_size;
3130 ctx->glGetIntegerv(ctx, GL_MAX_TEXTURE_SIZE, &max_texture_size);
3131 ctx->glGetIntegerv(ctx, GL_MAX_CUBE_MAP_TEXTURE_SIZE, &max_cube_map_texture_size);
3132 SET_ERROR_IF(level < 0, GL_INVALID_VALUE);
3133 SET_ERROR_IF(level > ilog2(max_texture_size), GL_INVALID_VALUE);
3134 SET_ERROR_IF(level > ilog2(max_cube_map_texture_size), GL_INVALID_VALUE);
3135 SET_ERROR_IF(width > max_texture_size, GL_INVALID_VALUE);
3136 SET_ERROR_IF(height > max_texture_size, GL_INVALID_VALUE);
3137 SET_ERROR_IF(border, GL_INVALID_VALUE);
3138 // If unpack buffer is nonzero, verify unmapped state.
3139 SET_ERROR_IF(ctx->isBufferTargetMapped(GL_PIXEL_UNPACK_BUFFER), GL_INVALID_OPERATION);
3140 SET_ERROR_IF(width < 0 || height < 0, GL_INVALID_VALUE);
3141 // If unpack buffer is nonzero, verify buffer data fits.
3142 SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
3143 ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
3144 (imageSize > ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size),
3145 GL_INVALID_OPERATION);
3146 // TODO: Fix:
3147 // If |imageSize| is inconsistent with compressed dimensions.
3148 // SET_ERROR_IF(GLESv2Validation::compressedTexImageSize(internalformat, width, height, 1) != imageSize, GL_INVALID_VALUE);
3149
3150 GLenum stateTarget = target;
3151 if (target == GL_TEXTURE_CUBE_MAP_POSITIVE_X ||
3152 target == GL_TEXTURE_CUBE_MAP_POSITIVE_Y ||
3153 target == GL_TEXTURE_CUBE_MAP_POSITIVE_Z ||
3154 target == GL_TEXTURE_CUBE_MAP_NEGATIVE_X ||
3155 target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y ||
3156 target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Z)
3157 stateTarget = GL_TEXTURE_CUBE_MAP;
3158 state->setBoundTextureInternalFormat(stateTarget, (GLint)internalformat);
3159 state->setBoundTextureDims(stateTarget, level, width, height, 1);
3160
Lingfeng Yanga9fff6a2018-03-02 13:42:51 -08003161 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
3162 ctx->override2DTextureTarget(target);
3163 }
3164
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003165 if (ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER)) {
3166 ctx->glCompressedTexImage2DOffsetAEMU(
3167 ctx, target, level, internalformat,
3168 width, height, border,
3169 imageSize, (uintptr_t)data);
3170 } else {
3171 ctx->m_glCompressedTexImage2D_enc(
3172 ctx, target, level, internalformat,
3173 width, height, border,
3174 imageSize, data);
3175 }
Lingfeng Yanga9fff6a2018-03-02 13:42:51 -08003176
3177 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
3178 ctx->restore2DTextureTarget(target);
3179 }
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003180}
3181
3182void GL2Encoder::s_glCompressedTexSubImage2D(void* self, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* data) {
3183 GL2Encoder* ctx = (GL2Encoder*)self;
3184 GLClientState* state = ctx->m_state;
3185
3186 SET_ERROR_IF(!GLESv2Validation::textureTarget(ctx, target), GL_INVALID_ENUM);
3187 // If unpack buffer is nonzero, verify unmapped state.
3188 SET_ERROR_IF(ctx->isBufferTargetMapped(GL_PIXEL_UNPACK_BUFFER), GL_INVALID_OPERATION);
3189 GLint max_texture_size;
3190 GLint max_cube_map_texture_size;
3191 ctx->glGetIntegerv(ctx, GL_MAX_TEXTURE_SIZE, &max_texture_size);
3192 ctx->glGetIntegerv(ctx, GL_MAX_CUBE_MAP_TEXTURE_SIZE, &max_cube_map_texture_size);
3193 SET_ERROR_IF(level < 0, GL_INVALID_VALUE);
3194 SET_ERROR_IF(level > ilog2(max_texture_size), GL_INVALID_VALUE);
3195 SET_ERROR_IF(level > ilog2(max_cube_map_texture_size), GL_INVALID_VALUE);
3196 SET_ERROR_IF(width < 0 || height < 0, GL_INVALID_VALUE);
3197 // If unpack buffer is nonzero, verify buffer data fits.
3198 SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
3199 ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
3200 (imageSize > ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size),
3201 GL_INVALID_OPERATION);
3202 SET_ERROR_IF(xoffset < 0 || yoffset < 0, GL_INVALID_VALUE);
3203
Lingfeng Yanga9fff6a2018-03-02 13:42:51 -08003204 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
3205 ctx->override2DTextureTarget(target);
3206 }
3207
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003208 if (ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER)) {
3209 ctx->glCompressedTexSubImage2DOffsetAEMU(
3210 ctx, target, level,
3211 xoffset, yoffset,
3212 width, height, format,
3213 imageSize, (uintptr_t)data);
3214 } else {
3215 ctx->m_glCompressedTexSubImage2D_enc(
3216 ctx, target, level,
3217 xoffset, yoffset,
3218 width, height, format,
3219 imageSize, data);
3220 }
Lingfeng Yanga9fff6a2018-03-02 13:42:51 -08003221
3222 if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
3223 ctx->restore2DTextureTarget(target);
3224 }
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003225}
3226
3227void GL2Encoder::s_glBindBufferRange(void* self, GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size) {
3228 GL2Encoder* ctx = (GL2Encoder*)self;
3229 GLClientState* state = ctx->m_state;
3230
3231 SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM);
3232
3233 // Only works with certain targets
3234 SET_ERROR_IF(
3235 !(target == GL_ATOMIC_COUNTER_BUFFER ||
3236 target == GL_SHADER_STORAGE_BUFFER ||
3237 target == GL_TRANSFORM_FEEDBACK_BUFFER ||
3238 target == GL_UNIFORM_BUFFER),
3239 GL_INVALID_ENUM);
3240
3241 // Can't exceed range
3242 SET_ERROR_IF(index < 0 ||
3243 index >= state->getMaxIndexedBufferBindings(target),
3244 GL_INVALID_VALUE);
3245 SET_ERROR_IF(buffer && size <= 0, GL_INVALID_VALUE);
3246 SET_ERROR_IF((target == GL_ATOMIC_COUNTER_BUFFER ||
3247 target == GL_TRANSFORM_FEEDBACK_BUFFER) &&
3248 (size % 4 || offset % 4),
3249 GL_INVALID_VALUE);
3250
3251 GLint ssbo_offset_align, ubo_offset_align;
3252 ctx->s_glGetIntegerv(ctx, GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT, &ssbo_offset_align);
3253 ctx->s_glGetIntegerv(ctx, GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &ubo_offset_align);
3254 SET_ERROR_IF(target == GL_SHADER_STORAGE_BUFFER &&
3255 offset % ssbo_offset_align,
3256 GL_INVALID_VALUE);
3257 SET_ERROR_IF(target == GL_UNIFORM_BUFFER &&
3258 offset % ubo_offset_align,
3259 GL_INVALID_VALUE);
3260
Lingfeng Yang554a5152019-02-21 20:20:48 -08003261 if (ctx->m_state->isIndexedBindNoOp(target, index, buffer, offset, size, 0, 0)) return;
3262
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003263 state->bindBuffer(target, buffer);
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08003264 ctx->m_state->addBuffer(buffer);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003265 state->bindIndexedBuffer(target, index, buffer, offset, size, 0, 0);
Lingfeng Yang554a5152019-02-21 20:20:48 -08003266
3267 ctx->m_glBindBufferRange_enc(ctx, target, index, buffer, offset, size);
3268 ctx->m_state->setLastEncodedBufferBind(target, buffer);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003269}
3270
3271void GL2Encoder::s_glBindBufferBase(void* self, GLenum target, GLuint index, GLuint buffer) {
3272 GL2Encoder* ctx = (GL2Encoder*)self;
3273 GLClientState* state = ctx->m_state;
3274
3275 SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM);
3276
3277 // Only works with certain targets
3278 SET_ERROR_IF(
3279 !(target == GL_ATOMIC_COUNTER_BUFFER ||
3280 target == GL_SHADER_STORAGE_BUFFER ||
3281 target == GL_TRANSFORM_FEEDBACK_BUFFER ||
3282 target == GL_UNIFORM_BUFFER),
3283 GL_INVALID_ENUM);
3284 // Can't exceed range
3285 SET_ERROR_IF(index < 0 ||
3286 index >= state->getMaxIndexedBufferBindings(target),
3287 GL_INVALID_VALUE);
3288
Lingfeng Yang554a5152019-02-21 20:20:48 -08003289 BufferData* buf = ctx->getBufferDataById(buffer);
3290 GLsizeiptr size = buf ? buf->m_size : 0;
3291
3292 if (ctx->m_state->isIndexedBindNoOp(target, index, buffer, 0, size, 0, 0)) return;
3293
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003294 state->bindBuffer(target, buffer);
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08003295 ctx->m_state->addBuffer(buffer);
Lingfeng Yang554a5152019-02-21 20:20:48 -08003296
3297 state->bindIndexedBuffer(target, index, buffer, 0, size, 0, 0);
3298
3299 ctx->m_glBindBufferBase_enc(ctx, target, index, buffer);
3300 ctx->m_state->setLastEncodedBufferBind(target, buffer);
3301}
3302
3303void GL2Encoder::doIndexedBufferBindEncodeCached(IndexedBufferBindOp op, GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size, GLintptr stride, GLintptr effectiveStride)
3304{
3305 if (m_state->isIndexedBindNoOp(target, index, buffer, offset, size, stride, effectiveStride)) return;
3306
3307 switch (op) {
3308 case BindBufferBase:
3309 // can emulate with bindBufferRange
3310 case BindBufferRange:
3311 m_glBindBufferRange_enc(this, target, index, buffer, offset, size);
3312 break;
3313 // TODO: other ops
3314 }
3315
3316 m_state->setLastEncodedBufferBind(target, buffer);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003317}
3318
3319void GL2Encoder::s_glCopyBufferSubData(void *self , GLenum readtarget, GLenum writetarget, GLintptr readoffset, GLintptr writeoffset, GLsizeiptr size) {
3320 GL2Encoder* ctx = (GL2Encoder*)self;
3321 GLClientState* state = ctx->m_state;
3322
3323 SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, readtarget), GL_INVALID_ENUM);
3324 SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, writetarget), GL_INVALID_ENUM);
3325 SET_ERROR_IF((readtarget == GL_ATOMIC_COUNTER_BUFFER ||
3326 readtarget == GL_DISPATCH_INDIRECT_BUFFER ||
3327 readtarget == GL_DRAW_INDIRECT_BUFFER ||
3328 readtarget == GL_SHADER_STORAGE_BUFFER), GL_INVALID_ENUM);
3329 SET_ERROR_IF((writetarget == GL_ATOMIC_COUNTER_BUFFER ||
3330 writetarget == GL_DISPATCH_INDIRECT_BUFFER ||
3331 writetarget == GL_DRAW_INDIRECT_BUFFER ||
3332 writetarget == GL_SHADER_STORAGE_BUFFER), GL_INVALID_ENUM);
3333 SET_ERROR_IF(!ctx->boundBuffer(readtarget), GL_INVALID_OPERATION);
3334 SET_ERROR_IF(!ctx->boundBuffer(writetarget), GL_INVALID_OPERATION);
3335 SET_ERROR_IF(ctx->isBufferTargetMapped(readtarget), GL_INVALID_OPERATION);
3336 SET_ERROR_IF(ctx->isBufferTargetMapped(writetarget), GL_INVALID_OPERATION);
3337 SET_ERROR_IF(readoffset < 0, GL_INVALID_VALUE);
3338 SET_ERROR_IF(writeoffset < 0, GL_INVALID_VALUE);
3339 SET_ERROR_IF(size < 0, GL_INVALID_VALUE);
3340 SET_ERROR_IF(
3341 ctx->getBufferData(readtarget) &&
3342 (readoffset + size > ctx->getBufferData(readtarget)->m_size),
3343 GL_INVALID_VALUE);
3344 SET_ERROR_IF(
3345 ctx->getBufferData(writetarget) &&
3346 (writeoffset + size > ctx->getBufferData(writetarget)->m_size),
3347 GL_INVALID_VALUE);
3348 SET_ERROR_IF(readtarget == writetarget &&
3349 !((writeoffset >= readoffset + size) ||
3350 (readoffset >= writeoffset + size)),
3351 GL_INVALID_VALUE);
3352
3353 ctx->m_glCopyBufferSubData_enc(self, readtarget, writetarget, readoffset, writeoffset, size);
3354}
3355
3356void GL2Encoder::s_glGetBufferParameteriv(void* self, GLenum target, GLenum pname, GLint* params) {
3357 GL2Encoder* ctx = (GL2Encoder*)self;
3358
3359 SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM);
3360 SET_ERROR_IF(
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08003361 target != GL_ARRAY_BUFFER &&
3362 target != GL_ELEMENT_ARRAY_BUFFER &&
3363 target != GL_COPY_READ_BUFFER &&
3364 target != GL_COPY_WRITE_BUFFER &&
3365 target != GL_PIXEL_PACK_BUFFER &&
3366 target != GL_PIXEL_UNPACK_BUFFER &&
3367 target != GL_TRANSFORM_FEEDBACK_BUFFER &&
3368 target != GL_UNIFORM_BUFFER,
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003369 GL_INVALID_ENUM);
3370 SET_ERROR_IF(!GLESv2Validation::bufferParam(ctx, pname), GL_INVALID_ENUM);
3371 SET_ERROR_IF(!ctx->boundBuffer(target), GL_INVALID_OPERATION);
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08003372 SET_ERROR_IF(pname != GL_BUFFER_ACCESS_FLAGS &&
3373 pname != GL_BUFFER_MAPPED &&
3374 pname != GL_BUFFER_SIZE &&
3375 pname != GL_BUFFER_USAGE &&
3376 pname != GL_BUFFER_MAP_LENGTH &&
3377 pname != GL_BUFFER_MAP_OFFSET,
3378 GL_INVALID_ENUM);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003379
3380 if (!params) return;
3381
3382 BufferData* buf = ctx->getBufferData(target);
3383
3384 switch (pname) {
3385 case GL_BUFFER_ACCESS_FLAGS:
3386 *params = buf ? buf->m_mappedAccess : 0;
3387 break;
3388 case GL_BUFFER_MAPPED:
3389 *params = buf ? (buf->m_mapped ? GL_TRUE : GL_FALSE) : GL_FALSE;
3390 break;
3391 case GL_BUFFER_SIZE:
3392 *params = buf ? buf->m_size : 0;
3393 break;
3394 case GL_BUFFER_USAGE:
3395 *params = buf ? buf->m_usage : GL_STATIC_DRAW;
3396 break;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08003397 case GL_BUFFER_MAP_LENGTH:
3398 *params = buf ? buf->m_mappedLength : 0;
3399 break;
3400 case GL_BUFFER_MAP_OFFSET:
3401 *params = buf ? buf->m_mappedOffset : 0;
3402 break;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003403 default:
3404 break;
3405 }
3406}
3407
3408void GL2Encoder::s_glGetBufferParameteri64v(void* self, GLenum target, GLenum pname, GLint64* params) {
3409 GL2Encoder* ctx = (GL2Encoder*)self;
3410
3411 SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM);
3412 SET_ERROR_IF(
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08003413 target != GL_ARRAY_BUFFER &&
3414 target != GL_ELEMENT_ARRAY_BUFFER &&
3415 target != GL_COPY_READ_BUFFER &&
3416 target != GL_COPY_WRITE_BUFFER &&
3417 target != GL_PIXEL_PACK_BUFFER &&
3418 target != GL_PIXEL_UNPACK_BUFFER &&
3419 target != GL_TRANSFORM_FEEDBACK_BUFFER &&
3420 target != GL_UNIFORM_BUFFER,
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003421 GL_INVALID_ENUM);
3422 SET_ERROR_IF(!GLESv2Validation::bufferParam(ctx, pname), GL_INVALID_ENUM);
3423 SET_ERROR_IF(!ctx->boundBuffer(target), GL_INVALID_OPERATION);
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08003424 SET_ERROR_IF(pname != GL_BUFFER_ACCESS_FLAGS &&
3425 pname != GL_BUFFER_MAPPED &&
3426 pname != GL_BUFFER_SIZE &&
3427 pname != GL_BUFFER_USAGE &&
3428 pname != GL_BUFFER_MAP_LENGTH &&
3429 pname != GL_BUFFER_MAP_OFFSET,
3430 GL_INVALID_ENUM);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003431
3432 if (!params) return;
3433
3434 BufferData* buf = ctx->getBufferData(target);
3435
3436 switch (pname) {
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08003437 case GL_BUFFER_ACCESS_FLAGS:
3438 *params = buf ? buf->m_mappedAccess : 0;
3439 break;
3440 case GL_BUFFER_MAPPED:
3441 *params = buf ? (buf->m_mapped ? GL_TRUE : GL_FALSE) : GL_FALSE;
3442 break;
3443 case GL_BUFFER_SIZE:
3444 *params = buf ? buf->m_size : 0;
3445 break;
3446 case GL_BUFFER_USAGE:
3447 *params = buf ? buf->m_usage : GL_STATIC_DRAW;
3448 break;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003449 case GL_BUFFER_MAP_LENGTH:
3450 *params = buf ? buf->m_mappedLength : 0;
3451 break;
3452 case GL_BUFFER_MAP_OFFSET:
3453 *params = buf ? buf->m_mappedOffset : 0;
3454 break;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003455 default:
3456 break;
3457 }
3458}
3459
3460void GL2Encoder::s_glGetBufferPointerv(void* self, GLenum target, GLenum pname, GLvoid** params) {
3461 GL2Encoder* ctx = (GL2Encoder*)self;
3462 SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM);
3463 SET_ERROR_IF(
3464 target == GL_ATOMIC_COUNTER_BUFFER ||
3465 target == GL_DISPATCH_INDIRECT_BUFFER ||
3466 target == GL_DRAW_INDIRECT_BUFFER ||
3467 target == GL_SHADER_STORAGE_BUFFER,
3468 GL_INVALID_ENUM);
3469 SET_ERROR_IF(pname != GL_BUFFER_MAP_POINTER, GL_INVALID_ENUM);
3470 SET_ERROR_IF(!ctx->boundBuffer(target), GL_INVALID_OPERATION);
3471 if (!params) return;
3472
3473 BufferData* buf = ctx->getBufferData(target);
3474
3475 if (!buf || !buf->m_mapped) { *params = NULL; return; }
3476
3477 *params = (GLvoid*)((char*)buf->m_fixedBuffer.ptr() + buf->m_mappedOffset);
3478}
3479
3480static const char* const kNameDelimiter = ";";
3481
3482static std::string packVarNames(GLsizei count, const char** names, GLint* err_out) {
3483
3484#define VALIDATE(cond, err) if (cond) { *err_out = err; return packed; } \
3485
3486 std::string packed;
3487 // validate the array of char[]'s
3488 const char* currName;
3489 for (GLsizei i = 0; i < count; i++) {
3490 currName = names[i];
3491 VALIDATE(!currName, GL_INVALID_OPERATION);
3492 // check if has reasonable size
3493 size_t len = strlen(currName);
3494 VALIDATE(!len, GL_INVALID_OPERATION);
3495 // check for our delimiter, which if present
3496 // in the name, means an invalid name anyway.
3497 VALIDATE(strstr(currName, kNameDelimiter),
3498 GL_INVALID_OPERATION);
3499 packed += currName;
3500 packed += ";";
3501 }
3502
3503 *err_out = GL_NO_ERROR;
3504 return packed;
3505}
3506
3507void GL2Encoder::s_glGetUniformIndices(void* self, GLuint program, GLsizei uniformCount, const GLchar ** uniformNames, GLuint* uniformIndices) {
3508 GL2Encoder* ctx = (GL2Encoder*)self;
3509
3510 if (!uniformCount) return;
3511
3512 GLint err = GL_NO_ERROR;
3513 std::string packed = packVarNames(uniformCount, (const char**)uniformNames, &err);
3514 SET_ERROR_IF(err != GL_NO_ERROR, GL_INVALID_OPERATION);
3515
3516 bool needLocationWAR = ctx->m_shared->needUniformLocationWAR(program);
3517 std::vector<int> arrIndices;
3518 for (size_t i = 0; i < uniformCount; i++) {
3519 int err;
3520 arrIndices.push_back(sArrIndexOfUniformExpr(uniformNames[i], &err));
3521 if (err) {
3522 ALOGE("%s: invalid uniform name %s!", __FUNCTION__, uniformNames[i]);
3523 return;
3524 }
3525 }
3526
3527 ctx->glGetUniformIndicesAEMU(ctx, program, uniformCount, (const GLchar*)&packed[0], packed.size() + 1, uniformIndices);
3528
3529 for (int i = 0; i < uniformCount; i++) {
3530 if (uniformIndices[i] >= 0 && needLocationWAR) {
3531 uniformIndices[i] =
3532 ctx->m_shared->locationWARHostToApp(program, uniformIndices[i], arrIndices[i]);
3533 }
3534 }
3535}
3536
3537void GL2Encoder::s_glUniform1ui(void* self, GLint location, GLuint v0) {
3538 GL2Encoder *ctx = (GL2Encoder*)self;
3539 GLClientState* state = ctx->m_state;
3540 GLSharedGroupPtr shared = ctx->m_shared;
3541
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08003542 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003543 ctx->m_glUniform1ui_enc(self, hostLoc, v0);
3544
3545 GLenum target;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08003546 if (shared->setSamplerUniform(state->currentShaderProgram(), location, v0, &target)) {
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003547 GLenum origActiveTexture = state->getActiveTextureUnit();
3548 if (ctx->updateHostTexture2DBinding(GL_TEXTURE0 + v0, target)) {
3549 ctx->m_glActiveTexture_enc(self, origActiveTexture);
3550 }
3551 state->setActiveTextureUnit(origActiveTexture);
3552 }
3553}
3554
3555void GL2Encoder::s_glUniform2ui(void* self, GLint location, GLuint v0, GLuint v1) {
3556 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08003557 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003558 ctx->m_glUniform2ui_enc(self, hostLoc, v0, v1);
3559}
3560
3561void GL2Encoder::s_glUniform3ui(void* self, GLint location, GLuint v0, GLuint v1, GLuint v2) {
3562 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08003563 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003564 ctx->m_glUniform3ui_enc(self, hostLoc, v0, v1, v2);
3565}
3566
3567void GL2Encoder::s_glUniform4ui(void* self, GLint location, GLint v0, GLuint v1, GLuint v2, GLuint v3) {
3568 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08003569 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003570 ctx->m_glUniform4ui_enc(self, hostLoc, v0, v1, v2, v3);
3571}
3572
3573void GL2Encoder::s_glUniform1uiv(void* self, GLint location, GLsizei count, const GLuint *value) {
3574 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08003575 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003576 ctx->m_glUniform1uiv_enc(self, hostLoc, count, value);
3577}
3578
3579void GL2Encoder::s_glUniform2uiv(void* self, GLint location, GLsizei count, const GLuint *value) {
3580 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08003581 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003582 ctx->m_glUniform2uiv_enc(self, hostLoc, count, value);
3583}
3584
3585void GL2Encoder::s_glUniform3uiv(void* self, GLint location, GLsizei count, const GLuint *value) {
3586 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08003587 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003588 ctx->m_glUniform3uiv_enc(self, hostLoc, count, value);
3589}
3590
3591void GL2Encoder::s_glUniform4uiv(void* self, GLint location, GLsizei count, const GLuint *value) {
3592 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08003593 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003594 ctx->m_glUniform4uiv_enc(self, hostLoc, count, value);
3595}
3596
3597void GL2Encoder::s_glUniformMatrix2x3fv(void* self, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
3598 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08003599 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003600 ctx->m_glUniformMatrix2x3fv_enc(self, hostLoc, count, transpose, value);
3601}
3602
3603void GL2Encoder::s_glUniformMatrix3x2fv(void* self, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
3604 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08003605 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003606 ctx->m_glUniformMatrix3x2fv_enc(self, hostLoc, count, transpose, value);
3607}
3608
3609void GL2Encoder::s_glUniformMatrix2x4fv(void* self, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
3610 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08003611 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003612 ctx->m_glUniformMatrix2x4fv_enc(self, hostLoc, count, transpose, value);
3613}
3614
3615void GL2Encoder::s_glUniformMatrix4x2fv(void* self, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
3616 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08003617 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003618 ctx->m_glUniformMatrix4x2fv_enc(self, hostLoc, count, transpose, value);
3619}
3620
3621void GL2Encoder::s_glUniformMatrix3x4fv(void* self, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
3622 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08003623 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003624 ctx->m_glUniformMatrix3x4fv_enc(self, hostLoc, count, transpose, value);
3625}
3626
3627void GL2Encoder::s_glUniformMatrix4x3fv(void* self, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
3628 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08003629 GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003630 ctx->m_glUniformMatrix4x3fv_enc(self, hostLoc, count, transpose, value);
3631}
3632
3633void GL2Encoder::s_glGetUniformuiv(void* self, GLuint program, GLint location, GLuint* params) {
3634 GL2Encoder *ctx = (GL2Encoder*)self;
3635 SET_ERROR_IF(!ctx->m_shared->isShaderOrProgramObject(program), GL_INVALID_VALUE);
3636 SET_ERROR_IF(!ctx->m_shared->isProgram(program), GL_INVALID_OPERATION);
3637 SET_ERROR_IF(!ctx->m_shared->isProgramInitialized(program), GL_INVALID_OPERATION);
3638 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
3639 SET_ERROR_IF(ctx->m_shared->getProgramUniformType(program,hostLoc)==0, GL_INVALID_OPERATION);
3640 ctx->m_glGetUniformuiv_enc(self, program, hostLoc, params);
3641}
3642
3643void GL2Encoder::s_glGetActiveUniformBlockiv(void* self, GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params) {
3644 GL2Encoder* ctx = (GL2Encoder*)self;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003645
3646 // refresh client state's # active uniforms in this block
3647 if (pname == GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES) {
3648 // TODO if worth it: cache uniform count and other params,
3649 // invalidate on program relinking.
3650 GLint numActiveUniforms;
3651 ctx->m_glGetActiveUniformBlockiv_enc(ctx,
3652 program, uniformBlockIndex,
3653 GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS,
3654 &numActiveUniforms);
3655 ctx->m_state->setNumActiveUniformsInUniformBlock(
3656 program, uniformBlockIndex, numActiveUniforms);
3657 }
3658
3659 ctx->m_glGetActiveUniformBlockiv_enc(ctx,
3660 program, uniformBlockIndex,
3661 pname, params);
3662}
3663
3664void GL2Encoder::s_glGetVertexAttribIiv(void* self, GLuint index, GLenum pname, GLint* params) {
3665 GL2Encoder *ctx = (GL2Encoder *)self;
3666 assert(ctx->m_state);
3667 GLint maxIndex;
3668 ctx->glGetIntegerv(self, GL_MAX_VERTEX_ATTRIBS, &maxIndex);
3669 SET_ERROR_IF(!(index < maxIndex), GL_INVALID_VALUE);
3670
3671 if (!ctx->m_state->getVertexAttribParameter<GLint>(index, pname, params)) {
3672 ctx->m_glGetVertexAttribIiv_enc(self, index, pname, params);
3673 }
3674}
3675
3676void GL2Encoder::s_glGetVertexAttribIuiv(void* self, GLuint index, GLenum pname, GLuint* params) {
3677 GL2Encoder *ctx = (GL2Encoder *)self;
3678 assert(ctx->m_state);
3679 GLint maxIndex;
3680 ctx->glGetIntegerv(self, GL_MAX_VERTEX_ATTRIBS, &maxIndex);
3681 SET_ERROR_IF(!(index < maxIndex), GL_INVALID_VALUE);
3682
3683 if (!ctx->m_state->getVertexAttribParameter<GLuint>(index, pname, params)) {
3684 ctx->m_glGetVertexAttribIuiv_enc(self, index, pname, params);
3685 }
3686}
3687
3688void GL2Encoder::s_glVertexAttribIPointer(void* self, GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid* pointer) {
3689 GL2Encoder *ctx = (GL2Encoder *)self;
3690 assert(ctx->m_state != NULL);
Lingfeng Yang07289902017-01-27 12:26:19 -08003691 VALIDATE_VERTEX_ATTRIB_INDEX(index);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003692 SET_ERROR_IF((size < 1 || size > 4), GL_INVALID_VALUE);
3693 SET_ERROR_IF(
3694 !(type == GL_BYTE ||
3695 type == GL_UNSIGNED_BYTE ||
3696 type == GL_SHORT ||
3697 type == GL_UNSIGNED_SHORT ||
3698 type == GL_INT ||
3699 type == GL_UNSIGNED_INT),
3700 GL_INVALID_ENUM);
3701 SET_ERROR_IF(stride < 0, GL_INVALID_VALUE);
3702
3703 ctx->m_state->setVertexAttribBinding(index, index);
3704 ctx->m_state->setVertexAttribFormat(index, size, type, false, 0, true);
3705 GLsizei effectiveStride = stride;
3706 if (stride == 0) {
Lingfeng Yang554a5152019-02-21 20:20:48 -08003707 effectiveStride = glSizeof(type) * size;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003708 }
3709 ctx->m_state->bindIndexedBuffer(0, index, ctx->m_state->currentArrayVbo(), (uintptr_t)pointer, 0, stride, effectiveStride);
3710
3711 if (ctx->m_state->currentArrayVbo() != 0) {
3712 ctx->glVertexAttribIPointerOffsetAEMU(ctx, index, size, type, stride, (uintptr_t)pointer);
3713 } else {
3714 SET_ERROR_IF(ctx->m_state->currentVertexArrayObject() != 0 && pointer, GL_INVALID_OPERATION);
3715 // wait for client-array handler
3716 }
3717}
3718
3719void GL2Encoder::s_glVertexAttribDivisor(void* self, GLuint index, GLuint divisor) {
3720 GL2Encoder *ctx = (GL2Encoder *)self;
3721 assert(ctx->m_state != NULL);
Lingfeng Yang07289902017-01-27 12:26:19 -08003722 VALIDATE_VERTEX_ATTRIB_INDEX(index);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003723 ctx->m_state->setVertexAttribBinding(index, index);
3724 ctx->m_state->setVertexBindingDivisor(index, divisor);
3725 ctx->m_glVertexAttribDivisor_enc(ctx, index, divisor);
3726}
3727
3728void GL2Encoder::s_glRenderbufferStorageMultisample(void* self,
3729 GLenum target, GLsizei samples, GLenum internalformat,
3730 GLsizei width, GLsizei height) {
3731 GL2Encoder *ctx = (GL2Encoder *)self;
3732 GLClientState* state = ctx->m_state;
3733
3734 SET_ERROR_IF(target != GL_RENDERBUFFER, GL_INVALID_ENUM);
3735 SET_ERROR_IF(!GLESv2Validation::rboFormat(ctx, internalformat), GL_INVALID_ENUM);
3736
3737 GLint max_samples;
3738 ctx->s_glGetInternalformativ(ctx, target, internalformat, GL_SAMPLES, 1, &max_samples);
3739 SET_ERROR_IF(samples > max_samples, GL_INVALID_OPERATION);
3740
3741 state->setBoundRenderbufferFormat(internalformat);
3742 state->setBoundRenderbufferSamples(samples);
3743 ctx->m_glRenderbufferStorageMultisample_enc(
3744 self, target, samples, internalformat, width, height);
3745}
3746
3747void GL2Encoder::s_glDrawBuffers(void* self, GLsizei n, const GLenum* bufs) {
3748 GL2Encoder* ctx = (GL2Encoder*)self;
3749 SET_ERROR_IF(!ctx->m_state->boundFramebuffer(GL_DRAW_FRAMEBUFFER) && n > 1, GL_INVALID_OPERATION);
3750 SET_ERROR_IF(n < 0 || n > ctx->m_state->getMaxDrawBuffers(), GL_INVALID_VALUE);
3751 for (int i = 0; i < n; i++) {
3752 SET_ERROR_IF(
3753 bufs[i] != GL_NONE &&
3754 bufs[i] != GL_BACK &&
3755 glUtilsColorAttachmentIndex(bufs[i]) == -1,
3756 GL_INVALID_ENUM);
3757 SET_ERROR_IF(
3758 !ctx->m_state->boundFramebuffer(GL_DRAW_FRAMEBUFFER) &&
3759 glUtilsColorAttachmentIndex(bufs[i]) != -1,
3760 GL_INVALID_OPERATION);
3761 SET_ERROR_IF(
3762 ctx->m_state->boundFramebuffer(GL_DRAW_FRAMEBUFFER) &&
3763 ((glUtilsColorAttachmentIndex(bufs[i]) != -1 &&
3764 glUtilsColorAttachmentIndex(bufs[i]) != i) ||
3765 (glUtilsColorAttachmentIndex(bufs[i]) == -1 &&
3766 bufs[i] != GL_NONE)),
3767 GL_INVALID_OPERATION);
3768 }
3769
3770 ctx->m_glDrawBuffers_enc(ctx, n, bufs);
3771}
3772
3773void GL2Encoder::s_glReadBuffer(void* self, GLenum src) {
3774 GL2Encoder* ctx = (GL2Encoder*)self;
3775
3776 SET_ERROR_IF(
3777 glUtilsColorAttachmentIndex(src) != -1 &&
3778 (glUtilsColorAttachmentIndex(src) >=
3779 ctx->m_state->getMaxColorAttachments()),
3780 GL_INVALID_OPERATION);
3781 SET_ERROR_IF(
3782 src != GL_NONE &&
3783 src != GL_BACK &&
3784 src > GL_COLOR_ATTACHMENT0 &&
3785 src < GL_DEPTH_ATTACHMENT &&
3786 (src - GL_COLOR_ATTACHMENT0) >
3787 ctx->m_state->getMaxColorAttachments(),
3788 GL_INVALID_OPERATION);
3789 SET_ERROR_IF(
3790 src != GL_NONE &&
3791 src != GL_BACK &&
3792 glUtilsColorAttachmentIndex(src) == -1,
3793 GL_INVALID_ENUM);
3794 SET_ERROR_IF(
3795 !ctx->m_state->boundFramebuffer(GL_READ_FRAMEBUFFER) &&
3796 src != GL_NONE &&
3797 src != GL_BACK,
3798 GL_INVALID_OPERATION);
3799 SET_ERROR_IF(
3800 ctx->m_state->boundFramebuffer(GL_READ_FRAMEBUFFER) &&
3801 src != GL_NONE &&
3802 glUtilsColorAttachmentIndex(src) == -1,
3803 GL_INVALID_OPERATION);
3804
3805 ctx->m_glReadBuffer_enc(ctx, src);
3806}
3807
3808void GL2Encoder::s_glFramebufferTextureLayer(void* self, GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) {
3809 GL2Encoder* ctx = (GL2Encoder*)self;
3810 GLClientState* state = ctx->m_state;
3811
3812 SET_ERROR_IF(!GLESv2Validation::framebufferTarget(ctx, target), GL_INVALID_ENUM);
3813 SET_ERROR_IF(!GLESv2Validation::framebufferAttachment(ctx, attachment), GL_INVALID_ENUM);
3814 GLenum lastBoundTarget = state->queryTexLastBoundTarget(texture);
3815 SET_ERROR_IF(lastBoundTarget != GL_TEXTURE_2D_ARRAY &&
3816 lastBoundTarget != GL_TEXTURE_3D,
3817 GL_INVALID_OPERATION);
3818 state->attachTextureObject(target, attachment, texture);
3819
3820 GLint max3DTextureSize;
3821 ctx->glGetIntegerv(ctx, GL_MAX_3D_TEXTURE_SIZE, &max3DTextureSize);
3822 SET_ERROR_IF(
3823 layer >= max3DTextureSize,
3824 GL_INVALID_VALUE);
3825
3826 ctx->m_glFramebufferTextureLayer_enc(self, target, attachment, texture, level, layer);
3827}
3828
3829void GL2Encoder::s_glTexStorage2D(void* self, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) {
3830 GL2Encoder* ctx = (GL2Encoder*)self;
3831 GLClientState* state = ctx->m_state;
3832
3833 SET_ERROR_IF(
3834 target != GL_TEXTURE_2D &&
3835 target != GL_TEXTURE_CUBE_MAP,
3836 GL_INVALID_ENUM);
3837 SET_ERROR_IF(!GLESv2Validation::pixelInternalFormat(internalformat), GL_INVALID_ENUM);
3838 SET_ERROR_IF(!state->getBoundTexture(target), GL_INVALID_OPERATION);
3839 SET_ERROR_IF(levels < 1 || width < 1 || height < 1, GL_INVALID_VALUE);
3840 SET_ERROR_IF(levels > ilog2((uint32_t)std::max(width, height)) + 1,
3841 GL_INVALID_OPERATION);
3842 SET_ERROR_IF(state->isBoundTextureImmutableFormat(target), GL_INVALID_OPERATION);
3843
3844 state->setBoundTextureInternalFormat(target, internalformat);
3845 state->setBoundTextureDims(target, -1, width, height, 1);
3846 state->setBoundTextureImmutableFormat(target);
Lingfeng Yanga9fff6a2018-03-02 13:42:51 -08003847
3848 if (target == GL_TEXTURE_2D) {
3849 ctx->override2DTextureTarget(target);
3850 }
3851
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003852 ctx->m_glTexStorage2D_enc(ctx, target, levels, internalformat, width, height);
Lingfeng Yanga9fff6a2018-03-02 13:42:51 -08003853
3854 if (target == GL_TEXTURE_2D) {
3855 ctx->restore2DTextureTarget(target);
3856 }
Lingfeng Yang46153ab2017-01-09 13:37:22 -08003857}
3858
3859void GL2Encoder::s_glTransformFeedbackVaryings(void* self, GLuint program, GLsizei count, const char** varyings, GLenum bufferMode) {
3860 GL2Encoder* ctx = (GL2Encoder*)self;
3861
3862 SET_ERROR_IF(!ctx->m_shared->isProgram(program), GL_INVALID_VALUE);
3863
3864 GLint maxCount = 0;
3865 ctx->glGetIntegerv(ctx, GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, &maxCount);
3866
3867 SET_ERROR_IF(
3868 bufferMode == GL_SEPARATE_ATTRIBS &&
3869 maxCount < count,
3870 GL_INVALID_VALUE);
3871 SET_ERROR_IF(
3872 bufferMode != GL_INTERLEAVED_ATTRIBS &&
3873 bufferMode != GL_SEPARATE_ATTRIBS,
3874 GL_INVALID_ENUM);
3875
3876 if (!count) return;
3877
3878 GLint err = GL_NO_ERROR;
3879 std::string packed = packVarNames(count, varyings, &err);
3880 SET_ERROR_IF(err != GL_NO_ERROR, GL_INVALID_OPERATION);
3881
3882 ctx->glTransformFeedbackVaryingsAEMU(ctx, program, count, (const char*)&packed[0], packed.size() + 1, bufferMode);
3883}
3884
3885void GL2Encoder::s_glBeginTransformFeedback(void* self, GLenum primitiveMode) {
3886 GL2Encoder* ctx = (GL2Encoder*)self;
3887 GLClientState* state = ctx->m_state;
3888 ctx->m_glBeginTransformFeedback_enc(ctx, primitiveMode);
3889 state->setTransformFeedbackActiveUnpaused(true);
3890}
3891
3892void GL2Encoder::s_glEndTransformFeedback(void* self) {
3893 GL2Encoder* ctx = (GL2Encoder*)self;
3894 GLClientState* state = ctx->m_state;
3895 ctx->m_glEndTransformFeedback_enc(ctx);
3896 state->setTransformFeedbackActiveUnpaused(false);
3897}
3898
3899void GL2Encoder::s_glPauseTransformFeedback(void* self) {
3900 GL2Encoder* ctx = (GL2Encoder*)self;
3901 GLClientState* state = ctx->m_state;
3902 ctx->m_glPauseTransformFeedback_enc(ctx);
3903 state->setTransformFeedbackActiveUnpaused(false);
3904}
3905
3906void GL2Encoder::s_glResumeTransformFeedback(void* self) {
3907 GL2Encoder* ctx = (GL2Encoder*)self;
3908 GLClientState* state = ctx->m_state;
3909 ctx->m_glResumeTransformFeedback_enc(ctx);
3910 state->setTransformFeedbackActiveUnpaused(true);
3911}
3912
3913void GL2Encoder::s_glTexImage3D(void* self, GLenum target, GLint level, GLint internalFormat,
3914 GLsizei width, GLsizei height, GLsizei depth,
3915 GLint border, GLenum format, GLenum type, const GLvoid* data) {
3916 GL2Encoder* ctx = (GL2Encoder*)self;
3917 GLClientState* state = ctx->m_state;
3918
3919 SET_ERROR_IF(target != GL_TEXTURE_3D &&
3920 target != GL_TEXTURE_2D_ARRAY,
3921 GL_INVALID_ENUM);
3922 SET_ERROR_IF(!GLESv2Validation::pixelType(ctx, type), GL_INVALID_ENUM);
3923 SET_ERROR_IF(!GLESv2Validation::pixelFormat(ctx, format), GL_INVALID_ENUM);
3924
3925 // If unpack buffer is nonzero, verify unmapped state.
3926 SET_ERROR_IF(ctx->isBufferTargetMapped(GL_PIXEL_UNPACK_BUFFER), GL_INVALID_OPERATION);
3927
3928 GLint max_texture_size;
3929 GLint max_3d_texture_size;
3930 ctx->glGetIntegerv(ctx, GL_MAX_TEXTURE_SIZE, &max_texture_size);
3931 ctx->glGetIntegerv(ctx, GL_MAX_3D_TEXTURE_SIZE, &max_3d_texture_size);
3932 SET_ERROR_IF(level < 0, GL_INVALID_VALUE);
3933 SET_ERROR_IF(level > ilog2(max_texture_size), GL_INVALID_VALUE);
3934 SET_ERROR_IF(level > ilog2(max_3d_texture_size), GL_INVALID_VALUE);
3935
3936 SET_ERROR_IF(width < 0 || height < 0 || depth < 0, GL_INVALID_VALUE);
3937 SET_ERROR_IF(width > GL_MAX_TEXTURE_SIZE, GL_INVALID_VALUE);
3938 SET_ERROR_IF(height > GL_MAX_TEXTURE_SIZE, GL_INVALID_VALUE);
3939 SET_ERROR_IF(depth > GL_MAX_TEXTURE_SIZE, GL_INVALID_VALUE);
3940 SET_ERROR_IF(width > GL_MAX_3D_TEXTURE_SIZE, GL_INVALID_VALUE);
3941 SET_ERROR_IF(height > GL_MAX_3D_TEXTURE_SIZE, GL_INVALID_VALUE);
3942 SET_ERROR_IF(depth > GL_MAX_3D_TEXTURE_SIZE, GL_INVALID_VALUE);
3943 SET_ERROR_IF(border != 0, GL_INVALID_VALUE);
3944 // If unpack buffer is nonzero, verify buffer data fits and is evenly divisible by the type.
3945 SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
3946 ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
3947 (ctx->m_state->pboNeededDataSize(width, height, depth, format, type, 0) >
3948 ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size),
3949 GL_INVALID_OPERATION);
3950 SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
3951 ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
3952 (ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size %
3953 glSizeof(type)),
3954 GL_INVALID_OPERATION);
3955 SET_ERROR_IF(state->isBoundTextureImmutableFormat(target), GL_INVALID_OPERATION);
3956
3957 state->setBoundTextureInternalFormat(target, internalFormat);
3958 state->setBoundTextureFormat(target, format);
3959 state->setBoundTextureType(target, type);
3960 state->setBoundTextureDims(target, level, width, height, depth);
3961
3962 if (ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER)) {
3963 ctx->glTexImage3DOffsetAEMU(
3964 ctx, target, level, internalFormat,
3965 width, height, depth,
3966 border, format, type, (uintptr_t)data);
3967 } else {
3968 ctx->m_glTexImage3D_enc(ctx,
3969 target, level, internalFormat,
3970 width, height, depth,
3971 border, format, type, data);
3972 }
3973}
3974
3975void 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) {
3976 GL2Encoder* ctx = (GL2Encoder*)self;
3977 GLClientState* state = ctx->m_state;
3978
3979 SET_ERROR_IF(target != GL_TEXTURE_3D &&
3980 target != GL_TEXTURE_2D_ARRAY,
3981 GL_INVALID_ENUM);
3982 SET_ERROR_IF(!GLESv2Validation::pixelType(ctx, type), GL_INVALID_ENUM);
3983 SET_ERROR_IF(!GLESv2Validation::pixelFormat(ctx, format), GL_INVALID_ENUM);
3984 // If unpack buffer is nonzero, verify unmapped state.
3985 SET_ERROR_IF(ctx->isBufferTargetMapped(GL_PIXEL_UNPACK_BUFFER), GL_INVALID_OPERATION);
3986 GLint max_texture_size;
3987 GLint max_3d_texture_size;
3988 ctx->glGetIntegerv(ctx, GL_MAX_TEXTURE_SIZE, &max_texture_size);
3989 ctx->glGetIntegerv(ctx, GL_MAX_3D_TEXTURE_SIZE, &max_3d_texture_size);
3990 SET_ERROR_IF(level < 0, GL_INVALID_VALUE);
3991 SET_ERROR_IF(level > ilog2(max_texture_size), GL_INVALID_VALUE);
3992 SET_ERROR_IF(level > ilog2(max_3d_texture_size), GL_INVALID_VALUE);
3993 SET_ERROR_IF(width < 0 || height < 0 || depth < 0, GL_INVALID_VALUE);
3994 SET_ERROR_IF(xoffset < 0 || yoffset < 0 || zoffset < 0, GL_INVALID_VALUE);
3995 GLuint tex = state->getBoundTexture(target);
3996 GLsizei neededWidth = xoffset + width;
3997 GLsizei neededHeight = yoffset + height;
3998 GLsizei neededDepth = zoffset + depth;
3999
4000 SET_ERROR_IF(tex &&
4001 (neededWidth > state->queryTexWidth(level, tex) ||
4002 neededHeight > state->queryTexHeight(level, tex) ||
4003 neededDepth > state->queryTexDepth(level, tex)),
4004 GL_INVALID_VALUE);
4005 // If unpack buffer is nonzero, verify buffer data fits and is evenly divisible by the type.
4006 SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
4007 ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
4008 (ctx->m_state->pboNeededDataSize(width, height, depth, format, type, 0) >
4009 ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size),
4010 GL_INVALID_OPERATION);
4011 SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
4012 ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
4013 (ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size %
4014 glSizeof(type)),
4015 GL_INVALID_OPERATION);
4016 SET_ERROR_IF(!ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) && !data, GL_INVALID_OPERATION);
4017 SET_ERROR_IF(xoffset < 0 || yoffset < 0 || zoffset < 0, GL_INVALID_VALUE);
4018
4019 if (ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER)) {
4020 ctx->glTexSubImage3DOffsetAEMU(ctx,
4021 target, level,
4022 xoffset, yoffset, zoffset,
4023 width, height, depth,
4024 format, type, (uintptr_t)data);
4025 } else {
4026 ctx->m_glTexSubImage3D_enc(ctx,
4027 target, level,
4028 xoffset, yoffset, zoffset,
4029 width, height, depth,
4030 format, type, data);
4031 }
4032}
4033
4034void GL2Encoder::s_glCompressedTexImage3D(void* self, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data) {
4035 GL2Encoder* ctx = (GL2Encoder*)self;
4036 GLClientState* state = ctx->m_state;
4037
4038 // Filter compressed formats support.
4039 SET_ERROR_IF(!GLESv2Validation::supportedCompressedFormat(ctx, internalformat), GL_INVALID_ENUM);
4040 // If unpack buffer is nonzero, verify unmapped state.
4041 SET_ERROR_IF(ctx->isBufferTargetMapped(GL_PIXEL_UNPACK_BUFFER), GL_INVALID_OPERATION);
4042 SET_ERROR_IF(width < 0 || height < 0 || depth < 0, GL_INVALID_VALUE);
4043 SET_ERROR_IF(border, GL_INVALID_VALUE);
4044 // If unpack buffer is nonzero, verify buffer data fits.
4045 SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
4046 ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
4047 (imageSize > ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size),
4048 GL_INVALID_OPERATION);
4049 // TODO: Fix:
4050 // If |imageSize| is too small for compressed dimensions.
4051 // SET_ERROR_IF(GLESv2Validation::compressedTexImageSize(internalformat, width, height, depth) > imageSize, GL_INVALID_VALUE);
4052 state->setBoundTextureInternalFormat(target, (GLint)internalformat);
4053 state->setBoundTextureDims(target, level, width, height, depth);
4054
4055 if (ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER)) {
4056 ctx->glCompressedTexImage3DOffsetAEMU(
4057 ctx, target, level, internalformat,
4058 width, height, depth, border,
4059 imageSize, (uintptr_t)data);
4060 } else {
4061 ctx->m_glCompressedTexImage3D_enc(
4062 ctx, target, level, internalformat,
4063 width, height, depth, border,
4064 imageSize, data);
4065 }
4066}
4067
4068void 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) {
4069 GL2Encoder* ctx = (GL2Encoder*)self;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004070
4071 SET_ERROR_IF(!GLESv2Validation::textureTarget(ctx, target), GL_INVALID_ENUM);
4072 // If unpack buffer is nonzero, verify unmapped state.
4073 SET_ERROR_IF(ctx->isBufferTargetMapped(GL_PIXEL_UNPACK_BUFFER), GL_INVALID_OPERATION);
4074 SET_ERROR_IF(width < 0 || height < 0 || depth < 0, GL_INVALID_VALUE);
4075 // If unpack buffer is nonzero, verify buffer data fits.
4076 SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
4077 ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
4078 (imageSize > ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size),
4079 GL_INVALID_OPERATION);
4080 SET_ERROR_IF(xoffset < 0 || yoffset < 0 || zoffset < 0, GL_INVALID_VALUE);
4081
4082 if (ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER)) {
4083 ctx->glCompressedTexSubImage3DOffsetAEMU(
4084 ctx, target, level,
4085 xoffset, yoffset, zoffset,
4086 width, height, depth,
4087 format, imageSize, (uintptr_t)data);
4088 } else {
4089 ctx->m_glCompressedTexSubImage3D_enc(
4090 ctx, target, level,
4091 xoffset, yoffset, zoffset,
4092 width, height, depth,
4093 format, imageSize, data);
4094
4095 }
4096}
4097
4098void GL2Encoder::s_glTexStorage3D(void* self, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) {
4099 GL2Encoder* ctx = (GL2Encoder*)self;
4100 GLClientState* state = ctx->m_state;
4101 SET_ERROR_IF(target != GL_TEXTURE_3D &&
4102 target != GL_TEXTURE_2D_ARRAY,
4103 GL_INVALID_ENUM);
4104 SET_ERROR_IF(!GLESv2Validation::pixelInternalFormat(internalformat), GL_INVALID_ENUM);
4105 SET_ERROR_IF(!state->getBoundTexture(target), GL_INVALID_OPERATION);
4106 SET_ERROR_IF(levels < 1 || width < 1 || height < 1, GL_INVALID_VALUE);
4107 SET_ERROR_IF(target == GL_TEXTURE_3D && (levels > ilog2((uint32_t)std::max(width, std::max(height, depth))) + 1),
4108 GL_INVALID_OPERATION);
4109 SET_ERROR_IF(target == GL_TEXTURE_2D_ARRAY && (levels > ilog2((uint32_t)std::max(width, height)) + 1),
4110 GL_INVALID_OPERATION);
4111 SET_ERROR_IF(state->isBoundTextureImmutableFormat(target), GL_INVALID_OPERATION);
4112
4113 state->setBoundTextureInternalFormat(target, internalformat);
4114 state->setBoundTextureDims(target, -1, width, height, depth);
4115 state->setBoundTextureImmutableFormat(target);
4116 ctx->m_glTexStorage3D_enc(ctx, target, levels, internalformat, width, height, depth);
4117 state->setBoundTextureImmutableFormat(target);
4118}
4119
4120void GL2Encoder::s_glDrawArraysInstanced(void* self, GLenum mode, GLint first, GLsizei count, GLsizei primcount) {
4121 GL2Encoder *ctx = (GL2Encoder *)self;
4122 assert(ctx->m_state != NULL);
4123 SET_ERROR_IF(!isValidDrawMode(mode), GL_INVALID_ENUM);
4124 SET_ERROR_IF(count < 0, GL_INVALID_VALUE);
4125
4126 bool has_client_vertex_arrays = false;
4127 bool has_indirect_arrays = false;
4128 ctx->getVBOUsage(&has_client_vertex_arrays,
4129 &has_indirect_arrays);
4130
4131 if (has_client_vertex_arrays ||
4132 (!has_client_vertex_arrays &&
4133 !has_indirect_arrays)) {
4134 ctx->sendVertexAttributes(first, count, true, primcount);
4135 ctx->m_glDrawArraysInstanced_enc(ctx, mode, 0, count, primcount);
4136 } else {
4137 ctx->sendVertexAttributes(0, count, false, primcount);
4138 ctx->m_glDrawArraysInstanced_enc(ctx, mode, first, count, primcount);
4139 }
4140 ctx->m_stream->flush();
4141}
4142
4143void GL2Encoder::s_glDrawElementsInstanced(void* self, GLenum mode, GLsizei count, GLenum type, const void* indices, GLsizei primcount)
4144{
4145
4146 GL2Encoder *ctx = (GL2Encoder *)self;
4147 assert(ctx->m_state != NULL);
4148 SET_ERROR_IF(!isValidDrawMode(mode), GL_INVALID_ENUM);
4149 SET_ERROR_IF(count < 0, GL_INVALID_VALUE);
4150 SET_ERROR_IF(!(type == GL_UNSIGNED_BYTE || type == GL_UNSIGNED_SHORT || type == GL_UNSIGNED_INT), GL_INVALID_ENUM);
4151 SET_ERROR_IF(ctx->m_state->getTransformFeedbackActiveUnpaused(), GL_INVALID_OPERATION);
4152
4153 bool has_client_vertex_arrays = false;
4154 bool has_indirect_arrays = false;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004155 GLintptr offset = 0;
4156
4157 ctx->getVBOUsage(&has_client_vertex_arrays, &has_indirect_arrays);
4158
4159 if (!has_client_vertex_arrays && !has_indirect_arrays) {
4160 // ALOGW("glDrawElements: no vertex arrays / buffers bound to the command\n");
4161 GLenum status = ctx->m_glCheckFramebufferStatus_enc(self, GL_FRAMEBUFFER);
4162 SET_ERROR_IF(status != GL_FRAMEBUFFER_COMPLETE, GL_INVALID_FRAMEBUFFER_OPERATION);
4163 }
4164
4165 BufferData* buf = NULL;
4166 int minIndex = 0, maxIndex = 0;
4167
4168 // For validation/immediate index array purposes,
4169 // we need the min/max vertex index of the index array.
4170 // If the VBO != 0, this may not be the first time we have
4171 // used this particular index buffer. getBufferIndexRange
4172 // can more quickly get min/max vertex index by
4173 // caching previous results.
4174 if (ctx->m_state->currentIndexVbo() != 0) {
4175 buf = ctx->m_shared->getBufferData(ctx->m_state->currentIndexVbo());
4176 offset = (GLintptr)indices;
4177 indices = (void*)((GLintptr)buf->m_fixedBuffer.ptr() + (GLintptr)indices);
4178 ctx->getBufferIndexRange(buf,
4179 indices,
4180 type,
4181 (size_t)count,
4182 (size_t)offset,
4183 &minIndex, &maxIndex);
4184 } else {
4185 // In this case, the |indices| field holds a real
4186 // array, so calculate the indices now. They will
4187 // also be needed to know how much data to
4188 // transfer to host.
4189 ctx->calcIndexRange(indices,
4190 type,
4191 count,
4192 &minIndex,
4193 &maxIndex);
4194 }
4195
Lingfeng Yang26e629a2018-10-13 20:00:12 -07004196 if (count == 0) return;
4197
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004198 bool adjustIndices = true;
4199 if (ctx->m_state->currentIndexVbo() != 0) {
4200 if (!has_client_vertex_arrays) {
4201 ctx->sendVertexAttributes(0, maxIndex + 1, false, primcount);
Lingfeng Yang554a5152019-02-21 20:20:48 -08004202 ctx->doBindBufferEncodeCached(GL_ELEMENT_ARRAY_BUFFER, ctx->m_state->currentIndexVbo());
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004203 ctx->glDrawElementsInstancedOffsetAEMU(ctx, mode, count, type, offset, primcount);
4204 ctx->flushDrawCall();
4205 adjustIndices = false;
4206 } else {
Lingfeng Yang554a5152019-02-21 20:20:48 -08004207 ctx->doBindBufferEncodeCached(GL_ELEMENT_ARRAY_BUFFER, 0);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004208 }
4209 }
4210 if (adjustIndices) {
4211 void *adjustedIndices =
4212 ctx->recenterIndices(indices,
4213 type,
4214 count,
4215 minIndex);
4216
4217 if (has_indirect_arrays || 1) {
4218 ctx->sendVertexAttributes(minIndex, maxIndex - minIndex + 1, true, primcount);
4219 ctx->glDrawElementsInstancedDataAEMU(ctx, mode, count, type, adjustedIndices, primcount, count * glSizeof(type));
4220 ctx->m_stream->flush();
4221 // XXX - OPTIMIZATION (see the other else branch) should be implemented
4222 if(!has_indirect_arrays) {
4223 //ALOGD("unoptimized drawelements !!!\n");
4224 }
4225 } else {
4226 // we are all direct arrays and immidate mode index array -
4227 // rebuild the arrays and the index array;
4228 ALOGE("glDrawElements: direct index & direct buffer data - will be implemented in later versions;\n");
4229 }
4230 }
4231}
4232
4233void GL2Encoder::s_glDrawRangeElements(void* self, GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void* indices)
4234{
4235
4236 GL2Encoder *ctx = (GL2Encoder *)self;
4237 assert(ctx->m_state != NULL);
4238 SET_ERROR_IF(!isValidDrawMode(mode), GL_INVALID_ENUM);
4239 SET_ERROR_IF(end < start, GL_INVALID_VALUE);
4240 SET_ERROR_IF(count < 0, GL_INVALID_VALUE);
4241 SET_ERROR_IF(!(type == GL_UNSIGNED_BYTE || type == GL_UNSIGNED_SHORT || type == GL_UNSIGNED_INT), GL_INVALID_ENUM);
4242 SET_ERROR_IF(ctx->m_state->getTransformFeedbackActiveUnpaused(), GL_INVALID_OPERATION);
4243
4244 bool has_client_vertex_arrays = false;
4245 bool has_indirect_arrays = false;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004246 GLintptr offset = 0;
4247
4248 ctx->getVBOUsage(&has_client_vertex_arrays, &has_indirect_arrays);
4249
4250 if (!has_client_vertex_arrays && !has_indirect_arrays) {
4251 // ALOGW("glDrawElements: no vertex arrays / buffers bound to the command\n");
4252 GLenum status = ctx->m_glCheckFramebufferStatus_enc(self, GL_FRAMEBUFFER);
4253 SET_ERROR_IF(status != GL_FRAMEBUFFER_COMPLETE, GL_INVALID_FRAMEBUFFER_OPERATION);
4254 }
4255
4256 BufferData* buf = NULL;
4257 int minIndex = 0, maxIndex = 0;
4258
4259 // For validation/immediate index array purposes,
4260 // we need the min/max vertex index of the index array.
4261 // If the VBO != 0, this may not be the first time we have
4262 // used this particular index buffer. getBufferIndexRange
4263 // can more quickly get min/max vertex index by
4264 // caching previous results.
4265 if (ctx->m_state->currentIndexVbo() != 0) {
4266 buf = ctx->m_shared->getBufferData(ctx->m_state->currentIndexVbo());
Lingfeng Yang2c3a0da2019-03-07 20:43:53 -08004267 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 -08004268 offset = (GLintptr)indices;
Lingfeng Yang2c3a0da2019-03-07 20:43:53 -08004269 void* oldIndices = (void*)indices;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004270 indices = (void*)((GLintptr)buf->m_fixedBuffer.ptr() + (GLintptr)indices);
Lingfeng Yang2c3a0da2019-03-07 20:43:53 -08004271 ALOGV("%s: indices arg: %p buffer start: %p indices: %p\n", __func__,
4272 (void*)(uintptr_t)(oldIndices),
4273 buf->m_fixedBuffer.ptr(),
4274 indices);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004275 ctx->getBufferIndexRange(buf,
4276 indices,
4277 type,
4278 (size_t)count,
4279 (size_t)offset,
4280 &minIndex, &maxIndex);
4281 } else {
4282 // In this case, the |indices| field holds a real
4283 // array, so calculate the indices now. They will
4284 // also be needed to know how much data to
4285 // transfer to host.
4286 ctx->calcIndexRange(indices,
4287 type,
4288 count,
4289 &minIndex,
4290 &maxIndex);
4291 }
4292
Lingfeng Yang26e629a2018-10-13 20:00:12 -07004293 if (count == 0) return;
4294
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004295 bool adjustIndices = true;
4296 if (ctx->m_state->currentIndexVbo() != 0) {
4297 if (!has_client_vertex_arrays) {
4298 ctx->sendVertexAttributes(0, maxIndex + 1, false);
Lingfeng Yang554a5152019-02-21 20:20:48 -08004299 ctx->doBindBufferEncodeCached(GL_ELEMENT_ARRAY_BUFFER, ctx->m_state->currentIndexVbo());
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004300 ctx->glDrawElementsOffset(ctx, mode, count, type, offset);
4301 ctx->flushDrawCall();
4302 adjustIndices = false;
4303 } else {
Lingfeng Yang554a5152019-02-21 20:20:48 -08004304 ctx->doBindBufferEncodeCached(GL_ELEMENT_ARRAY_BUFFER, 0);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004305 }
4306 }
4307 if (adjustIndices) {
4308 void *adjustedIndices =
4309 ctx->recenterIndices(indices,
4310 type,
4311 count,
4312 minIndex);
4313
4314 if (has_indirect_arrays || 1) {
4315 ctx->sendVertexAttributes(minIndex, maxIndex - minIndex + 1, true);
4316 ctx->glDrawElementsData(ctx, mode, count, type, adjustedIndices, count * glSizeof(type));
4317 ctx->m_stream->flush();
4318 // XXX - OPTIMIZATION (see the other else branch) should be implemented
4319 if(!has_indirect_arrays) {
4320 //ALOGD("unoptimized drawelements !!!\n");
4321 }
4322 } else {
4323 // we are all direct arrays and immidate mode index array -
4324 // rebuild the arrays and the index array;
4325 ALOGE("glDrawElements: direct index & direct buffer data - will be implemented in later versions;\n");
4326 }
4327 }
4328}
4329
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004330const GLubyte* GL2Encoder::s_glGetStringi(void* self, GLenum name, GLuint index) {
4331 GL2Encoder *ctx = (GL2Encoder *)self;
Lingfeng Yanga16eb2e2018-02-23 11:26:53 -08004332 const GLubyte *retval = (GLubyte *) "";
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004333
4334 RET_AND_SET_ERROR_IF(
4335 name != GL_VENDOR &&
4336 name != GL_RENDERER &&
4337 name != GL_VERSION &&
4338 name != GL_EXTENSIONS,
4339 GL_INVALID_ENUM,
4340 retval);
4341
4342 RET_AND_SET_ERROR_IF(
Lingfeng Yang44209df2018-09-21 10:04:17 -07004343 (name == GL_VENDOR ||
4344 name == GL_RENDERER ||
4345 name == GL_VERSION) &&
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004346 index != 0,
4347 GL_INVALID_VALUE,
4348 retval);
4349
Lingfeng Yanga16eb2e2018-02-23 11:26:53 -08004350 RET_AND_SET_ERROR_IF(
4351 name == GL_EXTENSIONS &&
4352 index >= ctx->m_currExtensionsArray.size(),
4353 GL_INVALID_VALUE,
4354 retval);
4355
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004356 switch (name) {
4357 case GL_VENDOR:
4358 retval = gVendorString;
4359 break;
4360 case GL_RENDERER:
4361 retval = gRendererString;
4362 break;
4363 case GL_VERSION:
4364 retval = gVersionString;
4365 break;
4366 case GL_EXTENSIONS:
Lingfeng Yanga16eb2e2018-02-23 11:26:53 -08004367 retval = (const GLubyte*)(ctx->m_currExtensionsArray[index].c_str());
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004368 break;
4369 }
4370
4371 return retval;
4372}
4373
4374void GL2Encoder::s_glGetProgramBinary(void* self, GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, void* binary) {
4375 GL2Encoder *ctx = (GL2Encoder *)self;
4376
4377 SET_ERROR_IF(!ctx->m_shared->isProgram(program), GL_INVALID_OPERATION);
4378
4379 GLint linkStatus = 0;
4380 ctx->glGetProgramiv(self, program, GL_LINK_STATUS, &linkStatus);
4381 GLint properLength = 0;
4382 ctx->glGetProgramiv(self, program, GL_PROGRAM_BINARY_LENGTH, &properLength);
4383
4384 SET_ERROR_IF(!linkStatus, GL_INVALID_OPERATION);
4385 SET_ERROR_IF(bufSize < properLength, GL_INVALID_OPERATION);
4386
4387 ctx->m_glGetProgramBinary_enc(ctx, program, bufSize, length, binaryFormat, binary);
4388}
4389
4390void GL2Encoder::s_glReadPixels(void* self, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels) {
4391 GL2Encoder *ctx = (GL2Encoder *)self;
4392
4393 SET_ERROR_IF(!GLESv2Validation::readPixelsFormat(format), GL_INVALID_ENUM);
4394 SET_ERROR_IF(!GLESv2Validation::readPixelsType(type), GL_INVALID_ENUM);
4395 SET_ERROR_IF(width < 0 || height < 0, GL_INVALID_VALUE);
4396 SET_ERROR_IF(ctx->isBufferTargetMapped(GL_PIXEL_PACK_BUFFER), GL_INVALID_OPERATION);
4397 SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_PACK_BUFFER) &&
4398 ctx->getBufferData(GL_PIXEL_PACK_BUFFER) &&
4399 (ctx->m_state->pboNeededDataSize(width, height, 1, format, type, 1) >
4400 ctx->getBufferData(GL_PIXEL_PACK_BUFFER)->m_size),
4401 GL_INVALID_OPERATION);
4402 /*
4403GL_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.
4404
4405GL_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.
4406
4407GL_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.
4408
4409GL_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.
4410*/
4411
4412 FboFormatInfo fbo_format_info;
4413 ctx->m_state->getBoundFramebufferFormat(
4414 GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, &fbo_format_info);
4415 SET_ERROR_IF(
4416 fbo_format_info.type == FBO_ATTACHMENT_TEXTURE &&
4417 !GLESv2Validation::readPixelsFboFormatMatch(
4418 format, type, fbo_format_info.tex_type),
4419 GL_INVALID_OPERATION);
4420
4421 if (ctx->boundBuffer(GL_PIXEL_PACK_BUFFER)) {
4422 ctx->glReadPixelsOffsetAEMU(
4423 ctx, x, y, width, height,
4424 format, type, (uintptr_t)pixels);
4425 } else {
4426 ctx->m_glReadPixels_enc(
4427 ctx, x, y, width, height,
4428 format, type, pixels);
4429 }
4430}
4431
4432// Track enabled state for some things like:
4433// - Primitive restart
4434void GL2Encoder::s_glEnable(void* self, GLenum what) {
4435 GL2Encoder *ctx = (GL2Encoder *)self;
4436
4437 switch (what) {
4438 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
4439 ctx->m_primitiveRestartEnabled = true;
4440 break;
4441 }
4442
4443 ctx->m_glEnable_enc(ctx, what);
4444}
4445
4446void GL2Encoder::s_glDisable(void* self, GLenum what) {
4447 GL2Encoder *ctx = (GL2Encoder *)self;
4448
4449 switch (what) {
4450 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
4451 ctx->m_primitiveRestartEnabled = false;
4452 break;
4453 }
4454
4455 ctx->m_glDisable_enc(ctx, what);
4456}
4457
4458void GL2Encoder::s_glClearBufferiv(void* self, GLenum buffer, GLint drawBuffer, const GLint * value) {
4459 GL2Encoder *ctx = (GL2Encoder *)self;
4460
4461 SET_ERROR_IF(buffer == GL_DEPTH || buffer == GL_DEPTH_STENCIL, GL_INVALID_ENUM);
4462
4463 ctx->m_glClearBufferiv_enc(ctx, buffer, drawBuffer, value);
4464}
4465
4466void GL2Encoder::s_glClearBufferuiv(void* self, GLenum buffer, GLint drawBuffer, const GLuint * value) {
4467 GL2Encoder *ctx = (GL2Encoder *)self;
4468
4469 SET_ERROR_IF(buffer == GL_DEPTH || buffer == GL_STENCIL || buffer == GL_DEPTH_STENCIL, GL_INVALID_ENUM);
4470
4471 ctx->m_glClearBufferuiv_enc(ctx, buffer, drawBuffer, value);
4472}
4473
4474void GL2Encoder::s_glClearBufferfv(void* self, GLenum buffer, GLint drawBuffer, const GLfloat * value) {
4475 GL2Encoder *ctx = (GL2Encoder *)self;
4476
4477 SET_ERROR_IF(buffer == GL_STENCIL || buffer == GL_DEPTH_STENCIL, GL_INVALID_ENUM);
4478
4479 ctx->m_glClearBufferfv_enc(ctx, buffer, drawBuffer, value);
4480}
4481
4482void 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) {
4483 GL2Encoder *ctx = (GL2Encoder *)self;
4484 GLClientState* state = ctx->m_state;
4485
Lingfeng Yangb678c362019-06-05 08:00:21 -07004486 bool validateColor = mask & GL_COLOR_BUFFER_BIT;
4487 bool validateDepth = mask & GL_DEPTH_BUFFER_BIT;
4488 bool validateStencil = mask & GL_STENCIL_BUFFER_BIT;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004489
4490 FboFormatInfo read_fbo_format_info;
4491 FboFormatInfo draw_fbo_format_info;
4492 if (validateColor) {
4493 state->getBoundFramebufferFormat(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, &read_fbo_format_info);
4494 state->getBoundFramebufferFormat(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, &draw_fbo_format_info);
4495
4496 if (read_fbo_format_info.type == FBO_ATTACHMENT_TEXTURE &&
4497 draw_fbo_format_info.type == FBO_ATTACHMENT_TEXTURE) {
4498 SET_ERROR_IF(
4499 state->boundFramebuffer(GL_READ_FRAMEBUFFER) &&
4500 state->boundFramebuffer(GL_DRAW_FRAMEBUFFER) &&
4501 !GLESv2Validation::blitFramebufferFormat(
4502 read_fbo_format_info.tex_type,
4503 draw_fbo_format_info.tex_type),
4504 GL_INVALID_OPERATION);
4505 }
4506 }
4507
4508 if (validateDepth) {
4509 state->getBoundFramebufferFormat(GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, &read_fbo_format_info);
4510 state->getBoundFramebufferFormat(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, &draw_fbo_format_info);
4511
4512 if (read_fbo_format_info.type == FBO_ATTACHMENT_RENDERBUFFER &&
4513 draw_fbo_format_info.type == FBO_ATTACHMENT_RENDERBUFFER) {
4514 SET_ERROR_IF(
4515 state->boundFramebuffer(GL_READ_FRAMEBUFFER) &&
4516 state->boundFramebuffer(GL_DRAW_FRAMEBUFFER) &&
4517 !GLESv2Validation::blitFramebufferFormat(
4518 read_fbo_format_info.rb_format,
4519 draw_fbo_format_info.rb_format),
4520 GL_INVALID_OPERATION);
4521 }
4522 }
4523
4524 if (validateStencil) {
4525 state->getBoundFramebufferFormat(GL_READ_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, &read_fbo_format_info);
4526 state->getBoundFramebufferFormat(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, &draw_fbo_format_info);
4527
4528 if (read_fbo_format_info.type == FBO_ATTACHMENT_RENDERBUFFER &&
4529 draw_fbo_format_info.type == FBO_ATTACHMENT_RENDERBUFFER) {
4530 SET_ERROR_IF(
4531 state->boundFramebuffer(GL_READ_FRAMEBUFFER) &&
4532 state->boundFramebuffer(GL_DRAW_FRAMEBUFFER) &&
4533 !GLESv2Validation::blitFramebufferFormat(
4534 read_fbo_format_info.rb_format,
4535 draw_fbo_format_info.rb_format),
4536 GL_INVALID_OPERATION);
4537 }
4538 }
4539
4540 state->getBoundFramebufferFormat(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, &draw_fbo_format_info);
4541 SET_ERROR_IF(
4542 draw_fbo_format_info.type == FBO_ATTACHMENT_RENDERBUFFER &&
4543 draw_fbo_format_info.rb_multisamples > 0,
4544 GL_INVALID_OPERATION);
4545 SET_ERROR_IF(
4546 draw_fbo_format_info.type == FBO_ATTACHMENT_TEXTURE &&
4547 draw_fbo_format_info.tex_multisamples > 0,
4548 GL_INVALID_OPERATION);
4549
4550 state->getBoundFramebufferFormat(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, &read_fbo_format_info);
4551 SET_ERROR_IF(
4552 read_fbo_format_info.type == FBO_ATTACHMENT_RENDERBUFFER &&
4553 read_fbo_format_info.rb_multisamples > 0 &&
4554 draw_fbo_format_info.type == FBO_ATTACHMENT_RENDERBUFFER &&
4555 state->boundFramebuffer(GL_READ_FRAMEBUFFER) &&
4556 state->boundFramebuffer(GL_DRAW_FRAMEBUFFER) &&
4557 (read_fbo_format_info.rb_format !=
4558 draw_fbo_format_info.rb_format),
4559 GL_INVALID_OPERATION);
4560 SET_ERROR_IF(
4561 read_fbo_format_info.type == FBO_ATTACHMENT_RENDERBUFFER &&
4562 read_fbo_format_info.rb_multisamples > 0 &&
4563 draw_fbo_format_info.type == FBO_ATTACHMENT_RENDERBUFFER &&
4564 (srcX0 != dstX0 || srcY0 != dstY0 ||
4565 srcX1 != dstX1 || srcY1 != dstY1),
4566 GL_INVALID_OPERATION);
4567
4568 ctx->m_glBlitFramebuffer_enc(ctx,
4569 srcX0, srcY0, srcX1, srcY1,
4570 dstX0, dstY0, dstX1, dstY1,
4571 mask, filter);
4572}
4573
4574void GL2Encoder::s_glGetInternalformativ(void* self, GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params) {
4575 GL2Encoder *ctx = (GL2Encoder *)self;
4576
4577 SET_ERROR_IF(pname != GL_NUM_SAMPLE_COUNTS &&
4578 pname != GL_SAMPLES,
4579 GL_INVALID_ENUM);
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08004580 SET_ERROR_IF(!GLESv2Validation::internalFormatTarget(ctx, target), GL_INVALID_ENUM);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004581 SET_ERROR_IF(!GLESv2Validation::unsizedFormat(internalformat) &&
Lingfeng Yang931817b2017-01-27 06:50:56 -08004582 !GLESv2Validation::colorRenderableFormat(ctx, internalformat) &&
4583 !GLESv2Validation::depthRenderableFormat(ctx, internalformat) &&
4584 !GLESv2Validation::stencilRenderableFormat(ctx, internalformat),
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004585 GL_INVALID_ENUM);
4586 SET_ERROR_IF(bufSize < 0, GL_INVALID_VALUE);
4587
4588 if (bufSize < 1) return;
4589
4590 // Desktop OpenGL can allow a mindboggling # samples per pixel (such as 64).
4591 // Limit to 4 (spec minimum) to keep dEQP tests from timing out.
4592 switch (pname) {
4593 case GL_NUM_SAMPLE_COUNTS:
4594 *params = 3;
4595 break;
4596 case GL_SAMPLES:
4597 params[0] = 4;
4598 if (bufSize > 1) params[1] = 2;
4599 if (bufSize > 2) params[2] = 1;
4600 break;
4601 default:
4602 break;
4603 }
4604}
4605
4606void GL2Encoder::s_glGenerateMipmap(void* self, GLenum target) {
4607 GL2Encoder *ctx = (GL2Encoder *)self;
4608 GLClientState* state = ctx->m_state;
4609
4610 SET_ERROR_IF(target != GL_TEXTURE_2D &&
4611 target != GL_TEXTURE_3D &&
Yahan Zhou53c64582018-04-16 15:46:17 -07004612 target != GL_TEXTURE_CUBE_MAP &&
4613 target != GL_TEXTURE_2D_ARRAY,
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004614 GL_INVALID_ENUM);
4615
4616 GLuint tex = state->getBoundTexture(target);
4617 GLenum internalformat = state->queryTexInternalFormat(tex);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004618
4619 SET_ERROR_IF(tex && GLESv2Validation::isCompressedFormat(internalformat),
4620 GL_INVALID_OPERATION);
4621 SET_ERROR_IF(tex &&
4622 !GLESv2Validation::unsizedFormat(internalformat) &&
Lingfeng Yang931817b2017-01-27 06:50:56 -08004623 !(GLESv2Validation::colorRenderableFormat(ctx, internalformat) &&
4624 GLESv2Validation::filterableTexFormat(ctx, internalformat)),
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004625 GL_INVALID_OPERATION);
4626
Lingfeng Yanga9fff6a2018-03-02 13:42:51 -08004627 if (target == GL_TEXTURE_2D) {
4628 ctx->override2DTextureTarget(target);
4629 }
4630
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004631 ctx->m_glGenerateMipmap_enc(ctx, target);
Lingfeng Yanga9fff6a2018-03-02 13:42:51 -08004632
4633 if (target == GL_TEXTURE_2D) {
4634 ctx->restore2DTextureTarget(target);
4635 }
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004636}
4637
4638void GL2Encoder::s_glBindSampler(void* self, GLuint unit, GLuint sampler) {
4639 GL2Encoder *ctx = (GL2Encoder *)self;
4640 GLint maxCombinedUnits;
4641 ctx->glGetIntegerv(ctx, GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxCombinedUnits);
4642 SET_ERROR_IF(unit >= maxCombinedUnits, GL_INVALID_VALUE);
4643
Lingfeng Yang554a5152019-02-21 20:20:48 -08004644 ctx->doSamplerBindEncodeCached(unit, sampler);
4645}
4646
4647void GL2Encoder::doSamplerBindEncodeCached(GLuint unit, GLuint sampler) {
4648 if (m_state->isSamplerBindNoOp(unit, sampler)) return;
4649 m_glBindSampler_enc(this, unit, sampler);
4650 m_state->bindSampler(unit, sampler);
4651}
4652
4653void GL2Encoder::s_glDeleteSamplers(void* self, GLsizei n, const GLuint* samplers) {
4654 GL2Encoder *ctx = (GL2Encoder *)self;
4655 ctx->m_state->onDeleteSamplers(n, samplers);
4656 ctx->m_glDeleteSamplers_enc(ctx, n, samplers);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004657}
4658
Lingfeng Yangf000ab42017-01-11 18:31:38 -08004659GLsync GL2Encoder::s_glFenceSync(void* self, GLenum condition, GLbitfield flags) {
4660 GL2Encoder *ctx = (GL2Encoder *)self;
4661 uint64_t syncHandle = ctx->glFenceSyncAEMU(ctx, condition, flags);
4662 return (GLsync)(uintptr_t)syncHandle;
4663}
4664
4665GLenum GL2Encoder::s_glClientWaitSync(void* self, GLsync wait_on, GLbitfield flags, GLuint64 timeout) {
4666 GL2Encoder *ctx = (GL2Encoder *)self;
4667 return ctx->glClientWaitSyncAEMU(ctx, (uint64_t)(uintptr_t)wait_on, flags, timeout);
4668}
4669
4670void GL2Encoder::s_glWaitSync(void* self, GLsync wait_on, GLbitfield flags, GLuint64 timeout) {
4671 GL2Encoder *ctx = (GL2Encoder *)self;
4672 ctx->glWaitSyncAEMU(ctx, (uint64_t)(uintptr_t)wait_on, flags, timeout);
4673}
4674
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004675void GL2Encoder::s_glDeleteSync(void* self, GLsync sync) {
4676 GL2Encoder *ctx = (GL2Encoder *)self;
4677
4678 if (!sync) return;
4679
Lingfeng Yangf000ab42017-01-11 18:31:38 -08004680 ctx->glDeleteSyncAEMU(ctx, (uint64_t)(uintptr_t)sync);
4681}
4682
4683GLboolean GL2Encoder::s_glIsSync(void* self, GLsync sync) {
4684 GL2Encoder *ctx = (GL2Encoder *)self;
4685 return ctx->glIsSyncAEMU(ctx, (uint64_t)(uintptr_t)sync);
4686}
4687
4688void GL2Encoder::s_glGetSynciv(void* self, GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values) {
4689 GL2Encoder *ctx = (GL2Encoder *)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08004690
4691 SET_ERROR_IF(bufSize < 0, GL_INVALID_VALUE);
4692
Lingfeng Yangf000ab42017-01-11 18:31:38 -08004693 return ctx->glGetSyncivAEMU(ctx, (uint64_t)(uintptr_t)sync, pname, bufSize, length, values);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004694}
4695
4696#define LIMIT_CASE(target, lim) \
4697 case target: \
4698 ctx->glGetIntegerv(ctx, lim, &limit); \
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08004699 SET_ERROR_IF(index < 0 || index >= limit, GL_INVALID_VALUE); \
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004700 break; \
4701
4702void GL2Encoder::s_glGetIntegeri_v(void* self, GLenum target, GLuint index, GLint* params) {
4703 GL2Encoder *ctx = (GL2Encoder *)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08004704 GLClientState* state = ctx->m_state;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004705
4706 GLint limit;
4707
4708 switch (target) {
4709 LIMIT_CASE(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS)
4710 LIMIT_CASE(GL_UNIFORM_BUFFER_BINDING, GL_MAX_UNIFORM_BUFFER_BINDINGS)
4711 LIMIT_CASE(GL_ATOMIC_COUNTER_BUFFER_BINDING, GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS)
4712 LIMIT_CASE(GL_SHADER_STORAGE_BUFFER_BINDING, GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS)
4713 default:
4714 break;
4715 }
4716
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08004717 const GLClientState::VertexAttribBindingVector& currBindings =
4718 state->currentVertexBufferBindings();
4719
4720 switch (target) {
4721 case GL_VERTEX_BINDING_DIVISOR:
4722 case GL_VERTEX_BINDING_OFFSET:
4723 case GL_VERTEX_BINDING_STRIDE:
4724 case GL_VERTEX_BINDING_BUFFER:
4725 SET_ERROR_IF(index < 0 || index > currBindings.size(), GL_INVALID_VALUE);
4726 break;
4727 default:
4728 break;
4729 }
4730
4731 switch (target) {
4732 case GL_VERTEX_BINDING_DIVISOR:
4733 *params = currBindings[index].divisor;
4734 return;
4735 case GL_VERTEX_BINDING_OFFSET:
4736 *params = currBindings[index].offset;
4737 return;
4738 case GL_VERTEX_BINDING_STRIDE:
4739 *params = currBindings[index].effectiveStride;
4740 return;
4741 case GL_VERTEX_BINDING_BUFFER:
4742 *params = currBindings[index].buffer;
4743 return;
4744 default:
4745 break;
4746 }
4747
Lingfeng Yang80a36332017-07-09 10:58:07 -07004748 ctx->safe_glGetIntegeri_v(target, index, params);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004749}
4750
4751void GL2Encoder::s_glGetInteger64i_v(void* self, GLenum target, GLuint index, GLint64* params) {
4752 GL2Encoder *ctx = (GL2Encoder *)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08004753 GLClientState* state = ctx->m_state;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004754
4755 GLint limit;
4756
4757 switch (target) {
4758 LIMIT_CASE(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS)
4759 LIMIT_CASE(GL_UNIFORM_BUFFER_BINDING, GL_MAX_UNIFORM_BUFFER_BINDINGS)
4760 LIMIT_CASE(GL_ATOMIC_COUNTER_BUFFER_BINDING, GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS)
4761 LIMIT_CASE(GL_SHADER_STORAGE_BUFFER_BINDING, GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS)
4762 default:
4763 break;
4764 }
4765
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08004766 const GLClientState::VertexAttribBindingVector& currBindings =
4767 state->currentVertexBufferBindings();
4768
4769 switch (target) {
4770 case GL_VERTEX_BINDING_DIVISOR:
4771 case GL_VERTEX_BINDING_OFFSET:
4772 case GL_VERTEX_BINDING_STRIDE:
4773 case GL_VERTEX_BINDING_BUFFER:
4774 SET_ERROR_IF(index < 0 || index > currBindings.size(), GL_INVALID_VALUE);
4775 break;
4776 default:
4777 break;
4778 }
4779
4780 switch (target) {
4781 case GL_VERTEX_BINDING_DIVISOR:
4782 *params = currBindings[index].divisor;
4783 return;
4784 case GL_VERTEX_BINDING_OFFSET:
4785 *params = currBindings[index].offset;
4786 return;
4787 case GL_VERTEX_BINDING_STRIDE:
4788 *params = currBindings[index].effectiveStride;
4789 return;
4790 case GL_VERTEX_BINDING_BUFFER:
4791 *params = currBindings[index].buffer;
4792 return;
4793 default:
4794 break;
4795 }
4796
Lingfeng Yang80a36332017-07-09 10:58:07 -07004797 ctx->safe_glGetInteger64i_v(target, index, params);
4798}
4799
4800void GL2Encoder::s_glGetInteger64v(void* self, GLenum param, GLint64* val) {
4801 GL2Encoder *ctx = (GL2Encoder *)self;
4802 ctx->safe_glGetInteger64v(param, val);
4803}
4804
4805void GL2Encoder::s_glGetBooleani_v(void* self, GLenum param, GLuint index, GLboolean* val) {
4806 GL2Encoder *ctx = (GL2Encoder *)self;
4807 ctx->safe_glGetBooleani_v(param, index, val);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004808}
4809
4810void GL2Encoder::s_glGetShaderiv(void* self, GLuint shader, GLenum pname, GLint* params) {
4811 GL2Encoder *ctx = (GL2Encoder *)self;
4812 ctx->m_glGetShaderiv_enc(self, shader, pname, params);
4813 if (pname == GL_SHADER_SOURCE_LENGTH) {
4814 ShaderData* shaderData = ctx->m_shared->getShaderData(shader);
4815 if (shaderData) {
4816 int totalLen = 0;
4817 for (int i = 0; i < shaderData->sources.size(); i++) {
4818 totalLen += shaderData->sources[i].size();
4819 }
4820 if (totalLen != 0) {
4821 *params = totalLen + 1; // account for null terminator
4822 }
4823 }
4824 }
4825}
4826
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08004827void GL2Encoder::s_glActiveShaderProgram(void* self, GLuint pipeline, GLuint program) {
4828 GL2Encoder *ctx = (GL2Encoder*)self;
4829 GLClientState* state = ctx->m_state;
4830 GLSharedGroupPtr shared = ctx->m_shared;
4831
4832 SET_ERROR_IF(!pipeline, GL_INVALID_OPERATION);
4833 SET_ERROR_IF(program && !shared->isShaderOrProgramObject(program), GL_INVALID_VALUE);
4834 SET_ERROR_IF(program && !shared->isProgram(program), GL_INVALID_OPERATION);
4835
4836 ctx->m_glActiveShaderProgram_enc(ctx, pipeline, program);
4837 if (!state->currentProgram()) {
4838 state->setCurrentShaderProgram(program);
4839 }
4840}
4841
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004842GLuint GL2Encoder::s_glCreateShaderProgramv(void* self, GLenum type, GLsizei count, const char** strings) {
4843
4844 GLint* length = NULL;
4845 GL2Encoder* ctx = (GL2Encoder*)self;
4846
4847 int len = glUtilsCalcShaderSourceLen((char**)strings, length, count);
4848 char *str = new char[len + 1];
4849 glUtilsPackStrings(str, (char**)strings, (GLint*)length, count);
Lingfeng Yang554a5152019-02-21 20:20:48 -08004850
4851 // Do GLSharedGroup and location WorkARound-specific initialization
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004852 // Phase 1: create a ShaderData and initialize with replaceSamplerExternalWith2D()
4853 uint32_t spDataId = ctx->m_shared->addNewShaderProgramData();
4854 ShaderProgramData* spData = ctx->m_shared->getShaderProgramDataById(spDataId);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004855
Lingfeng Yang44209df2018-09-21 10:04:17 -07004856 if (!replaceSamplerExternalWith2D(str, &spData->shaderData)) {
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004857 delete [] str;
4858 ctx->setError(GL_OUT_OF_MEMORY);
4859 ctx->m_shared->deleteShaderProgramDataById(spDataId);
4860 return -1;
4861 }
4862
4863 GLuint res = ctx->glCreateShaderProgramvAEMU(ctx, type, count, str, len + 1);
4864 delete [] str;
4865
4866 // Phase 2: do glLinkProgram-related initialization for locationWorkARound
4867 GLint linkStatus = 0;
4868 ctx->glGetProgramiv(self, res, GL_LINK_STATUS ,&linkStatus);
4869 if (!linkStatus) {
4870 ctx->m_shared->deleteShaderProgramDataById(spDataId);
4871 return -1;
4872 }
4873
4874 ctx->m_shared->associateGLShaderProgram(res, spDataId);
4875
4876 GLint numUniforms = 0;
Lingfeng Yang80a36332017-07-09 10:58:07 -07004877 ctx->glGetProgramiv(self, res, GL_ACTIVE_UNIFORMS, &numUniforms);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004878 ctx->m_shared->initShaderProgramData(res, numUniforms);
4879
4880 GLint maxLength=0;
4881 ctx->glGetProgramiv(self, res, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxLength);
4882
4883 GLint size; GLenum uniformType; GLchar* name = new GLchar[maxLength + 1];
4884
4885 for (GLint i = 0; i < numUniforms; ++i) {
4886 ctx->glGetActiveUniform(self, res, i, maxLength, NULL, &size, &uniformType, name);
4887 GLint location = ctx->m_glGetUniformLocation_enc(self, res, name);
4888 ctx->m_shared->setShaderProgramIndexInfo(res, i, location, size, uniformType, name);
4889 }
4890
4891 ctx->m_shared->setupShaderProgramLocationShiftWAR(res);
4892
4893 delete [] name;
4894
4895 return res;
4896}
4897
4898void GL2Encoder::s_glProgramUniform1f(void* self, GLuint program, GLint location, GLfloat v0)
4899{
4900 GL2Encoder *ctx = (GL2Encoder*)self;
4901 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
4902 ctx->m_glProgramUniform1f_enc(self, program, hostLoc, v0);
4903}
4904
4905void GL2Encoder::s_glProgramUniform1fv(void* self, GLuint program, GLint location, GLsizei count, const GLfloat *value)
4906{
4907 GL2Encoder *ctx = (GL2Encoder*)self;
4908 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
4909 ctx->m_glProgramUniform1fv_enc(self, program, hostLoc, count, value);
4910}
4911
4912void GL2Encoder::s_glProgramUniform1i(void* self, GLuint program, GLint location, GLint v0)
4913{
4914 GL2Encoder *ctx = (GL2Encoder*)self;
4915 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08004916 ctx->m_glProgramUniform1i_enc(self, program, hostLoc, v0);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08004917
4918 GLClientState* state = ctx->m_state;
4919 GLSharedGroupPtr shared = ctx->m_shared;
4920 GLenum target;
4921
4922 if (shared->setSamplerUniform(program, location, v0, &target)) {
4923 GLenum origActiveTexture = state->getActiveTextureUnit();
4924 if (ctx->updateHostTexture2DBinding(GL_TEXTURE0 + v0, target)) {
4925 ctx->m_glActiveTexture_enc(self, origActiveTexture);
4926 }
4927 state->setActiveTextureUnit(origActiveTexture);
4928 }
4929}
4930
4931void GL2Encoder::s_glProgramUniform1iv(void* self, GLuint program, GLint location, GLsizei count, const GLint *value)
4932{
4933 GL2Encoder *ctx = (GL2Encoder*)self;
4934 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
4935 ctx->m_glProgramUniform1iv_enc(self, program, hostLoc, count, value);
4936}
4937
4938void GL2Encoder::s_glProgramUniform1ui(void* self, GLuint program, GLint location, GLuint v0)
4939{
4940 GL2Encoder *ctx = (GL2Encoder*)self;
4941 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
4942 ctx->m_glProgramUniform1ui_enc(self, program, hostLoc, v0);
4943
4944 GLClientState* state = ctx->m_state;
4945 GLSharedGroupPtr shared = ctx->m_shared;
4946 GLenum target;
4947
4948 if (shared->setSamplerUniform(program, location, v0, &target)) {
4949 GLenum origActiveTexture = state->getActiveTextureUnit();
4950 if (ctx->updateHostTexture2DBinding(GL_TEXTURE0 + v0, target)) {
4951 ctx->m_glActiveTexture_enc(self, origActiveTexture);
4952 }
4953 state->setActiveTextureUnit(origActiveTexture);
4954 }
4955}
4956
4957void GL2Encoder::s_glProgramUniform1uiv(void* self, GLuint program, GLint location, GLsizei count, const GLuint *value)
4958{
4959 GL2Encoder *ctx = (GL2Encoder*)self;
4960 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
4961 ctx->m_glProgramUniform1uiv_enc(self, program, hostLoc, count, value);
4962}
4963
4964void GL2Encoder::s_glProgramUniform2f(void* self, GLuint program, GLint location, GLfloat v0, GLfloat v1)
4965{
4966 GL2Encoder *ctx = (GL2Encoder*)self;
4967 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
4968 ctx->m_glProgramUniform2f_enc(self, program, hostLoc, v0, v1);
4969}
4970
4971void GL2Encoder::s_glProgramUniform2fv(void* self, GLuint program, GLint location, GLsizei count, const GLfloat *value)
4972{
4973 GL2Encoder *ctx = (GL2Encoder*)self;
4974 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
4975 ctx->m_glProgramUniform2fv_enc(self, program, hostLoc, count, value);
4976}
4977
4978void GL2Encoder::s_glProgramUniform2i(void* self, GLuint program, GLint location, GLint v0, GLint v1)
4979{
4980 GL2Encoder *ctx = (GL2Encoder*)self;
4981 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
4982 ctx->m_glProgramUniform2i_enc(self, program, hostLoc, v0, v1);
4983}
4984
4985void GL2Encoder::s_glProgramUniform2iv(void* self, GLuint program, GLint location, GLsizei count, const GLint *value)
4986{
4987 GL2Encoder *ctx = (GL2Encoder*)self;
4988 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
4989 ctx->m_glProgramUniform2iv_enc(self, program, hostLoc, count, value);
4990}
4991
4992void GL2Encoder::s_glProgramUniform2ui(void* self, GLuint program, GLint location, GLint v0, GLuint v1)
4993{
4994 GL2Encoder *ctx = (GL2Encoder*)self;
4995 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
4996 ctx->m_glProgramUniform2ui_enc(self, program, hostLoc, v0, v1);
4997}
4998
4999void GL2Encoder::s_glProgramUniform2uiv(void* self, GLuint program, GLint location, GLsizei count, const GLuint *value)
5000{
5001 GL2Encoder *ctx = (GL2Encoder*)self;
5002 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
5003 ctx->m_glProgramUniform2uiv_enc(self, program, hostLoc, count, value);
5004}
5005
5006void GL2Encoder::s_glProgramUniform3f(void* self, GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2)
5007{
5008 GL2Encoder *ctx = (GL2Encoder*)self;
5009 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
5010 ctx->m_glProgramUniform3f_enc(self, program, hostLoc, v0, v1, v2);
5011}
5012
5013void GL2Encoder::s_glProgramUniform3fv(void* self, GLuint program, GLint location, GLsizei count, const GLfloat *value)
5014{
5015 GL2Encoder *ctx = (GL2Encoder*)self;
5016 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
5017 ctx->m_glProgramUniform3fv_enc(self, program, hostLoc, count, value);
5018}
5019
5020void GL2Encoder::s_glProgramUniform3i(void* self, GLuint program, GLint location, GLint v0, GLint v1, GLint v2)
5021{
5022 GL2Encoder *ctx = (GL2Encoder*)self;
5023 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
5024 ctx->m_glProgramUniform3i_enc(self, program, hostLoc, v0, v1, v2);
5025}
5026
5027void GL2Encoder::s_glProgramUniform3iv(void* self, GLuint program, GLint location, GLsizei count, const GLint *value)
5028{
5029 GL2Encoder *ctx = (GL2Encoder*)self;
5030 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
5031 ctx->m_glProgramUniform3iv_enc(self, program, hostLoc, count, value);
5032}
5033
5034void GL2Encoder::s_glProgramUniform3ui(void* self, GLuint program, GLint location, GLint v0, GLint v1, GLuint v2)
5035{
5036 GL2Encoder *ctx = (GL2Encoder*)self;
5037 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
5038 ctx->m_glProgramUniform3ui_enc(self, program, hostLoc, v0, v1, v2);
5039}
5040
5041void GL2Encoder::s_glProgramUniform3uiv(void* self, GLuint program, GLint location, GLsizei count, const GLuint *value)
5042{
5043 GL2Encoder *ctx = (GL2Encoder*)self;
5044 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
5045 ctx->m_glProgramUniform3uiv_enc(self, program, hostLoc, count, value);
5046}
5047
5048void GL2Encoder::s_glProgramUniform4f(void* self, GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3)
5049{
5050 GL2Encoder *ctx = (GL2Encoder*)self;
5051 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
5052 ctx->m_glProgramUniform4f_enc(self, program, hostLoc, v0, v1, v2, v3);
5053}
5054
5055void GL2Encoder::s_glProgramUniform4fv(void* self, GLuint program, GLint location, GLsizei count, const GLfloat *value)
5056{
5057 GL2Encoder *ctx = (GL2Encoder*)self;
5058 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
5059 ctx->m_glProgramUniform4fv_enc(self, program, hostLoc, count, value);
5060}
5061
5062void GL2Encoder::s_glProgramUniform4i(void* self, GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3)
5063{
5064 GL2Encoder *ctx = (GL2Encoder*)self;
5065 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
5066 ctx->m_glProgramUniform4i_enc(self, program, hostLoc, v0, v1, v2, v3);
5067}
5068
5069void GL2Encoder::s_glProgramUniform4iv(void* self, GLuint program, GLint location, GLsizei count, const GLint *value)
5070{
5071 GL2Encoder *ctx = (GL2Encoder*)self;
5072 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
5073 ctx->m_glProgramUniform4iv_enc(self, program, hostLoc, count, value);
5074}
5075
5076void GL2Encoder::s_glProgramUniform4ui(void* self, GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLuint v3)
5077{
5078 GL2Encoder *ctx = (GL2Encoder*)self;
5079 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
5080 ctx->m_glProgramUniform4ui_enc(self, program, hostLoc, v0, v1, v2, v3);
5081}
5082
5083void GL2Encoder::s_glProgramUniform4uiv(void* self, GLuint program, GLint location, GLsizei count, const GLuint *value)
5084{
5085 GL2Encoder *ctx = (GL2Encoder*)self;
5086 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
5087 ctx->m_glProgramUniform4uiv_enc(self, program, hostLoc, count, value);
5088}
5089
5090void GL2Encoder::s_glProgramUniformMatrix2fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
5091{
5092 GL2Encoder *ctx = (GL2Encoder*)self;
5093 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
5094 ctx->m_glProgramUniformMatrix2fv_enc(self, program, hostLoc, count, transpose, value);
5095}
5096
5097void GL2Encoder::s_glProgramUniformMatrix2x3fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
5098{
5099 GL2Encoder *ctx = (GL2Encoder*)self;
5100 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
5101 ctx->m_glProgramUniformMatrix2x3fv_enc(self, program, hostLoc, count, transpose, value);
5102}
5103
5104void GL2Encoder::s_glProgramUniformMatrix2x4fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
5105{
5106 GL2Encoder *ctx = (GL2Encoder*)self;
5107 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
5108 ctx->m_glProgramUniformMatrix2x4fv_enc(self, program, hostLoc, count, transpose, value);
5109}
5110
5111void GL2Encoder::s_glProgramUniformMatrix3fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
5112{
5113 GL2Encoder *ctx = (GL2Encoder*)self;
5114 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
5115 ctx->m_glProgramUniformMatrix3fv_enc(self, program, hostLoc, count, transpose, value);
5116}
5117
5118void GL2Encoder::s_glProgramUniformMatrix3x2fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
5119{
5120 GL2Encoder *ctx = (GL2Encoder*)self;
5121 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
5122 ctx->m_glProgramUniformMatrix3x2fv_enc(self, program, hostLoc, count, transpose, value);
5123}
5124
5125void GL2Encoder::s_glProgramUniformMatrix3x4fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
5126{
5127 GL2Encoder *ctx = (GL2Encoder*)self;
5128 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
5129 ctx->m_glProgramUniformMatrix3x4fv_enc(self, program, hostLoc, count, transpose, value);
5130}
5131
5132void GL2Encoder::s_glProgramUniformMatrix4fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
5133{
5134 GL2Encoder *ctx = (GL2Encoder*)self;
5135 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
5136 ctx->m_glProgramUniformMatrix4fv_enc(self, program, hostLoc, count, transpose, value);
5137}
5138
5139void GL2Encoder::s_glProgramUniformMatrix4x2fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
5140{
5141 GL2Encoder *ctx = (GL2Encoder*)self;
5142 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
5143 ctx->m_glProgramUniformMatrix4x2fv_enc(self, program, hostLoc, count, transpose, value);
5144}
5145
5146void GL2Encoder::s_glProgramUniformMatrix4x3fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
5147{
5148 GL2Encoder *ctx = (GL2Encoder*)self;
5149 GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
5150 ctx->m_glProgramUniformMatrix4x3fv_enc(self, program, hostLoc, count, transpose, value);
5151}
5152
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08005153void GL2Encoder::s_glProgramParameteri(void* self, GLuint program, GLenum pname, GLint value) {
5154 GL2Encoder* ctx = (GL2Encoder*)self;
5155 ctx->m_glProgramParameteri_enc(self, program, pname, value);
5156}
5157
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005158void GL2Encoder::s_glUseProgramStages(void *self, GLuint pipeline, GLbitfield stages, GLuint program)
5159{
5160 GL2Encoder *ctx = (GL2Encoder*)self;
5161 GLClientState* state = ctx->m_state;
5162 GLSharedGroupPtr shared = ctx->m_shared;
5163
5164 SET_ERROR_IF(!pipeline, GL_INVALID_OPERATION);
5165 SET_ERROR_IF(program && !shared->isShaderOrProgramObject(program), GL_INVALID_VALUE);
5166 SET_ERROR_IF(program && !shared->isProgram(program), GL_INVALID_OPERATION);
5167
5168 ctx->m_glUseProgramStages_enc(self, pipeline, stages, program);
5169 state->associateProgramWithPipeline(program, pipeline);
5170
5171 // There is an active non-separable shader program in effect; no need to update external/2D bindings.
5172 if (state->currentProgram()) {
5173 return;
5174 }
5175
5176 // Otherwise, update host texture 2D bindings.
5177 ctx->updateHostTexture2DBindingsFromProgramData(program);
5178}
5179
5180void GL2Encoder::s_glBindProgramPipeline(void* self, GLuint pipeline)
5181{
5182 GL2Encoder *ctx = (GL2Encoder*)self;
5183 GLClientState* state = ctx->m_state;
5184
5185 ctx->m_glBindProgramPipeline_enc(self, pipeline);
5186
5187 // There is an active non-separable shader program in effect; no need to update external/2D bindings.
5188 if (!pipeline || state->currentProgram()) {
5189 return;
5190 }
5191
5192 GLClientState::ProgramPipelineIterator it = state->programPipelineBegin();
5193 for (; it != state->programPipelineEnd(); ++it) {
5194 if (it->second == pipeline) {
5195 ctx->updateHostTexture2DBindingsFromProgramData(it->first);
5196 }
5197 }
5198}
5199
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08005200void GL2Encoder::s_glGetProgramResourceiv(void* self, GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum * props, GLsizei bufSize, GLsizei * length, GLint * params) {
5201 GL2Encoder *ctx = (GL2Encoder*)self;
5202 SET_ERROR_IF(bufSize < 0, GL_INVALID_VALUE);
5203 if (bufSize == 0) {
5204 if (length) *length = 0;
5205 return;
5206 }
5207
5208 // Avoid modifying |name| if |*length| < bufSize.
5209 GLint* intermediate = new GLint[bufSize];
5210 GLsizei* myLength = length ? length : new GLsizei;
5211 bool needFreeLength = length == NULL;
5212
5213 ctx->m_glGetProgramResourceiv_enc(self, program, programInterface, index, propCount, props, bufSize, myLength, intermediate);
5214 GLsizei writtenInts = *myLength;
5215 memcpy(params, intermediate, writtenInts * sizeof(GLint));
5216
5217 delete [] intermediate;
5218 if (needFreeLength)
5219 delete myLength;
5220}
5221
5222GLuint GL2Encoder::s_glGetProgramResourceIndex(void* self, GLuint program, GLenum programInterface, const char* name) {
5223 GL2Encoder *ctx = (GL2Encoder*)self;
5224 return ctx->m_glGetProgramResourceIndex_enc(self, program, programInterface, name);
5225}
5226
5227GLint GL2Encoder::s_glGetProgramResourceLocation(void* self, GLuint program, GLenum programInterface, const char* name) {
5228 GL2Encoder *ctx = (GL2Encoder*)self;
5229 return ctx->m_glGetProgramResourceLocation_enc(self, program, programInterface, name);
5230}
5231
5232void GL2Encoder::s_glGetProgramResourceName(void* self, GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei* length, char* name) {
5233 GL2Encoder *ctx = (GL2Encoder*)self;
5234 SET_ERROR_IF(bufSize < 0, GL_INVALID_VALUE);
5235 if (bufSize == 0) {
5236 if (length) *length = 0;
5237 return;
5238 }
5239
5240 // Avoid modifying |name| if |*length| < bufSize.
5241 char* intermediate = new char[bufSize];
5242 GLsizei* myLength = length ? length : new GLsizei;
5243 bool needFreeLength = length == NULL;
5244
5245 ctx->m_glGetProgramResourceName_enc(self, program, programInterface, index, bufSize, myLength, intermediate);
5246 GLsizei writtenStrLen = *myLength;
5247 memcpy(name, intermediate, writtenStrLen + 1);
5248
5249 delete [] intermediate;
5250 if (needFreeLength)
5251 delete myLength;
5252}
5253
5254void GL2Encoder::s_glGetProgramPipelineInfoLog(void* self, GLuint pipeline, GLsizei bufSize, GLsizei* length, GLchar* infoLog) {
5255 GL2Encoder *ctx = (GL2Encoder*)self;
5256 SET_ERROR_IF(bufSize < 0, GL_INVALID_VALUE);
5257 if (bufSize == 0) {
5258 if (length) *length = 0;
5259 return;
5260 }
5261
5262 // Avoid modifying |infoLog| if |*length| < bufSize.
5263 GLchar* intermediate = new GLchar[bufSize];
5264 GLsizei* myLength = length ? length : new GLsizei;
5265 bool needFreeLength = length == NULL;
5266
5267 ctx->m_glGetProgramPipelineInfoLog_enc(self, pipeline, bufSize, myLength, intermediate);
5268 GLsizei writtenStrLen = *myLength;
5269 memcpy(infoLog, intermediate, writtenStrLen + 1);
5270
5271 delete [] intermediate;
5272 if (needFreeLength)
5273 delete myLength;
5274}
5275
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005276void GL2Encoder::s_glVertexAttribFormat(void* self, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset) {
5277 GL2Encoder *ctx = (GL2Encoder*)self;
5278 GLClientState* state = ctx->m_state;
5279
Lingfeng Yang07289902017-01-27 12:26:19 -08005280 VALIDATE_VERTEX_ATTRIB_INDEX(attribindex);
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08005281 SET_ERROR_IF(!state->currentVertexArrayObject(), GL_INVALID_OPERATION);
5282
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005283 state->setVertexAttribFormat(attribindex, size, type, normalized, relativeoffset, false);
5284 ctx->m_glVertexAttribFormat_enc(ctx, attribindex, size, type, normalized, relativeoffset);
5285}
5286
5287void GL2Encoder::s_glVertexAttribIFormat(void* self, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset) {
5288 GL2Encoder *ctx = (GL2Encoder*)self;
5289 GLClientState* state = ctx->m_state;
5290
Lingfeng Yang07289902017-01-27 12:26:19 -08005291 VALIDATE_VERTEX_ATTRIB_INDEX(attribindex);
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08005292 SET_ERROR_IF(!state->currentVertexArrayObject(), GL_INVALID_OPERATION);
5293
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005294 state->setVertexAttribFormat(attribindex, size, type, GL_FALSE, relativeoffset, true);
5295 ctx->m_glVertexAttribIFormat_enc(ctx, attribindex, size, type, relativeoffset);
5296}
5297
5298void GL2Encoder::s_glVertexBindingDivisor(void* self, GLuint bindingindex, GLuint divisor) {
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005299 GL2Encoder *ctx = (GL2Encoder*)self;
5300 GLClientState* state = ctx->m_state;
5301
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08005302 SET_ERROR_IF(!state->currentVertexArrayObject(), GL_INVALID_OPERATION);
5303
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005304 state->setVertexBindingDivisor(bindingindex, divisor);
5305 ctx->m_glVertexBindingDivisor_enc(ctx, bindingindex, divisor);
5306}
5307
5308void GL2Encoder::s_glVertexAttribBinding(void* self, GLuint attribindex, GLuint bindingindex) {
5309 GL2Encoder *ctx = (GL2Encoder*)self;
5310 GLClientState* state = ctx->m_state;
Lingfeng Yang07289902017-01-27 12:26:19 -08005311 VALIDATE_VERTEX_ATTRIB_INDEX(attribindex);
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08005312 SET_ERROR_IF(!state->currentVertexArrayObject(), GL_INVALID_OPERATION);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005313
5314 state->setVertexAttribBinding(attribindex, bindingindex);
5315 ctx->m_glVertexAttribBinding_enc(ctx, attribindex, bindingindex);
5316}
5317
5318void GL2Encoder::s_glBindVertexBuffer(void* self, GLuint bindingindex, GLuint buffer, GLintptr offset, GLintptr stride) {
5319 GL2Encoder *ctx = (GL2Encoder*)self;
5320 GLClientState* state = ctx->m_state;
5321
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08005322 SET_ERROR_IF(offset < 0, GL_INVALID_VALUE);
5323
5324 GLint maxStride;
5325 ctx->glGetIntegerv(ctx, GL_MAX_VERTEX_ATTRIB_STRIDE, &maxStride);
5326 SET_ERROR_IF(stride < 0 || stride > maxStride, GL_INVALID_VALUE);
5327
5328 SET_ERROR_IF(!state->currentVertexArrayObject(), GL_INVALID_OPERATION);
5329
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005330 state->bindIndexedBuffer(0, bindingindex, buffer, offset, 0, stride, stride);
5331 ctx->m_glBindVertexBuffer_enc(ctx, bindingindex, buffer, offset, stride);
5332}
5333
5334void GL2Encoder::s_glDrawArraysIndirect(void* self, GLenum mode, const void* indirect) {
5335 GL2Encoder *ctx = (GL2Encoder*)self;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08005336 GLClientState* state = ctx->m_state;
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005337
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08005338 bool hasClientArrays = false;
5339 ctx->getVBOUsage(&hasClientArrays, NULL);
5340
5341 SET_ERROR_IF(hasClientArrays, GL_INVALID_OPERATION);
5342 SET_ERROR_IF(!state->currentVertexArrayObject(), GL_INVALID_OPERATION);
5343 SET_ERROR_IF(!ctx->boundBuffer(GL_DRAW_INDIRECT_BUFFER), GL_INVALID_OPERATION);
5344
5345 GLuint indirectStructSize = glUtilsIndirectStructSize(INDIRECT_COMMAND_DRAWARRAYS);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005346 if (ctx->boundBuffer(GL_DRAW_INDIRECT_BUFFER)) {
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08005347 // BufferData* buf = ctx->getBufferData(target);
5348 // if (buf) {
5349 // SET_ERROR_IF((GLuint)(uintptr_t)indirect + indirectStructSize > buf->m_size, GL_INVALID_VALUE);
5350 // }
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005351 ctx->glDrawArraysIndirectOffsetAEMU(ctx, mode, (uintptr_t)indirect);
5352 } else {
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08005353 // Client command structs are technically allowed in desktop OpenGL, but not in ES.
5354 // This is purely for debug/dev purposes.
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005355 ctx->glDrawArraysIndirectDataAEMU(ctx, mode, indirect, indirectStructSize);
5356 }
5357}
5358
5359void GL2Encoder::s_glDrawElementsIndirect(void* self, GLenum mode, GLenum type, const void* indirect) {
5360 GL2Encoder *ctx = (GL2Encoder*)self;
5361
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08005362 GLClientState* state = ctx->m_state;
5363
5364 bool hasClientArrays = false;
5365 ctx->getVBOUsage(&hasClientArrays, NULL);
5366
5367 SET_ERROR_IF(hasClientArrays, GL_INVALID_OPERATION);
5368 SET_ERROR_IF(!state->currentVertexArrayObject(), GL_INVALID_OPERATION);
5369 SET_ERROR_IF(!ctx->boundBuffer(GL_DRAW_INDIRECT_BUFFER), GL_INVALID_OPERATION);
5370
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005371 SET_ERROR_IF(ctx->m_state->getTransformFeedbackActiveUnpaused(), GL_INVALID_OPERATION);
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08005372
5373 GLuint indirectStructSize = glUtilsIndirectStructSize(INDIRECT_COMMAND_DRAWELEMENTS);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005374 if (ctx->boundBuffer(GL_DRAW_INDIRECT_BUFFER)) {
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08005375 // BufferData* buf = ctx->getBufferData(target);
5376 // if (buf) {
5377 // SET_ERROR_IF((GLuint)(uintptr_t)indirect + indirectStructSize > buf->m_size, GL_INVALID_VALUE);
5378 // }
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005379 ctx->glDrawElementsIndirectOffsetAEMU(ctx, mode, type, (uintptr_t)indirect);
5380 } else {
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08005381 // Client command structs are technically allowed in desktop OpenGL, but not in ES.
5382 // This is purely for debug/dev purposes.
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005383 ctx->glDrawElementsIndirectDataAEMU(ctx, mode, type, indirect, indirectStructSize);
5384 }
5385
5386}
5387
5388void GL2Encoder::s_glTexStorage2DMultisample(void* self, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations) {
5389 GL2Encoder *ctx = (GL2Encoder*)self;
5390 GLClientState* state = ctx->m_state;
5391
5392 SET_ERROR_IF(target != GL_TEXTURE_2D_MULTISAMPLE, GL_INVALID_ENUM);
5393 SET_ERROR_IF(!GLESv2Validation::pixelInternalFormat(internalformat), GL_INVALID_ENUM);
5394 SET_ERROR_IF(!state->getBoundTexture(target), GL_INVALID_OPERATION);
5395 SET_ERROR_IF(width < 1 || height < 1, GL_INVALID_VALUE);
5396 SET_ERROR_IF(state->isBoundTextureImmutableFormat(target), GL_INVALID_OPERATION);
Lingfeng Yangd3ae1062017-01-18 11:42:04 -08005397 GLint max_samples;
5398 ctx->s_glGetInternalformativ(ctx, target, internalformat, GL_SAMPLES, 1, &max_samples);
5399 SET_ERROR_IF(samples > max_samples, GL_INVALID_OPERATION);
Lingfeng Yang46153ab2017-01-09 13:37:22 -08005400
5401 state->setBoundTextureInternalFormat(target, internalformat);
5402 state->setBoundTextureDims(target, 0, width, height, 1);
5403 state->setBoundTextureImmutableFormat(target);
5404 state->setBoundTextureSamples(target, samples);
5405
5406 ctx->m_glTexStorage2DMultisample_enc(ctx, target, samples, internalformat, width, height, fixedsamplelocations);
5407}
5408
Yahan Zhou72944ba2019-01-02 15:43:46 -08005409GLenum GL2Encoder::s_glGetGraphicsResetStatusEXT(void* self) {
5410 (void)self;
5411 return GL_NO_ERROR;
5412}
5413
5414void GL2Encoder::s_glReadnPixelsEXT(void* self, GLint x, GLint y, GLsizei width,
5415 GLsizei height, GLenum format, GLenum type, GLsizei bufSize,
5416 GLvoid* pixels) {
5417 GL2Encoder *ctx = (GL2Encoder*)self;
5418 SET_ERROR_IF(bufSize < glesv2_enc::pixelDataSize(self, width, height, format,
5419 type, 1), GL_INVALID_OPERATION);
5420 s_glReadPixels(self, x, y, width, height, format, type, pixels);
5421}
5422
5423void GL2Encoder::s_glGetnUniformfvEXT(void *self, GLuint program, GLint location,
5424 GLsizei bufSize, GLfloat* params) {
5425 GL2Encoder *ctx = (GL2Encoder*)self;
5426 SET_ERROR_IF(bufSize < glSizeof(glesv2_enc::uniformType(self, program,
5427 location)), GL_INVALID_OPERATION);
5428 s_glGetUniformfv(self, program, location, params);
5429}
5430
5431void GL2Encoder::s_glGetnUniformivEXT(void *self, GLuint program, GLint location,
5432 GLsizei bufSize, GLint* params) {
5433 GL2Encoder *ctx = (GL2Encoder*)self;
5434 SET_ERROR_IF(bufSize < glSizeof(glesv2_enc::uniformType(self, program,
5435 location)), GL_INVALID_OPERATION);
5436 s_glGetUniformiv(self, program, location, params);
5437}