1 /*
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 #ifdef _WIN32
18 #undef  GL_APICALL
19 #define GL_API
20 #define GL_APICALL
21 #endif // !_WIN32
22 
23 #define GL_GLEXT_PROTOTYPES
24 #include <GLES2/gl2.h>
25 #include <GLES2/gl2ext.h>
26 #include <GLES3/gl3.h>
27 #include <GLES3/gl31.h>
28 
29 #include "aemu/base/system/System.h"
30 #include "host-common/logging.h"
31 
32 #include "GLESv2Context.h"
33 #include "GLESv2Validate.h"
34 #include "GLcommon/FramebufferData.h"
35 #include "GLcommon/GLutils.h"
36 #include "GLcommon/SaveableTexture.h"
37 #include "GLcommon/TextureData.h"
38 #include "GLcommon/TextureUtils.h"
39 #include "GLcommon/TranslatorIfaces.h"
40 #include "ProgramData.h"
41 #include "SamplerData.h"
42 #include "ShaderParser.h"
43 #include "TransformFeedbackData.h"
44 
45 #include "host-common/crash_reporter.h"
46 
47 #include "ANGLEShaderParser.h"
48 
49 #include <math.h>
50 #include <stdio.h>
51 
52 #include <numeric>
53 #include <unordered_map>
54 
55 
56 #ifdef _MSC_VER
57 #include "aemu/base/msvc.h"
58 #else
59 #include <sys/time.h>
60 #endif
61 
62 #define GLES2_NAMESPACED(f) translator::gles2::f
63 
64 namespace translator {
65 namespace gles2 {
66 
67 GL_API void GL_APIENTRY  glFlush( void);
68 GL_API void GL_APIENTRY  glFinish( void);
69 GL_API GLenum GL_APIENTRY  glGetError( void);
70 
71 } // namespace gles1
72 } // namespace translator
73 
74 extern "C" {
75 
76 //decleration
77 static void initGLESx(bool isGles2Gles);
78 static void initContext(GLEScontext* ctx, ShareGroupPtr grp, bool nativeTextureDecompressionEnabled);
79 static void setMaxGlesVersion(GLESVersion version);
80 static void deleteGLESContext(GLEScontext* ctx);
81 static void setShareGroup(GLEScontext* ctx,ShareGroupPtr grp);
82 static GLEScontext* createGLESContext(void);
83 static GLEScontext* createGLESxContext(int maj, int min, GlobalNameSpace* globalNameSpace, android::base::Stream* stream);
84 static __translatorMustCastToProperFunctionPointerType getProcAddressGles2(const char* procName);
85 static void preSaveTexture();
86 static void postSaveTexture();
87 static void saveTexture(SaveableTexture* texture, android::base::Stream* stream,
88                         android::base::SmallVector<unsigned char>* buffer);
89 static SaveableTexture* createTexture(GlobalNameSpace* globalNameSpace,
90                                       SaveableTexture::loader_t&& loader);
91 static void restoreTexture(SaveableTexture* texture);
92 static void blitFromCurrentReadBufferANDROID(EGLImage image);
93 static bool vulkanInteropSupported();
94 
95 namespace translator {
96 namespace gles2 {
97 
98 static GLsync internal_glFenceSync(GLenum condition, GLbitfield flags);
99 static GLenum internal_glClientWaitSync(GLsync wait_on, GLbitfield flags, GLuint64 timeout);
100 static void internal_glWaitSync(GLsync wait_on, GLbitfield flags, GLuint64 timeout);
101 static void internal_glDeleteSync(GLsync to_delete);
102 static void internal_glGetSynciv(GLsync sync, GLenum pname, GLsizei bufsize, GLsizei *length, GLint *values);
103 
104 } // namespace translator
105 } // namespace gles2
106 
107 }
108 
109 /************************************** GLES EXTENSIONS *********************************************************/
110 typedef std::unordered_map<std::string, __translatorMustCastToProperFunctionPointerType> ProcTableMap;
111 ProcTableMap *s_gles2Extensions = NULL;
112 /****************************************************************************************************************/
113 
114 static EGLiface*  s_eglIface = NULL;
115 static GLESiface s_glesIface = {
116     .initGLESx = initGLESx,
117     .createGLESContext = createGLESxContext,
118     .initContext = initContext,
119     .setMaxGlesVersion = setMaxGlesVersion,
120     .deleteGLESContext = deleteGLESContext,
121     .flush = (FUNCPTR_NO_ARGS_RET_VOID)GLES2_NAMESPACED(glFlush),
122     .finish = (FUNCPTR_NO_ARGS_RET_VOID)GLES2_NAMESPACED(glFinish),
123     .getError = (FUNCPTR_NO_ARGS_RET_INT)GLES2_NAMESPACED(glGetError),
124     .setShareGroup = setShareGroup,
125     .getProcAddress = getProcAddressGles2,
126 
127     .fenceSync = (FUNCPTR_FENCE_SYNC)translator::gles2::internal_glFenceSync,
128     .clientWaitSync = (FUNCPTR_CLIENT_WAIT_SYNC)translator::gles2::internal_glClientWaitSync,
129     .waitSync = (FUNCPTR_WAIT_SYNC)translator::gles2::internal_glWaitSync,
130     .deleteSync = (FUNCPTR_DELETE_SYNC)translator::gles2::internal_glDeleteSync,
131     .preSaveTexture = preSaveTexture,
132     .postSaveTexture = postSaveTexture,
133     .saveTexture = saveTexture,
134     .createTexture = createTexture,
135     .restoreTexture = restoreTexture,
136     .deleteRbo = deleteRenderbufferGlobal,
137     .blitFromCurrentReadBufferANDROID = blitFromCurrentReadBufferANDROID,
138     .vulkanInteropSupported = vulkanInteropSupported,
139     .getSynciv = (FUNCPTR_GET_SYNC_IV)translator::gles2::internal_glGetSynciv,
140 };
141 
142 #include <GLcommon/GLESmacros.h>
143 
144 namespace translator {
145 namespace gles2 {
146 
147 GL_APICALL void GL_APIENTRY glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image);
148 GL_APICALL void GL_APIENTRY glEGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image);
149 GL_API void GL_APIENTRY glBindTexture (GLenum target, GLuint texture);
150 
151 GL_APICALL void  GL_APIENTRY glVertexAttribPointerWithDataSize(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr, GLsizei dataSize);
152 GL_APICALL void  GL_APIENTRY glVertexAttribIPointerWithDataSize(GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid* ptr, GLsizei dataSize);
153 GL_APICALL void  GL_APIENTRY glTestHostDriverPerformance(GLuint count, uint64_t* duration_us, uint64_t* duration_cpu_us);
154 GL_APICALL void  GL_APIENTRY glDrawArraysNullAEMU(GLenum mode, GLint first, GLsizei count);
155 GL_APICALL void  GL_APIENTRY glDrawElementsNullAEMU(GLenum mode, GLsizei count, GLenum type, const void* indices);
156 
157 
158 // Vulkan/GL interop
159 // https://www.khronos.org/registry/OpenGL/extensions/EXT/EXT_external_objects.txt
160 // Common between GL_EXT_memory_object and GL_EXT_semaphore
161 GL_APICALL void GL_APIENTRY glGetUnsignedBytevEXT(GLenum pname, GLubyte* data);
162 GL_APICALL void GL_APIENTRY glGetUnsignedBytei_vEXT(GLenum target, GLuint index, GLubyte* data);
163 
164 // GL_EXT_memory_object
165 GL_APICALL void GL_APIENTRY glImportMemoryFdEXT(GLuint memory, GLuint64 size, GLenum handleType, GLint fd);
166 GL_APICALL void GL_APIENTRY glImportMemoryWin32HandleEXT(GLuint memory, GLuint64 size, GLenum handleType, void* handle);
167 GL_APICALL void GL_APIENTRY glDeleteMemoryObjectsEXT(GLsizei n, const GLuint *memoryObjects);
168 GL_APICALL GLboolean GL_APIENTRY glIsMemoryObjectEXT(GLuint memoryObject);
169 GL_APICALL void GL_APIENTRY glCreateMemoryObjectsEXT(GLsizei n, GLuint *memoryObjects);
170 GL_APICALL void GL_APIENTRY glMemoryObjectParameterivEXT(GLuint memoryObject, GLenum pname, const GLint *params);
171 GL_APICALL void GL_APIENTRY glGetMemoryObjectParameterivEXT(GLuint memoryObject, GLenum pname, GLint *params);
172 GL_APICALL void GL_APIENTRY glTexStorageMem2DEXT(GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLuint memory, GLuint64 offset);
173 GL_APICALL void GL_APIENTRY glTexStorageMem2DMultisampleEXT(GLenum target, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset);
174 GL_APICALL void GL_APIENTRY glTexStorageMem3DEXT(GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLuint memory, GLuint64 offset);
175 GL_APICALL void GL_APIENTRY glTexStorageMem3DMultisampleEXT(GLenum target, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset);
176 GL_APICALL void GL_APIENTRY glBufferStorageMemEXT(GLenum target, GLsizeiptr size, GLuint memory, GLuint64 offset);
177 GL_APICALL void GL_APIENTRY glTexParameteriHOST(GLenum target, GLenum pname, GLint param);
178 
179 // GL_OES_texture_buffer
180 GL_APICALL void GL_APIENTRY glTexBufferOES(GLenum target, GLenum internalformat, GLuint buffer);
181 GL_APICALL void GL_APIENTRY glTexBufferRangeOES(GLenum target, GLenum internalformat, GLuint buffer,
182                                                 GLintptr offset, GLsizeiptr size);
183 
184 // GL_EXT_texture_buffer
185 GL_APICALL void GL_APIENTRY glTexBufferEXT(GLenum target, GLenum internalformat, GLuint buffer);
186 GL_APICALL void GL_APIENTRY glTexBufferRangeEXT(GLenum target, GLenum internalformat, GLuint buffer,
187                                                 GLintptr offset, GLsizeiptr size);
188 
189 // GL_EXT_draw_buffers_indexed
190 GL_APICALL void GL_APIENTRY glTexBufferOES(GLenum target, GLenum internalFormat, GLuint buffer);
191 GL_APICALL void GL_APIENTRY glTexBufferRangeOES(GLenum target, GLenum internalFormat, GLuint buffer, GLintptr offset, GLsizeiptr size);
192 GL_APICALL void GL_APIENTRY glTexBufferEXT(GLenum target, GLenum internalFormat, GLuint buffer);
193 GL_APICALL void GL_APIENTRY glTexBufferRangeEXT(GLenum target, GLenum internalFormat, GLuint buffer, GLintptr offset, GLsizeiptr size);
194 GL_APICALL void GL_APIENTRY glEnableiEXT(GLenum cap, GLuint index);
195 GL_APICALL void GL_APIENTRY glDisableiEXT(GLenum cap, GLuint index);
196 GL_APICALL void GL_APIENTRY glBlendEquationiEXT(GLuint index, GLenum mode);
197 GL_APICALL void GL_APIENTRY glBlendEquationSeparateiEXT(GLuint index, GLenum modeRGB, GLenum modeAlpha);
198 GL_APICALL void GL_APIENTRY glBlendFunciEXT(GLuint index, GLenum sfactor, GLenum dfactor);
199 GL_APICALL void GL_APIENTRY glBlendFuncSeparateiEXT(GLuint index, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
200 GL_APICALL void GL_APIENTRY glColorMaskiEXT(GLuint index, GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
201 GL_APICALL GLboolean GL_APIENTRY glIsEnablediEXT(GLenum cap, GLuint index);
202 
203 // Not included: direct-state-access, 1D function pointers
204 
205 // GL_EXT_semaphore
206 GL_APICALL void GL_APIENTRY glImportSemaphoreFdEXT(GLuint semaphore, GLenum handleType, GLint fd);
207 GL_APICALL void GL_APIENTRY glImportSemaphoreWin32HandleEXT(GLuint semaphore, GLenum handleType, void* handle);
208 GL_APICALL void GL_APIENTRY glGenSemaphoresEXT(GLsizei n, GLuint *semaphores);
209 GL_APICALL void GL_APIENTRY glDeleteSemaphoresEXT(GLsizei n, const GLuint *semaphores);
210 GL_APICALL GLboolean glIsSemaphoreEXT(GLuint semaphore);
211 GL_APICALL void GL_APIENTRY glSemaphoreParameterui64vEXT(GLuint semaphore, GLenum pname, const GLuint64 *params);
212 GL_APICALL void GL_APIENTRY glGetSemaphoreParameterui64vEXT(GLuint semaphore, GLenum pname, GLuint64 *params);
213 GL_APICALL void GL_APIENTRY glWaitSemaphoreEXT(GLuint semaphore, GLuint numBufferBarriers, const GLuint *buffers, GLuint numTextureBarriers, const GLuint *textures, const GLenum *srcLayouts);
214 GL_APICALL void GL_APIENTRY glSignalSemaphoreEXT(GLuint semaphore, GLuint numBufferBarriers, const GLuint *buffers, GLuint numTextureBarriers, const GLuint *textures, const GLenum *dstLayouts);
215 
216 // Utility to get global names
217 GL_APICALL GLuint GL_APIENTRY glGetGlobalTexName(GLuint localName);
218 GL_APICALL void  GL_APIENTRY glGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLvoid* pixels);
219 
220 GL_APICALL void GL_APIENTRY glDebugMessageControlKHR(GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint* ids, GLboolean enabled);
221 GL_APICALL void GL_APIENTRY glDebugMessageInsertKHR(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* buf);
222 GL_APICALL void GL_APIENTRY glDebugMessageCallbackKHR(GLDEBUGPROCKHR callback, const void* userdata);
223 GL_APICALL GLuint GL_APIENTRY glGetDebugMessageLogKHR(GLuint count, GLsizei size, GLenum* sources, GLenum* types, GLuint* ids, GLenum* severities, GLsizei* lengths, GLchar* log);
224 GL_APICALL void GL_APIENTRY glPushDebugGroupKHR(GLenum source, GLuint id, GLsizei length, const GLchar* message);
225 GL_APICALL void GL_APIENTRY glPopDebugGroupKHR(void);
226 
227 GL_APICALL void GL_APIENTRY glDebugMessageControl(GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint* ids, GLboolean enabled);
228 GL_APICALL void GL_APIENTRY glDebugMessageInsert(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* buf);
229 GL_APICALL void GL_APIENTRY glDebugMessageCallback(GLDEBUGPROC callback, const void* userdata);
230 GL_APICALL GLuint GL_APIENTRY glGetDebugMessageLog(GLuint count, GLsizei size, GLenum* sources, GLenum* types, GLuint* ids, GLenum* severities, GLsizei* lengths, GLchar* log);
231 GL_APICALL void GL_APIENTRY glPushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar* message);
232 GL_APICALL void GL_APIENTRY glPopDebugGroup(void);
233 
234 
235 } // namespace gles2
236 } // namespace translator
237 
238 extern "C" {
239 
setMaxGlesVersion(GLESVersion version)240 static void setMaxGlesVersion(GLESVersion version) {
241     GLESv2Context::setMaxGlesVersion(version);
242 }
243 
initContext(GLEScontext * ctx,ShareGroupPtr grp,bool nativeTextureDecompressionEnabled)244 static void initContext(GLEScontext* ctx, ShareGroupPtr grp, bool nativeTextureDecompressionEnabled) {
245     setCoreProfile(ctx->isCoreProfile());
246     GLESv2Context::initGlobal(s_eglIface);
247 
248     if (!ctx->shareGroup()) {
249         ctx->setShareGroup(grp);
250     }
251     if (!ctx->isInitialized()) {
252         ctx->init(nativeTextureDecompressionEnabled);
253         translator::gles2::glBindTexture(GL_TEXTURE_2D,0);
254         translator::gles2::glBindTexture(GL_TEXTURE_CUBE_MAP,0);
255     }
256     if (ctx->needRestore()) {
257         ctx->restore();
258     }
259 }
260 
createGLESContext()261 static GLEScontext* createGLESContext() {
262     return new GLESv2Context(2, 0, nullptr, nullptr, nullptr);
263 }
createGLESxContext(int maj,int min,GlobalNameSpace * globalNameSpace,android::base::Stream * stream)264 static GLEScontext* createGLESxContext(int maj, int min,
265         GlobalNameSpace* globalNameSpace, android::base::Stream* stream) {
266     return new GLESv2Context(maj, min, globalNameSpace, stream,
267             s_eglIface->eglGetGlLibrary());
268 }
269 
270 static bool shaderParserInitialized = false;
271 static bool sDebugPrintShaders = false;
272 
273 #define SHADER_DEBUG_PRINT(fmt,...) \
274     if (sDebugPrintShaders) { \
275         printf("shader_debug: %s: " fmt "\n", __func__, ##__VA_ARGS__); \
276     } \
277 
initGLESx(bool isGles2Gles)278 static void initGLESx(bool isGles2Gles) {
279     setGles2Gles(isGles2Gles);
280 }
281 
deleteGLESContext(GLEScontext * ctx)282 static void deleteGLESContext(GLEScontext* ctx) {
283     delete ctx;
284 }
285 
setShareGroup(GLEScontext * ctx,ShareGroupPtr grp)286 static void setShareGroup(GLEScontext* ctx,ShareGroupPtr grp) {
287     if(ctx) {
288         ctx->setShareGroup(grp);
289     }
290 }
291 
getProcAddressGles2(const char * procName)292 static __translatorMustCastToProperFunctionPointerType getProcAddressGles2(const char* procName) {
293     GET_CTX_RET(NULL)
294     ctx->getGlobalLock();
295     static bool proc_table_initialized = false;
296     if (!proc_table_initialized) {
297         proc_table_initialized = true;
298         if (!s_gles2Extensions)
299             s_gles2Extensions = new ProcTableMap();
300         else
301             s_gles2Extensions->clear();
302         (*s_gles2Extensions)["glEGLImageTargetTexture2DOES"] = (__translatorMustCastToProperFunctionPointerType)GLES2_NAMESPACED(glEGLImageTargetTexture2DOES);
303         (*s_gles2Extensions)["glEGLImageTargetRenderbufferStorageOES"]=(__translatorMustCastToProperFunctionPointerType)GLES2_NAMESPACED(glEGLImageTargetRenderbufferStorageOES);
304         (*s_gles2Extensions)["glVertexAttribPointerWithDataSize"] = (__translatorMustCastToProperFunctionPointerType)GLES2_NAMESPACED(glVertexAttribPointerWithDataSize);
305         (*s_gles2Extensions)["glVertexAttribIPointerWithDataSize"] = (__translatorMustCastToProperFunctionPointerType)GLES2_NAMESPACED(glVertexAttribIPointerWithDataSize);
306         (*s_gles2Extensions)["glTestHostDriverPerformance"] = (__translatorMustCastToProperFunctionPointerType)GLES2_NAMESPACED(glTestHostDriverPerformance);
307         (*s_gles2Extensions)["glDrawArraysNullAEMU"] = (__translatorMustCastToProperFunctionPointerType)GLES2_NAMESPACED(glDrawArraysNullAEMU);
308         (*s_gles2Extensions)["glDrawElementsNullAEMU"] = (__translatorMustCastToProperFunctionPointerType)GLES2_NAMESPACED(glDrawElementsNullAEMU);
309         (*s_gles2Extensions)["glGetUnsignedBytevEXT"] = (__translatorMustCastToProperFunctionPointerType)GLES2_NAMESPACED(glGetUnsignedBytevEXT);
310         (*s_gles2Extensions)["glGetUnsignedBytei_vEXT"] = (__translatorMustCastToProperFunctionPointerType)GLES2_NAMESPACED(glGetUnsignedBytei_vEXT);
311         (*s_gles2Extensions)["glImportMemoryFdEXT"] = (__translatorMustCastToProperFunctionPointerType)GLES2_NAMESPACED(glImportMemoryFdEXT);
312         (*s_gles2Extensions)["glImportMemoryWin32HandleEXT"] = (__translatorMustCastToProperFunctionPointerType)GLES2_NAMESPACED(glImportMemoryWin32HandleEXT);
313         (*s_gles2Extensions)["glDeleteMemoryObjectsEXT"] = (__translatorMustCastToProperFunctionPointerType)GLES2_NAMESPACED(glDeleteMemoryObjectsEXT);
314         (*s_gles2Extensions)["glIsMemoryObjectEXT"] = (__translatorMustCastToProperFunctionPointerType)GLES2_NAMESPACED(glIsMemoryObjectEXT);
315         (*s_gles2Extensions)["glCreateMemoryObjectsEXT"] = (__translatorMustCastToProperFunctionPointerType)GLES2_NAMESPACED(glCreateMemoryObjectsEXT);
316         (*s_gles2Extensions)["glMemoryObjectParameterivEXT"] = (__translatorMustCastToProperFunctionPointerType)GLES2_NAMESPACED(glMemoryObjectParameterivEXT);
317         (*s_gles2Extensions)["glGetMemoryObjectParameterivEXT"] = (__translatorMustCastToProperFunctionPointerType)GLES2_NAMESPACED(glGetMemoryObjectParameterivEXT);
318         (*s_gles2Extensions)["glTexStorageMem2DEXT"] = (__translatorMustCastToProperFunctionPointerType)GLES2_NAMESPACED(glTexStorageMem2DEXT);
319         (*s_gles2Extensions)["glTexStorageMem2DMultisampleEXT"] = (__translatorMustCastToProperFunctionPointerType)GLES2_NAMESPACED(glTexStorageMem2DMultisampleEXT);
320         (*s_gles2Extensions)["glTexStorageMem3DEXT"] = (__translatorMustCastToProperFunctionPointerType)GLES2_NAMESPACED(glTexStorageMem3DEXT);
321         (*s_gles2Extensions)["glTexStorageMem3DMultisampleEXT"] = (__translatorMustCastToProperFunctionPointerType)GLES2_NAMESPACED(glTexStorageMem3DMultisampleEXT);
322         (*s_gles2Extensions)["glBufferStorageMemEXT"] = (__translatorMustCastToProperFunctionPointerType)GLES2_NAMESPACED(glBufferStorageMemEXT);
323         (*s_gles2Extensions)["glTexParameteriHOST"] = (__translatorMustCastToProperFunctionPointerType)GLES2_NAMESPACED(glTexParameteriHOST);
324         (*s_gles2Extensions)["glImportSemaphoreFdEXT"] = (__translatorMustCastToProperFunctionPointerType)GLES2_NAMESPACED(glImportSemaphoreFdEXT);
325         (*s_gles2Extensions)["glImportSemaphoreWin32HandleEXT"] = (__translatorMustCastToProperFunctionPointerType)GLES2_NAMESPACED(glImportSemaphoreWin32HandleEXT);
326         (*s_gles2Extensions)["glGenSemaphoresEXT"] = (__translatorMustCastToProperFunctionPointerType)GLES2_NAMESPACED(glGenSemaphoresEXT);
327         (*s_gles2Extensions)["glDeleteSemaphoresEXT"] = (__translatorMustCastToProperFunctionPointerType)GLES2_NAMESPACED(glDeleteSemaphoresEXT);
328         (*s_gles2Extensions)["glIsSemaphoreEXT"] = (__translatorMustCastToProperFunctionPointerType)GLES2_NAMESPACED(glIsSemaphoreEXT);
329         (*s_gles2Extensions)["glSemaphoreParameterui64vEXT"] = (__translatorMustCastToProperFunctionPointerType)GLES2_NAMESPACED(glSemaphoreParameterui64vEXT);
330         (*s_gles2Extensions)["glGetSemaphoreParameterui64vEXT"] = (__translatorMustCastToProperFunctionPointerType)GLES2_NAMESPACED(glGetSemaphoreParameterui64vEXT);
331         (*s_gles2Extensions)["glWaitSemaphoreEXT"] = (__translatorMustCastToProperFunctionPointerType)GLES2_NAMESPACED(glWaitSemaphoreEXT);
332         (*s_gles2Extensions)["glSignalSemaphoreEXT"] = (__translatorMustCastToProperFunctionPointerType)GLES2_NAMESPACED(glSignalSemaphoreEXT);
333         (*s_gles2Extensions)["glGetGlobalTexName"] = (__translatorMustCastToProperFunctionPointerType)GLES2_NAMESPACED(glGetGlobalTexName);
334         (*s_gles2Extensions)["glGetTexImage"] = (__translatorMustCastToProperFunctionPointerType)GLES2_NAMESPACED(glGetTexImage);
335         (*s_gles2Extensions)["glDebugMessageControlKHR"] = (__translatorMustCastToProperFunctionPointerType)GLES2_NAMESPACED(glDebugMessageControlKHR);
336         (*s_gles2Extensions)["glDebugMessageInsertKHR"] = (__translatorMustCastToProperFunctionPointerType)GLES2_NAMESPACED(glDebugMessageInsertKHR);
337         (*s_gles2Extensions)["glDebugMessageCallbackKHR"] = (__translatorMustCastToProperFunctionPointerType)GLES2_NAMESPACED(glDebugMessageCallbackKHR);
338         (*s_gles2Extensions)["glGetDebugMessageLogKHR"] = (__translatorMustCastToProperFunctionPointerType)GLES2_NAMESPACED(glGetDebugMessageLogKHR);
339         (*s_gles2Extensions)["glPushDebugGroupKHR"] = (__translatorMustCastToProperFunctionPointerType)GLES2_NAMESPACED(glPushDebugGroupKHR);
340         (*s_gles2Extensions)["glPopDebugGroupKHR"] = (__translatorMustCastToProperFunctionPointerType)GLES2_NAMESPACED(glPopDebugGroupKHR);
341         (*s_gles2Extensions)["glDebugMessageControl"] = (__translatorMustCastToProperFunctionPointerType)GLES2_NAMESPACED(glDebugMessageControl);
342         (*s_gles2Extensions)["glDebugMessageCallback"] = (__translatorMustCastToProperFunctionPointerType)GLES2_NAMESPACED(glDebugMessageCallback);
343         (*s_gles2Extensions)["glDebugMessageInsert"] = (__translatorMustCastToProperFunctionPointerType)GLES2_NAMESPACED(glDebugMessageInsert);
344         (*s_gles2Extensions)["glGetDebugMessageLog"] = (__translatorMustCastToProperFunctionPointerType)GLES2_NAMESPACED(glGetDebugMessageLog);
345         (*s_gles2Extensions)["glPushDebugGroup"] = (__translatorMustCastToProperFunctionPointerType)GLES2_NAMESPACED(glPushDebugGroup);
346         (*s_gles2Extensions)["glPopDebugGroup"] = (__translatorMustCastToProperFunctionPointerType)GLES2_NAMESPACED(glPopDebugGroup);
347         (*s_gles2Extensions)["glTexBufferOES"] = (__translatorMustCastToProperFunctionPointerType)GLES2_NAMESPACED(glTexBufferOES);
348         (*s_gles2Extensions)["glTexBufferRangeOES"] = (__translatorMustCastToProperFunctionPointerType)GLES2_NAMESPACED(glTexBufferRangeOES);
349         (*s_gles2Extensions)["glTexBufferEXT"] = (__translatorMustCastToProperFunctionPointerType)GLES2_NAMESPACED(glTexBufferEXT);
350         (*s_gles2Extensions)["glTexBufferRangeEXT"] = (__translatorMustCastToProperFunctionPointerType)GLES2_NAMESPACED(glTexBufferRangeEXT);
351         (*s_gles2Extensions)["glEnableiEXT"] = (__translatorMustCastToProperFunctionPointerType)GLES2_NAMESPACED(glEnableiEXT);
352         (*s_gles2Extensions)["glDisableiEXT"] = (__translatorMustCastToProperFunctionPointerType)GLES2_NAMESPACED(glDisableiEXT);
353         (*s_gles2Extensions)["glBlendEquationiEXT"] = (__translatorMustCastToProperFunctionPointerType)GLES2_NAMESPACED(glBlendEquationiEXT);
354         (*s_gles2Extensions)["glBlendEquationSeparateiEXT"] = (__translatorMustCastToProperFunctionPointerType)GLES2_NAMESPACED(glBlendEquationSeparateiEXT);
355         (*s_gles2Extensions)["glBlendFunciEXT"] = (__translatorMustCastToProperFunctionPointerType)GLES2_NAMESPACED(glBlendFunciEXT);
356         (*s_gles2Extensions)["glBlendFuncSeparateiEXT"] = (__translatorMustCastToProperFunctionPointerType)GLES2_NAMESPACED(glBlendFuncSeparateiEXT);
357         (*s_gles2Extensions)["glColorMaskiEXT"] = (__translatorMustCastToProperFunctionPointerType)GLES2_NAMESPACED(glColorMaskiEXT);
358         (*s_gles2Extensions)["glIsEnablediEXT"] = (__translatorMustCastToProperFunctionPointerType)GLES2_NAMESPACED(glIsEnablediEXT);
359     }
360     __translatorMustCastToProperFunctionPointerType ret=NULL;
361     ProcTableMap::iterator val = s_gles2Extensions->find(procName);
362     if (val!=s_gles2Extensions->end())
363         ret = val->second;
364     ctx->releaseGlobalLock();
365 
366     return ret;
367 }
368 
preSaveTexture()369 static void preSaveTexture() {
370     SaveableTexture::preSave();
371 }
372 
postSaveTexture()373 static void postSaveTexture() {
374     SaveableTexture::postSave();
375 }
376 
saveTexture(SaveableTexture * texture,android::base::Stream * stream,SaveableTexture::Buffer * buffer)377 static void saveTexture(SaveableTexture* texture, android::base::Stream* stream,
378                         SaveableTexture::Buffer* buffer) {
379     texture->onSave(stream);
380 }
381 
createTexture(GlobalNameSpace * globalNameSpace,SaveableTexture::loader_t && loader)382 static SaveableTexture* createTexture(GlobalNameSpace* globalNameSpace,
383                                       SaveableTexture::loader_t&& loader) {
384     return new SaveableTexture(globalNameSpace, std::move(loader));
385 }
386 
restoreTexture(SaveableTexture * texture)387 static void restoreTexture(SaveableTexture* texture) {
388     if (!texture) return;
389     texture->touch();
390 }
391 
392 extern "C" {
393 
394 GLESiface* static_translator_glesv2_getIfaces(const EGLiface* eglIface);
395 
static_translator_glesv2_getIfaces(const EGLiface * eglIface)396 GLESiface* static_translator_glesv2_getIfaces(const EGLiface* eglIface) {
397     s_eglIface = (EGLiface*)eglIface;
398     return & s_glesIface;
399 }
400 
401 }
402 
vulkanInteropSupported()403 static bool vulkanInteropSupported() {
404     return GLEScontext::vulkanInteropSupported();
405 }
406 
blitFromCurrentReadBufferANDROID(EGLImage image)407 static void blitFromCurrentReadBufferANDROID(EGLImage image) {
408     GET_CTX()
409     unsigned int imagehndl = SafeUIntFromPointer(image);
410     ImagePtr img = s_eglIface->getEGLImage(imagehndl);
411     if (!img ||
412         !ctx->shareGroup().get()) {
413         // emugl_crash_reporter(
414         //         "FATAL: blitFromCurrentReadBufferANDROID: "
415         //         "image (%p) or share group (%p) not found",
416         //         img.get(), ctx->shareGroup().get());
417         return;
418     }
419 
420     // Could be a bad snapshot load
421     if (!img->isNative) {
422         if (!img->saveableTexture) {
423             return;
424         }
425     }
426 
427     if (img->globalTexObj) {
428         img->saveableTexture->makeDirty();
429         GLuint globalTexObj = img->globalTexObj->getGlobalName();
430         ctx->blitFromReadBufferToTextureFlipped(
431                 globalTexObj, img->width, img->height,
432                 img->internalFormat, img->format, img->type);
433     } else if (img->isNative) {
434         if (!img->width || !img->height || !img->internalFormat) {
435             fprintf(stderr, "%s: error: Tried to blit to internal image, "
436                     "but we don't know the width, height or internalformat.\n", __func__);
437             return;
438         }
439         ctx->blitFromReadBufferToEGLImage(
440 		    img->nativeImage,
441 			img->internalFormat,
442 			img->width, img->height);
443     }
444 }
445 
446 }  // extern "C"
447 
s_attachShader(GLEScontext * ctx,GLuint program,GLuint shader,ShaderParser * shaderParser)448 static void s_attachShader(GLEScontext* ctx, GLuint program, GLuint shader,
449                            ShaderParser* shaderParser) {
450     if (ctx && program && shader && shaderParser) {
451         shaderParser->attachProgram(program);
452     }
453 }
454 
s_detachShader(GLEScontext * ctx,GLuint program,GLuint shader)455 static void s_detachShader(GLEScontext* ctx, GLuint program, GLuint shader) {
456     if (ctx && shader && ctx->shareGroup().get()) {
457         auto shaderData = ctx->shareGroup()->getObjectData(
458                 NamedObjectType::SHADER_OR_PROGRAM, shader);
459         if (!shaderData) return;
460         ShaderParser* shaderParser = (ShaderParser*)shaderData;
461         shaderParser->detachProgram(program);
462         if (shaderParser->getDeleteStatus()
463                 && !shaderParser->hasAttachedPrograms()) {
464             ctx->shareGroup()->deleteName(NamedObjectType::SHADER_OR_PROGRAM, shader);
465         }
466     }
467 }
468 
getTextureData(ObjectLocalName tex)469 static TextureData* getTextureData(ObjectLocalName tex) {
470     GET_CTX_RET(NULL);
471     TextureData *texData = NULL;
472     auto objData =
473             ctx->shareGroup()->getObjectData(NamedObjectType::TEXTURE, tex);
474     if(!objData){
475         texData = new TextureData();
476         ctx->shareGroup()->setObjectData(NamedObjectType::TEXTURE, tex,
477                                          ObjectDataPtr(texData));
478     } else {
479         texData = (TextureData*)objData;
480     }
481     return texData;
482 }
483 
getTextureTargetData(GLenum target)484 static TextureData* getTextureTargetData(GLenum target){
485     GET_CTX_RET(NULL);
486     unsigned int tex = ctx->getBindedTexture(target);
487     return getTextureData(ctx->getTextureLocalName(target,tex));
488 }
489 
490 namespace translator {
491 namespace gles2 {
492 
glActiveTexture(GLenum texture)493 GL_APICALL void  GL_APIENTRY glActiveTexture(GLenum texture){
494     GET_CTX_V2();
495     SET_ERROR_IF (!GLESv2Validate::textureEnum(texture,ctx->getMaxCombinedTexUnits()),GL_INVALID_ENUM);
496     ctx->setActiveTexture(texture);
497     ctx->dispatcher().glActiveTexture(texture);
498 }
499 
glAttachShader(GLuint program,GLuint shader)500 GL_APICALL void  GL_APIENTRY glAttachShader(GLuint program, GLuint shader){
501     GET_CTX();
502     if(ctx->shareGroup().get()) {
503         const GLuint globalProgramName = ctx->shareGroup()->getGlobalName(
504                 NamedObjectType::SHADER_OR_PROGRAM, program);
505         SET_ERROR_IF(globalProgramName==0, GL_INVALID_VALUE);
506         const GLuint globalShaderName = ctx->shareGroup()->getGlobalName(
507                 NamedObjectType::SHADER_OR_PROGRAM, shader);
508         SET_ERROR_IF(globalShaderName==0, GL_INVALID_VALUE);
509 
510         auto programData = ctx->shareGroup()->getObjectData(
511                 NamedObjectType::SHADER_OR_PROGRAM, program);
512         auto shaderData = ctx->shareGroup()->getObjectData(
513                 NamedObjectType::SHADER_OR_PROGRAM, shader);
514         SET_ERROR_IF(!shaderData || !programData ,GL_INVALID_OPERATION);
515         SET_ERROR_IF(!(shaderData->getDataType() ==SHADER_DATA) ||
516                      !(programData->getDataType()==PROGRAM_DATA) ,GL_INVALID_OPERATION);
517 
518         GLenum shaderType = ((ShaderParser*)shaderData)->getType();
519         ProgramData* pData = (ProgramData*)programData;
520         SET_ERROR_IF((pData->getAttachedShader(shaderType)!=0), GL_INVALID_OPERATION);
521         pData->attachShader(shader, (ShaderParser*)shaderData, shaderType);
522         s_attachShader(ctx, program, shader, (ShaderParser*)shaderData);
523 
524         SHADER_DEBUG_PRINT(
525             "attach shader %u to program %u", shader, program);
526         ctx->dispatcher().glAttachShader(globalProgramName,globalShaderName);
527     }
528 }
529 
glBindAttribLocation(GLuint program,GLuint index,const GLchar * name)530 GL_APICALL void  GL_APIENTRY glBindAttribLocation(GLuint program, GLuint index, const GLchar* name){
531     GET_CTX();
532     SET_ERROR_IF(!GLESv2Validate::attribName(name),GL_INVALID_OPERATION);
533     SET_ERROR_IF(!GLESv2Validate::attribIndex(index, ctx->getCaps()->maxVertexAttribs),GL_INVALID_VALUE);
534     if(ctx->shareGroup().get()) {
535         const GLuint globalProgramName = ctx->shareGroup()->getGlobalName(
536                 NamedObjectType::SHADER_OR_PROGRAM, program);
537         SET_ERROR_IF(globalProgramName==0, GL_INVALID_VALUE);
538         auto objData = ctx->shareGroup()->getObjectData(
539                 NamedObjectType::SHADER_OR_PROGRAM, program);
540         SET_ERROR_IF(objData->getDataType()!=PROGRAM_DATA,GL_INVALID_OPERATION);
541 
542         ProgramData* pData = (ProgramData*)objData;
543 
544         ctx->dispatcher().glBindAttribLocation(
545                 globalProgramName, index,
546                 pData->getTranslatedName(name).c_str());
547 
548         pData->bindAttribLocation(name, index);
549     }
550 }
551 
glBindBuffer(GLenum target,GLuint buffer)552 GL_APICALL void  GL_APIENTRY glBindBuffer(GLenum target, GLuint buffer){
553     GET_CTX_V2();
554     SET_ERROR_IF(!GLESv2Validate::bufferTarget(ctx, target), GL_INVALID_ENUM);
555 
556     GLuint globalBufferName = ctx->bindBuffer(target,buffer);
557     ctx->dispatcher().glBindBuffer(target, globalBufferName);
558 }
559 
sIsFboTextureTarget(GLenum target)560 static bool sIsFboTextureTarget(GLenum target) {
561     switch (target) {
562     case GL_TEXTURE_2D:
563     case GL_TEXTURE_CUBE_MAP:
564     case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
565     case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
566     case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
567     case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
568     case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
569     case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
570     case GL_TEXTURE_2D_ARRAY:
571     case GL_TEXTURE_3D:
572     case GL_TEXTURE_2D_MULTISAMPLE:
573         return true;
574     default:
575         return false;
576     }
577 }
578 
579 template <class T>
sHasAttachmentWithFormat(const GLESv2Context * ctx,FramebufferData * fbData,const T & attachments,const std::initializer_list<GLenum> formats)580 static bool sHasAttachmentWithFormat(const GLESv2Context* ctx,
581                                      FramebufferData* fbData,
582                                      const T& attachments,
583                                      const std::initializer_list<GLenum> formats) {
584 
585     for (auto attachment : attachments) {
586         GLenum target;
587         GLuint name = fbData->getAttachment(attachment, &target, NULL);
588 
589         if (!name) continue;
590 
591         if (target == GL_RENDERBUFFER) {
592             auto objData = ctx->shareGroup()->getObjectData(
593                     NamedObjectType::RENDERBUFFER, name);
594             if (auto rbData = (RenderbufferData*)objData) {
595                 GLenum rb_internalformat = rbData->internalformat;
596                 for (auto triggerFormat : formats) {
597                     if (rb_internalformat == triggerFormat) {
598                         return true;
599                     }
600                 }
601             }
602         } else if (sIsFboTextureTarget(target)) {
603             if (TextureData* tex = getTextureData(name)) {
604                 GLenum tex_internalformat = tex->internalFormat;
605                 for (auto triggerFormat : formats) {
606                     if (tex_internalformat == triggerFormat) {
607                         return true;
608                     }
609                 }
610             }
611         }
612     }
613 
614     return false;
615 }
616 
617 
sSetDesktopGLEnable(const GLESv2Context * ctx,bool enable,GLenum cap)618 static void sSetDesktopGLEnable(const GLESv2Context* ctx, bool enable, GLenum cap) {
619     if (enable)
620         ctx->dispatcher().glEnable(cap);
621     else
622         ctx->dispatcher().glDisable(cap);
623 }
624 
625 // Framebuffer format workarounds:
626 // Desktop OpenGL implicit framebuffer behavior is much more configurable
627 // than that of OpenGL ES. In OpenGL ES, some implicit operations can happen
628 // depending on the internal format and attachment combinations of the
629 // framebuffer object.
sUpdateFboEmulation(GLESv2Context * ctx)630 static void sUpdateFboEmulation(GLESv2Context* ctx) {
631     if (ctx->getMajorVersion() < 3 || isGles2Gles()) {
632         return;
633     }
634 
635     std::vector<GLenum> colorAttachments(ctx->getCaps()->maxDrawBuffers);
636     std::iota(colorAttachments.begin(), colorAttachments.end(), GL_COLOR_ATTACHMENT0);
637     const auto depthAttachments =
638         {GL_DEPTH_ATTACHMENT, GL_DEPTH_STENCIL_ATTACHMENT};
639 
640     GLuint read_fbo = ctx->getFramebufferBinding(GL_READ_FRAMEBUFFER);
641     GLuint draw_fbo = ctx->getFramebufferBinding(GL_DRAW_FRAMEBUFFER);
642 
643     bool enableSRGB = false;
644     bool enableDepth32fClamp = false;
645 
646     for (auto fbObj : {ctx->getFBOData(read_fbo),
647                        ctx->getFBOData(draw_fbo)}) {
648 
649         if (fbObj == nullptr) { continue; }
650 
651         // Enable GL_FRAMEBUFFER_SRGB when any framebuffer has SRGB color attachment.
652         if (sHasAttachmentWithFormat(ctx, fbObj,
653                     colorAttachments, {GL_SRGB8_ALPHA8}))
654             enableSRGB = true;
655 
656         // Enable GL_DEPTH_CLAMP when any fbo's
657         // GL_DEPTH_ATTACHMENT or GL_DEPTH_STENCIL_ATTACHMENT is of internal format
658         // GL_DEPTH_COMPONENT32F or GL_DEPTH32F_STENCIL8.
659         if (sHasAttachmentWithFormat(ctx, fbObj,
660                     depthAttachments, {GL_DEPTH_COMPONENT32F, GL_DEPTH32F_STENCIL8}))
661             enableDepth32fClamp = true;
662 
663         // Perform any necessary workarounds for apps that use separate depth/stencil
664         // attachments.
665         fbObj->separateDepthStencilWorkaround(ctx);
666     }
667 
668     // TODO: GLES3: snapshot those enable value as well?
669     sSetDesktopGLEnable(ctx, enableSRGB, GL_FRAMEBUFFER_SRGB);
670     sSetDesktopGLEnable(ctx, enableDepth32fClamp, GL_DEPTH_CLAMP);
671 }
672 
glBindFramebuffer(GLenum target,GLuint framebuffer)673 GL_APICALL void  GL_APIENTRY glBindFramebuffer(GLenum target, GLuint framebuffer){
674     GET_CTX_V2();
675     SET_ERROR_IF(!GLESv2Validate::framebufferTarget(ctx, target),GL_INVALID_ENUM);
676 
677     GLuint globalFrameBufferName;
678     bool isDefaultFBO = !framebuffer;
679     if (isDefaultFBO) {
680        globalFrameBufferName = ctx->getDefaultFBOGlobalName();
681        ctx->dispatcher().glBindFramebuffer(target, globalFrameBufferName);
682        ctx->setFramebufferBinding(target, 0);
683     } else {
684         globalFrameBufferName = framebuffer;
685         if(framebuffer){
686             globalFrameBufferName = ctx->getFBOGlobalName(framebuffer);
687             //if framebuffer wasn't generated before,generate one
688             if(!globalFrameBufferName){
689                 ctx->genFBOName(framebuffer);
690                 globalFrameBufferName = ctx->getFBOGlobalName(framebuffer);
691                 ctx->setFBOData(framebuffer,
692                         ObjectDataPtr(new FramebufferData(framebuffer,
693                                                           globalFrameBufferName)));
694             }
695             // set that this framebuffer has been bound before
696             auto fbObj = ctx->getFBOData(framebuffer);
697             fbObj->setBoundAtLeastOnce();
698         }
699         ctx->dispatcher().glBindFramebuffer(target,globalFrameBufferName);
700         ctx->setFramebufferBinding(target, framebuffer);
701     }
702 
703     sUpdateFboEmulation(ctx);
704 }
705 
glBindRenderbuffer(GLenum target,GLuint renderbuffer)706 GL_APICALL void  GL_APIENTRY glBindRenderbuffer(GLenum target, GLuint renderbuffer){
707     GET_CTX();
708     SET_ERROR_IF(!GLESv2Validate::renderbufferTarget(target),GL_INVALID_ENUM);
709 
710     GLuint globalRenderBufferName = renderbuffer;
711     if(renderbuffer && ctx->shareGroup().get()){
712         globalRenderBufferName = ctx->shareGroup()->getGlobalName(
713                 NamedObjectType::RENDERBUFFER, renderbuffer);
714         //if renderbuffer wasn't generated before,generate one
715         if(!globalRenderBufferName){
716             ctx->shareGroup()->genName(NamedObjectType::RENDERBUFFER,
717                                        renderbuffer);
718             RenderbufferData* rboData = new RenderbufferData();
719             rboData->everBound = true;
720             ctx->shareGroup()->setObjectData(
721                     NamedObjectType::RENDERBUFFER, renderbuffer,
722                     ObjectDataPtr(rboData));
723             globalRenderBufferName = ctx->shareGroup()->getGlobalName(
724                     NamedObjectType::RENDERBUFFER, renderbuffer);
725         } else {
726             RenderbufferData* rboData = (RenderbufferData*)(ctx->shareGroup()->getObjectDataPtr(
727                     NamedObjectType::RENDERBUFFER, renderbuffer).get());
728             if (rboData) rboData->everBound = true;
729         }
730     }
731     ctx->dispatcher().glBindRenderbuffer(target,globalRenderBufferName);
732 
733     // update renderbuffer binding state
734     ctx->setRenderbufferBinding(renderbuffer);
735 }
736 
glGetGlobalTexName(GLuint localName)737 GL_APICALL GLuint GL_APIENTRY glGetGlobalTexName(GLuint localName) {
738     GET_CTX_V2_RET(0);
739     GLuint globalTextureName = ctx->shareGroup()->getGlobalName(
740             NamedObjectType::TEXTURE, localName);
741     return globalTextureName;
742 }
743 
glBindTexture(GLenum target,GLuint texture)744 GL_APICALL void  GL_APIENTRY glBindTexture(GLenum target, GLuint texture){
745     GET_CTX_V2();
746     SET_ERROR_IF(!GLESv2Validate::textureTarget(ctx, target), GL_INVALID_ENUM);
747 
748     //for handling default texture (0)
749     ObjectLocalName localTexName = ctx->getTextureLocalName(target,texture);
750     GLuint globalTextureName = localTexName;
751     if (ctx->shareGroup().get()) {
752         globalTextureName = ctx->shareGroup()->getGlobalName(
753                 NamedObjectType::TEXTURE, localTexName);
754         //if texture wasn't generated before,generate one
755         if(!globalTextureName){
756             ctx->shareGroup()->genName(NamedObjectType::TEXTURE, localTexName);
757             globalTextureName = ctx->shareGroup()->getGlobalName(
758                     NamedObjectType::TEXTURE, localTexName);
759         }
760 
761         TextureData* texData = getTextureData(localTexName);
762         if (texData->target==0) {
763             texData->setTarget(target);
764         }
765         //if texture was already bound to another target
766 
767         if (ctx->GLTextureTargetToLocal(texData->target) != ctx->GLTextureTargetToLocal(target)) {
768             fprintf(stderr, "%s: Set invalid operation!\n", __func__);
769         }
770         SET_ERROR_IF(ctx->GLTextureTargetToLocal(texData->target) != ctx->GLTextureTargetToLocal(target), GL_INVALID_OPERATION);
771         texData->setGlobalName(globalTextureName);
772         if (!texData->wasBound) {
773             texData->resetSaveableTexture();
774         }
775         texData->wasBound = true;
776     }
777 
778     ctx->setBindedTexture(target,texture);
779     ctx->dispatcher().glBindTexture(target,globalTextureName);
780 
781     if (ctx->getMajorVersion() < 3) return;
782 
783     // OpenGL ES assumes that rendered depth textures shade as (v, 0, 0, 1)
784     // when coming out of the fragment shader.
785     // Desktop OpenGL assumes (v, v, v, 1).
786     // GL_DEPTH_TEXTURE_MODE can be set to GL_RED to follow the OpenGL ES behavior.
787     if (!ctx->isCoreProfile() && !isGles2Gles()) {
788 #define GL_DEPTH_TEXTURE_MODE 0x884B
789         ctx->dispatcher().glTexParameteri(target ,GL_DEPTH_TEXTURE_MODE, GL_RED);
790     }
791 }
792 
glBlendColor(GLclampf red,GLclampf green,GLclampf blue,GLclampf alpha)793 GL_APICALL void  GL_APIENTRY glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha){
794     GET_CTX();
795     ctx->dispatcher().glBlendColor(red,green,blue,alpha);
796 }
797 
glBlendEquation(GLenum mode)798 GL_APICALL void  GL_APIENTRY glBlendEquation( GLenum mode ){
799     GET_CTX_V2();
800     SET_ERROR_IF(!GLESv2Validate::blendEquationMode(ctx, mode), GL_INVALID_ENUM);
801     ctx->setBlendEquationSeparate(mode, mode);
802     ctx->dispatcher().glBlendEquation(mode);
803 }
804 
glBlendEquationSeparate(GLenum modeRGB,GLenum modeAlpha)805 GL_APICALL void  GL_APIENTRY glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha){
806     GET_CTX_V2();
807     SET_ERROR_IF(!(GLESv2Validate::blendEquationMode(ctx, modeRGB) &&
808                    GLESv2Validate::blendEquationMode(ctx, modeAlpha)), GL_INVALID_ENUM);
809     ctx->setBlendEquationSeparate(modeRGB, modeAlpha);
810     ctx->dispatcher().glBlendEquationSeparate(modeRGB,modeAlpha);
811 }
812 
glBlendFunc(GLenum sfactor,GLenum dfactor)813 GL_APICALL void  GL_APIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor){
814     GET_CTX();
815     SET_ERROR_IF(!GLESv2Validate::blendSrc(sfactor) || !GLESv2Validate::blendDst(dfactor),GL_INVALID_ENUM)
816     ctx->setBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor);
817     ctx->dispatcher().glBlendFunc(sfactor,dfactor);
818 }
819 
glBlendFuncSeparate(GLenum srcRGB,GLenum dstRGB,GLenum srcAlpha,GLenum dstAlpha)820 GL_APICALL void  GL_APIENTRY glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha){
821     GET_CTX();
822     SET_ERROR_IF(
823 !(GLESv2Validate::blendSrc(srcRGB) && GLESv2Validate::blendDst(dstRGB) && GLESv2Validate::blendSrc(srcAlpha) && GLESv2Validate::blendDst(dstAlpha)),GL_INVALID_ENUM);
824     ctx->setBlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
825     ctx->dispatcher().glBlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
826 }
827 
glBufferData(GLenum target,GLsizeiptr size,const GLvoid * data,GLenum usage)828 GL_APICALL void  GL_APIENTRY glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage){
829     GET_CTX_V2();
830     SET_ERROR_IF(!GLESv2Validate::bufferTarget(ctx, target), GL_INVALID_ENUM);
831     SET_ERROR_IF(!ctx->isBindedBuffer(target),GL_INVALID_OPERATION);
832     SET_ERROR_IF(!GLESv2Validate::bufferUsage(ctx, usage), GL_INVALID_ENUM);
833     ctx->setBufferData(target,size,data,usage);
834     ctx->dispatcher().glBufferData(target, size, data, usage);
835 }
836 
glBufferSubData(GLenum target,GLintptr offset,GLsizeiptr size,const GLvoid * data)837 GL_APICALL void  GL_APIENTRY glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data){
838     GET_CTX_V2();
839     SET_ERROR_IF(!GLESv2Validate::bufferTarget(ctx, target), GL_INVALID_ENUM);
840     SET_ERROR_IF(!ctx->isBindedBuffer(target),GL_INVALID_OPERATION);
841     SET_ERROR_IF(!ctx->setBufferSubData(target,offset,size,data),GL_INVALID_VALUE);
842     ctx->dispatcher().glBufferSubData(target, offset, size, data);
843 }
844 
845 
glCheckFramebufferStatus(GLenum target)846 GL_APICALL GLenum GL_APIENTRY glCheckFramebufferStatus(GLenum target){
847     GET_CTX_V2_RET(GL_FRAMEBUFFER_COMPLETE);
848     RET_AND_SET_ERROR_IF(!GLESv2Validate::framebufferTarget(ctx, target), GL_INVALID_ENUM, GL_FRAMEBUFFER_COMPLETE);
849     // We used to issue ctx->drawValidate() here, but it can corrupt the status of
850     // separately bound draw/read framebuffer objects. So we just don't call it now.
851     return ctx->dispatcher().glCheckFramebufferStatus(target);
852 }
853 
glClear(GLbitfield mask)854 GL_APICALL void  GL_APIENTRY glClear(GLbitfield mask){
855     GET_CTX();
856     GLbitfield allowed_bits = GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
857     GLbitfield has_disallowed_bits = (mask & ~allowed_bits);
858     SET_ERROR_IF(has_disallowed_bits, GL_INVALID_VALUE);
859 
860     if (ctx->getMajorVersion() < 3)
861         ctx->drawValidate();
862 
863     ctx->dispatcher().glClear(mask);
864 }
glClearColor(GLclampf red,GLclampf green,GLclampf blue,GLclampf alpha)865 GL_APICALL void  GL_APIENTRY glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha){
866     GET_CTX();
867     ctx->setClearColor(red,green, blue, alpha);
868     ctx->dispatcher().glClearColor(red,green,blue,alpha);
869 }
glClearDepthf(GLclampf depth)870 GL_APICALL void  GL_APIENTRY glClearDepthf(GLclampf depth){
871     GET_CTX();
872     ctx->setClearDepth(depth);
873     if (isGles2Gles()) {
874         ctx->dispatcher().glClearDepthf(depth);
875     } else {
876         ctx->dispatcher().glClearDepth(depth);
877     }
878 }
glClearStencil(GLint s)879 GL_APICALL void  GL_APIENTRY glClearStencil(GLint s){
880     GET_CTX();
881     ctx->setClearStencil(s);
882     ctx->dispatcher().glClearStencil(s);
883 }
glColorMask(GLboolean red,GLboolean green,GLboolean blue,GLboolean alpha)884 GL_APICALL void  GL_APIENTRY glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha){
885     GET_CTX();
886     ctx->setColorMask(red, green, blue, alpha);
887     ctx->dispatcher().glColorMask(red,green,blue,alpha);
888 }
889 
glCompileShader(GLuint shader)890 GL_APICALL void  GL_APIENTRY glCompileShader(GLuint shader){
891     GET_CTX();
892     if(ctx->shareGroup().get()) {
893         const GLuint globalShaderName = ctx->shareGroup()->getGlobalName(
894                 NamedObjectType::SHADER_OR_PROGRAM, shader);
895         SET_ERROR_IF(globalShaderName==0, GL_INVALID_VALUE);
896         auto objData = ctx->shareGroup()->getObjectData(
897                 NamedObjectType::SHADER_OR_PROGRAM, shader);
898         SET_ERROR_IF(objData->getDataType()!= SHADER_DATA,GL_INVALID_OPERATION);
899         ShaderParser* sp = (ShaderParser*)objData;
900         SET_ERROR_IF(sp->getDeleteStatus(), GL_INVALID_VALUE);
901         GLint compileStatus;
902         if (sp->validShader()) {
903             ctx->dispatcher().glCompileShader(globalShaderName);
904 
905             GLsizei infoLogLength=0;
906             GLchar* infoLog;
907             ctx->dispatcher().glGetShaderiv(globalShaderName,GL_INFO_LOG_LENGTH,&infoLogLength);
908             infoLog = new GLchar[infoLogLength+1];
909             ctx->dispatcher().glGetShaderInfoLog(globalShaderName,infoLogLength,NULL,infoLog);
910             if (infoLogLength == 0) {
911                 infoLog[0] = 0;
912             }
913             sp->setInfoLog(infoLog);
914 
915             ctx->dispatcher().glGetShaderiv(globalShaderName,GL_COMPILE_STATUS,&compileStatus);
916             sp->setCompileStatus(compileStatus == GL_FALSE ? false : true);
917         } else {
918             ctx->dispatcher().glCompileShader(globalShaderName);
919             sp->setCompileStatus(false);
920             ctx->dispatcher().glGetShaderiv(globalShaderName,GL_COMPILE_STATUS,&compileStatus);
921             if (compileStatus != GL_FALSE) {
922                 fprintf(stderr, "%s: Warning: underlying GL compiled invalid shader!\n", __func__);
923             }
924         }
925     }
926 }
927 
928 GL_APICALL void  GL_APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels);
929 
glCompressedTexImage2D(GLenum target,GLint level,GLenum internalformat,GLsizei width,GLsizei height,GLint border,GLsizei imageSize,const GLvoid * data)930 GL_APICALL void  GL_APIENTRY glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* data)
931 {
932     GET_CTX();
933     SET_ERROR_IF(!GLESv2Validate::textureTargetEx(ctx, target),GL_INVALID_ENUM);
934     SET_ERROR_IF(level < 0 || imageSize < 0, GL_INVALID_VALUE);
935 
936     auto funcPtr = translator::gles2::glTexImage2D;
937 
938     if (shouldPassthroughCompressedFormat(ctx, internalformat)) {
939         doCompressedTexImage2DNative(ctx, target, level, internalformat,
940                                           width, height, border, imageSize, data);
941     } else {
942         doCompressedTexImage2D(ctx, target, level, internalformat,
943                                     width, height, border,
944                                     imageSize, data, funcPtr);
945     }
946 
947     TextureData* texData = getTextureTargetData(target);
948     if (texData) {
949         texData->compressed = true;
950         texData->compressedFormat = internalformat;
951         if (shouldPassthroughCompressedFormat(ctx, internalformat)) {
952             texData->internalFormat = internalformat;
953         }
954     }
955 }
956 
957 GL_APICALL void  GL_APIENTRY glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid* pixels);
958 
glCompressedTexSubImage2D(GLenum target,GLint level,GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,GLenum format,GLsizei imageSize,const GLvoid * data)959 GL_APICALL void  GL_APIENTRY glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* data){
960     GET_CTX();
961     SET_ERROR_IF(!GLESv2Validate::textureTargetEx(ctx, target),GL_INVALID_ENUM);
962     if (ctx->shareGroup().get()) {
963         TextureData* texData = getTextureTargetData(target);
964         if (texData) {
965             if (isEtc2Format(texData->compressedFormat)) {
966                 int encodedDataSize =
967                     etc_get_encoded_data_size(
968                         getEtcFormat(texData->compressedFormat),
969                         width, height);
970                 SET_ERROR_IF(imageSize != encodedDataSize, GL_INVALID_VALUE);
971                 GLsizei lvlWidth = texData->width >> level;
972                 GLsizei lvlHeight = texData->height >> level;
973                 if (texData->width && !lvlWidth) lvlWidth = 1;
974                 if (texData->height && !lvlHeight) lvlHeight = 1;
975                 SET_ERROR_IF((width % 4) && ((xoffset + width) != (GLsizei)lvlWidth), GL_INVALID_OPERATION);
976                 SET_ERROR_IF((height % 4) && ((yoffset + height) != (GLsizei)lvlHeight), GL_INVALID_OPERATION);
977                 SET_ERROR_IF(xoffset % 4, GL_INVALID_OPERATION);
978                 SET_ERROR_IF(yoffset % 4, GL_INVALID_OPERATION);
979             }
980             SET_ERROR_IF(format != texData->compressedFormat, GL_INVALID_OPERATION);
981         }
982         SET_ERROR_IF(ctx->getMajorVersion() < 3 && !data, GL_INVALID_OPERATION);
983         if (shouldPassthroughCompressedFormat(ctx, format)) {
984             doCompressedTexSubImage2DNative(ctx, target, level, xoffset, yoffset,
985                                                  width, height, format, imageSize, data);
986         } else {
987             doCompressedTexImage2D(ctx, target, level, format,
988                     width, height, 0, imageSize, data,
989                     [xoffset, yoffset](GLenum target, GLint level,
990                     GLint internalformat, GLsizei width, GLsizei height,
991                     GLint border, GLenum format, GLenum type,
992                     const GLvoid* data) {
993                         glTexSubImage2D(target, level, xoffset, yoffset,
994                             width, height, format, type, data);
995                     });
996         }
997     }
998 }
999 
s_glInitTexImage2D(GLenum target,GLint level,GLint internalformat,GLsizei width,GLsizei height,GLint border,GLint samples,GLenum * format,GLenum * type,GLint * internalformat_out)1000 void s_glInitTexImage2D(GLenum target, GLint level, GLint internalformat,
1001         GLsizei width, GLsizei height, GLint border, GLint samples, GLenum* format,
1002         GLenum* type, GLint* internalformat_out) {
1003     GET_CTX();
1004 
1005     if (ctx->shareGroup().get()) {
1006         TextureData *texData = getTextureTargetData(target);
1007 
1008         if (texData) {
1009             texData->hasStorage = true;
1010             texData->setMipmapLevelAtLeast(static_cast<unsigned int>(level));
1011         }
1012 
1013         if (texData && level == 0) {
1014             assert(texData->target == GL_TEXTURE_2D ||
1015                     texData->target == GL_TEXTURE_2D_MULTISAMPLE ||
1016                     texData->target == GL_TEXTURE_CUBE_MAP);
1017             if (GLESv2Validate::isCompressedFormat(internalformat)) {
1018                 texData->compressed = true;
1019                 texData->compressedFormat = internalformat;
1020                 texData->internalFormat = shouldPassthroughCompressedFormat(ctx, internalformat) ? internalformat : decompressedInternalFormat(ctx, internalformat);
1021             } else {
1022                 texData->internalFormat = internalformat;
1023             }
1024             if (internalformat_out) {
1025                 *internalformat_out = texData->internalFormat;
1026             }
1027             texData->width = width;
1028             texData->height = height;
1029             texData->border = border;
1030             texData->samples = samples;
1031             if (format) texData->format = *format;
1032             if (type) texData->type = *type;
1033 
1034             if (texData->sourceEGLImage != 0) {
1035                 //
1036                 // This texture was a target of EGLImage,
1037                 // but now it is re-defined so we need to
1038                 // re-generate global texture name for it.
1039                 //
1040                 unsigned int tex = ctx->getBindedTexture(target);
1041                 ctx->shareGroup()->genName(NamedObjectType::TEXTURE, tex,
1042                         false);
1043                 unsigned int globalTextureName =
1044                     ctx->shareGroup()->getGlobalName(
1045                             NamedObjectType::TEXTURE, tex);
1046                 ctx->dispatcher().glBindTexture(GL_TEXTURE_2D,
1047                         globalTextureName);
1048                 texData->sourceEGLImage = 0;
1049                 texData->setGlobalName(globalTextureName);
1050             }
1051             texData->resetSaveableTexture();
1052         }
1053         texData->makeDirty();
1054     }
1055 
1056 }
1057 
s_glInitTexImage3D(GLenum target,GLint level,GLint internalformat,GLsizei width,GLsizei height,GLsizei depth,GLint border,GLenum format,GLenum type)1058 void s_glInitTexImage3D(GLenum target, GLint level, GLint internalformat,
1059         GLsizei width, GLsizei height, GLsizei depth, GLint border,
1060         GLenum format, GLenum type){
1061     GET_CTX();
1062 
1063     if (ctx->shareGroup().get()){
1064         TextureData *texData = getTextureTargetData(target);
1065 
1066         if (texData) {
1067             texData->hasStorage = true;
1068             texData->setMipmapLevelAtLeast(static_cast<unsigned int>(level));
1069         }
1070 
1071         if (texData && level == 0) {
1072             texData->width = width;
1073             texData->height = height;
1074             texData->depth = depth;
1075             texData->border = border;
1076             texData->internalFormat = internalformat;
1077             texData->target = target;
1078             texData->format = format;
1079             texData->type = type;
1080             texData->resetSaveableTexture();
1081         }
1082         texData->makeDirty();
1083     }
1084 }
1085 
glCopyTexImage2D(GLenum target,GLint level,GLenum internalformat,GLint x,GLint y,GLsizei width,GLsizei height,GLint border)1086 GL_APICALL void  GL_APIENTRY glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border){
1087     GET_CTX_V2();
1088     SET_ERROR_IF(!(GLESv2Validate::pixelFrmt(ctx,internalformat) &&
1089                    (GLESv2Validate::textureTarget(ctx, target) ||
1090                     GLESv2Validate::textureTargetEx(ctx, target))), GL_INVALID_ENUM);
1091     SET_ERROR_IF((GLESv2Validate::textureIsCubeMap(target) && width != height), GL_INVALID_VALUE);
1092     SET_ERROR_IF(border != 0,GL_INVALID_VALUE);
1093 
1094     GLenum format = baseFormatOfInternalFormat((GLint)internalformat);
1095     GLenum type = accurateTypeOfInternalFormat((GLint)internalformat);
1096     s_glInitTexImage2D(
1097         target, level, internalformat, width, height, border, 0,
1098         &format, &type, (GLint*)&internalformat);
1099 
1100     TextureData* texData = getTextureTargetData(target);
1101     if (texData && isCoreProfile() &&
1102         isCoreProfileEmulatedFormat(texData->format)) {
1103         GLEScontext::prepareCoreProfileEmulatedTexture(
1104             getTextureTargetData(target),
1105             false, target, format, type,
1106             (GLint*)&internalformat, &format);
1107         ctx->copyTexImageWithEmulation(
1108             texData, false, target, level, internalformat,
1109             0, 0, x, y, width, height, border);
1110     } else {
1111         ctx->dispatcher().glCopyTexImage2D(
1112             target, level, internalformat,
1113             x, y, width, height, border);
1114     }
1115 }
1116 
glCopyTexSubImage2D(GLenum target,GLint level,GLint xoffset,GLint yoffset,GLint x,GLint y,GLsizei width,GLsizei height)1117 GL_APICALL void  GL_APIENTRY glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height){
1118     GET_CTX_V2();
1119     SET_ERROR_IF(!(GLESv2Validate::textureTarget(ctx, target) ||
1120                    GLESv2Validate::textureTargetEx(ctx, target)), GL_INVALID_ENUM);
1121     TextureData* texData = getTextureTargetData(target);
1122     if (texData) {
1123         texData->makeDirty();
1124     }
1125     if (texData && isCoreProfile() &&
1126         isCoreProfileEmulatedFormat(texData->format)) {
1127         ctx->copyTexImageWithEmulation(
1128             texData, true, target, level, 0, xoffset, yoffset, x, y, width, height, 0);
1129     } else {
1130         ctx->dispatcher().glCopyTexSubImage2D(target,level,xoffset,yoffset,x,y,width,height);
1131     }
1132 }
1133 
glCreateProgram(void)1134 GL_APICALL GLuint GL_APIENTRY glCreateProgram(void){
1135     GET_CTX_RET(0);
1136     if(ctx->shareGroup().get()) {
1137         ProgramData* programInfo =
1138             new ProgramData(ctx->getMajorVersion(),
1139                             ctx->getMinorVersion());
1140         const GLuint localProgramName =
1141                 ctx->shareGroup()->genName(ShaderProgramType::PROGRAM, 0, true);
1142         ctx->shareGroup()->setObjectData(NamedObjectType::SHADER_OR_PROGRAM,
1143                                          localProgramName,
1144                                          ObjectDataPtr(programInfo));
1145         programInfo->addProgramName(ctx->shareGroup()->getGlobalName(
1146                          NamedObjectType::SHADER_OR_PROGRAM, localProgramName));
1147         return localProgramName;
1148     }
1149     return 0;
1150 }
1151 
glCreateShader(GLenum type)1152 GL_APICALL GLuint GL_APIENTRY glCreateShader(GLenum type){
1153     GET_CTX_V2_RET(0);
1154     // Lazy init so we can catch the caps.
1155     if (!shaderParserInitialized) {
1156         shaderParserInitialized = true;
1157         sDebugPrintShaders =
1158             android::base::getEnvironmentVariable(
1159                 "ANDROID_EMUGL_SHADER_PRINT") == "1";
1160 
1161         auto& gl = ctx->dispatcher();
1162         auto glesMajorVersion = ctx->getMajorVersion();
1163         auto glesMinorVersion = ctx->getMinorVersion();
1164 
1165 #ifdef USE_ANGLE_SHADER_PARSER
1166         ANGLEShaderParser::BuiltinResourcesEditCallback editCallback =
1167             [&gl, glesMajorVersion,
1168              glesMinorVersion](ST_BuiltInResources& res) {
1169                 gl.glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &res.MaxVertexAttribs);
1170                 gl.glGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS,
1171                                  &res.MaxVertexUniformVectors);
1172                 gl.glGetIntegerv(GL_MAX_VARYING_VECTORS,
1173                                  &res.MaxVaryingVectors);
1174                 gl.glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS,
1175                                  &res.MaxVertexTextureImageUnits);
1176                 gl.glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS,
1177                                  &res.MaxCombinedTextureImageUnits);
1178                 gl.glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS,
1179                                  &res.MaxTextureImageUnits);
1180                 gl.glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS,
1181                                  &res.MaxFragmentUniformVectors);
1182                 gl.glGetIntegerv(GL_MAX_DRAW_BUFFERS, &res.MaxDrawBuffers);
1183 
1184                 res.FragmentPrecisionHigh = 1;
1185 
1186                 GLint tmp;
1187                 gl.glGetIntegerv(GL_MAX_VERTEX_OUTPUT_COMPONENTS, &tmp);
1188                 res.MaxVertexOutputVectors = tmp / 4;
1189                 gl.glGetIntegerv(GL_MAX_FRAGMENT_INPUT_COMPONENTS, &tmp);
1190                 res.MaxFragmentInputVectors = tmp / 4;
1191 
1192                 gl.glGetIntegerv(GL_MIN_PROGRAM_TEXEL_OFFSET,
1193                                  &res.MinProgramTexelOffset);
1194                 gl.glGetIntegerv(GL_MAX_PROGRAM_TEXEL_OFFSET,
1195                                  &res.MaxProgramTexelOffset);
1196 
1197                 res.MaxDualSourceDrawBuffers = 1;
1198 
1199                 res.OES_standard_derivatives = 1;
1200                 res.OES_EGL_image_external = 0;
1201                 res.EXT_gpu_shader5 = 1;
1202 
1203                 bool shaderFramebufferFetch =
1204                     GLEScontext::shaderFramebufferFetchSupported();
1205 
1206                 res.EXT_shader_framebuffer_fetch =
1207                     shaderFramebufferFetch ? 1 : 0;
1208 
1209                 // GLES 3.1 constants
1210                 gl.glGetIntegerv(GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET,
1211                                  &res.MaxProgramTextureGatherOffset);
1212                 gl.glGetIntegerv(GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET,
1213                                  &res.MinProgramTextureGatherOffset);
1214                 gl.glGetIntegerv(GL_MAX_IMAGE_UNITS, &res.MaxImageUnits);
1215                 gl.glGetIntegerv(GL_MAX_COMPUTE_IMAGE_UNIFORMS,
1216                                  &res.MaxComputeImageUniforms);
1217                 gl.glGetIntegerv(GL_MAX_VERTEX_IMAGE_UNIFORMS,
1218                                  &res.MaxVertexImageUniforms);
1219                 gl.glGetIntegerv(GL_MAX_FRAGMENT_IMAGE_UNIFORMS,
1220                                  &res.MaxFragmentImageUniforms);
1221                 gl.glGetIntegerv(GL_MAX_COMBINED_IMAGE_UNIFORMS,
1222                                  &res.MaxCombinedImageUniforms);
1223                 gl.glGetIntegerv(GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES,
1224                                  &res.MaxCombinedShaderOutputResources);
1225                 gl.glGetIntegerv(GL_MAX_UNIFORM_LOCATIONS,
1226                                  &res.MaxUniformLocations);
1227 
1228                 GLint maxComputeWorkGroupCount[3];
1229                 GLint maxComputeWorkGroupSize[3];
1230 
1231                 for (uint32_t i = 0; i < 3; ++i) {
1232                     if (gl.glGetIntegeri_v &&
1233                         !(glesMajorVersion == 3 && glesMinorVersion == 0)) {
1234                         gl.glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, i,
1235                                            &maxComputeWorkGroupCount[i]);
1236                         gl.glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, i,
1237                                            &maxComputeWorkGroupSize[i]);
1238                     } else {
1239                         maxComputeWorkGroupCount[i] = 65536;
1240                         maxComputeWorkGroupSize[i] = 128;
1241                     }
1242                     res.MaxComputeWorkGroupCount[i] =
1243                         maxComputeWorkGroupCount[i];
1244                     res.MaxComputeWorkGroupSize[i] = maxComputeWorkGroupSize[i];
1245                 }
1246 
1247                 gl.glGetIntegerv(GL_MAX_COMPUTE_UNIFORM_COMPONENTS,
1248                                  &res.MaxComputeUniformComponents);
1249                 gl.glGetIntegerv(GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS,
1250                                  &res.MaxComputeTextureImageUnits);
1251 
1252                 gl.glGetIntegerv(GL_MAX_COMPUTE_ATOMIC_COUNTERS,
1253                                  &res.MaxComputeAtomicCounters);
1254                 gl.glGetIntegerv(GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS,
1255                                  &res.MaxComputeAtomicCounterBuffers);
1256 
1257                 gl.glGetIntegerv(GL_MAX_VERTEX_ATOMIC_COUNTERS,
1258                                  &res.MaxVertexAtomicCounters);
1259                 gl.glGetIntegerv(GL_MAX_FRAGMENT_ATOMIC_COUNTERS,
1260                                  &res.MaxFragmentAtomicCounters);
1261                 gl.glGetIntegerv(GL_MAX_COMBINED_ATOMIC_COUNTERS,
1262                                  &res.MaxCombinedAtomicCounters);
1263                 gl.glGetIntegerv(GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS,
1264                                  &res.MaxAtomicCounterBindings);
1265                 gl.glGetIntegerv(GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS,
1266                                  &res.MaxVertexAtomicCounterBuffers);
1267                 gl.glGetIntegerv(GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS,
1268                                  &res.MaxFragmentAtomicCounterBuffers);
1269                 gl.glGetIntegerv(GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS,
1270                                  &res.MaxCombinedAtomicCounterBuffers);
1271                 gl.glGetIntegerv(GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE,
1272                                  &res.MaxAtomicCounterBufferSize);
1273 
1274                 gl.glGetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS,
1275                                  &res.MaxUniformBufferBindings);
1276                 gl.glGetIntegerv(GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS,
1277                                  &res.MaxShaderStorageBufferBindings);
1278 
1279                 // Clear GL errors if the underlying GL doesn't have those
1280                 // enums.
1281                 gl.glGetError();
1282             };
1283 
1284         ANGLEShaderParser::globalInitialize(
1285                 isGles2Gles(),
1286                 editCallback);
1287 #endif
1288     }
1289 
1290     RET_AND_SET_ERROR_IF(!GLESv2Validate::shaderType(ctx, type), GL_INVALID_ENUM, 0);
1291     if(ctx->shareGroup().get()) {
1292         ShaderProgramType shaderProgramType;
1293         switch (type) {
1294         case GL_VERTEX_SHADER:
1295             shaderProgramType = ShaderProgramType::VERTEX_SHADER;
1296             break;
1297         case GL_FRAGMENT_SHADER:
1298             shaderProgramType = ShaderProgramType::FRAGMENT_SHADER;
1299             break;
1300         case GL_COMPUTE_SHADER:
1301             shaderProgramType = ShaderProgramType::COMPUTE_SHADER;
1302             break;
1303         default:
1304             shaderProgramType = ShaderProgramType::VERTEX_SHADER;
1305             break;
1306         }
1307         const GLuint localShaderName = ctx->shareGroup()->genName(
1308                                                 shaderProgramType, 0, true);
1309         ShaderParser* sp = new ShaderParser(type, isCoreProfile());
1310         ctx->shareGroup()->setObjectData(NamedObjectType::SHADER_OR_PROGRAM,
1311                                          localShaderName, ObjectDataPtr(sp));
1312         return localShaderName;
1313     }
1314     return 0;
1315 }
1316 
glCullFace(GLenum mode)1317 GL_APICALL void  GL_APIENTRY glCullFace(GLenum mode){
1318     GET_CTX();
1319     ctx->setCullFace(mode);
1320     ctx->dispatcher().glCullFace(mode);
1321 }
1322 
glDeleteBuffers(GLsizei n,const GLuint * buffers)1323 GL_APICALL void  GL_APIENTRY glDeleteBuffers(GLsizei n, const GLuint* buffers){
1324     GET_CTX();
1325     SET_ERROR_IF(n<0,GL_INVALID_VALUE);
1326     if(ctx->shareGroup().get()) {
1327         for(int i=0; i < n; i++){
1328             ctx->shareGroup()->deleteName(NamedObjectType::VERTEXBUFFER,
1329                                           buffers[i]);
1330             ctx->unbindBuffer(buffers[i]);
1331         }
1332     }
1333 }
1334 
glDeleteFramebuffers(GLsizei n,const GLuint * framebuffers)1335 GL_APICALL void  GL_APIENTRY glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers){
1336     GET_CTX_V2();
1337     SET_ERROR_IF(n < 0, GL_INVALID_VALUE);
1338     for (int i = 0; i < n; i++) {
1339         if (ctx->getFramebufferBinding(GL_FRAMEBUFFER) == framebuffers[i]) {
1340             glBindFramebuffer(GL_FRAMEBUFFER, 0);
1341         }
1342         else if (ctx->getFramebufferBinding(GL_READ_FRAMEBUFFER) == framebuffers[i]) {
1343             glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
1344         }
1345         ctx->deleteFBO(framebuffers[i]);
1346     }
1347 }
1348 
1349 GL_APICALL void  GL_APIENTRY glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
1350 GL_APICALL void  GL_APIENTRY glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
1351 
s_detachFromFramebuffer(NamedObjectType bufferType,GLuint texture,GLenum target)1352 static void s_detachFromFramebuffer(NamedObjectType bufferType,
1353                                     GLuint texture,
1354                                     GLenum target) {
1355     GET_CTX();
1356     GLuint fbName = ctx->getFramebufferBinding(target);
1357     if (!fbName) return;
1358     auto fbObj = ctx->getFBOData(fbName);
1359     if (fbObj == NULL) return;
1360     const GLenum kAttachments[] = {
1361         GL_COLOR_ATTACHMENT0,
1362         GL_COLOR_ATTACHMENT1,
1363         GL_COLOR_ATTACHMENT2,
1364         GL_COLOR_ATTACHMENT3,
1365         GL_COLOR_ATTACHMENT4,
1366         GL_COLOR_ATTACHMENT5,
1367         GL_COLOR_ATTACHMENT6,
1368         GL_COLOR_ATTACHMENT7,
1369         GL_COLOR_ATTACHMENT8,
1370         GL_COLOR_ATTACHMENT9,
1371         GL_COLOR_ATTACHMENT10,
1372         GL_COLOR_ATTACHMENT11,
1373         GL_COLOR_ATTACHMENT12,
1374         GL_COLOR_ATTACHMENT13,
1375         GL_COLOR_ATTACHMENT14,
1376         GL_COLOR_ATTACHMENT15,
1377         GL_DEPTH_ATTACHMENT,
1378         GL_STENCIL_ATTACHMENT,
1379         GL_DEPTH_STENCIL_ATTACHMENT };
1380     const size_t sizen = sizeof(kAttachments)/sizeof(GLenum);
1381     GLenum textarget;
1382     for (size_t i = 0; i < sizen; ++i ) {
1383         GLuint name = fbObj->getAttachment(kAttachments[i], &textarget, NULL);
1384         if (name != texture) continue;
1385         if (NamedObjectType::TEXTURE == bufferType &&
1386             GLESv2Validate::textureTargetEx(ctx, textarget)) {
1387             glFramebufferTexture2D(GL_FRAMEBUFFER, kAttachments[i], textarget, 0, 0);
1388         } else if (NamedObjectType::RENDERBUFFER == bufferType &&
1389                    GLESv2Validate::renderbufferTarget(textarget)) {
1390             glFramebufferRenderbuffer(GL_FRAMEBUFFER, kAttachments[i], textarget, 0);
1391         }
1392         // detach
1393         fbObj->setAttachment(
1394             ctx, kAttachments[i], (GLenum)0, 0, nullptr, false);
1395     }
1396 }
1397 
glDeleteRenderbuffers(GLsizei n,const GLuint * renderbuffers)1398 GL_APICALL void  GL_APIENTRY glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers){
1399     GET_CTX();
1400     SET_ERROR_IF(n<0,GL_INVALID_VALUE);
1401     if(ctx->shareGroup().get()) {
1402         for(int i=0; i < n; i++){
1403             ctx->shareGroup()->deleteName(NamedObjectType::RENDERBUFFER,
1404                                           renderbuffers[i]);
1405             s_detachFromFramebuffer(NamedObjectType::RENDERBUFFER,
1406                                     renderbuffers[i], GL_DRAW_FRAMEBUFFER);
1407             s_detachFromFramebuffer(NamedObjectType::RENDERBUFFER,
1408                                     renderbuffers[i], GL_READ_FRAMEBUFFER);
1409         }
1410     }
1411 }
1412 
glDeleteTextures(GLsizei n,const GLuint * textures)1413 GL_APICALL void  GL_APIENTRY glDeleteTextures(GLsizei n, const GLuint* textures){
1414     GET_CTX();
1415     SET_ERROR_IF(n<0,GL_INVALID_VALUE);
1416     if(ctx->shareGroup().get()) {
1417         for(int i=0; i < n; i++){
1418             if (textures[i]!=0) {
1419                 if (ctx->getBindedTexture(GL_TEXTURE_2D) == textures[i])
1420                     ctx->setBindedTexture(GL_TEXTURE_2D,0);
1421                 if (ctx->getBindedTexture(GL_TEXTURE_CUBE_MAP) == textures[i])
1422                     ctx->setBindedTexture(GL_TEXTURE_CUBE_MAP,0);
1423                 if (ctx->getBindedTexture(GL_TEXTURE_2D_ARRAY) == textures[i])
1424                     ctx->setBindedTexture(GL_TEXTURE_2D_ARRAY,0);
1425                 if (ctx->getBindedTexture(GL_TEXTURE_3D) == textures[i])
1426                     ctx->setBindedTexture(GL_TEXTURE_3D,0);
1427                 if (ctx->getBindedTexture(GL_TEXTURE_2D_MULTISAMPLE) == textures[i])
1428                     ctx->setBindedTexture(GL_TEXTURE_2D_MULTISAMPLE,0);
1429                 if (ctx->getBindedTexture(GL_TEXTURE_BUFFER) == textures[i])
1430                     ctx->setBindedTexture(GL_TEXTURE_BUFFER,0);
1431                 s_detachFromFramebuffer(NamedObjectType::TEXTURE, textures[i], GL_DRAW_FRAMEBUFFER);
1432                 s_detachFromFramebuffer(NamedObjectType::TEXTURE, textures[i], GL_READ_FRAMEBUFFER);
1433                 ctx->shareGroup()->deleteName(NamedObjectType::TEXTURE,
1434                                               textures[i]);
1435             }
1436         }
1437     }
1438 }
1439 
glDeleteProgram(GLuint program)1440 GL_APICALL void  GL_APIENTRY glDeleteProgram(GLuint program){
1441     GET_CTX();
1442     if(program && ctx->shareGroup().get()) {
1443         const GLuint globalProgramName = ctx->shareGroup()->getGlobalName(
1444                 NamedObjectType::SHADER_OR_PROGRAM, program);
1445         SET_ERROR_IF(!globalProgramName, GL_INVALID_VALUE);
1446 
1447         auto programData = ctx->shareGroup()->getObjectData(
1448                 NamedObjectType::SHADER_OR_PROGRAM, program);
1449         SET_ERROR_IF(!(programData->getDataType()==PROGRAM_DATA),
1450                 GL_INVALID_OPERATION);
1451         ProgramData* pData = (ProgramData*)programData;
1452         if (pData && pData->isInUse()) {
1453             pData->setDeleteStatus(true);
1454             return;
1455         }
1456         s_detachShader(ctx, program, pData->getAttachedVertexShader());
1457         s_detachShader(ctx, program, pData->getAttachedFragmentShader());
1458         s_detachShader(ctx, program, pData->getAttachedComputeShader());
1459 
1460         ctx->shareGroup()->deleteName(NamedObjectType::SHADER_OR_PROGRAM, program);
1461     }
1462 }
1463 
glDeleteShader(GLuint shader)1464 GL_APICALL void  GL_APIENTRY glDeleteShader(GLuint shader){
1465     GET_CTX();
1466     if(shader && ctx->shareGroup().get()) {
1467         const GLuint globalShaderName = ctx->shareGroup()->getGlobalName(
1468                 NamedObjectType::SHADER_OR_PROGRAM, shader);
1469         SET_ERROR_IF(!globalShaderName, GL_INVALID_VALUE);
1470         auto objData = ctx->shareGroup()->getObjectData(
1471                 NamedObjectType::SHADER_OR_PROGRAM, shader);
1472         SET_ERROR_IF(!objData ,GL_INVALID_OPERATION);
1473         SET_ERROR_IF(objData->getDataType()!=SHADER_DATA,GL_INVALID_OPERATION);
1474         ShaderParser* sp = (ShaderParser*)objData;
1475         SET_ERROR_IF(sp->getDeleteStatus(), GL_INVALID_VALUE);
1476         if (sp->hasAttachedPrograms()) {
1477             sp->setDeleteStatus(true);
1478         } else {
1479             ctx->shareGroup()->deleteName(NamedObjectType::SHADER_OR_PROGRAM, shader);
1480         }
1481     }
1482 }
1483 
glDepthFunc(GLenum func)1484 GL_APICALL void  GL_APIENTRY glDepthFunc(GLenum func){
1485     GET_CTX();
1486     ctx->setDepthFunc(func);
1487     ctx->dispatcher().glDepthFunc(func);
1488 }
glDepthMask(GLboolean flag)1489 GL_APICALL void  GL_APIENTRY glDepthMask(GLboolean flag){
1490     GET_CTX();
1491     ctx->setDepthMask(flag);
1492     ctx->dispatcher().glDepthMask(flag);
1493 }
1494 
glDepthRangef(GLclampf zNear,GLclampf zFar)1495 GL_APICALL void  GL_APIENTRY glDepthRangef(GLclampf zNear, GLclampf zFar){
1496     GET_CTX();
1497     ctx->setDepthRangef(zNear, zFar);
1498     if (isGles2Gles()) {
1499         ctx->dispatcher().glDepthRangef(zNear,zFar);
1500     } else {
1501         ctx->dispatcher().glDepthRange(zNear,zFar);
1502     }
1503 }
1504 
glDetachShader(GLuint program,GLuint shader)1505 GL_APICALL void  GL_APIENTRY glDetachShader(GLuint program, GLuint shader){
1506     GET_CTX();
1507     if(ctx->shareGroup().get()) {
1508         const GLuint globalProgramName = ctx->shareGroup()->getGlobalName(
1509                 NamedObjectType::SHADER_OR_PROGRAM, program);
1510         SET_ERROR_IF(globalProgramName==0, GL_INVALID_VALUE);
1511         const GLuint globalShaderName = ctx->shareGroup()->getGlobalName(
1512                 NamedObjectType::SHADER_OR_PROGRAM, shader);
1513         SET_ERROR_IF(globalShaderName==0, GL_INVALID_VALUE);
1514 
1515         auto objData = ctx->shareGroup()->getObjectData(
1516                 NamedObjectType::SHADER_OR_PROGRAM, program);
1517         SET_ERROR_IF(!objData,GL_INVALID_OPERATION);
1518         SET_ERROR_IF(!(objData->getDataType()==PROGRAM_DATA) ,GL_INVALID_OPERATION);
1519 
1520         ProgramData* programData = (ProgramData*)objData;
1521         SET_ERROR_IF(!programData->isAttached(shader),GL_INVALID_OPERATION);
1522         programData->detachShader(shader);
1523 
1524         s_detachShader(ctx, program, shader);
1525 
1526         ctx->dispatcher().glDetachShader(globalProgramName,globalShaderName);
1527     }
1528 }
1529 
glDisable(GLenum cap)1530 GL_APICALL void  GL_APIENTRY glDisable(GLenum cap){
1531     GET_CTX();
1532     if (isCoreProfile()) {
1533         switch (cap) {
1534         case GL_TEXTURE_2D:
1535         case GL_POINT_SPRITE_OES:
1536             // always enabled in core
1537             return;
1538         }
1539     }
1540 #ifdef __APPLE__
1541     if (!isGles2Gles()) {
1542         switch (cap) {
1543         case GL_PRIMITIVE_RESTART_FIXED_INDEX:
1544             ctx->setPrimitiveRestartEnabled(false);
1545             ctx->setEnable(cap, false);
1546             return;
1547         }
1548     }
1549 #endif
1550     ctx->setEnable(cap, false);
1551     ctx->dispatcher().glDisable(cap);
1552 }
1553 
glDisableVertexAttribArray(GLuint index)1554 GL_APICALL void  GL_APIENTRY glDisableVertexAttribArray(GLuint index){
1555     GET_CTX();
1556     SET_ERROR_IF((!GLESv2Validate::arrayIndex(ctx,index)),GL_INVALID_VALUE);
1557     ctx->enableArr(index,false);
1558     ctx->dispatcher().glDisableVertexAttribArray(index);
1559 }
1560 
1561 // s_glDrawPre/Post() are for draw calls' fast paths.
s_glDrawPre(GLESv2Context * ctx,GLenum mode,GLenum type=0)1562 static void s_glDrawPre(GLESv2Context* ctx, GLenum mode, GLenum type = 0) {
1563 
1564     SHADER_DEBUG_PRINT("draw with program %u", ctx->getCurrentProgram());
1565 
1566     if (isGles2Gles()) {
1567         return;
1568     }
1569     if (ctx->getMajorVersion() < 3)
1570         ctx->drawValidate();
1571 
1572     //Enable texture generation for GL_POINTS and gl_PointSize shader variable
1573     //GLES2 assumes this is enabled by default, we need to set this state for GL
1574     if (mode==GL_POINTS) {
1575         ctx->dispatcher().glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
1576         if (!isCoreProfile()) {
1577             ctx->dispatcher().glEnable(GL_POINT_SPRITE);
1578         }
1579     }
1580 
1581 #ifdef __APPLE__
1582     if (ctx->primitiveRestartEnabled() && type) {
1583         ctx->updatePrimitiveRestartIndex(type);
1584     }
1585 #endif
1586 }
1587 
s_glDrawPost(GLESv2Context * ctx,GLenum mode)1588 static void s_glDrawPost(GLESv2Context* ctx, GLenum mode) {
1589     if (isGles2Gles()) {
1590         return;
1591     }
1592     if (mode == GL_POINTS) {
1593         ctx->dispatcher().glDisable(GL_VERTEX_PROGRAM_POINT_SIZE);
1594         if (!isCoreProfile()) {
1595             ctx->dispatcher().glDisable(GL_POINT_SPRITE);
1596         }
1597     }
1598 }
1599 
glDrawArrays(GLenum mode,GLint first,GLsizei count)1600 GL_APICALL void  GL_APIENTRY glDrawArrays(GLenum mode, GLint first, GLsizei count){
1601     GET_CTX_V2();
1602     SET_ERROR_IF(count < 0,GL_INVALID_VALUE)
1603     SET_ERROR_IF(!GLESv2Validate::drawMode(mode),GL_INVALID_ENUM);
1604 
1605     if (ctx->vertexAttributesBufferBacked()) {
1606         s_glDrawPre(ctx, mode);
1607         ctx->dispatcher().glDrawArrays(mode,first,count);
1608         s_glDrawPost(ctx, mode);
1609     } else {
1610         ctx->drawWithEmulations(
1611                 GLESv2Context::DrawCallCmd::Arrays,
1612                 mode, first, count,
1613                 0, nullptr, 0, 0, 0 /* type, indices, primcount, start, end unused */);
1614     }
1615 }
1616 
glDrawArraysNullAEMU(GLenum mode,GLint first,GLsizei count)1617 GL_APICALL void  GL_APIENTRY glDrawArraysNullAEMU(GLenum mode, GLint first, GLsizei count) {
1618     GET_CTX_V2();
1619     SET_ERROR_IF(count < 0,GL_INVALID_VALUE)
1620     SET_ERROR_IF(!GLESv2Validate::drawMode(mode),GL_INVALID_ENUM);
1621 
1622     if (ctx->vertexAttributesBufferBacked()) {
1623         s_glDrawPre(ctx, mode);
1624         // No host driver draw
1625         s_glDrawPost(ctx, mode);
1626     } else {
1627         // TODO: Null draw with emulations
1628         ctx->drawWithEmulations(
1629                 GLESv2Context::DrawCallCmd::Arrays,
1630                 mode, first, count,
1631                 0, nullptr, 0, 0, 0 /* type, indices, primcount, start, end unused */);
1632     }
1633 }
1634 
glDrawElements(GLenum mode,GLsizei count,GLenum type,const GLvoid * indices)1635 GL_APICALL void  GL_APIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices) {
1636     GET_CTX_V2();
1637     SET_ERROR_IF(count < 0,GL_INVALID_VALUE)
1638     SET_ERROR_IF(!(GLESv2Validate::drawMode(mode) && GLESv2Validate::drawType(type)),GL_INVALID_ENUM);
1639 
1640     if (ctx->isBindedBuffer(GL_ELEMENT_ARRAY_BUFFER) &&
1641         ctx->vertexAttributesBufferBacked()) {
1642         s_glDrawPre(ctx, mode, type);
1643         ctx->dispatcher().glDrawElements(mode, count, type, indices);
1644         s_glDrawPost(ctx, mode);
1645     } else {
1646         ctx->drawWithEmulations(
1647                 GLESv2Context::DrawCallCmd::Elements,
1648                 mode, 0 /* first (unused) */, count, type, indices,
1649                 0, 0, 0 /* primcount, start, end (unused) */);
1650     }
1651 }
1652 
glDrawElementsNullAEMU(GLenum mode,GLsizei count,GLenum type,const GLvoid * indices)1653 GL_APICALL void  GL_APIENTRY glDrawElementsNullAEMU(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices) {
1654     GET_CTX_V2();
1655     SET_ERROR_IF(count < 0,GL_INVALID_VALUE)
1656     SET_ERROR_IF(!(GLESv2Validate::drawMode(mode) && GLESv2Validate::drawType(type)),GL_INVALID_ENUM);
1657 
1658     if (ctx->isBindedBuffer(GL_ELEMENT_ARRAY_BUFFER) &&
1659         ctx->vertexAttributesBufferBacked()) {
1660         s_glDrawPre(ctx, mode, type);
1661         // No host driver draw
1662         s_glDrawPost(ctx, mode);
1663     } else {
1664         ctx->drawWithEmulations(
1665                 GLESv2Context::DrawCallCmd::Elements,
1666                 mode, 0 /* first (unused) */, count, type, indices,
1667                 0, 0, 0 /* primcount, start, end (unused) */);
1668     }
1669 }
1670 
glEnable(GLenum cap)1671 GL_APICALL void  GL_APIENTRY glEnable(GLenum cap){
1672     GET_CTX();
1673     if (isCoreProfile()) {
1674         switch (cap) {
1675         case GL_TEXTURE_2D:
1676         case GL_POINT_SPRITE_OES:
1677             return;
1678         }
1679     }
1680 #ifdef __APPLE__
1681     if (!isGles2Gles()) {
1682         switch (cap) {
1683         case GL_PRIMITIVE_RESTART_FIXED_INDEX:
1684             ctx->setPrimitiveRestartEnabled(true);
1685             ctx->setEnable(cap, true);
1686             return;
1687         }
1688     }
1689 #endif
1690     ctx->setEnable(cap, true);
1691     ctx->dispatcher().glEnable(cap);
1692 }
1693 
glEnableVertexAttribArray(GLuint index)1694 GL_APICALL void  GL_APIENTRY glEnableVertexAttribArray(GLuint index){
1695     GET_CTX();
1696     SET_ERROR_IF(!(GLESv2Validate::arrayIndex(ctx,index)),GL_INVALID_VALUE);
1697     ctx->enableArr(index,true);
1698     ctx->dispatcher().glEnableVertexAttribArray(index);
1699 }
1700 
glFinish(void)1701 GL_APICALL void  GL_APIENTRY glFinish(void){
1702     GET_CTX();
1703     ctx->dispatcher().glFinish();
1704 }
glFlush(void)1705 GL_APICALL void  GL_APIENTRY glFlush(void){
1706     GET_CTX();
1707     ctx->dispatcher().glFlush();
1708 }
1709 
1710 
glFramebufferRenderbuffer(GLenum target,GLenum attachment,GLenum renderbuffertarget,GLuint renderbuffer)1711 GL_APICALL void  GL_APIENTRY glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer){
1712     GET_CTX_V2();
1713     SET_ERROR_IF(!(GLESv2Validate::framebufferTarget(ctx, target) &&
1714                    GLESv2Validate::renderbufferTarget(renderbuffertarget) &&
1715                    GLESv2Validate::framebufferAttachment(ctx, attachment)), GL_INVALID_ENUM);
1716     SET_ERROR_IF(!ctx->shareGroup().get(), GL_INVALID_OPERATION);
1717     SET_ERROR_IF(ctx->isDefaultFBOBound(target), GL_INVALID_OPERATION);
1718 
1719     GLuint globalRenderbufferName = 0;
1720     ObjectDataPtr obj;
1721 
1722     // generate the renderbuffer object if not yet exist
1723     if(renderbuffer) {
1724         if (!ctx->shareGroup()->isObject(NamedObjectType::RENDERBUFFER,
1725                                          renderbuffer)) {
1726             ctx->shareGroup()->genName(NamedObjectType::RENDERBUFFER,
1727                                        renderbuffer);
1728             RenderbufferData* rboData = new RenderbufferData();
1729             rboData->everBound = true;
1730             obj = ObjectDataPtr(rboData);
1731             ctx->shareGroup()->setObjectData(NamedObjectType::RENDERBUFFER,
1732                                              renderbuffer, obj);
1733         }
1734         else {
1735             obj = ctx->shareGroup()->getObjectDataPtr(
1736                     NamedObjectType::RENDERBUFFER, renderbuffer);
1737         }
1738 
1739         globalRenderbufferName = ctx->shareGroup()->getGlobalName(
1740                 NamedObjectType::RENDERBUFFER, renderbuffer);
1741     }
1742 
1743     // Update the the current framebuffer object attachment state
1744     GLuint fbName = ctx->getFramebufferBinding(target);
1745     auto fbObj = ctx->getFBOData(fbName);
1746     if (fbObj != NULL) {
1747         fbObj->setAttachment(
1748             ctx, attachment, renderbuffertarget, renderbuffer, obj);
1749     }
1750 
1751     if (renderbuffer && obj.get() != NULL) {
1752         RenderbufferData *rbData = (RenderbufferData *)obj.get();
1753         if (rbData->eglImageGlobalTexObject) {
1754             //
1755             // This renderbuffer object is an eglImage target
1756             // attach the eglimage's texture instead the renderbuffer.
1757             //
1758             ctx->dispatcher().glFramebufferTexture2D(target,
1759                                     attachment,
1760                                     GL_TEXTURE_2D,
1761                                     rbData->eglImageGlobalTexObject->getGlobalName(),
1762                                     0);
1763             return;
1764         }
1765     }
1766 
1767     ctx->dispatcher().glFramebufferRenderbuffer(target,attachment,renderbuffertarget,globalRenderbufferName);
1768 
1769     sUpdateFboEmulation(ctx);
1770 }
1771 
glFramebufferTexture2D(GLenum target,GLenum attachment,GLenum textarget,GLuint texture,GLint level)1772 GL_APICALL void  GL_APIENTRY glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level){
1773     GET_CTX_V2();
1774     SET_ERROR_IF(!(GLESv2Validate::framebufferTarget(ctx, target) &&
1775                    GLESv2Validate::textureTargetEx(ctx, textarget)  &&
1776                    GLESv2Validate::framebufferAttachment(ctx, attachment)), GL_INVALID_ENUM);
1777     SET_ERROR_IF(ctx->getMajorVersion() < 3 && level != 0, GL_INVALID_VALUE);
1778     SET_ERROR_IF(!ctx->shareGroup().get(), GL_INVALID_OPERATION);
1779     SET_ERROR_IF(ctx->isDefaultFBOBound(target), GL_INVALID_OPERATION);
1780     SET_ERROR_IF(texture &&
1781             !ctx->shareGroup()->isObject(NamedObjectType::TEXTURE, texture),
1782             GL_INVALID_OPERATION);
1783 
1784     GLuint globalTextureName = 0;
1785 
1786     if(texture) {
1787         ObjectLocalName texname = ctx->getTextureLocalName(textarget,texture);
1788         globalTextureName = ctx->shareGroup()->getGlobalName(
1789                 NamedObjectType::TEXTURE, texname);
1790         TextureData* texData = getTextureData(texname);
1791         if (texData) {
1792             texData->makeDirty();
1793         }
1794     }
1795 
1796     ctx->dispatcher().glFramebufferTexture2D(target,attachment,textarget,globalTextureName,level);
1797 
1798     // Update the the current framebuffer object attachment state
1799     GLuint fbName = ctx->getFramebufferBinding(target);
1800     auto fbObj = ctx->getFBOData(fbName);
1801     if (fbObj) {
1802         fbObj->setAttachment(
1803             ctx, attachment, textarget, texture, ObjectDataPtr());
1804     }
1805 
1806     sUpdateFboEmulation(ctx);
1807 }
1808 
1809 
glFrontFace(GLenum mode)1810 GL_APICALL void  GL_APIENTRY glFrontFace(GLenum mode){
1811     GET_CTX();
1812     ctx->setFrontFace(mode);
1813     ctx->dispatcher().glFrontFace(mode);
1814 }
1815 
glGenBuffers(GLsizei n,GLuint * buffers)1816 GL_APICALL void  GL_APIENTRY glGenBuffers(GLsizei n, GLuint* buffers){
1817     GET_CTX();
1818     SET_ERROR_IF(n<0,GL_INVALID_VALUE);
1819     if(ctx->shareGroup().get()) {
1820         for(int i=0; i<n ;i++) {
1821             buffers[i] = ctx->shareGroup()->genName(
1822                     NamedObjectType::VERTEXBUFFER, 0, true);
1823             //generating vbo object related to this buffer name
1824             ctx->shareGroup()->setObjectData(NamedObjectType::VERTEXBUFFER,
1825                                              buffers[i],
1826                                              ObjectDataPtr(new GLESbuffer()));
1827         }
1828     }
1829 }
1830 
maxMipmapLevel(GLsizei width,GLsizei height)1831 static int maxMipmapLevel(GLsizei width, GLsizei height) {
1832     // + 0.5 for potential floating point rounding issue
1833     return log2(std::max(width, height) + 0.5);
1834 }
1835 
glGenerateMipmap(GLenum target)1836 GL_APICALL void  GL_APIENTRY glGenerateMipmap(GLenum target){
1837     GET_CTX_V2();
1838     SET_ERROR_IF(!GLESv2Validate::textureTarget(ctx, target), GL_INVALID_ENUM);
1839     // Assuming we advertised GL_OES_texture_npot
1840     if (ctx->shareGroup().get()) {
1841         TextureData *texData = getTextureTargetData(target);
1842         if (texData) {
1843             texData->setMipmapLevelAtLeast(maxMipmapLevel(texData->width,
1844                     texData->height));
1845         }
1846     }
1847     ctx->dispatcher().glGenerateMipmap(target);
1848 }
1849 
glGenFramebuffers(GLsizei n,GLuint * framebuffers)1850 GL_APICALL void  GL_APIENTRY glGenFramebuffers(GLsizei n, GLuint* framebuffers){
1851     GET_CTX();
1852     SET_ERROR_IF(n<0,GL_INVALID_VALUE);
1853     if(ctx->shareGroup().get()) {
1854         for(int i=0; i<n ;i++) {
1855             framebuffers[i] = ctx->genFBOName(0, true);
1856             ctx->setFBOData(framebuffers[i],
1857                 ObjectDataPtr(
1858                     new FramebufferData(
1859                             framebuffers[i],
1860                             ctx->getFBOGlobalName(framebuffers[i]))));
1861         }
1862     }
1863 }
1864 
glGenRenderbuffers(GLsizei n,GLuint * renderbuffers)1865 GL_APICALL void  GL_APIENTRY glGenRenderbuffers(GLsizei n, GLuint* renderbuffers){
1866     GET_CTX();
1867     SET_ERROR_IF(n<0,GL_INVALID_VALUE);
1868     if(ctx->shareGroup().get()) {
1869         for(int i=0; i<n ;i++) {
1870             renderbuffers[i] = ctx->shareGroup()->genName(
1871                     NamedObjectType::RENDERBUFFER, 0, true);
1872             ctx->shareGroup()->setObjectData(
1873                     NamedObjectType::RENDERBUFFER, renderbuffers[i],
1874                     ObjectDataPtr(new RenderbufferData()));
1875         }
1876     }
1877 }
1878 
glGenTextures(GLsizei n,GLuint * textures)1879 GL_APICALL void  GL_APIENTRY glGenTextures(GLsizei n, GLuint* textures){
1880     GET_CTX();
1881     SET_ERROR_IF(n<0,GL_INVALID_VALUE);
1882     if(ctx->shareGroup().get()) {
1883         for(int i=0; i<n ;i++) {
1884             textures[i] = ctx->shareGroup()->genName(NamedObjectType::TEXTURE,
1885                                                      0, true);
1886         }
1887     }
1888 }
1889 
s_getActiveAttribOrUniform(bool isUniform,GLEScontext * ctx,ProgramData * pData,GLuint globalProgramName,GLuint index,GLsizei bufsize,GLsizei * length,GLint * size,GLenum * type,GLchar * name)1890 static void s_getActiveAttribOrUniform(bool isUniform, GLEScontext* ctx,
1891                                        ProgramData* pData,
1892                                        GLuint globalProgramName, GLuint index,
1893                                        GLsizei bufsize, GLsizei* length,
1894                                        GLint* size, GLenum* type,
1895                                        GLchar* name) {
1896     auto& gl = ctx->dispatcher();
1897 
1898     GLsizei hostBufSize = 256;
1899     GLsizei hostLen = 0;
1900     GLint hostSize = 0;
1901     GLenum hostType = 0;
1902     gl.glGetProgramiv(
1903         globalProgramName,
1904         isUniform ? GL_ACTIVE_UNIFORM_MAX_LENGTH : GL_ACTIVE_ATTRIBUTE_MAX_LENGTH,
1905         (GLint*)&hostBufSize);
1906 
1907     std::string hostVarName(hostBufSize + 1, 0);
1908     char watch_val = 0xfe;
1909     hostVarName[0] = watch_val;
1910 
1911     if (isUniform) {
1912         gl.glGetActiveUniform(globalProgramName, index, hostBufSize, &hostLen,
1913                               &hostSize, &hostType, &hostVarName[0]);
1914     } else {
1915         gl.glGetActiveAttrib(globalProgramName, index, hostBufSize, &hostLen,
1916                              &hostSize, &hostType, &hostVarName[0]);
1917     }
1918 
1919     // here, something failed on the host side,
1920     // so bail early.
1921     if (hostVarName[0] == watch_val) {
1922         return;
1923     }
1924 
1925     // Got a valid string from host GL, but
1926     // we need to return the exact strlen to the GL user.
1927     hostVarName.resize(strlen(hostVarName.c_str()));
1928 
1929     // Things seem to have gone right, so translate the name
1930     // and fill out all applicable guest fields.
1931     auto guestVarName = pData->getDetranslatedName(hostVarName);
1932 
1933     // Don't overstate how many non-nullterminator characters
1934     // we are returning.
1935     int strlenForGuest = std::min((int)(bufsize - 1), (int)guestVarName.size());
1936 
1937     if (length) *length = strlenForGuest;
1938     if (size) *size = hostSize;
1939     if (type) *type = hostType;
1940     // use the guest's bufsize, but don't run over.
1941     if (name) memcpy(name, guestVarName.data(), strlenForGuest + 1);
1942 }
1943 
glGetActiveAttrib(GLuint program,GLuint index,GLsizei bufsize,GLsizei * length,GLint * size,GLenum * type,GLchar * name)1944 GL_APICALL void  GL_APIENTRY glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name){
1945     GET_CTX();
1946     if(ctx->shareGroup().get()) {
1947         const GLuint globalProgramName = ctx->shareGroup()->getGlobalName(
1948                 NamedObjectType::SHADER_OR_PROGRAM, program);
1949         SET_ERROR_IF(globalProgramName==0, GL_INVALID_VALUE);
1950         auto objData = ctx->shareGroup()->getObjectData(
1951                 NamedObjectType::SHADER_OR_PROGRAM, program);
1952         SET_ERROR_IF(objData->getDataType()!=PROGRAM_DATA,GL_INVALID_OPERATION);
1953 
1954         GLint numActiveAttributes = 0;
1955         ctx->dispatcher().glGetProgramiv(
1956             globalProgramName, GL_ACTIVE_ATTRIBUTES, &numActiveAttributes);
1957         SET_ERROR_IF(index >= numActiveAttributes, GL_INVALID_VALUE);
1958         SET_ERROR_IF(bufsize < 0, GL_INVALID_VALUE);
1959 
1960         ProgramData* pData = (ProgramData*)objData;
1961         s_getActiveAttribOrUniform(false, ctx, pData,
1962                                    globalProgramName, index, bufsize, length,
1963                                    size, type, name);
1964     }
1965 }
1966 
glGetActiveUniform(GLuint program,GLuint index,GLsizei bufsize,GLsizei * length,GLint * size,GLenum * type,GLchar * name)1967 GL_APICALL void  GL_APIENTRY glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name){
1968     GET_CTX();
1969     if(ctx->shareGroup().get()) {
1970         const GLuint globalProgramName = ctx->shareGroup()->getGlobalName(
1971                 NamedObjectType::SHADER_OR_PROGRAM, program);
1972         SET_ERROR_IF(globalProgramName==0, GL_INVALID_VALUE);
1973         auto objData = ctx->shareGroup()->getObjectData(
1974                 NamedObjectType::SHADER_OR_PROGRAM, program);
1975         SET_ERROR_IF(objData->getDataType()!=PROGRAM_DATA,GL_INVALID_OPERATION);
1976 
1977         GLint numActiveUniforms = 0;
1978         ctx->dispatcher().glGetProgramiv(globalProgramName, GL_ACTIVE_UNIFORMS,
1979                                          &numActiveUniforms);
1980         SET_ERROR_IF(index >= numActiveUniforms, GL_INVALID_VALUE);
1981         SET_ERROR_IF(bufsize < 0, GL_INVALID_VALUE);
1982 
1983         ProgramData* pData = (ProgramData*)objData;
1984         s_getActiveAttribOrUniform(true, ctx, pData,
1985                                    globalProgramName, index, bufsize, length,
1986                                    size, type, name);
1987     }
1988 }
1989 
glGetAttachedShaders(GLuint program,GLsizei maxcount,GLsizei * count,GLuint * shaders)1990 GL_APICALL void  GL_APIENTRY glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders){
1991     GET_CTX();
1992     if(ctx->shareGroup().get()) {
1993         const GLuint globalProgramName = ctx->shareGroup()->getGlobalName(
1994                 NamedObjectType::SHADER_OR_PROGRAM, program);
1995         SET_ERROR_IF(globalProgramName==0, GL_INVALID_VALUE);
1996         ctx->dispatcher().glGetAttachedShaders(globalProgramName,maxcount,count,shaders);
1997         auto objData = ctx->shareGroup()->getObjectData(
1998                 NamedObjectType::SHADER_OR_PROGRAM, program);
1999         SET_ERROR_IF(objData->getDataType()!=PROGRAM_DATA,GL_INVALID_OPERATION);
2000         GLint numShaders=0;
2001         ctx->dispatcher().glGetProgramiv(globalProgramName,GL_ATTACHED_SHADERS,&numShaders);
2002         for(int i=0 ; i < maxcount && i<numShaders ;i++){
2003             shaders[i] = ctx->shareGroup()->getLocalName(
2004                     NamedObjectType::SHADER_OR_PROGRAM, shaders[i]);
2005         }
2006     }
2007 }
2008 
glGetAttribLocation(GLuint program,const GLchar * name)2009 GL_APICALL int GL_APIENTRY glGetAttribLocation(GLuint program, const GLchar* name){
2010      GET_CTX_RET(-1);
2011      if(ctx->shareGroup().get()) {
2012          const GLuint globalProgramName = ctx->shareGroup()->getGlobalName(
2013                  NamedObjectType::SHADER_OR_PROGRAM, program);
2014          RET_AND_SET_ERROR_IF(globalProgramName == 0, GL_INVALID_VALUE, -1);
2015          auto objData = ctx->shareGroup()->getObjectData(
2016                  NamedObjectType::SHADER_OR_PROGRAM, program);
2017          RET_AND_SET_ERROR_IF(objData->getDataType() != PROGRAM_DATA,
2018                               GL_INVALID_OPERATION, -1);
2019          ProgramData* pData = (ProgramData*)objData;
2020 #if !defined(TOLERATE_PROGRAM_LINK_ERROR) || !TOLERATE_PROGRAM_LINK_ERROR
2021          RET_AND_SET_ERROR_IF(!pData->getLinkStatus(), GL_INVALID_OPERATION,
2022                               -1);
2023 #endif
2024          int ret = ctx->dispatcher().glGetAttribLocation(
2025                  globalProgramName, pData->getTranslatedName(name).c_str());
2026          if (ret != -1) {
2027              pData->linkedAttribLocation(name, ret);
2028          }
2029          return ret;
2030      }
2031      return -1;
2032 }
2033 
2034 template <typename T>
2035 using GLStateQueryFunc = void (*)(GLenum pname, T* params);
2036 
2037 template <typename T>
2038 using GLStateQueryFuncIndexed = void (*)(GLenum pname, GLuint index, T* params);
2039 
s_glGetBooleanv_wrapper(GLenum pname,GLboolean * params)2040 static void s_glGetBooleanv_wrapper(GLenum pname, GLboolean* params) {
2041     GET_CTX();
2042     ctx->dispatcher().glGetBooleanv(pname, params);
2043 }
2044 
s_glGetIntegerv_wrapper(GLenum pname,GLint * params)2045 static void s_glGetIntegerv_wrapper(GLenum pname, GLint* params) {
2046     GET_CTX();
2047     ctx->dispatcher().glGetIntegerv(pname, params);
2048 }
2049 
s_glGetInteger64v_wrapper(GLenum pname,GLint64 * params)2050 static void s_glGetInteger64v_wrapper(GLenum pname, GLint64* params) {
2051     GET_CTX();
2052     ctx->dispatcher().glGetInteger64v(pname, params);
2053 }
2054 
s_glGetFloatv_wrapper(GLenum pname,GLfloat * params)2055 static void s_glGetFloatv_wrapper(GLenum pname, GLfloat* params) {
2056     GET_CTX();
2057     ctx->dispatcher().glGetFloatv(pname, params);
2058 }
2059 
s_glGetIntegeri_v_wrapper(GLenum pname,GLuint index,GLint * data)2060 static void s_glGetIntegeri_v_wrapper(GLenum pname, GLuint index, GLint* data) {
2061     GET_CTX_V2();
2062     ctx->dispatcher().glGetIntegeri_v(pname, index, data);
2063 }
2064 
s_glGetInteger64i_v_wrapper(GLenum pname,GLuint index,GLint64 * data)2065 static void s_glGetInteger64i_v_wrapper(GLenum pname, GLuint index, GLint64* data) {
2066     GET_CTX_V2();
2067     ctx->dispatcher().glGetInteger64i_v(pname, index, data);
2068 }
2069 
2070 template <class T>
s_glStateQueryTv(bool es2,GLenum pname,T * params,GLStateQueryFunc<T> getter)2071 static void s_glStateQueryTv(bool es2, GLenum pname, T* params, GLStateQueryFunc<T> getter) {
2072     T i;
2073     GLint iparams[4];
2074     GET_CTX_V2();
2075     switch (pname) {
2076     case GL_VIEWPORT:
2077         ctx->getViewport(iparams);
2078         params[0] = (T)iparams[0];
2079         params[1] = (T)iparams[1];
2080         params[2] = (T)iparams[2];
2081         params[3] = (T)iparams[3];
2082         break;
2083     case GL_CURRENT_PROGRAM:
2084         if (ctx->shareGroup().get()) {
2085             *params = (T)ctx->getCurrentProgram();
2086         }
2087         break;
2088     case GL_FRAMEBUFFER_BINDING:
2089     case GL_READ_FRAMEBUFFER_BINDING:
2090         getter(pname,&i);
2091         *params = ctx->getFBOLocalName(i);
2092         break;
2093     case GL_RENDERBUFFER_BINDING:
2094         if (ctx->shareGroup().get()) {
2095             getter(pname,&i);
2096             *params = ctx->shareGroup()->getLocalName(
2097                     NamedObjectType::RENDERBUFFER, i);
2098         }
2099         break;
2100     case GL_READ_BUFFER:
2101     case GL_DRAW_BUFFER0:
2102         if (ctx->shareGroup().get()) {
2103             getter(pname, &i);
2104             GLenum target = pname == GL_READ_BUFFER ? GL_READ_FRAMEBUFFER : GL_DRAW_FRAMEBUFFER;
2105             if (ctx->isDefaultFBOBound(target) && (GLint)i == GL_COLOR_ATTACHMENT0) {
2106                 i = (T)GL_BACK;
2107             }
2108             *params = i;
2109         }
2110         break;
2111     case GL_VERTEX_ARRAY_BINDING:
2112         getter(pname,&i);
2113         *params = ctx->getVAOLocalName(i);
2114         break;
2115     case GL_ARRAY_BUFFER_BINDING:
2116         *params = ctx->getBuffer(GL_ARRAY_BUFFER);
2117         break;
2118     case GL_ELEMENT_ARRAY_BUFFER_BINDING:
2119         *params = ctx->getBuffer(GL_ELEMENT_ARRAY_BUFFER);
2120         break;
2121     case GL_COPY_READ_BUFFER_BINDING:
2122         *params = ctx->getBuffer(GL_COPY_READ_BUFFER);
2123         break;
2124     case GL_COPY_WRITE_BUFFER_BINDING:
2125         *params = ctx->getBuffer(GL_COPY_WRITE_BUFFER);
2126         break;
2127     case GL_PIXEL_PACK_BUFFER_BINDING:
2128         *params = ctx->getBuffer(GL_PIXEL_PACK_BUFFER);
2129         break;
2130     case GL_PIXEL_UNPACK_BUFFER_BINDING:
2131         *params = ctx->getBuffer(GL_PIXEL_UNPACK_BUFFER);
2132         break;
2133     case GL_TRANSFORM_FEEDBACK_BINDING:
2134         *params = ctx->getTransformFeedbackBinding();
2135         break;
2136     case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
2137         *params = ctx->getBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
2138         break;
2139     case GL_UNIFORM_BUFFER_BINDING:
2140         *params = ctx->getBuffer(GL_UNIFORM_BUFFER);
2141         break;
2142     case GL_ATOMIC_COUNTER_BUFFER_BINDING:
2143         *params = ctx->getBuffer(GL_ATOMIC_COUNTER_BUFFER);
2144         break;
2145     case GL_DISPATCH_INDIRECT_BUFFER_BINDING:
2146         *params = ctx->getBuffer(GL_DISPATCH_INDIRECT_BUFFER);
2147         break;
2148     case GL_DRAW_INDIRECT_BUFFER_BINDING:
2149         *params = ctx->getBuffer(GL_DRAW_INDIRECT_BUFFER);
2150         break;
2151     case GL_SHADER_STORAGE_BUFFER_BINDING:
2152         *params = ctx->getBuffer(GL_SHADER_STORAGE_BUFFER);
2153         break;
2154     case GL_TEXTURE_BUFFER_BINDING:
2155         *params = ctx->getBuffer(GL_TEXTURE_BUFFER);
2156         break;
2157     case GL_TEXTURE_BINDING_2D:
2158         *params = ctx->getBindedTexture(GL_TEXTURE_2D);
2159         break;
2160     case GL_TEXTURE_BINDING_CUBE_MAP:
2161         *params = ctx->getBindedTexture(GL_TEXTURE_CUBE_MAP);
2162         break;
2163     case GL_TEXTURE_BINDING_2D_ARRAY:
2164         *params = ctx->getBindedTexture(GL_TEXTURE_2D_ARRAY);
2165         break;
2166     case GL_TEXTURE_BINDING_3D:
2167         *params = ctx->getBindedTexture(GL_TEXTURE_3D);
2168         break;
2169     case GL_TEXTURE_BINDING_2D_MULTISAMPLE:
2170         *params = ctx->getBindedTexture(GL_TEXTURE_2D_MULTISAMPLE);
2171         break;
2172     case GL_TEXTURE_BINDING_BUFFER:
2173         *params = ctx->getBindedTexture(GL_TEXTURE_BUFFER);
2174         break;
2175     case GL_SAMPLER_BINDING:
2176         if (ctx->shareGroup().get()) {
2177             getter(pname,&i);
2178             *params = ctx->shareGroup()->getLocalName(
2179                     NamedObjectType::SAMPLER, i);
2180         }
2181         break;
2182 
2183     case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
2184         *params = (T)getCompressedFormats(2, NULL);
2185         break;
2186     case GL_COMPRESSED_TEXTURE_FORMATS:
2187         {
2188             int nparams = getCompressedFormats(2, NULL);
2189             if (nparams > 0) {
2190                 int* iparams = new int[nparams];
2191                 getCompressedFormats(2, iparams);
2192                 for (int i = 0; i < nparams; i++) {
2193                     params[i] = (T)iparams[i];
2194                 }
2195                 delete [] iparams;
2196             }
2197         }
2198         break;
2199     case GL_SHADER_COMPILER:
2200         if(es2)
2201             getter(pname, params);
2202         else
2203             *params = 1;
2204         break;
2205 
2206     case GL_SHADER_BINARY_FORMATS:
2207         if(es2)
2208             getter(pname,params);
2209         break;
2210 
2211     case GL_NUM_SHADER_BINARY_FORMATS:
2212         if(es2)
2213             getter(pname,params);
2214         else
2215             *params = 0;
2216         break;
2217 
2218     case GL_MAX_VERTEX_UNIFORM_VECTORS:
2219         if(es2)
2220             getter(pname,params);
2221         else
2222             *params = 128;
2223         break;
2224 
2225     case GL_MAX_VERTEX_ATTRIBS:
2226         *params = kMaxVertexAttributes;
2227         break;
2228 
2229     case GL_MAX_VARYING_VECTORS:
2230         if(es2)
2231             getter(pname,params);
2232         else
2233             *params = 8;
2234         break;
2235 
2236     case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
2237         if(es2)
2238             getter(pname,params);
2239         else
2240             *params = 16;
2241         break;
2242 
2243     case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
2244         getter(pname,params);
2245         break;
2246     case GL_STENCIL_BACK_VALUE_MASK:
2247     case GL_STENCIL_BACK_WRITEMASK:
2248     case GL_STENCIL_VALUE_MASK:
2249     case GL_STENCIL_WRITEMASK:
2250         {
2251             T myT = 0;
2252             getter(pname, &myT);
2253             *params = myT;
2254         }
2255         break;
2256     // Core-profile related fixes
2257     case GL_GENERATE_MIPMAP_HINT:
2258         if (isCoreProfile()) {
2259             *params = ctx->getHint(GL_GENERATE_MIPMAP_HINT);
2260         } else {
2261             getter(pname, params);
2262         }
2263         break;
2264     case GL_RED_BITS:
2265     case GL_GREEN_BITS:
2266     case GL_BLUE_BITS:
2267     case GL_ALPHA_BITS:
2268     case GL_DEPTH_BITS:
2269     case GL_STENCIL_BITS:
2270         if (isCoreProfile()) {
2271             GLuint fboBinding = ctx->getFramebufferBinding(GL_DRAW_FRAMEBUFFER);
2272             *params = (T)ctx->queryCurrFboBits(fboBinding, pname);
2273         } else {
2274             getter(pname, params);
2275         }
2276         break;
2277     case GL_ALIASED_POINT_SIZE_RANGE:
2278         if (isCoreProfile()) {
2279 #ifndef GL_POINT_SIZE_RANGE
2280 #define GL_POINT_SIZE_RANGE               0x0B12
2281 #endif
2282             getter(GL_POINT_SIZE_RANGE, params);
2283         } else {
2284             getter(pname, params);
2285         }
2286         break;
2287     default:
2288         getter(pname,params);
2289         break;
2290     }
2291 }
2292 
2293 template <typename T>
s_glStateQueryTi_v(GLenum pname,GLuint index,T * params,GLStateQueryFuncIndexed<T> getter)2294 static void s_glStateQueryTi_v(GLenum pname, GLuint index, T* params, GLStateQueryFuncIndexed<T> getter) {
2295     GET_CTX_V2();
2296     switch (pname) {
2297     case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
2298         *params = ctx->getIndexedBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, index);
2299         break;
2300     case GL_UNIFORM_BUFFER_BINDING:
2301         *params = ctx->getIndexedBuffer(GL_UNIFORM_BUFFER, index);
2302         break;
2303     case GL_ATOMIC_COUNTER_BUFFER_BINDING:
2304         *params = ctx->getIndexedBuffer(GL_ATOMIC_COUNTER_BUFFER, index);
2305         break;
2306     case GL_SHADER_STORAGE_BUFFER_BINDING:
2307         *params = ctx->getIndexedBuffer(GL_SHADER_STORAGE_BUFFER, index);
2308         break;
2309     case GL_IMAGE_BINDING_NAME:
2310         // Need the local name here.
2311         getter(pname, index, params);
2312         *params = ctx->shareGroup()->getLocalName(NamedObjectType::TEXTURE, *params);
2313         break;
2314     default:
2315         getter(pname, index, params);
2316         break;
2317     }
2318 }
2319 
glGetBooleanv(GLenum pname,GLboolean * params)2320 GL_APICALL void  GL_APIENTRY glGetBooleanv(GLenum pname, GLboolean* params){
2321     GET_CTX_V2();
2322 #define TO_GLBOOL(params, x) \
2323     *params = x ? GL_TRUE : GL_FALSE; \
2324 
2325     GLint i = 0;
2326     switch (pname) {
2327     case GL_CURRENT_PROGRAM:
2328         if (ctx->shareGroup().get()) {
2329             s_glGetIntegerv_wrapper(pname,&i);
2330             TO_GLBOOL(params,ctx->shareGroup()->getLocalName(NamedObjectType::SHADER_OR_PROGRAM, i));
2331         }
2332         break;
2333     case GL_FRAMEBUFFER_BINDING:
2334     case GL_READ_FRAMEBUFFER_BINDING:
2335         s_glGetIntegerv_wrapper(pname,&i);
2336         TO_GLBOOL(params,ctx->getFBOLocalName(i));
2337         break;
2338     case GL_RENDERBUFFER_BINDING:
2339         if (ctx->shareGroup().get()) {
2340             s_glGetIntegerv_wrapper(pname,&i);
2341             TO_GLBOOL(params,ctx->shareGroup()->getLocalName(NamedObjectType::RENDERBUFFER, i));
2342         }
2343         break;
2344     case GL_ARRAY_BUFFER_BINDING:
2345         TO_GLBOOL(params, ctx->getBuffer(GL_ARRAY_BUFFER));
2346         break;
2347     case GL_ELEMENT_ARRAY_BUFFER_BINDING:
2348         TO_GLBOOL(params, ctx->getBuffer(GL_ELEMENT_ARRAY_BUFFER));
2349         break;
2350     case GL_COPY_READ_BUFFER_BINDING:
2351         TO_GLBOOL(params, ctx->getBuffer(GL_COPY_READ_BUFFER));
2352         break;
2353     case GL_COPY_WRITE_BUFFER_BINDING:
2354         TO_GLBOOL(params, ctx->getBuffer(GL_COPY_WRITE_BUFFER));
2355         break;
2356     case GL_PIXEL_PACK_BUFFER_BINDING:
2357         TO_GLBOOL(params, ctx->getBuffer(GL_PIXEL_PACK_BUFFER));
2358         break;
2359     case GL_PIXEL_UNPACK_BUFFER_BINDING:
2360         TO_GLBOOL(params, ctx->getBuffer(GL_PIXEL_UNPACK_BUFFER));
2361         break;
2362     case GL_TRANSFORM_FEEDBACK_BINDING:
2363         TO_GLBOOL(params, ctx->getTransformFeedbackBinding());
2364         break;
2365     case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
2366         TO_GLBOOL(params, ctx->getBuffer(GL_TRANSFORM_FEEDBACK_BUFFER));
2367         break;
2368     case GL_UNIFORM_BUFFER_BINDING:
2369         TO_GLBOOL(params, ctx->getBuffer(GL_UNIFORM_BUFFER));
2370         break;
2371     case GL_ATOMIC_COUNTER_BUFFER_BINDING:
2372         TO_GLBOOL(params, ctx->getBuffer(GL_ATOMIC_COUNTER_BUFFER));
2373         break;
2374     case GL_DISPATCH_INDIRECT_BUFFER_BINDING:
2375         TO_GLBOOL(params, ctx->getBuffer(GL_DISPATCH_INDIRECT_BUFFER));
2376         break;
2377     case GL_DRAW_INDIRECT_BUFFER_BINDING:
2378         TO_GLBOOL(params, ctx->getBuffer(GL_DRAW_INDIRECT_BUFFER));
2379         break;
2380     case GL_SHADER_STORAGE_BUFFER_BINDING:
2381         TO_GLBOOL(params, ctx->getBuffer(GL_SHADER_STORAGE_BUFFER));
2382         break;
2383     case GL_TEXTURE_BUFFER_BINDING:
2384         TO_GLBOOL(params, ctx->getBuffer(GL_TEXTURE_BUFFER));
2385         break;
2386     case GL_TEXTURE_BINDING_2D:
2387         TO_GLBOOL(params, ctx->getBindedTexture(GL_TEXTURE_2D));
2388         break;
2389     case GL_TEXTURE_BINDING_CUBE_MAP:
2390         TO_GLBOOL(params, ctx->getBindedTexture(GL_TEXTURE_CUBE_MAP));
2391         break;
2392     case GL_TEXTURE_BINDING_2D_ARRAY:
2393         TO_GLBOOL(params, ctx->getBindedTexture(GL_TEXTURE_2D_ARRAY));
2394         break;
2395     case GL_TEXTURE_BINDING_3D:
2396         TO_GLBOOL(params, ctx->getBindedTexture(GL_TEXTURE_3D));
2397         break;
2398     case GL_TEXTURE_BINDING_2D_MULTISAMPLE:
2399         TO_GLBOOL(params, ctx->getBindedTexture(GL_TEXTURE_2D_MULTISAMPLE));
2400         break;
2401     case GL_TEXTURE_BINDING_BUFFER:
2402         TO_GLBOOL(params, ctx->getBindedTexture(GL_TEXTURE_BUFFER));
2403         break;
2404     case GL_SAMPLER_BINDING:
2405         if (ctx->shareGroup().get()) {
2406             s_glGetIntegerv_wrapper(pname,&i);
2407             TO_GLBOOL(params,ctx->shareGroup()->getLocalName(NamedObjectType::SAMPLER, i));
2408         }
2409         break;
2410     case GL_VERTEX_ARRAY_BINDING:
2411         s_glGetIntegerv_wrapper(pname,&i);
2412         TO_GLBOOL(params, ctx->getVAOLocalName(i));
2413         break;
2414     case GL_GENERATE_MIPMAP_HINT:
2415         if (isCoreProfile()) {
2416             TO_GLBOOL(params, ctx->getHint(GL_GENERATE_MIPMAP_HINT));
2417         } else {
2418             s_glGetBooleanv_wrapper(pname, params);
2419         }
2420         break;
2421     case GL_RED_BITS:
2422     case GL_GREEN_BITS:
2423     case GL_BLUE_BITS:
2424     case GL_ALPHA_BITS:
2425     case GL_DEPTH_BITS:
2426     case GL_STENCIL_BITS:
2427         if (isCoreProfile()) {
2428             GLuint fboBinding = ctx->getFramebufferBinding(GL_DRAW_FRAMEBUFFER);
2429             TO_GLBOOL(params, ctx->queryCurrFboBits(fboBinding, pname));
2430         } else {
2431             s_glGetBooleanv_wrapper(pname, params);
2432         }
2433         break;
2434     case GL_ALIASED_POINT_SIZE_RANGE:
2435         if (isCoreProfile()) {
2436 #ifndef GL_POINT_SIZE_RANGE
2437 #define GL_POINT_SIZE_RANGE               0x0B12
2438 #endif
2439             s_glGetBooleanv_wrapper(GL_POINT_SIZE_RANGE, params);
2440         } else {
2441             s_glGetBooleanv_wrapper(pname, params);
2442         }
2443         break;
2444     default:
2445         s_glGetBooleanv_wrapper(pname, params);
2446         break;
2447     }
2448 }
2449 
glGetBufferParameteriv(GLenum target,GLenum pname,GLint * params)2450 GL_APICALL void  GL_APIENTRY glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params){
2451     GET_CTX_V2();
2452     SET_ERROR_IF(!GLESv2Validate::bufferTarget(ctx, target), GL_INVALID_ENUM);
2453     SET_ERROR_IF(!GLESv2Validate::bufferParam(ctx, pname), GL_INVALID_ENUM);
2454     SET_ERROR_IF(!ctx->isBindedBuffer(target),GL_INVALID_OPERATION);
2455     switch(pname) {
2456     case GL_BUFFER_SIZE:
2457         ctx->getBufferSize(target,params);
2458         break;
2459     case GL_BUFFER_USAGE:
2460         ctx->getBufferUsage(target,params);
2461         break;
2462     }
2463 }
2464 
2465 
glGetError(void)2466 GL_APICALL GLenum GL_APIENTRY glGetError(void){
2467     GET_CTX_RET(GL_NO_ERROR)
2468     GLenum err = ctx->getGLerror();
2469     if(err != GL_NO_ERROR) {
2470         ctx->setGLerror(GL_NO_ERROR);
2471         return err;
2472     }
2473     return ctx->dispatcher().glGetError();
2474 }
2475 
glGetFloatv(GLenum pname,GLfloat * params)2476 GL_APICALL void  GL_APIENTRY glGetFloatv(GLenum pname, GLfloat* params){
2477     GET_CTX();
2478     s_glStateQueryTv<GLfloat>(true, pname, params, s_glGetFloatv_wrapper);
2479 }
2480 
glGetIntegerv(GLenum pname,GLint * params)2481 GL_APICALL void  GL_APIENTRY glGetIntegerv(GLenum pname, GLint* params){
2482     int destroyCtx = 0;
2483     GET_CTX();
2484 
2485     if (!ctx) {
2486         ctx = createGLESContext();
2487         if (ctx)
2488             destroyCtx = 1;
2489     }
2490     if (ctx->glGetIntegerv(pname,params))
2491     {
2492         if (destroyCtx)
2493             deleteGLESContext(ctx);
2494         return;
2495     }
2496 
2497     // For non-int64 glGetIntegerv, the following params have precision issues,
2498     // so just use glGetFloatv straight away:
2499     GLfloat floatVals[4];
2500     switch (pname) {
2501     case GL_DEPTH_RANGE:
2502     case GL_BLEND_COLOR:
2503     case GL_COLOR_CLEAR_VALUE:
2504     case GL_DEPTH_CLEAR_VALUE:
2505         ctx->dispatcher().glGetFloatv(pname, floatVals);
2506     default:
2507         break;
2508     }
2509 
2510     int converted_float_params = 0;
2511 
2512     switch (pname) {
2513     case GL_DEPTH_RANGE:
2514         converted_float_params = 2;
2515         break;
2516     case GL_BLEND_COLOR:
2517     case GL_COLOR_CLEAR_VALUE:
2518         converted_float_params = 4;
2519         break;
2520     case GL_DEPTH_CLEAR_VALUE:
2521         converted_float_params = 1;
2522         break;
2523     default:
2524         break;
2525     }
2526 
2527     if (converted_float_params) {
2528         for (int i = 0; i < converted_float_params; i++) {
2529             params[i] = (GLint)((GLint64)(floatVals[i] * 2147483647.0));
2530         }
2531         return;
2532     }
2533 
2534     bool es2 = ctx->getCaps()->GL_ARB_ES2_COMPATIBILITY;
2535     s_glStateQueryTv<GLint>(es2, pname, params, s_glGetIntegerv_wrapper);
2536 
2537     if (destroyCtx)
2538         deleteGLESContext(ctx);
2539 }
2540 
glGetFramebufferAttachmentParameteriv(GLenum target,GLenum attachment,GLenum pname,GLint * params)2541 GL_APICALL void  GL_APIENTRY glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params){
2542     GET_CTX_V2();
2543 
2544     //
2545     // Take the attachment attribute from our state - if available
2546     //
2547     GLuint fbName = ctx->getFramebufferBinding(target);
2548     if (fbName) {
2549         auto fbObj = ctx->getFBOData(fbName);
2550         if (fbObj != NULL) {
2551             GLenum target;
2552             GLuint name = fbObj->getAttachment(attachment, &target, NULL);
2553             if (!name) {
2554                 SET_ERROR_IF(pname != GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE &&
2555                         pname != GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, GL_INVALID_ENUM);
2556             }
2557             if (pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE) {
2558                 if (target == GL_TEXTURE_2D) {
2559                     *params = GL_TEXTURE;
2560                     return;
2561                 }
2562                 else if (target == GL_RENDERBUFFER) {
2563                     *params = GL_RENDERBUFFER;
2564                     return;
2565                 } else {
2566                     *params = GL_NONE;
2567                 }
2568             }
2569             else if (pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) {
2570                 *params = name;
2571                 return;
2572             }
2573         }
2574     }
2575 
2576     if (ctx->isDefaultFBOBound(target)) {
2577         SET_ERROR_IF(
2578             attachment == GL_DEPTH_ATTACHMENT ||
2579             attachment == GL_STENCIL_ATTACHMENT ||
2580             attachment == GL_DEPTH_STENCIL_ATTACHMENT ||
2581             (attachment >= GL_COLOR_ATTACHMENT0 &&
2582              attachment <= GL_COLOR_ATTACHMENT15), GL_INVALID_OPERATION);
2583         SET_ERROR_IF(pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, GL_INVALID_ENUM);
2584 
2585         if (attachment == GL_BACK)
2586             attachment = GL_COLOR_ATTACHMENT0;
2587         if (attachment == GL_DEPTH)
2588             attachment = GL_DEPTH_ATTACHMENT;
2589         if (attachment == GL_STENCIL)
2590             attachment = GL_STENCIL_ATTACHMENT;
2591     }
2592 
2593     ctx->dispatcher().glGetFramebufferAttachmentParameteriv(target,attachment,pname,params);
2594 
2595     if (ctx->isDefaultFBOBound(target) && *params == GL_RENDERBUFFER) {
2596         *params = GL_FRAMEBUFFER_DEFAULT;
2597     }
2598 }
2599 
glGetRenderbufferParameteriv(GLenum target,GLenum pname,GLint * params)2600 GL_APICALL void  GL_APIENTRY glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params){
2601     GET_CTX_V2();
2602     SET_ERROR_IF(!(GLESv2Validate::renderbufferTarget(target) &&
2603                    GLESv2Validate::renderbufferParam(ctx, pname)), GL_INVALID_ENUM);
2604 
2605     //
2606     // If this is a renderbuffer which is eglimage's target, we
2607     // should query the underlying eglimage's texture object instead.
2608     //
2609     GLuint rb = ctx->getRenderbufferBinding();
2610     if (rb) {
2611         auto objData = ctx->shareGroup()->getObjectData(
2612                 NamedObjectType::RENDERBUFFER, rb);
2613         RenderbufferData *rbData = (RenderbufferData *)objData;
2614         if (rbData && rbData->eglImageGlobalTexObject) {
2615             GLenum texPname;
2616             switch(pname) {
2617                 case GL_RENDERBUFFER_WIDTH:
2618                     texPname = GL_TEXTURE_WIDTH;
2619                     break;
2620                 case GL_RENDERBUFFER_HEIGHT:
2621                     texPname = GL_TEXTURE_HEIGHT;
2622                     break;
2623                 case GL_RENDERBUFFER_INTERNAL_FORMAT:
2624                     texPname = GL_TEXTURE_INTERNAL_FORMAT;
2625                     break;
2626                 case GL_RENDERBUFFER_RED_SIZE:
2627                     texPname = GL_TEXTURE_RED_SIZE;
2628                     break;
2629                 case GL_RENDERBUFFER_GREEN_SIZE:
2630                     texPname = GL_TEXTURE_GREEN_SIZE;
2631                     break;
2632                 case GL_RENDERBUFFER_BLUE_SIZE:
2633                     texPname = GL_TEXTURE_BLUE_SIZE;
2634                     break;
2635                 case GL_RENDERBUFFER_ALPHA_SIZE:
2636                     texPname = GL_TEXTURE_ALPHA_SIZE;
2637                     break;
2638                 case GL_RENDERBUFFER_DEPTH_SIZE:
2639                     texPname = GL_TEXTURE_DEPTH_SIZE;
2640                     break;
2641                 case GL_RENDERBUFFER_STENCIL_SIZE:
2642                 default:
2643                     *params = 0; //XXX
2644                     return;
2645                     break;
2646             }
2647 
2648             GLint prevTex;
2649             ctx->dispatcher().glGetIntegerv(GL_TEXTURE_BINDING_2D, &prevTex);
2650             ctx->dispatcher().glBindTexture(GL_TEXTURE_2D,
2651                                             rbData->eglImageGlobalTexObject->getGlobalName());
2652             ctx->dispatcher().glGetTexLevelParameteriv(GL_TEXTURE_2D, 0,
2653                                                        texPname,
2654                                                        params);
2655             ctx->dispatcher().glBindTexture(GL_TEXTURE_2D, prevTex);
2656             return;
2657         }
2658     }
2659 
2660     ctx->dispatcher().glGetRenderbufferParameteriv(target,pname,params);
2661 
2662     // An uninitialized renderbuffer storage may give a format of GL_RGBA on
2663     // some drivers; GLES2 default is GL_RGBA4.
2664     if (pname == GL_RENDERBUFFER_INTERNAL_FORMAT && *params == GL_RGBA) {
2665         *params = GL_RGBA4;
2666     }
2667 }
2668 
2669 
glGetProgramiv(GLuint program,GLenum pname,GLint * params)2670 GL_APICALL void  GL_APIENTRY glGetProgramiv(GLuint program, GLenum pname, GLint* params){
2671     GET_CTX_V2();
2672     SET_ERROR_IF(!GLESv2Validate::programParam(ctx, pname), GL_INVALID_ENUM);
2673     if(ctx->shareGroup().get()) {
2674         const GLuint globalProgramName = ctx->shareGroup()->getGlobalName(
2675                 NamedObjectType::SHADER_OR_PROGRAM, program);
2676         SET_ERROR_IF(globalProgramName==0, GL_INVALID_VALUE);
2677         switch(pname) {
2678         case GL_DELETE_STATUS:
2679             {
2680             auto objData = ctx->shareGroup()->getObjectData(
2681                     NamedObjectType::SHADER_OR_PROGRAM, program);
2682             SET_ERROR_IF(!objData, GL_INVALID_OPERATION);
2683             SET_ERROR_IF(objData->getDataType() != PROGRAM_DATA,
2684                          GL_INVALID_OPERATION);
2685             ProgramData* programData = (ProgramData*)objData;
2686             params[0] = programData->getDeleteStatus() ? GL_TRUE : GL_FALSE;
2687             }
2688             break;
2689         case GL_LINK_STATUS:
2690             {
2691             auto objData = ctx->shareGroup()->getObjectData(
2692                     NamedObjectType::SHADER_OR_PROGRAM, program);
2693             SET_ERROR_IF(!objData, GL_INVALID_OPERATION);
2694             SET_ERROR_IF(objData->getDataType() != PROGRAM_DATA,
2695                          GL_INVALID_OPERATION);
2696             ProgramData* programData = (ProgramData*)objData;
2697             params[0] = programData->getLinkStatus() ? GL_TRUE : GL_FALSE;
2698             }
2699             break;
2700         //validate status should not return GL_TRUE if link failed
2701         case GL_VALIDATE_STATUS:
2702             {
2703             auto objData = ctx->shareGroup()->getObjectData(
2704                     NamedObjectType::SHADER_OR_PROGRAM, program);
2705             SET_ERROR_IF(!objData, GL_INVALID_OPERATION);
2706             SET_ERROR_IF(objData->getDataType() != PROGRAM_DATA,
2707                          GL_INVALID_OPERATION);
2708             ProgramData* programData = (ProgramData*)objData;
2709             params[0] = programData->getValidateStatus() ? GL_TRUE : GL_FALSE;
2710             }
2711             break;
2712         case GL_INFO_LOG_LENGTH:
2713             {
2714             auto objData = ctx->shareGroup()->getObjectData(
2715                     NamedObjectType::SHADER_OR_PROGRAM, program);
2716             SET_ERROR_IF(!objData, GL_INVALID_OPERATION);
2717             SET_ERROR_IF(objData->getDataType() != PROGRAM_DATA,
2718                          GL_INVALID_OPERATION);
2719             ProgramData* programData = (ProgramData*)objData;
2720             GLint logLength = strlen(programData->getInfoLog());
2721             params[0] = (logLength > 0) ? logLength + 1 : 0;
2722             }
2723             break;
2724         default:
2725             ctx->dispatcher().glGetProgramiv(globalProgramName,pname,params);
2726         }
2727     }
2728 }
2729 
glGetProgramInfoLog(GLuint program,GLsizei bufsize,GLsizei * length,GLchar * infolog)2730 GL_APICALL void  GL_APIENTRY glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog){
2731     GET_CTX();
2732     if(ctx->shareGroup().get()) {
2733         const GLuint globalProgramName = ctx->shareGroup()->getGlobalName(
2734                 NamedObjectType::SHADER_OR_PROGRAM, program);
2735         SET_ERROR_IF(globalProgramName==0, GL_INVALID_VALUE);
2736         auto objData = ctx->shareGroup()->getObjectData(
2737                 NamedObjectType::SHADER_OR_PROGRAM, program);
2738         SET_ERROR_IF(!objData ,GL_INVALID_OPERATION);
2739         SET_ERROR_IF(objData->getDataType()!=PROGRAM_DATA,GL_INVALID_OPERATION);
2740         ProgramData* programData = (ProgramData*)objData;
2741 
2742         if (bufsize==0) {
2743             if (length) {
2744                 *length = 0;
2745             }
2746             return;
2747         }
2748 
2749         GLsizei logLength;
2750         logLength = strlen(programData->getInfoLog());
2751 
2752         GLsizei returnLength=0;
2753         if (infolog) {
2754             returnLength = bufsize-1 < logLength ? bufsize-1 : logLength;
2755             strncpy(infolog,programData->getInfoLog(),returnLength+1);
2756             infolog[returnLength] = '\0';
2757         }
2758         if (length) {
2759             *length = returnLength;
2760         }
2761     }
2762 }
2763 
glGetShaderiv(GLuint shader,GLenum pname,GLint * params)2764 GL_APICALL void  GL_APIENTRY glGetShaderiv(GLuint shader, GLenum pname, GLint* params){
2765     GET_CTX();
2766     if(ctx->shareGroup().get()) {
2767         const GLuint globalShaderName = ctx->shareGroup()->getGlobalName(
2768                 NamedObjectType::SHADER_OR_PROGRAM, shader);
2769         SET_ERROR_IF(globalShaderName==0, GL_INVALID_VALUE);
2770         auto objData = ctx->shareGroup()->getObjectData(
2771                 NamedObjectType::SHADER_OR_PROGRAM, shader);
2772         SET_ERROR_IF(!objData, GL_INVALID_OPERATION);
2773         SET_ERROR_IF(objData->getDataType() != SHADER_DATA,
2774                      GL_INVALID_OPERATION);
2775         ShaderParser* sp = (ShaderParser*)objData;
2776         switch(pname) {
2777         case GL_DELETE_STATUS:
2778             {
2779             params[0]  = (sp->getDeleteStatus()) ? GL_TRUE : GL_FALSE;
2780             }
2781             break;
2782         case GL_INFO_LOG_LENGTH:
2783             {
2784             GLint logLength = strlen(sp->getInfoLog());
2785             params[0] = (logLength > 0) ? logLength + 1 : 0;
2786             }
2787             break;
2788         case GL_SHADER_SOURCE_LENGTH:
2789             {
2790             GLint srcLength = sp->getOriginalSrc().length();
2791             params[0] = (srcLength > 0) ? srcLength + 1 : 0;
2792             }
2793             break;
2794         default:
2795             ctx->dispatcher().glGetShaderiv(globalShaderName,pname,params);
2796         }
2797     }
2798 }
2799 
2800 
glGetShaderInfoLog(GLuint shader,GLsizei bufsize,GLsizei * length,GLchar * infolog)2801 GL_APICALL void  GL_APIENTRY glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog){
2802     GET_CTX();
2803     if(ctx->shareGroup().get()) {
2804         const GLuint globalShaderName = ctx->shareGroup()->getGlobalName(
2805                 NamedObjectType::SHADER_OR_PROGRAM, shader);
2806         SET_ERROR_IF(globalShaderName==0, GL_INVALID_VALUE);
2807         auto objData = ctx->shareGroup()->getObjectData(
2808                 NamedObjectType::SHADER_OR_PROGRAM, shader);
2809         SET_ERROR_IF(!objData ,GL_INVALID_OPERATION);
2810         SET_ERROR_IF(objData->getDataType()!=SHADER_DATA,GL_INVALID_OPERATION);
2811         ShaderParser* sp = (ShaderParser*)objData;
2812 
2813         if (bufsize==0) {
2814             if (length) {
2815                 *length = 0;
2816             }
2817             return;
2818         }
2819 
2820         GLsizei logLength;
2821         logLength = strlen(sp->getInfoLog());
2822 
2823         GLsizei returnLength=0;
2824         if (infolog) {
2825             returnLength = bufsize-1 <logLength ? bufsize-1 : logLength;
2826             strncpy(infolog,sp->getInfoLog(),returnLength+1);
2827             infolog[returnLength] = '\0';
2828         }
2829         if (length) {
2830             *length = returnLength;
2831         }
2832     }
2833 }
2834 
glGetShaderPrecisionFormat(GLenum shadertype,GLenum precisiontype,GLint * range,GLint * precision)2835 GL_APICALL void  GL_APIENTRY glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision){
2836     GET_CTX_V2();
2837     SET_ERROR_IF(!(GLESv2Validate::shaderType(ctx, shadertype) &&
2838                    GLESv2Validate::precisionType(precisiontype)),GL_INVALID_ENUM);
2839 
2840     switch (precisiontype) {
2841     case GL_LOW_INT:
2842     case GL_MEDIUM_INT:
2843         // range[0] = range[1] = 16;
2844         // *precision = 0;
2845         // break;
2846     case GL_HIGH_INT:
2847         range[0] = 31;
2848         range[1] = 30;
2849         *precision = 0;
2850         break;
2851 
2852     case GL_LOW_FLOAT:
2853     case GL_MEDIUM_FLOAT:
2854     case GL_HIGH_FLOAT:
2855         if(ctx->dispatcher().glGetShaderPrecisionFormat != NULL) {
2856             ctx->dispatcher().glGetShaderPrecisionFormat(shadertype,precisiontype,range,precision);
2857         } else {
2858             range[0] = range[1] = 127;
2859             *precision = 24;
2860         }
2861         break;
2862     }
2863 }
2864 
glGetShaderSource(GLuint shader,GLsizei bufsize,GLsizei * length,GLchar * source)2865 GL_APICALL void  GL_APIENTRY glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source){
2866     GET_CTX();
2867     if(ctx->shareGroup().get()) {
2868         const GLuint globalShaderName = ctx->shareGroup()->getGlobalName(
2869                 NamedObjectType::SHADER_OR_PROGRAM, shader);
2870         SET_ERROR_IF(globalShaderName == 0, GL_INVALID_VALUE);
2871         auto objData = ctx->shareGroup()->getObjectData(
2872                 NamedObjectType::SHADER_OR_PROGRAM, shader);
2873         SET_ERROR_IF(!objData, GL_INVALID_OPERATION);
2874         SET_ERROR_IF(objData->getDataType() != SHADER_DATA,
2875                      GL_INVALID_OPERATION);
2876         const std::string& src =
2877                 ((ShaderParser*)objData)->getOriginalSrc();
2878         int srcLength = static_cast<int>(src.size());
2879 
2880         int returnLength = bufsize < srcLength ? bufsize - 1 : srcLength;
2881         if (returnLength) {
2882             strncpy(source, src.c_str(), returnLength);
2883             source[returnLength] = '\0';
2884        }
2885 
2886        if (length)
2887           *length = returnLength;
2888     }
2889 }
2890 
2891 
glGetString(GLenum name)2892 GL_APICALL const GLubyte* GL_APIENTRY glGetString(GLenum name){
2893     GET_CTX_V2_RET(NULL)
2894     static const GLubyte SHADING[] = "OpenGL ES GLSL ES 1.0.17";
2895     static const GLubyte SHADING30[] = "OpenGL ES GLSL ES 3.00";
2896     static const GLubyte SHADING31[] = "OpenGL ES GLSL ES 3.10";
2897     static const GLubyte SHADING32[] = "OpenGL ES GLSL ES 3.20";
2898     switch(name) {
2899         case GL_VENDOR:
2900             return (const GLubyte*)ctx->getVendorString(false /* not gles1 */);
2901         case GL_RENDERER:
2902             return (const GLubyte*)ctx->getRendererString(false /* not gles1 */);
2903         case GL_VERSION:
2904             return (const GLubyte*)ctx->getVersionString(false /* not gles1 */);
2905         case GL_SHADING_LANGUAGE_VERSION:
2906             switch (ctx->getMajorVersion()) {
2907             case 3:
2908                 switch (ctx->getMinorVersion()) {
2909                 case 0:
2910                     return SHADING30;
2911                 case 1:
2912                     return SHADING31;
2913                 case 2:
2914                     return SHADING32;
2915                 default:
2916                     return SHADING31;
2917                 }
2918             default:
2919                 return SHADING;
2920              }
2921         case GL_EXTENSIONS:
2922             return (const GLubyte*)ctx->getExtensionString(false /* not gles1 */);
2923         default:
2924             RET_AND_SET_ERROR_IF(true,GL_INVALID_ENUM,NULL);
2925     }
2926 }
2927 
sShouldEmulateSwizzles(TextureData * texData,GLenum target,GLenum pname)2928 static bool sShouldEmulateSwizzles(TextureData* texData, GLenum target, GLenum pname) {
2929     return texData && isCoreProfile() && isSwizzleParam(pname) &&
2930            isCoreProfileEmulatedFormat(texData->format);
2931 }
2932 
glGetTexParameterfv(GLenum target,GLenum pname,GLfloat * params)2933 GL_APICALL void  GL_APIENTRY glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params){
2934     GET_CTX_V2();
2935     SET_ERROR_IF(!(GLESv2Validate::textureTarget(ctx, target) &&
2936                    GLESv2Validate::textureParams(ctx, pname)),
2937                  GL_INVALID_ENUM);
2938 
2939     TextureData* texData = getTextureTargetData(target);
2940     if (sShouldEmulateSwizzles(texData, target, pname)) {
2941         *params = (GLfloat)(texData->getSwizzle(pname));
2942         return;
2943     }
2944     ctx->dispatcher().glGetTexParameterfv(target, pname, params);
2945 }
2946 
glGetTexParameteriv(GLenum target,GLenum pname,GLint * params)2947 GL_APICALL void  GL_APIENTRY glGetTexParameteriv(GLenum target, GLenum pname, GLint* params){
2948     GET_CTX_V2();
2949     SET_ERROR_IF(!(GLESv2Validate::textureTarget(ctx, target) &&
2950                    GLESv2Validate::textureParams(ctx, pname)),
2951                  GL_INVALID_ENUM);
2952 
2953     TextureData* texData = getTextureTargetData(target);
2954     if (sShouldEmulateSwizzles(texData, target, pname)) {
2955         *params = texData->getSwizzle(pname);
2956         return;
2957     }
2958     ctx->dispatcher().glGetTexParameteriv(target, pname, params);
2959 }
2960 
glGetUniformfv(GLuint program,GLint location,GLfloat * params)2961 GL_APICALL void  GL_APIENTRY glGetUniformfv(GLuint program, GLint location, GLfloat* params){
2962     GET_CTX();
2963     SET_ERROR_IF(location < 0,GL_INVALID_OPERATION);
2964     if(ctx->shareGroup().get()) {
2965         const GLuint globalProgramName = ctx->shareGroup()->getGlobalName(
2966                 NamedObjectType::SHADER_OR_PROGRAM, program);
2967         SET_ERROR_IF(globalProgramName==0, GL_INVALID_VALUE);
2968         auto objData = ctx->shareGroup()->getObjectData(
2969                 NamedObjectType::SHADER_OR_PROGRAM, program);
2970         SET_ERROR_IF(objData->getDataType()!=PROGRAM_DATA,GL_INVALID_OPERATION);
2971         ProgramData* pData = (ProgramData *)objData;
2972 #if !defined(TOLERATE_PROGRAM_LINK_ERROR) || !TOLERATE_PROGRAM_LINK_ERROR
2973         SET_ERROR_IF(!pData->getLinkStatus(), GL_INVALID_OPERATION);
2974 #endif
2975         ctx->dispatcher().glGetUniformfv(globalProgramName,
2976             pData->getHostUniformLocation(location), params);
2977     }
2978 }
2979 
glGetUniformiv(GLuint program,GLint location,GLint * params)2980 GL_APICALL void  GL_APIENTRY glGetUniformiv(GLuint program, GLint location, GLint* params){
2981     GET_CTX();
2982     SET_ERROR_IF(location < 0,GL_INVALID_OPERATION);
2983     if(ctx->shareGroup().get()) {
2984         const GLuint globalProgramName = ctx->shareGroup()->getGlobalName(
2985                 NamedObjectType::SHADER_OR_PROGRAM, program);
2986         SET_ERROR_IF(globalProgramName==0, GL_INVALID_VALUE);
2987         auto objData = ctx->shareGroup()->getObjectData(
2988                 NamedObjectType::SHADER_OR_PROGRAM, program);
2989         SET_ERROR_IF(objData->getDataType()!=PROGRAM_DATA,GL_INVALID_OPERATION);
2990         ProgramData* pData = (ProgramData *)objData;
2991 #if !defined(TOLERATE_PROGRAM_LINK_ERROR) || !TOLERATE_PROGRAM_LINK_ERROR
2992         SET_ERROR_IF(!pData->getLinkStatus(), GL_INVALID_OPERATION);
2993 #endif
2994         ctx->dispatcher().glGetUniformiv(globalProgramName,
2995             pData->getHostUniformLocation(location), params);
2996     }
2997 }
2998 
glGetUniformLocation(GLuint program,const GLchar * name)2999 GL_APICALL int GL_APIENTRY glGetUniformLocation(GLuint program, const GLchar* name){
3000     GET_CTX_RET(-1);
3001     if(ctx->shareGroup().get()) {
3002         const GLuint globalProgramName = ctx->shareGroup()->getGlobalName(
3003                 NamedObjectType::SHADER_OR_PROGRAM, program);
3004         RET_AND_SET_ERROR_IF(globalProgramName==0, GL_INVALID_VALUE,-1);
3005         auto objData = ctx->shareGroup()->getObjectData(
3006                 NamedObjectType::SHADER_OR_PROGRAM, program);
3007         RET_AND_SET_ERROR_IF(objData->getDataType()!=PROGRAM_DATA,GL_INVALID_OPERATION,-1);
3008         ProgramData* pData = (ProgramData *)objData;
3009 #if !defined(TOLERATE_PROGRAM_LINK_ERROR) || !TOLERATE_PROGRAM_LINK_ERROR
3010         RET_AND_SET_ERROR_IF(!pData->getLinkStatus(), GL_INVALID_OPERATION, -1);
3011 #endif
3012         return pData->getGuestUniformLocation(name);
3013     }
3014     return -1;
3015 }
3016 
s_invalidVertexAttribIndex(GLuint index)3017 static bool s_invalidVertexAttribIndex(GLuint index) {
3018     GLint param=0;
3019     glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &param);
3020     return (param < 0 || index >= (GLuint)param);
3021 }
3022 
glGetVertexAttribfv(GLuint index,GLenum pname,GLfloat * params)3023 GL_APICALL void  GL_APIENTRY glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params){
3024     GET_CTX_V2();
3025     SET_ERROR_IF(s_invalidVertexAttribIndex(index), GL_INVALID_VALUE);
3026     const GLESpointer* p = ctx->getPointer(index);
3027     if(p) {
3028         switch(pname){
3029         case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
3030             *params = 0;
3031             break;
3032         case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
3033             *params = p->isEnable();
3034             break;
3035         case GL_VERTEX_ATTRIB_ARRAY_SIZE:
3036             *params = p->getSize();
3037             break;
3038         case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
3039             *params = p->getStride();
3040             break;
3041         case GL_VERTEX_ATTRIB_ARRAY_TYPE:
3042             *params = p->getType();
3043             break;
3044         case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
3045             *params = p->isNormalize();
3046             break;
3047         case GL_CURRENT_VERTEX_ATTRIB:
3048             if(index == 0)
3049             {
3050                 const float* att0 = ctx->getAtt0();
3051                 for(int i=0; i<4; i++)
3052                     params[i] = att0[i];
3053             }
3054             else
3055                 ctx->dispatcher().glGetVertexAttribfv(index,pname,params);
3056             break;
3057         default:
3058             ctx->setGLerror(GL_INVALID_ENUM);
3059         }
3060     } else {
3061         ctx->setGLerror(GL_INVALID_VALUE);
3062     }
3063 }
3064 
glGetVertexAttribiv(GLuint index,GLenum pname,GLint * params)3065 GL_APICALL void  GL_APIENTRY glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params){
3066     GET_CTX_V2();
3067     SET_ERROR_IF(s_invalidVertexAttribIndex(index), GL_INVALID_VALUE);
3068     const GLESpointer* p = ctx->getPointer(index);
3069     if (p) {
3070         switch (pname) {
3071             case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
3072                 *params = p->getBufferName();
3073                 break;
3074             case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
3075                 *params = p->isEnable();
3076                 break;
3077             case GL_VERTEX_ATTRIB_ARRAY_SIZE:
3078                 *params = p->getSize();
3079                 break;
3080             case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
3081                 *params = p->getStride();
3082                 break;
3083             case GL_VERTEX_ATTRIB_ARRAY_TYPE:
3084                 *params = p->getType();
3085                 break;
3086             case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
3087                 *params = p->isNormalize();
3088                 break;
3089             case GL_CURRENT_VERTEX_ATTRIB:
3090                 if (index == 0) {
3091                     const float* att0 = ctx->getAtt0();
3092                     for (int i = 0; i < 4; i++)
3093                         params[i] = (GLint)att0[i];
3094                 } else
3095                     ctx->dispatcher().glGetVertexAttribiv(index, pname, params);
3096                 break;
3097             default:
3098                 ctx->setGLerror(GL_INVALID_ENUM);
3099         }
3100     } else {
3101         ctx->setGLerror(GL_INVALID_VALUE);
3102     }
3103 }
3104 
glGetVertexAttribPointerv(GLuint index,GLenum pname,GLvoid ** pointer)3105 GL_APICALL void  GL_APIENTRY glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer){
3106     GET_CTX();
3107     SET_ERROR_IF(pname != GL_VERTEX_ATTRIB_ARRAY_POINTER,GL_INVALID_ENUM);
3108     SET_ERROR_IF((!GLESv2Validate::arrayIndex(ctx,index)),GL_INVALID_VALUE);
3109 
3110     const GLESpointer* p = ctx->getPointer(index);
3111     if (p) {
3112         if (p->getBufferName() == 0) {
3113             // vertex attrib has no buffer, return array data pointer
3114             *pointer = const_cast<GLvoid*>(p->getArrayData());
3115         } else {
3116             // vertex attrib has buffer, return offset
3117             *pointer = reinterpret_cast<GLvoid*>(p->getBufferOffset());
3118         }
3119     } else {
3120         ctx->setGLerror(GL_INVALID_VALUE);
3121     }
3122 }
3123 
glHint(GLenum target,GLenum mode)3124 GL_APICALL void  GL_APIENTRY glHint(GLenum target, GLenum mode){
3125     GET_CTX();
3126     SET_ERROR_IF(!GLESv2Validate::hintTargetMode(target,mode),GL_INVALID_ENUM);
3127 
3128     if (isCoreProfile() &&
3129         target == GL_GENERATE_MIPMAP_HINT) {
3130         ctx->setHint(target, mode);
3131     } else {
3132         ctx->dispatcher().glHint(target,mode);
3133     }
3134 }
3135 
glIsEnabled(GLenum cap)3136 GL_APICALL GLboolean    GL_APIENTRY glIsEnabled(GLenum cap){
3137     GET_CTX_RET(GL_FALSE);
3138     return ctx->dispatcher().glIsEnabled(cap);
3139 }
3140 
glIsBuffer(GLuint buffer)3141 GL_APICALL GLboolean    GL_APIENTRY glIsBuffer(GLuint buffer){
3142     GET_CTX_RET(GL_FALSE)
3143     if(buffer && ctx->shareGroup().get()) {
3144         auto objData = ctx->shareGroup()->getObjectData(
3145                 NamedObjectType::VERTEXBUFFER, buffer);
3146         return objData ? ((GLESbuffer*)objData)->wasBinded()
3147                              : GL_FALSE;
3148     }
3149     return GL_FALSE;
3150 }
3151 
glIsFramebuffer(GLuint framebuffer)3152 GL_APICALL GLboolean    GL_APIENTRY glIsFramebuffer(GLuint framebuffer){
3153     GET_CTX_RET(GL_FALSE)
3154     if(framebuffer){
3155         if (!ctx->isFBO(framebuffer))
3156             return GL_FALSE;
3157         auto fbObj = ctx->getFBOData(framebuffer);
3158         if (!fbObj) return GL_FALSE;
3159         return fbObj->hasBeenBoundAtLeastOnce() ? GL_TRUE : GL_FALSE;
3160     }
3161     return GL_FALSE;
3162 }
3163 
glIsRenderbuffer(GLuint renderbuffer)3164 GL_APICALL GLboolean    GL_APIENTRY glIsRenderbuffer(GLuint renderbuffer){
3165     GET_CTX_RET(GL_FALSE)
3166     if(renderbuffer && ctx->shareGroup().get()){
3167         auto obj = ctx->shareGroup()->getObjectDataPtr(
3168                 NamedObjectType::RENDERBUFFER, renderbuffer);
3169         if (obj) {
3170             RenderbufferData *rboData = (RenderbufferData *)obj.get();
3171             return rboData->everBound ? GL_TRUE : GL_FALSE;
3172         }
3173     }
3174     return GL_FALSE;
3175 }
3176 
glIsTexture(GLuint texture)3177 GL_APICALL GLboolean    GL_APIENTRY glIsTexture(GLuint texture){
3178     GET_CTX_RET(GL_FALSE)
3179     if (texture==0)
3180         return GL_FALSE;
3181     TextureData* tex = getTextureData(texture);
3182     return tex ? tex->wasBound : GL_FALSE;
3183 }
3184 
glIsProgram(GLuint program)3185 GL_APICALL GLboolean    GL_APIENTRY glIsProgram(GLuint program){
3186     GET_CTX_RET(GL_FALSE)
3187     if (program && ctx->shareGroup().get() &&
3188         ctx->shareGroup()->isObject(NamedObjectType::SHADER_OR_PROGRAM, program)) {
3189         const GLuint globalProgramName = ctx->shareGroup()->getGlobalName(
3190                 NamedObjectType::SHADER_OR_PROGRAM, program);
3191         return ctx->dispatcher().glIsProgram(globalProgramName);
3192     }
3193     return GL_FALSE;
3194 }
3195 
glIsShader(GLuint shader)3196 GL_APICALL GLboolean    GL_APIENTRY glIsShader(GLuint shader){
3197     GET_CTX_RET(GL_FALSE)
3198     if (shader && ctx->shareGroup().get() &&
3199         ctx->shareGroup()->isObject(NamedObjectType::SHADER_OR_PROGRAM, shader)) {
3200         const GLuint globalShaderName = ctx->shareGroup()->getGlobalName(
3201                 NamedObjectType::SHADER_OR_PROGRAM, shader);
3202         return ctx->dispatcher().glIsShader(globalShaderName);
3203     }
3204     return GL_FALSE;
3205 }
3206 
glLineWidth(GLfloat width)3207 GL_APICALL void  GL_APIENTRY glLineWidth(GLfloat width){
3208     GET_CTX();
3209     ctx->setLineWidth(width);
3210 #ifdef __APPLE__
3211     // There is no line width setting on Mac core profile.
3212     // Line width emulation can be done (replace user's
3213     // vertex buffer with thick triangles of our own),
3214     // but just have thin lines on Mac for now.
3215     if (!ctx->isCoreProfile() || isGles2Gles()) {
3216         ctx->dispatcher().glLineWidth(width);
3217     }
3218 #else
3219     ctx->dispatcher().glLineWidth(width);
3220 #endif
3221 }
3222 
glLinkProgram(GLuint program)3223 GL_APICALL void  GL_APIENTRY glLinkProgram(GLuint program){
3224     GET_CTX_V2();
3225     GLint linkStatus = GL_FALSE;
3226     if(ctx->shareGroup().get()) {
3227         const GLuint globalProgramName = ctx->shareGroup()->getGlobalName(
3228                 NamedObjectType::SHADER_OR_PROGRAM, program);
3229         SET_ERROR_IF(globalProgramName==0, GL_INVALID_VALUE);
3230 
3231         auto objData = ctx->shareGroup()->getObjectData(
3232                 NamedObjectType::SHADER_OR_PROGRAM, program);
3233         SET_ERROR_IF(!objData, GL_INVALID_OPERATION);
3234         SET_ERROR_IF(objData->getDataType()!=PROGRAM_DATA, GL_INVALID_OPERATION);
3235 
3236         ProgramData* programData = (ProgramData*)objData;
3237         GLint fragmentShader   = programData->getAttachedFragmentShader();
3238         GLint vertexShader =  programData->getAttachedVertexShader();
3239 
3240         if (ctx->getMajorVersion() >= 3 && ctx->getMinorVersion() >= 1) {
3241             ctx->dispatcher().glLinkProgram(globalProgramName);
3242             ctx->dispatcher().glGetProgramiv(globalProgramName,GL_LINK_STATUS,&linkStatus);
3243             programData->setHostLinkStatus(linkStatus);
3244         } else {
3245             if (vertexShader != 0 && fragmentShader!=0) {
3246                 auto fragObjData = ctx->shareGroup()->getObjectData(
3247                         NamedObjectType::SHADER_OR_PROGRAM, fragmentShader);
3248                 auto vertObjData = ctx->shareGroup()->getObjectData(
3249                         NamedObjectType::SHADER_OR_PROGRAM, vertexShader);
3250                 ShaderParser* fragSp = (ShaderParser*)fragObjData;
3251                 ShaderParser* vertSp = (ShaderParser*)vertObjData;
3252 
3253                 if(fragSp->getCompileStatus() && vertSp->getCompileStatus()) {
3254                     ctx->dispatcher().glLinkProgram(globalProgramName);
3255                     ctx->dispatcher().glGetProgramiv(globalProgramName,GL_LINK_STATUS,&linkStatus);
3256                     programData->setHostLinkStatus(linkStatus);
3257                     if (!programData->validateLink(fragSp, vertSp)) {
3258                         programData->setLinkStatus(GL_FALSE);
3259                         programData->setErrInfoLog();
3260                         return;
3261                     }
3262                 }
3263             }
3264         }
3265 
3266         programData->setLinkStatus(linkStatus);
3267 
3268         GLsizei infoLogLength = 0, cLog = 0;
3269         ctx->dispatcher().glGetProgramiv(globalProgramName, GL_INFO_LOG_LENGTH,
3270                                          &infoLogLength);
3271         std::unique_ptr<GLchar[]> log(new GLchar[infoLogLength + 1]);
3272         ctx->dispatcher().glGetProgramInfoLog(globalProgramName, infoLogLength,
3273                                               &cLog, log.get());
3274 
3275         // Only update when there actually is something to update.
3276         if (cLog > 0) {
3277             programData->setInfoLog(log.release());
3278         }
3279     }
3280 }
3281 
glPixelStorei(GLenum pname,GLint param)3282 GL_APICALL void  GL_APIENTRY glPixelStorei(GLenum pname, GLint param){
3283     GET_CTX_V2();
3284     SET_ERROR_IF(!GLESv2Validate::pixelStoreParam(ctx, pname), GL_INVALID_ENUM);
3285     switch (pname) {
3286     case GL_PACK_ALIGNMENT:
3287     case GL_UNPACK_ALIGNMENT:
3288         SET_ERROR_IF(!((param==1)||(param==2)||(param==4)||(param==8)), GL_INVALID_VALUE);
3289         break;
3290     default:
3291         SET_ERROR_IF(param < 0, GL_INVALID_VALUE);
3292         break;
3293     }
3294     ctx->setPixelStorei(pname, param);
3295     ctx->dispatcher().glPixelStorei(pname,param);
3296 }
3297 
glPolygonOffset(GLfloat factor,GLfloat units)3298 GL_APICALL void  GL_APIENTRY glPolygonOffset(GLfloat factor, GLfloat units){
3299     GET_CTX();
3300     ctx->setPolygonOffset(factor, units);
3301     ctx->dispatcher().glPolygonOffset(factor,units);
3302 }
3303 
3304 GL_APICALL void  GL_APIENTRY glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
3305 GL_APICALL void GL_APIENTRY glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
3306 
glReadPixels(GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLvoid * pixels)3307 GL_APICALL void  GL_APIENTRY glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels){
3308     GET_CTX_V2();
3309     SET_ERROR_IF(!(GLESv2Validate::pixelOp(format,type)),GL_INVALID_OPERATION);
3310     SET_ERROR_IF(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE, GL_INVALID_FRAMEBUFFER_OPERATION);
3311     if (ctx->isDefaultFBOBound(GL_READ_FRAMEBUFFER) &&
3312         ctx->getDefaultFBOMultisamples()) {
3313 
3314         GLint prev_bound_rbo;
3315         GLint prev_bound_draw_fbo;
3316 
3317         glGetIntegerv(GL_RENDERBUFFER_BINDING, &prev_bound_rbo);
3318         glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &prev_bound_draw_fbo);
3319 
3320         GLuint resolve_fbo = 0;
3321         GLuint resolve_rbo = 0;
3322         glGenFramebuffers(1, &resolve_fbo);
3323         glGenRenderbuffers(1, &resolve_rbo);
3324 
3325         int fboFormat = ctx->getDefaultFBOColorFormat();
3326         int fboWidth = ctx->getDefaultFBOWidth();
3327         int fboHeight = ctx->getDefaultFBOHeight();
3328 
3329         glBindRenderbuffer(GL_RENDERBUFFER, resolve_rbo);
3330         glRenderbufferStorage(GL_RENDERBUFFER, fboFormat, fboWidth, fboHeight);
3331         glBindFramebuffer(GL_FRAMEBUFFER, resolve_fbo);
3332         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, resolve_rbo);
3333 
3334         glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
3335         glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolve_fbo);
3336 
3337         bool scissorEnabled = glIsEnabled(GL_SCISSOR_TEST);
3338 
3339         if (scissorEnabled) glDisable(GL_SCISSOR_TEST);
3340         glBlitFramebuffer(0, 0, fboWidth, fboHeight, 0, 0, fboWidth, fboHeight,
3341                           GL_COLOR_BUFFER_BIT, GL_LINEAR);
3342         if (scissorEnabled) glEnable(GL_SCISSOR_TEST);
3343 
3344         glBindFramebuffer(GL_READ_FRAMEBUFFER, resolve_fbo);
3345 
3346         ctx->dispatcher().glReadPixels(x,y,width,height,format,type,pixels);
3347 
3348         glDeleteRenderbuffers(1, &resolve_rbo);
3349         glDeleteFramebuffers(1, &resolve_fbo);
3350 
3351         glBindRenderbuffer(GL_RENDERBUFFER, prev_bound_rbo);
3352 
3353         glBindFramebuffer(GL_DRAW_FRAMEBUFFER, prev_bound_draw_fbo);
3354         glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
3355     } else {
3356         ctx->dispatcher().glReadPixels(x,y,width,height,format,type,pixels);
3357     }
3358 }
3359 
3360 
glReleaseShaderCompiler(void)3361 GL_APICALL void  GL_APIENTRY glReleaseShaderCompiler(void){
3362 // this function doesn't work on Mac OS with MacOSX10.9sdk
3363 #ifndef __APPLE__
3364 
3365     /* Use this function with mesa will cause potential bug. Specifically,
3366      * calling this function between glCompileShader() and glLinkProgram() will
3367      * release resources that would be potentially used by glLinkProgram,
3368      * resulting in a segmentation fault.
3369      */
3370     const char* env = ::getenv("ANDROID_GL_LIB");
3371     if (env && !strcmp(env, "mesa")) {
3372         return;
3373     }
3374 
3375     GET_CTX();
3376 
3377     if(ctx->dispatcher().glReleaseShaderCompiler != NULL)
3378     {
3379         ctx->dispatcher().glReleaseShaderCompiler();
3380     }
3381 #endif // !__APPLE__
3382 }
3383 
sPrepareRenderbufferStorage(GLenum internalformat,GLsizei width,GLsizei height,GLint samples,GLint * err)3384 static GLenum sPrepareRenderbufferStorage(GLenum internalformat, GLsizei width,
3385         GLsizei height, GLint samples, GLint* err) {
3386     GET_CTX_V2_RET(GL_NONE);
3387     GLenum internal = internalformat;
3388     if (!isGles2Gles() && ctx->getMajorVersion() < 3) {
3389         switch (internalformat) {
3390             case GL_RGB565:
3391                 internal = GL_RGB;
3392                 break;
3393             case GL_RGB5_A1:
3394                 internal = GL_RGBA;
3395                 break;
3396             default:
3397                 break;
3398         }
3399     }
3400 
3401     // Get current bounded renderbuffer
3402     // raise INVALID_OPERATIOn if no renderbuffer is bounded
3403     GLuint rb = ctx->getRenderbufferBinding();
3404     if (!rb) { *err = GL_INVALID_OPERATION; return GL_NONE; }
3405     auto objData = ctx->shareGroup()->getObjectData(NamedObjectType::RENDERBUFFER, rb);
3406     RenderbufferData *rbData = (RenderbufferData *)objData;
3407     if (!rbData) { *err = GL_INVALID_OPERATION; return GL_NONE; }
3408 
3409     rbData->internalformat = internalformat;
3410     rbData->hostInternalFormat = internal;
3411     rbData->width = width;
3412     rbData->height = height;
3413     rbData->samples = samples;
3414 
3415     //
3416     // if the renderbuffer was an eglImage target, release
3417     // its underlying texture.
3418     //
3419     rbData->eglImageGlobalTexObject.reset();
3420     rbData->saveableTexture.reset();
3421 
3422     *err = GL_NO_ERROR;
3423 
3424     return internal;
3425 }
3426 
glRenderbufferStorage(GLenum target,GLenum internalformat,GLsizei width,GLsizei height)3427 GL_APICALL void  GL_APIENTRY glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height){
3428     GET_CTX();
3429     GLint err = GL_NO_ERROR;
3430     internalformat = sPrepareRenderbufferStorage(internalformat, width, height, 0, &err);
3431     SET_ERROR_IF(err != GL_NO_ERROR, err);
3432     ctx->dispatcher().glRenderbufferStorage(target,internalformat,width,height);
3433 }
3434 
glSampleCoverage(GLclampf value,GLboolean invert)3435 GL_APICALL void  GL_APIENTRY glSampleCoverage(GLclampf value, GLboolean invert){
3436     GET_CTX();
3437     ctx->setSampleCoverage(value, invert);
3438     ctx->dispatcher().glSampleCoverage(value,invert);
3439 }
3440 
glScissor(GLint x,GLint y,GLsizei width,GLsizei height)3441 GL_APICALL void  GL_APIENTRY glScissor(GLint x, GLint y, GLsizei width, GLsizei height){
3442     GET_CTX();
3443     ctx->setScissor(x, y, width, height);
3444     ctx->dispatcher().glScissor(x,y,width,height);
3445 }
3446 
glShaderBinary(GLsizei n,const GLuint * shaders,GLenum binaryformat,const GLvoid * binary,GLsizei length)3447 GL_APICALL void  GL_APIENTRY glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length){
3448     GET_CTX();
3449 
3450     SET_ERROR_IF( (ctx->dispatcher().glShaderBinary == NULL), GL_INVALID_OPERATION);
3451 
3452     if(ctx->shareGroup().get()){
3453         for(int i=0; i < n ; i++){
3454             const GLuint globalShaderName = ctx->shareGroup()->getGlobalName(
3455                     NamedObjectType::SHADER_OR_PROGRAM, shaders[i]);
3456             SET_ERROR_IF(globalShaderName == 0,GL_INVALID_VALUE);
3457             ctx->dispatcher().glShaderBinary(1,&globalShaderName,binaryformat,binary,length);
3458         }
3459     }
3460 }
3461 
glShaderSource(GLuint shader,GLsizei count,const GLchar * const * string,const GLint * length)3462 GL_APICALL void  GL_APIENTRY glShaderSource(GLuint shader, GLsizei count, const GLchar* const* string, const GLint* length){
3463     GET_CTX_V2();
3464     SET_ERROR_IF(count < 0,GL_INVALID_VALUE);
3465     if(ctx->shareGroup().get()){
3466         const GLuint globalShaderName = ctx->shareGroup()->getGlobalName(
3467                 NamedObjectType::SHADER_OR_PROGRAM, shader);
3468         SET_ERROR_IF(globalShaderName == 0, GL_INVALID_VALUE);
3469         auto objData = ctx->shareGroup()->getObjectData(
3470                 NamedObjectType::SHADER_OR_PROGRAM, shader);
3471         SET_ERROR_IF(!objData, GL_INVALID_OPERATION);
3472         SET_ERROR_IF(objData->getDataType() != SHADER_DATA,
3473                      GL_INVALID_OPERATION);
3474         ShaderParser* sp = (ShaderParser*)objData;
3475         sp->setSrc(count, string, length);
3476         if (isGles2Gles()) {
3477             if (sDebugPrintShaders) { // save repeated checks
3478                 for (GLsizei i = 0; i < count; ++i) {
3479                     SHADER_DEBUG_PRINT(
3480                         "(GLES->GLES) shader "
3481                         "%u source %d of %d: [%s]\n",
3482                         shader,
3483                         i, count,
3484                         string[i]);
3485                 }
3486             }
3487             ctx->dispatcher().glShaderSource(globalShaderName, count, string,
3488                                          length);
3489         } else {
3490             if (sDebugPrintShaders) { // save repeated checks
3491                 for (GLsizei i = 0; i < 1; ++i) {
3492                     SHADER_DEBUG_PRINT(
3493                         "(GLES->GL translated) "
3494                         "shader %u source %d of %d: [%s]\n",
3495                         shader,
3496                         i, count,
3497                         sp->parsedLines()[i]);
3498                 }
3499             }
3500             ctx->dispatcher().glShaderSource(globalShaderName, 1, sp->parsedLines(),
3501                                          NULL);
3502         }
3503     }
3504 }
3505 
glStencilFunc(GLenum func,GLint ref,GLuint mask)3506 GL_APICALL void  GL_APIENTRY glStencilFunc(GLenum func, GLint ref, GLuint mask){
3507     GET_CTX();
3508     ctx->setStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
3509     ctx->dispatcher().glStencilFunc(func,ref,mask);
3510 }
glStencilFuncSeparate(GLenum face,GLenum func,GLint ref,GLuint mask)3511 GL_APICALL void  GL_APIENTRY glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask){
3512     GET_CTX();
3513     ctx->setStencilFuncSeparate(face, func, ref, mask);
3514     ctx->dispatcher().glStencilFuncSeparate(face,func,ref,mask);
3515 }
glStencilMask(GLuint mask)3516 GL_APICALL void  GL_APIENTRY glStencilMask(GLuint mask){
3517     GET_CTX();
3518     ctx->setStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
3519     ctx->dispatcher().glStencilMask(mask);
3520 }
3521 
glStencilMaskSeparate(GLenum face,GLuint mask)3522 GL_APICALL void  GL_APIENTRY glStencilMaskSeparate(GLenum face, GLuint mask){
3523     GET_CTX();
3524     ctx->setStencilMaskSeparate(face, mask);
3525     ctx->dispatcher().glStencilMaskSeparate(face,mask);
3526 }
3527 
glStencilOp(GLenum fail,GLenum zfail,GLenum zpass)3528 GL_APICALL void  GL_APIENTRY glStencilOp(GLenum fail, GLenum zfail, GLenum zpass){
3529     GET_CTX();
3530     ctx->setStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
3531     ctx->dispatcher().glStencilOp(fail,zfail,zpass);
3532 }
3533 
glStencilOpSeparate(GLenum face,GLenum fail,GLenum zfail,GLenum zpass)3534 GL_APICALL void  GL_APIENTRY glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass){
3535     GET_CTX();
3536     switch (face) {
3537         case GL_FRONT:
3538         case GL_BACK:
3539         case GL_FRONT_AND_BACK:
3540             break;
3541         default:
3542             SET_ERROR_IF(1, GL_INVALID_ENUM);
3543     }
3544     ctx->setStencilOpSeparate(face, fail, zfail, zpass);
3545     ctx->dispatcher().glStencilOpSeparate(face, fail,zfail,zpass);
3546 }
3547 
3548 #define GL_RGBA32F                        0x8814
3549 #define GL_RGB32F                         0x8815
3550 
sPrepareTexImage2D(GLenum target,GLsizei level,GLint internalformat,GLsizei width,GLsizei height,GLint border,GLenum format,GLenum type,GLint samples,const GLvoid * pixels,GLenum * type_out,GLint * internalformat_out,GLint * err_out)3551 static void sPrepareTexImage2D(GLenum target, GLsizei level, GLint internalformat,
3552                                GLsizei width, GLsizei height, GLint border,
3553                                GLenum format, GLenum type, GLint samples, const GLvoid* pixels,
3554                                GLenum* type_out,
3555                                GLint* internalformat_out,
3556                                GLint* err_out) {
3557     GET_CTX_V2();
3558 #define VALIDATE(cond, err) do { if (cond) { *err_out = err; fprintf(stderr, "%s:%d failed validation\n", __FUNCTION__, __LINE__); return; } } while(0) \
3559 
3560     bool isCompressedFormat =
3561         GLESv2Validate::isCompressedFormat(internalformat);
3562 
3563     if (!isCompressedFormat) {
3564         VALIDATE(!(GLESv2Validate::textureTarget(ctx, target) ||
3565                    GLESv2Validate::textureTargetEx(ctx, target)), GL_INVALID_ENUM);
3566         VALIDATE(!GLESv2Validate::pixelFrmt(ctx, format), GL_INVALID_ENUM);
3567         VALIDATE(!GLESv2Validate::pixelType(ctx, type), GL_INVALID_ENUM);
3568 
3569         VALIDATE(!GLESv2Validate::pixelItnlFrmt(ctx,internalformat), GL_INVALID_VALUE);
3570         VALIDATE((GLESv2Validate::textureIsCubeMap(target) && width != height), GL_INVALID_VALUE);
3571         VALIDATE(ctx->getMajorVersion() < 3 &&
3572                 (format == GL_DEPTH_COMPONENT || internalformat == GL_DEPTH_COMPONENT) &&
3573                 (type != GL_UNSIGNED_SHORT && type != GL_UNSIGNED_INT), GL_INVALID_OPERATION);
3574 
3575         VALIDATE(ctx->getMajorVersion() < 3 &&
3576                 (type == GL_UNSIGNED_SHORT || type == GL_UNSIGNED_INT) &&
3577                 !((format == GL_DEPTH_COMPONENT && internalformat == GL_DEPTH_COMPONENT)
3578                 || (format == GL_LUMINANCE && internalformat == GL_LUMINANCE)), GL_INVALID_OPERATION);
3579 
3580         VALIDATE(!GLESv2Validate::pixelOp(format,type),GL_INVALID_OPERATION);
3581         VALIDATE(!GLESv2Validate::pixelSizedFrmt(ctx, internalformat, format, type), GL_INVALID_OPERATION);
3582     }
3583 
3584     VALIDATE(border != 0,GL_INVALID_VALUE);
3585 
3586     s_glInitTexImage2D(target, level, internalformat, width, height, border, samples,
3587             &format, &type, &internalformat);
3588 
3589     if (!isCompressedFormat && ctx->getMajorVersion() < 3 && !isGles2Gles()) {
3590         if (type==GL_HALF_FLOAT_OES && !isGles2Gles())
3591             type = GL_HALF_FLOAT_NV;
3592         if (pixels==NULL && type==GL_UNSIGNED_SHORT_5_5_5_1)
3593             type = GL_UNSIGNED_BYTE;
3594         if (type == GL_FLOAT)
3595             internalformat = (format == GL_RGBA) ? GL_RGBA32F : GL_RGB32F;
3596     }
3597 
3598     // Desktop OpenGL doesn't support GL_BGRA_EXT as internal format.
3599     if (!isGles2Gles() && type == GL_UNSIGNED_BYTE && format == GL_BGRA_EXT &&
3600         internalformat == GL_BGRA_EXT) {
3601         internalformat = GL_RGBA;
3602     }
3603 
3604     *type_out = type;
3605     *internalformat_out = internalformat;
3606     *err_out = GL_NO_ERROR;
3607 }
3608 
glTexImage2D(GLenum target,GLint level,GLint internalformat,GLsizei width,GLsizei height,GLint border,GLenum format,GLenum type,const GLvoid * pixels)3609 GL_APICALL void  GL_APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels){
3610     GET_CTX_V2();
3611     // clear previous error
3612     GLint err = ctx->dispatcher().glGetError();
3613     if (err != GL_NO_ERROR) {
3614         fprintf(stderr, "%s: got err pre :( 0x%x internal 0x%x format 0x%x type 0x%x\n", __func__, err, internalformat, format, type);
3615     }
3616 
3617     sPrepareTexImage2D(target, level, internalformat, width, height, border, format, type, 0, pixels, &type, &internalformat, &err);
3618     SET_ERROR_IF(err != GL_NO_ERROR, err);
3619 
3620     if (isCoreProfile()) {
3621         GLEScontext::prepareCoreProfileEmulatedTexture(
3622             getTextureTargetData(target),
3623             false, target, format, type,
3624             &internalformat, &format);
3625     }
3626 
3627     ctx->dispatcher().glTexImage2D(target,level,internalformat,width,height,border,format,type,pixels);
3628 
3629     err = ctx->dispatcher().glGetError();
3630     if (err != GL_NO_ERROR) {
3631         fprintf(stderr, "%s: got err :( 0x%x internal 0x%x format 0x%x type 0x%x\n", __func__, err, internalformat, format, type);
3632         ctx->setGLerror(err);                                    \
3633     }
3634 }
3635 
sEmulateUserTextureSwizzle(TextureData * texData,GLenum target,GLenum pname,GLint param)3636 static void sEmulateUserTextureSwizzle(TextureData* texData,
3637                                        GLenum target, GLenum pname, GLint param) {
3638     GET_CTX_V2();
3639     TextureSwizzle emulatedBaseSwizzle =
3640         getSwizzleForEmulatedFormat(texData->format);
3641     GLenum userSwz =
3642         texData->getSwizzle(pname);
3643     GLenum hostEquivalentSwizzle =
3644         swizzleComponentOf(emulatedBaseSwizzle, userSwz);
3645     ctx->dispatcher().glTexParameteri(target, pname, hostEquivalentSwizzle);
3646 }
3647 
glTexParameterf(GLenum target,GLenum pname,GLfloat param)3648 GL_APICALL void  GL_APIENTRY glTexParameterf(GLenum target, GLenum pname, GLfloat param){
3649     GET_CTX_V2();
3650     SET_ERROR_IF(!(GLESv2Validate::textureTarget(ctx, target) &&
3651                    GLESv2Validate::textureParams(ctx, pname)),
3652                  GL_INVALID_ENUM);
3653 
3654     TextureData *texData = getTextureTargetData(target);
3655     if (texData) {
3656         texData->setTexParam(pname, static_cast<GLint>(param));
3657     }
3658 
3659     if (sShouldEmulateSwizzles(texData, target, pname)) {
3660         sEmulateUserTextureSwizzle(texData, target, pname, (GLint)param);
3661     } else {
3662         ctx->dispatcher().glTexParameterf(target,pname,param);
3663     }
3664 }
3665 
glTexParameterfv(GLenum target,GLenum pname,const GLfloat * params)3666 GL_APICALL void  GL_APIENTRY glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params){
3667     GET_CTX_V2();
3668     SET_ERROR_IF(!(GLESv2Validate::textureTarget(ctx, target) &&
3669                    GLESv2Validate::textureParams(ctx, pname)),
3670                  GL_INVALID_ENUM);
3671 
3672     TextureData *texData = getTextureTargetData(target);
3673     if (texData) {
3674         texData->setTexParam(pname, static_cast<GLint>(params[0]));
3675     }
3676 
3677     if (sShouldEmulateSwizzles(texData, target, pname)) {
3678         sEmulateUserTextureSwizzle(texData, target, pname, (GLint)params[0]);
3679     } else {
3680         ctx->dispatcher().glTexParameterfv(target,pname,params);
3681     }
3682 }
3683 
glTexParameteri(GLenum target,GLenum pname,GLint param)3684 GL_APICALL void  GL_APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param){
3685     GET_CTX_V2();
3686     SET_ERROR_IF(!(GLESv2Validate::textureTarget(ctx, target) &&
3687                    GLESv2Validate::textureParams(ctx, pname)),
3688                  GL_INVALID_ENUM);
3689 
3690     TextureData *texData = getTextureTargetData(target);
3691     if (texData) {
3692         texData->setTexParam(pname, param);
3693     }
3694 
3695     if (sShouldEmulateSwizzles(texData, target, pname)) {
3696         sEmulateUserTextureSwizzle(texData, target, pname, param);
3697     } else {
3698         ctx->dispatcher().glTexParameteri(target,pname,param);
3699     }
3700 }
3701 
glTexParameteriv(GLenum target,GLenum pname,const GLint * params)3702 GL_APICALL void  GL_APIENTRY glTexParameteriv(GLenum target, GLenum pname, const GLint* params){
3703     GET_CTX_V2();
3704     SET_ERROR_IF(!(GLESv2Validate::textureTarget(ctx, target) &&
3705                    GLESv2Validate::textureParams(ctx, pname)),
3706                  GL_INVALID_ENUM);
3707     TextureData *texData = getTextureTargetData(target);
3708     if (texData) {
3709         texData->setTexParam(pname, params[0]);
3710     }
3711 
3712 
3713     if (sShouldEmulateSwizzles(texData, target, pname)) {
3714         sEmulateUserTextureSwizzle(texData, target, pname, params[0]);
3715     } else {
3716         ctx->dispatcher().glTexParameteriv(target,pname,params);
3717     }
3718 }
3719 
glGetTexImage(GLenum target,GLint level,GLenum format,GLenum type,GLvoid * pixels)3720 GL_APICALL void  GL_APIENTRY glGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLvoid* pixels){
3721     GET_CTX_V2();
3722     SET_ERROR_IF(!(GLESv2Validate::textureTarget(ctx, target) ||
3723                    GLESv2Validate::textureTargetEx(ctx, target)), GL_INVALID_ENUM);
3724     SET_ERROR_IF(!GLESv2Validate::pixelFrmt(ctx,format), GL_INVALID_ENUM);
3725     SET_ERROR_IF(!GLESv2Validate::pixelType(ctx,type),GL_INVALID_ENUM);
3726 
3727     // set an error if level < 0 or level > log 2 max
3728     SET_ERROR_IF(level < 0 || 1<<level > ctx->getMaxTexSize(), GL_INVALID_VALUE);
3729     SET_ERROR_IF(!(GLESv2Validate::pixelFrmt(ctx,format) &&
3730                    GLESv2Validate::pixelType(ctx,type)),GL_INVALID_ENUM);
3731     SET_ERROR_IF(!GLESv2Validate::pixelOp(format,type),GL_INVALID_OPERATION);
3732 
3733     if (isCoreProfile() &&
3734         isCoreProfileEmulatedFormat(format)) {
3735         format = getCoreProfileEmulatedFormat(format);
3736     }
3737 
3738     uint8_t* data = (uint8_t*)pixels;
3739 
3740     if (ctx->dispatcher().glGetTexImage) {
3741         ctx->dispatcher().glGetTexImage(target,level,format,type,data);
3742     } else {
3743 
3744         // Best effort via readPixels, assume gles 3.0 capabilities underneath
3745         GLint prevViewport[4];
3746         GLint prevFbo;
3747         GLint packAlignment;
3748 
3749         auto gl = ctx->dispatcher();
3750 
3751         gl.glGetIntegerv(GL_VIEWPORT, prevViewport);
3752         gl.glGetIntegerv(GL_PACK_ALIGNMENT, &packAlignment);
3753         gl.glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &prevFbo);
3754 
3755         GLint width;
3756         GLint height;
3757         GLint depth;
3758         gl.glGetTexLevelParameteriv(target, level, GL_TEXTURE_WIDTH, &width);
3759         gl.glGetTexLevelParameteriv(target, level, GL_TEXTURE_HEIGHT, &height);
3760         gl.glGetTexLevelParameteriv(target, level, GL_TEXTURE_DEPTH, &depth);
3761 
3762         GLuint fbo;
3763         gl.glGenFramebuffers(1, &fbo);
3764         gl.glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
3765 
3766         GLenum attachment = GL_COLOR_ATTACHMENT0;
3767 
3768         switch (format) {
3769             case GL_DEPTH_COMPONENT:
3770                 attachment = GL_DEPTH_ATTACHMENT;
3771                 break;
3772             case GL_DEPTH_STENCIL:
3773                 attachment = GL_DEPTH_STENCIL_ATTACHMENT;
3774                 break;
3775         }
3776 
3777         unsigned int tex = ctx->getBindedTexture(target);
3778         GLuint globalName = ctx->shareGroup()->getGlobalName(
3779                 NamedObjectType::TEXTURE, tex);
3780 
3781         // Do stuff
3782         switch (target) {
3783             case GL_TEXTURE_2D:
3784             case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
3785             case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
3786             case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
3787             case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
3788             case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
3789             case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
3790                 gl.glFramebufferTexture2D(
3791                         GL_READ_FRAMEBUFFER, attachment, target,
3792                         globalName, level);
3793                 gl.glReadPixels(0, 0, width, height,
3794                         format, type,
3795                         data);
3796                 gl.glFramebufferTexture2D(
3797                         GL_READ_FRAMEBUFFER, attachment, target,
3798                         0, level);
3799                 break;
3800             case GL_TEXTURE_3D: {
3801                 unsigned int layerImgSize = texImageSize(
3802                         format, type, packAlignment, width, height);
3803                 for (unsigned int d = 0; d < depth; d++) {
3804                     gl.glFramebufferTexture3DOES(
3805                             GL_READ_FRAMEBUFFER, attachment, target,
3806                             globalName, level, d);
3807                     gl.glReadPixels(0, 0, width,
3808                             height, format,
3809                             type, data +
3810                             layerImgSize * d);
3811                     gl.glFramebufferTexture3DOES(
3812                             GL_READ_FRAMEBUFFER, attachment, target,
3813                             0, level, d);
3814                 }
3815                 break;
3816             }
3817             case GL_TEXTURE_2D_ARRAY: {
3818                 unsigned int layerImgSize = texImageSize(
3819                         format, type, packAlignment, width, height);
3820                 for (unsigned int d = 0; d < depth; d++) {
3821                     gl.glFramebufferTextureLayer(
3822                             GL_READ_FRAMEBUFFER, attachment,
3823                             globalName, level, d);
3824                     gl.glReadPixels(0, 0, width,
3825                             height, format,
3826                             type, data +
3827                             layerImgSize * d);
3828                     gl.glFramebufferTextureLayer(
3829                             GL_READ_FRAMEBUFFER, attachment,
3830                             0, level, d);
3831                 }
3832                 break;
3833             }
3834         }
3835 
3836         gl.glBindFramebuffer(GL_READ_FRAMEBUFFER, prevFbo);
3837         gl.glDeleteFramebuffers(1, &fbo);
3838         gl.glViewport(prevViewport[0], prevViewport[1], prevViewport[2], prevViewport[3]);
3839         gl.glGetError();
3840     }
3841 }
3842 
glDebugMessageControlKHR(GLenum source,GLenum type,GLenum severity,GLsizei count,const GLuint * ids,GLboolean enabled)3843 GL_APICALL void GL_APIENTRY glDebugMessageControlKHR(GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint* ids, GLboolean enabled) {
3844     GET_CTX_V2();
3845     ctx->dispatcher().glDebugMessageControlKHR(source, type, severity, count, ids, enabled);
3846 }
3847 
glDebugMessageInsertKHR(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar * buf)3848 GL_APICALL void GL_APIENTRY glDebugMessageInsertKHR(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* buf) {
3849     GET_CTX_V2();
3850     ctx->dispatcher().glDebugMessageInsertKHR(source, type, id, severity, length, buf);
3851 }
3852 
glDebugMessageCallbackKHR(GLDEBUGPROCKHR callback,const void * userdata)3853 GL_APICALL void GL_APIENTRY glDebugMessageCallbackKHR(GLDEBUGPROCKHR callback, const void* userdata) {
3854     GET_CTX_V2();
3855     ctx->dispatcher().glDebugMessageCallbackKHR(callback, userdata);
3856 }
3857 
glGetDebugMessageLogKHR(GLuint count,GLsizei size,GLenum * sources,GLenum * types,GLuint * ids,GLenum * severities,GLsizei * lengths,GLchar * log)3858 GL_APICALL GLuint GL_APIENTRY glGetDebugMessageLogKHR(GLuint count, GLsizei size, GLenum* sources, GLenum* types, GLuint* ids, GLenum* severities, GLsizei* lengths, GLchar* log) {
3859     GET_CTX_V2_RET(0);
3860     return ctx->dispatcher().glGetDebugMessageLogKHR(count, size, sources, types, ids, severities, lengths, log);
3861 }
3862 
glPushDebugGroupKHR(GLenum source,GLuint id,GLsizei length,const GLchar * message)3863 GL_APICALL void GL_APIENTRY glPushDebugGroupKHR(GLenum source, GLuint id, GLsizei length, const GLchar* message) {
3864     GET_CTX_V2();
3865     ctx->dispatcher().glPushDebugGroupKHR(source, id, length, message);
3866 }
3867 
glPopDebugGroupKHR(void)3868 GL_APICALL void GL_APIENTRY glPopDebugGroupKHR(void) {
3869     GET_CTX_V2();
3870     ctx->dispatcher().glPopDebugGroupKHR();
3871 }
3872 
glTexSubImage2D(GLenum target,GLint level,GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,GLenum format,GLenum type,const GLvoid * pixels)3873 GL_APICALL void  GL_APIENTRY glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid* pixels){
3874     GET_CTX_V2();
3875     SET_ERROR_IF(!(GLESv2Validate::textureTarget(ctx, target) ||
3876                    GLESv2Validate::textureTargetEx(ctx, target)), GL_INVALID_ENUM);
3877     SET_ERROR_IF(!GLESv2Validate::pixelFrmt(ctx,format), GL_INVALID_ENUM);
3878     SET_ERROR_IF(!GLESv2Validate::pixelType(ctx,type),GL_INVALID_ENUM);
3879 
3880     // set an error if level < 0 or level > log 2 max
3881     SET_ERROR_IF(level < 0 || 1<<level > ctx->getMaxTexSize(), GL_INVALID_VALUE);
3882     SET_ERROR_IF(xoffset < 0 || yoffset < 0 || width < 0 || height < 0, GL_INVALID_VALUE);
3883     TextureData *texData = getTextureTargetData(target);
3884     if (texData) {
3885         SET_ERROR_IF(xoffset + width > (GLint)texData->width ||
3886                  yoffset + height > (GLint)texData->height,
3887                  GL_INVALID_VALUE);
3888     }
3889     SET_ERROR_IF(!(GLESv2Validate::pixelFrmt(ctx,format) &&
3890                    GLESv2Validate::pixelType(ctx,type)),GL_INVALID_ENUM);
3891     SET_ERROR_IF(!GLESv2Validate::pixelOp(format,type),GL_INVALID_OPERATION);
3892     SET_ERROR_IF(!pixels && !ctx->isBindedBuffer(GL_PIXEL_UNPACK_BUFFER),GL_INVALID_OPERATION);
3893     if (type==GL_HALF_FLOAT_OES)
3894         type = GL_HALF_FLOAT_NV;
3895 
3896     if (isCoreProfile() &&
3897         isCoreProfileEmulatedFormat(format)) {
3898         format = getCoreProfileEmulatedFormat(format);
3899     }
3900     texData->setMipmapLevelAtLeast(level);
3901     texData->makeDirty();
3902     ctx->dispatcher().glTexSubImage2D(target,level,xoffset,yoffset,width,height,format,type,pixels);
3903 }
3904 
s_getHostLocOrSetError(GLESv2Context * ctx,GLint location)3905 static int s_getHostLocOrSetError(GLESv2Context* ctx, GLint location) {
3906     if (!ctx) return -1;
3907     ProgramData* pData = ctx->getUseProgram();
3908     RET_AND_SET_ERROR_IF(!pData, GL_INVALID_OPERATION, -2);
3909     return pData->getHostUniformLocation(location);
3910 }
3911 
s_getHostLocOrSetError(GLESv2Context * ctx,GLuint program,GLint location)3912 static int s_getHostLocOrSetError(GLESv2Context* ctx, GLuint program,
3913         GLint location) {
3914     if (!ctx) return -1;
3915     ProgramData* pData = (ProgramData*)ctx->shareGroup()->getObjectDataPtr(
3916             NamedObjectType::SHADER_OR_PROGRAM, program).get();
3917     RET_AND_SET_ERROR_IF(!pData, GL_INVALID_OPERATION, -2);
3918     return pData->getHostUniformLocation(location);
3919 }
3920 
glUniform1f(GLint location,GLfloat x)3921 GL_APICALL void  GL_APIENTRY glUniform1f(GLint location, GLfloat x){
3922     GET_CTX_V2();
3923     int hostLoc = s_getHostLocOrSetError(ctx, location);
3924     SET_ERROR_IF(hostLoc < -1, GL_INVALID_OPERATION);
3925     ctx->dispatcher().glUniform1f(hostLoc,x);
3926 }
3927 
glUniform1fv(GLint location,GLsizei count,const GLfloat * v)3928 GL_APICALL void  GL_APIENTRY glUniform1fv(GLint location, GLsizei count, const GLfloat* v){
3929     GET_CTX_V2();
3930     int hostLoc = s_getHostLocOrSetError(ctx, location);
3931     SET_ERROR_IF(hostLoc < -1, GL_INVALID_OPERATION);
3932     ctx->dispatcher().glUniform1fv(hostLoc,count,v);
3933 }
3934 
glUniform1i(GLint location,GLint x)3935 GL_APICALL void  GL_APIENTRY glUniform1i(GLint location, GLint x){
3936     GET_CTX_V2();
3937     int hostLoc = s_getHostLocOrSetError(ctx, location);
3938     SET_ERROR_IF(hostLoc < -1, GL_INVALID_OPERATION);
3939     ctx->dispatcher().glUniform1i(hostLoc, x);
3940 }
3941 
glUniform1iv(GLint location,GLsizei count,const GLint * v)3942 GL_APICALL void  GL_APIENTRY glUniform1iv(GLint location, GLsizei count, const GLint* v){
3943     GET_CTX_V2();
3944     int hostLoc = s_getHostLocOrSetError(ctx, location);
3945     SET_ERROR_IF(hostLoc < -1, GL_INVALID_OPERATION);
3946     ctx->dispatcher().glUniform1iv(hostLoc, count,v);
3947 }
3948 
glUniform2f(GLint location,GLfloat x,GLfloat y)3949 GL_APICALL void  GL_APIENTRY glUniform2f(GLint location, GLfloat x, GLfloat y){
3950     GET_CTX_V2();
3951     int hostLoc = s_getHostLocOrSetError(ctx, location);
3952     SET_ERROR_IF(hostLoc < -1, GL_INVALID_OPERATION);
3953     ctx->dispatcher().glUniform2f(hostLoc, x, y);
3954 }
3955 
glUniform2fv(GLint location,GLsizei count,const GLfloat * v)3956 GL_APICALL void  GL_APIENTRY glUniform2fv(GLint location, GLsizei count, const GLfloat* v){
3957     GET_CTX_V2();
3958     int hostLoc = s_getHostLocOrSetError(ctx, location);
3959     SET_ERROR_IF(hostLoc < -1, GL_INVALID_OPERATION);
3960     ctx->dispatcher().glUniform2fv(hostLoc,count,v);
3961 }
3962 
glUniform2i(GLint location,GLint x,GLint y)3963 GL_APICALL void  GL_APIENTRY glUniform2i(GLint location, GLint x, GLint y){
3964     GET_CTX_V2();
3965     int hostLoc = s_getHostLocOrSetError(ctx, location);
3966     SET_ERROR_IF(hostLoc < -1, GL_INVALID_OPERATION);
3967     ctx->dispatcher().glUniform2i(hostLoc, x, y);
3968 }
3969 
glUniform2iv(GLint location,GLsizei count,const GLint * v)3970 GL_APICALL void  GL_APIENTRY glUniform2iv(GLint location, GLsizei count, const GLint* v){
3971     GET_CTX_V2();
3972     int hostLoc = s_getHostLocOrSetError(ctx, location);
3973     SET_ERROR_IF(hostLoc < -1, GL_INVALID_OPERATION);
3974     ctx->dispatcher().glUniform2iv(hostLoc,count,v);
3975 }
3976 
glUniform3f(GLint location,GLfloat x,GLfloat y,GLfloat z)3977 GL_APICALL void  GL_APIENTRY glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z){
3978     GET_CTX_V2();
3979     int hostLoc = s_getHostLocOrSetError(ctx, location);
3980     SET_ERROR_IF(hostLoc < -1, GL_INVALID_OPERATION);
3981     ctx->dispatcher().glUniform3f(hostLoc,x,y,z);
3982 }
3983 
glUniform3fv(GLint location,GLsizei count,const GLfloat * v)3984 GL_APICALL void  GL_APIENTRY glUniform3fv(GLint location, GLsizei count, const GLfloat* v){
3985     GET_CTX_V2();
3986     int hostLoc = s_getHostLocOrSetError(ctx, location);
3987     SET_ERROR_IF(hostLoc < -1, GL_INVALID_OPERATION);
3988     ctx->dispatcher().glUniform3fv(hostLoc,count,v);
3989 }
3990 
glUniform3i(GLint location,GLint x,GLint y,GLint z)3991 GL_APICALL void  GL_APIENTRY glUniform3i(GLint location, GLint x, GLint y, GLint z){
3992     GET_CTX_V2();
3993     int hostLoc = s_getHostLocOrSetError(ctx, location);
3994     SET_ERROR_IF(hostLoc < -1, GL_INVALID_OPERATION);
3995     ctx->dispatcher().glUniform3i(hostLoc,x,y,z);
3996 }
3997 
glUniform3iv(GLint location,GLsizei count,const GLint * v)3998 GL_APICALL void  GL_APIENTRY glUniform3iv(GLint location, GLsizei count, const GLint* v){
3999     GET_CTX_V2();
4000     int hostLoc = s_getHostLocOrSetError(ctx, location);
4001     SET_ERROR_IF(hostLoc < -1, GL_INVALID_OPERATION);
4002     ctx->dispatcher().glUniform3iv(hostLoc,count,v);
4003 }
4004 
glUniform4f(GLint location,GLfloat x,GLfloat y,GLfloat z,GLfloat w)4005 GL_APICALL void  GL_APIENTRY glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w){
4006     GET_CTX_V2();
4007     int hostLoc = s_getHostLocOrSetError(ctx, location);
4008     SET_ERROR_IF(hostLoc < -1, GL_INVALID_OPERATION);
4009     ctx->dispatcher().glUniform4f(hostLoc,x,y,z,w);
4010 }
4011 
glUniform4fv(GLint location,GLsizei count,const GLfloat * v)4012 GL_APICALL void  GL_APIENTRY glUniform4fv(GLint location, GLsizei count, const GLfloat* v){
4013     GET_CTX_V2();
4014     int hostLoc = s_getHostLocOrSetError(ctx, location);
4015     SET_ERROR_IF(hostLoc < -1, GL_INVALID_OPERATION);
4016     ctx->dispatcher().glUniform4fv(hostLoc,count,v);
4017 }
4018 
glUniform4i(GLint location,GLint x,GLint y,GLint z,GLint w)4019 GL_APICALL void  GL_APIENTRY glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w){
4020     GET_CTX_V2();
4021     int hostLoc = s_getHostLocOrSetError(ctx, location);
4022     SET_ERROR_IF(hostLoc < -1, GL_INVALID_OPERATION);
4023     ctx->dispatcher().glUniform4i(hostLoc,x,y,z,w);
4024 }
4025 
glUniform4iv(GLint location,GLsizei count,const GLint * v)4026 GL_APICALL void  GL_APIENTRY glUniform4iv(GLint location, GLsizei count, const GLint* v){
4027     GET_CTX_V2();
4028     int hostLoc = s_getHostLocOrSetError(ctx, location);
4029     SET_ERROR_IF(hostLoc < -1, GL_INVALID_OPERATION);
4030     ctx->dispatcher().glUniform4iv(hostLoc,count,v);
4031 }
4032 
glUniformMatrix2fv(GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)4033 GL_APICALL void  GL_APIENTRY glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value){
4034     GET_CTX_V2();
4035     SET_ERROR_IF(ctx->getMajorVersion() < 3 &&
4036                  transpose != GL_FALSE,GL_INVALID_VALUE);
4037     int hostLoc = s_getHostLocOrSetError(ctx, location);
4038     SET_ERROR_IF(hostLoc < -1, GL_INVALID_OPERATION);
4039     ctx->dispatcher().glUniformMatrix2fv(hostLoc,count,transpose,value);
4040 }
4041 
glUniformMatrix3fv(GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)4042 GL_APICALL void  GL_APIENTRY glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value){
4043     GET_CTX_V2();
4044     SET_ERROR_IF(ctx->getMajorVersion() < 3 &&
4045                  transpose != GL_FALSE,GL_INVALID_VALUE);
4046     int hostLoc = s_getHostLocOrSetError(ctx, location);
4047     SET_ERROR_IF(hostLoc < -1, GL_INVALID_OPERATION);
4048     ctx->dispatcher().glUniformMatrix3fv(hostLoc,count,transpose,value);
4049 }
4050 
glUniformMatrix4fv(GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)4051 GL_APICALL void  GL_APIENTRY glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value){
4052     GET_CTX_V2();
4053     SET_ERROR_IF(ctx->getMajorVersion() < 3 &&
4054                  transpose != GL_FALSE,GL_INVALID_VALUE);
4055     int hostLoc = s_getHostLocOrSetError(ctx, location);
4056     SET_ERROR_IF(hostLoc < -1, GL_INVALID_OPERATION);
4057     ctx->dispatcher().glUniformMatrix4fv(hostLoc,count,transpose,value);
4058 }
4059 
s_unUseCurrentProgram()4060 static void s_unUseCurrentProgram() {
4061     GET_CTX();
4062     GLint localCurrentProgram = 0;
4063     glGetIntegerv(GL_CURRENT_PROGRAM, &localCurrentProgram);
4064     if (!localCurrentProgram) return;
4065 
4066     auto objData = ctx->shareGroup()->getObjectData(
4067             NamedObjectType::SHADER_OR_PROGRAM, localCurrentProgram);
4068     SET_ERROR_IF(objData->getDataType()!=PROGRAM_DATA,GL_INVALID_OPERATION);
4069     ProgramData* programData = (ProgramData*)objData;
4070     programData->setInUse(false);
4071     if (programData->getDeleteStatus()) {
4072         s_detachShader(ctx, localCurrentProgram,
4073                 programData->getAttachedVertexShader());
4074         s_detachShader(ctx, localCurrentProgram,
4075                 programData->getAttachedFragmentShader());
4076         s_detachShader(ctx, localCurrentProgram,
4077                 programData->getAttachedComputeShader());
4078         ctx->shareGroup()->deleteName(NamedObjectType::SHADER_OR_PROGRAM,
4079                                       localCurrentProgram);
4080     }
4081 }
4082 
glUseProgram(GLuint program)4083 GL_APICALL void  GL_APIENTRY glUseProgram(GLuint program){
4084     GET_CTX_V2();
4085     if(ctx->shareGroup().get()) {
4086         const GLuint globalProgramName = ctx->shareGroup()->getGlobalName(
4087                 NamedObjectType::SHADER_OR_PROGRAM, program);
4088         SET_ERROR_IF(program!=0 && globalProgramName==0,GL_INVALID_VALUE);
4089         auto objData = ctx->shareGroup()->getObjectDataPtr(
4090                 NamedObjectType::SHADER_OR_PROGRAM, program);
4091         SET_ERROR_IF(objData && (objData->getDataType()!=PROGRAM_DATA),GL_INVALID_OPERATION);
4092 
4093         s_unUseCurrentProgram();
4094 
4095         ProgramData* programData = (ProgramData*)objData.get();
4096         if (programData) programData->setInUse(true);
4097 
4098         ctx->setUseProgram(program, objData);
4099         SHADER_DEBUG_PRINT("use program %u", program);
4100 
4101         ctx->dispatcher().glUseProgram(globalProgramName);
4102     }
4103 }
4104 
glValidateProgram(GLuint program)4105 GL_APICALL void  GL_APIENTRY glValidateProgram(GLuint program){
4106     GET_CTX();
4107     if(ctx->shareGroup().get()) {
4108         const GLuint globalProgramName = ctx->shareGroup()->getGlobalName(
4109                 NamedObjectType::SHADER_OR_PROGRAM, program);
4110         SET_ERROR_IF(globalProgramName==0, GL_INVALID_VALUE);
4111         auto objData = ctx->shareGroup()->getObjectData(
4112                 NamedObjectType::SHADER_OR_PROGRAM, program);
4113         SET_ERROR_IF(objData->getDataType()!=PROGRAM_DATA,GL_INVALID_OPERATION);
4114         ProgramData* programData = (ProgramData*)objData;
4115         ctx->dispatcher().glValidateProgram(globalProgramName);
4116 
4117         GLint validateStatus;
4118         ctx->dispatcher().glGetProgramiv(globalProgramName, GL_VALIDATE_STATUS,
4119                                          &validateStatus);
4120         programData->setValidateStatus(static_cast<bool>(validateStatus));
4121 
4122         GLsizei infoLogLength = 0, cLength = 0;
4123         ctx->dispatcher().glGetProgramiv(globalProgramName,GL_INFO_LOG_LENGTH,&infoLogLength);
4124         std::unique_ptr<GLchar[]> infoLog(new GLchar[infoLogLength + 1]);
4125         ctx->dispatcher().glGetProgramInfoLog(globalProgramName, infoLogLength,
4126                                               &cLength, infoLog.get());
4127         if (cLength > 0) {
4128             programData->setInfoLog(infoLog.release());
4129         }
4130     }
4131 }
4132 
glVertexAttrib1f(GLuint index,GLfloat x)4133 GL_APICALL void  GL_APIENTRY glVertexAttrib1f(GLuint index, GLfloat x){
4134     GET_CTX_V2();
4135     SET_ERROR_IF((!GLESv2Validate::arrayIndex(ctx,index)),GL_INVALID_VALUE);
4136     ctx->dispatcher().glVertexAttrib1f(index,x);
4137     ctx->setAttribValue(index, 1, &x);
4138     if(index == 0)
4139         ctx->setAttribute0value(x, 0.0, 0.0, 1.0);
4140 }
4141 
glVertexAttrib1fv(GLuint index,const GLfloat * values)4142 GL_APICALL void  GL_APIENTRY glVertexAttrib1fv(GLuint index, const GLfloat* values){
4143     GET_CTX_V2();
4144     SET_ERROR_IF((!GLESv2Validate::arrayIndex(ctx,index)),GL_INVALID_VALUE);
4145     ctx->dispatcher().glVertexAttrib1fv(index,values);
4146     ctx->setAttribValue(index, 1, values);
4147     if(index == 0)
4148         ctx->setAttribute0value(values[0], 0.0, 0.0, 1.0);
4149 }
4150 
glVertexAttrib2f(GLuint index,GLfloat x,GLfloat y)4151 GL_APICALL void  GL_APIENTRY glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y){
4152     GET_CTX_V2();
4153     SET_ERROR_IF((!GLESv2Validate::arrayIndex(ctx,index)),GL_INVALID_VALUE);
4154     ctx->dispatcher().glVertexAttrib2f(index,x,y);
4155     GLfloat values[] = {x, y};
4156     ctx->setAttribValue(index, 2, values);
4157     if(index == 0)
4158         ctx->setAttribute0value(x, y, 0.0, 1.0);
4159 }
4160 
glVertexAttrib2fv(GLuint index,const GLfloat * values)4161 GL_APICALL void  GL_APIENTRY glVertexAttrib2fv(GLuint index, const GLfloat* values){
4162     GET_CTX_V2();
4163     SET_ERROR_IF((!GLESv2Validate::arrayIndex(ctx,index)),GL_INVALID_VALUE);
4164     ctx->dispatcher().glVertexAttrib2fv(index,values);
4165     ctx->setAttribValue(index, 2, values);
4166     if(index == 0)
4167         ctx->setAttribute0value(values[0], values[1], 0.0, 1.0);
4168 }
4169 
glVertexAttrib3f(GLuint index,GLfloat x,GLfloat y,GLfloat z)4170 GL_APICALL void  GL_APIENTRY glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z){
4171     GET_CTX_V2();
4172     SET_ERROR_IF((!GLESv2Validate::arrayIndex(ctx,index)),GL_INVALID_VALUE);
4173     ctx->dispatcher().glVertexAttrib3f(index,x,y,z);
4174     GLfloat values[3] = {x, y, z};
4175     ctx->setAttribValue(index, 3, values);
4176     if(index == 0)
4177         ctx->setAttribute0value(x, y, z, 1.0);
4178 }
4179 
glVertexAttrib3fv(GLuint index,const GLfloat * values)4180 GL_APICALL void  GL_APIENTRY glVertexAttrib3fv(GLuint index, const GLfloat* values){
4181     GET_CTX_V2();
4182     SET_ERROR_IF((!GLESv2Validate::arrayIndex(ctx,index)),GL_INVALID_VALUE);
4183     ctx->dispatcher().glVertexAttrib3fv(index,values);
4184     ctx->setAttribValue(index, 3, values);
4185     if(index == 0)
4186         ctx->setAttribute0value(values[0], values[1], values[2], 1.0);
4187 }
4188 
glVertexAttrib4f(GLuint index,GLfloat x,GLfloat y,GLfloat z,GLfloat w)4189 GL_APICALL void  GL_APIENTRY glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w){
4190     GET_CTX_V2();
4191     SET_ERROR_IF((!GLESv2Validate::arrayIndex(ctx,index)),GL_INVALID_VALUE);
4192     ctx->dispatcher().glVertexAttrib4f(index,x,y,z,w);
4193     GLfloat values[4] = {x, y, z, z};
4194     ctx->setAttribValue(index, 4, values);
4195     if(index == 0)
4196         ctx->setAttribute0value(x, y, z, w);
4197 }
4198 
glVertexAttrib4fv(GLuint index,const GLfloat * values)4199 GL_APICALL void  GL_APIENTRY glVertexAttrib4fv(GLuint index, const GLfloat* values){
4200     GET_CTX_V2();
4201     SET_ERROR_IF((!GLESv2Validate::arrayIndex(ctx,index)),GL_INVALID_VALUE);
4202     ctx->dispatcher().glVertexAttrib4fv(index,values);
4203     ctx->setAttribValue(index, 4, values);
4204     if(index == 0)
4205         ctx->setAttribute0value(values[0], values[1], values[2], values[3]);
4206 }
4207 
s_glPrepareVertexAttribPointer(GLESv2Context * ctx,GLuint index,GLint size,GLenum type,GLboolean normalized,GLsizei stride,const GLvoid * ptr,GLsizei dataSize,bool isInt)4208 static void s_glPrepareVertexAttribPointer(GLESv2Context* ctx, GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr, GLsizei dataSize, bool isInt) {
4209     ctx->setVertexAttribBindingIndex(index, index);
4210     GLsizei effectiveStride = stride;
4211     if (stride == 0) {
4212         effectiveStride = GLESv2Validate::sizeOfType(type) * size;
4213         switch (type) {
4214             case GL_INT_2_10_10_10_REV:
4215             case GL_UNSIGNED_INT_2_10_10_10_REV:
4216                 effectiveStride /= 4;
4217                 break;
4218             default:
4219                 break;
4220         }
4221     }
4222     ctx->bindIndexedBuffer(0, index, ctx->getBuffer(GL_ARRAY_BUFFER), (GLintptr)ptr, 0, effectiveStride);
4223     ctx->setVertexAttribFormat(index, size, type, normalized, 0, isInt);
4224     // Still needed to deal with client arrays
4225     ctx->setPointer(index, size, type, stride, ptr, dataSize, normalized, isInt);
4226 }
4227 
glVertexAttribPointer(GLuint index,GLint size,GLenum type,GLboolean normalized,GLsizei stride,const GLvoid * ptr)4228 GL_APICALL void  GL_APIENTRY glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr){
4229     GET_CTX_V2();
4230     SET_ERROR_IF((!GLESv2Validate::arrayIndex(ctx,index)),GL_INVALID_VALUE);
4231     if (type == GL_HALF_FLOAT_OES) type = GL_HALF_FLOAT;
4232 
4233     s_glPrepareVertexAttribPointer(ctx, index, size, type, normalized, stride, ptr, 0, false);
4234     if (ctx->isBindedBuffer(GL_ARRAY_BUFFER)) {
4235         ctx->dispatcher().glVertexAttribPointer(index, size, type, normalized, stride, ptr);
4236     }
4237 }
4238 
glVertexAttribPointerWithDataSize(GLuint index,GLint size,GLenum type,GLboolean normalized,GLsizei stride,const GLvoid * ptr,GLsizei dataSize)4239 GL_APICALL void  GL_APIENTRY glVertexAttribPointerWithDataSize(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr, GLsizei dataSize) {
4240     GET_CTX_V2();
4241     SET_ERROR_IF((!GLESv2Validate::arrayIndex(ctx,index)),GL_INVALID_VALUE);
4242     if (type == GL_HALF_FLOAT_OES) type = GL_HALF_FLOAT;
4243 
4244     s_glPrepareVertexAttribPointer(ctx, index, size, type, normalized, stride, ptr, dataSize, false);
4245     if (ctx->isBindedBuffer(GL_ARRAY_BUFFER)) {
4246         ctx->dispatcher().glVertexAttribPointer(index, size, type, normalized, stride, ptr);
4247     }
4248 }
4249 
glViewport(GLint x,GLint y,GLsizei width,GLsizei height)4250 GL_APICALL void  GL_APIENTRY glViewport(GLint x, GLint y, GLsizei width, GLsizei height){
4251     GET_CTX();
4252     ctx->setViewport(x, y, width, height);
4253     ctx->dispatcher().glViewport(x,y,width,height);
4254 }
4255 
glEGLImageTargetTexture2DOES(GLenum target,GLeglImageOES image)4256 GL_APICALL void GL_APIENTRY glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image)
4257 {
4258     GET_CTX_V2();
4259     SET_ERROR_IF(!GLESv2Validate::textureTargetLimited(target),GL_INVALID_ENUM);
4260     unsigned int imagehndl = SafeUIntFromPointer(image);
4261     ImagePtr img = s_eglIface->getEGLImage(imagehndl);
4262     if (img) {
4263 
4264         // For native underlying EGL images, call underlying native
4265         // glEGLImageTargetTexture2DOES and exit, without replacing it with
4266         // another global tex obj ourselves. This will implicitly replace the
4267         // underlying texture that's stored in our global info.
4268         if (img->isNative) {
4269             if (!ctx->dispatcher().glEGLImageTargetTexture2DOES) {
4270                 fprintf(stderr, "%s: warning, glEGLImageTargetTexture2DOES not found\n", __func__);
4271 			} else {
4272 				ctx->dispatcher().glEGLImageTargetTexture2DOES(target, (GLeglImageOES)img->nativeImage);
4273 			}
4274 
4275             // We need to update our records about this texture.
4276             if (ctx->shareGroup().get()) {
4277                 TextureData *texData = getTextureTargetData(target);
4278                 SET_ERROR_IF(texData==NULL,GL_INVALID_OPERATION);
4279                 texData->width = img->width;
4280                 texData->height = img->height;
4281                 texData->border = img->border;
4282                 texData->internalFormat = img->internalFormat;
4283                 texData->format = img->format;
4284                 texData->type = img->type;
4285                 texData->texStorageLevels = img->texStorageLevels;
4286                 texData->sourceEGLImage = imagehndl;
4287                 if (img->sync) {
4288                     // insert gpu side fence to make sure we are done with any blit ops.
4289                     ctx->dispatcher().glWaitSync(img->sync, 0, GL_TIMEOUT_IGNORED);
4290                 }
4291                 if (!imagehndl) {
4292                     fprintf(stderr, "glEGLImageTargetTexture2DOES with empty handle\n");
4293                 }
4294             }
4295             return;
4296         }
4297 
4298         // Could be from a bad snapshot; in this case, skip.
4299         if (!img->globalTexObj) return;
4300 
4301         // Create the texture object in the underlying EGL implementation,
4302         // flag to the OpenGL layer to skip the image creation and map the
4303         // current binded texture object to the existing global object.
4304         if (ctx->shareGroup().get()) {
4305             ObjectLocalName tex = ctx->getTextureLocalName(target,ctx->getBindedTexture(target));
4306 
4307             // Replace mapping for this local texture id
4308             // with |img|'s global GL texture id
4309             ctx->shareGroup()->replaceGlobalObject(NamedObjectType::TEXTURE, tex,
4310                                                    img->globalTexObj);
4311             ctx->dispatcher().glBindTexture(GL_TEXTURE_2D, img->globalTexObj->getGlobalName());
4312             TextureData *texData = getTextureTargetData(target);
4313             SET_ERROR_IF(texData==NULL,GL_INVALID_OPERATION);
4314             texData->width = img->width;
4315             texData->height = img->height;
4316             texData->border = img->border;
4317             texData->internalFormat = img->internalFormat;
4318             texData->format = img->format;
4319             texData->type = img->type;
4320             texData->texStorageLevels = img->texStorageLevels;
4321             texData->sourceEGLImage = imagehndl;
4322             texData->setGlobalName(img->globalTexObj->getGlobalName());
4323             texData->setSaveableTexture(
4324                     SaveableTexturePtr(img->saveableTexture));
4325             if (img->sync) {
4326                 // insert gpu side fence to make sure we are done with any blit ops.
4327                 ctx->dispatcher().glWaitSync(img->sync, 0, GL_TIMEOUT_IGNORED);
4328             }
4329             if (!imagehndl) {
4330                 fprintf(stderr, "glEGLImageTargetTexture2DOES with empty handle\n");
4331             }
4332         }
4333     }
4334 }
4335 
glEGLImageTargetRenderbufferStorageOES(GLenum target,GLeglImageOES image)4336 GL_APICALL void GL_APIENTRY glEGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)
4337 {
4338     GET_CTX();
4339     SET_ERROR_IF(target != GL_RENDERBUFFER_OES,GL_INVALID_ENUM);
4340     unsigned int imagehndl = SafeUIntFromPointer(image);
4341     ImagePtr img = s_eglIface->getEGLImage(imagehndl);
4342     SET_ERROR_IF(!img,GL_INVALID_VALUE);
4343     SET_ERROR_IF(!ctx->shareGroup().get(),GL_INVALID_OPERATION);
4344 
4345     if (img->isNative) {
4346         if (!ctx->dispatcher().glEGLImageTargetRenderbufferStorageOES) {
4347             fprintf(stderr, "%s: warning, glEGLImageTargetRenderbufferStorageOES not found\n", __func__);
4348         } else {
4349             ctx->dispatcher().glEGLImageTargetRenderbufferStorageOES(target, (GLeglImageOES)img->nativeImage);
4350         }
4351         return;
4352     }
4353 
4354     // Get current bounded renderbuffer
4355     // raise INVALID_OPERATIOn if no renderbuffer is bounded
4356     GLuint rb = ctx->getRenderbufferBinding();
4357     SET_ERROR_IF(rb == 0,GL_INVALID_OPERATION);
4358     auto objData =
4359             ctx->shareGroup()->getObjectData(NamedObjectType::RENDERBUFFER, rb);
4360     RenderbufferData *rbData = (RenderbufferData *)objData;
4361     SET_ERROR_IF(!rbData,GL_INVALID_OPERATION);
4362 
4363     //
4364     // acquire the texture in the renderbufferData that it is an eglImage target
4365     //
4366     rbData->eglImageGlobalTexObject = img->globalTexObj;
4367     rbData->saveableTexture = img->saveableTexture;
4368     img->saveableTexture->makeDirty();
4369 
4370     //
4371     // if the renderbuffer is attached to a framebuffer
4372     // change the framebuffer attachment in the undelying OpenGL
4373     // to point to the eglImage texture object.
4374     //
4375     if (rbData->attachedFB) {
4376         // update the framebuffer attachment point to the
4377         // underlying texture of the img
4378         GLuint prevFB = ctx->getFramebufferBinding(GL_FRAMEBUFFER_EXT);
4379         if (prevFB != rbData->attachedFB) {
4380             ctx->dispatcher().glBindFramebuffer(GL_FRAMEBUFFER_EXT,
4381                                                    rbData->attachedFB);
4382         }
4383         ctx->dispatcher().glFramebufferTexture2D(GL_FRAMEBUFFER_EXT,
4384                                                     rbData->attachedPoint,
4385                                                     GL_TEXTURE_2D,
4386                                                     img->globalTexObj->getGlobalName(),
4387                                                     0);
4388         if (prevFB != rbData->attachedFB) {
4389             ctx->dispatcher().glBindFramebuffer(GL_FRAMEBUFFER_EXT,
4390                                                    prevFB);
4391         }
4392     }
4393 }
4394 
4395 // Extension: Vertex array objects
glGenVertexArraysOES(GLsizei n,GLuint * arrays)4396 GL_APICALL void GL_APIENTRY glGenVertexArraysOES(GLsizei n, GLuint* arrays) {
4397     GET_CTX_V2();
4398     SET_ERROR_IF(n < 0,GL_INVALID_VALUE);
4399     for (GLsizei i = 0; i < n; i++) {
4400         arrays[i] = ctx->genVAOName(0, true);
4401     }
4402     ctx->addVertexArrayObjects(n, arrays);
4403 }
4404 
glBindVertexArrayOES(GLuint array)4405 GL_APICALL void GL_APIENTRY glBindVertexArrayOES(GLuint array) {
4406     GET_CTX_V2();
4407     if (ctx->setVertexArrayObject(array)) {
4408         // TODO: This could be useful for a glIsVertexArray
4409         // that doesn't use the host GPU, but currently, it doesn't
4410         // really work. VAOs need to be bound first if glIsVertexArray
4411         // is to return true, and for now let's just ask the GPU
4412         // directly.
4413         ctx->setVAOEverBound();
4414     }
4415     ctx->dispatcher().glBindVertexArray(ctx->getVAOGlobalName(array));
4416 }
4417 
glDeleteVertexArraysOES(GLsizei n,const GLuint * arrays)4418 GL_APICALL void GL_APIENTRY glDeleteVertexArraysOES(GLsizei n, const GLuint * arrays) {
4419     GET_CTX_V2();
4420     SET_ERROR_IF(n < 0,GL_INVALID_VALUE);
4421     ctx->removeVertexArrayObjects(n, arrays);
4422     for (GLsizei i = 0; i < n; i++) {
4423         ctx->deleteVAO(arrays[i]);
4424     }
4425 }
4426 
glIsVertexArrayOES(GLuint array)4427 GL_APICALL GLboolean GL_APIENTRY glIsVertexArrayOES(GLuint array) {
4428     GET_CTX_V2_RET(0);
4429     if (!array) return GL_FALSE;
4430     // TODO: Figure out how to answer this completely in software.
4431     // Currently, state gets weird so we need to ask the GPU directly.
4432     return ctx->dispatcher().glIsVertexArray(ctx->getVAOGlobalName(array));
4433 }
4434 
4435 #define EXTERN_PART
4436 
4437 #include "GLESv30Imp.cpp"
4438 #include "GLESv31Imp.cpp"
4439 #include "GLESv32Imp.cpp"
4440 
4441 namespace glperf {
4442 
compileShader(GLDispatch * gl,GLenum shaderType,const char * src)4443 static GLuint compileShader(GLDispatch* gl,
4444                                 GLenum shaderType,
4445                                 const char* src) {
4446 
4447     GLuint shader = gl->glCreateShader(shaderType);
4448     gl->glShaderSource(shader, 1, (const GLchar* const*)&src, nullptr);
4449     gl->glCompileShader(shader);
4450 
4451     GLint compileStatus;
4452     gl->glGetShaderiv(shader, GL_COMPILE_STATUS, &compileStatus);
4453 
4454     if (compileStatus != GL_TRUE) {
4455         GLsizei infoLogLength = 0;
4456         gl->glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
4457         std::vector<char> infoLog(infoLogLength + 1, 0);
4458         gl->glGetShaderInfoLog(shader, infoLogLength, nullptr, infoLog.data());
4459         fprintf(stderr, "Failed to compile shader. Info log: [%s]\n", infoLog.data());
4460     }
4461 
4462     return shader;
4463 }
4464 
compileAndLinkShaderProgram(GLDispatch * gl,const char * vshaderSrc,const char * fshaderSrc)4465 static GLint compileAndLinkShaderProgram(GLDispatch* gl,
4466                                          const char* vshaderSrc,
4467                                          const char* fshaderSrc) {
4468     GLuint vshader = compileShader(gl, GL_VERTEX_SHADER, vshaderSrc);
4469     GLuint fshader = compileShader(gl, GL_FRAGMENT_SHADER, fshaderSrc);
4470 
4471     GLuint program = gl->glCreateProgram();
4472     gl->glAttachShader(program, vshader);
4473     gl->glAttachShader(program, fshader);
4474     gl->glLinkProgram(program);
4475 
4476     gl->glDeleteShader(vshader);
4477     gl->glDeleteShader(fshader);
4478 
4479     GLint linkStatus;
4480     gl->glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
4481 
4482     gl->glClearColor(0.0f, 0.0f, 1.0f, 0.0f);
4483 
4484     if (linkStatus != GL_TRUE) {
4485         GLsizei infoLogLength = 0;
4486         gl->glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLength);
4487         std::vector<char> infoLog(infoLogLength + 1, 0);
4488         gl->glGetProgramInfoLog(program, infoLogLength, nullptr,
4489                             infoLog.data());
4490         fprintf(stderr, "Failed to link program. Info log: [%s]\n", infoLog.data());
4491     }
4492 
4493     return program;
4494 }
4495 
4496 } // namespace glperf
4497 
4498 GL_APICALL void GL_APIENTRY
glTestHostDriverPerformance(GLuint count,uint64_t * duration_us,uint64_t * duration_cpu_us)4499 glTestHostDriverPerformance(GLuint count,
4500                             uint64_t* duration_us,
4501                             uint64_t* duration_cpu_us) {
4502     GET_CTX_V2();
4503     auto gl = &(ctx->dispatcher());
4504 
4505     constexpr char vshaderSrcEs[] = R"(#version 300 es
4506     precision highp float;
4507 
4508     layout (location = 0) in vec2 pos;
4509     layout (location = 1) in vec3 color;
4510 
4511     uniform mat4 transform;
4512 
4513     out vec3 color_varying;
4514 
4515     void main() {
4516         gl_Position = transform * vec4(pos, 0.0, 1.0);
4517         color_varying = (transform * vec4(color, 1.0)).xyz;
4518     }
4519     )";
4520 
4521     constexpr char fshaderSrcEs[] = R"(#version 300 es
4522     precision highp float;
4523 
4524     in vec3 color_varying;
4525 
4526     out vec4 fragColor;
4527 
4528     void main() {
4529         fragColor = vec4(color_varying, 1.0);
4530     }
4531     )";
4532 
4533     constexpr char vshaderSrcCore[] = R"(#version 330 core
4534     precision highp float;
4535 
4536     layout (location = 0) in vec2 pos;
4537     layout (location = 1) in vec3 color;
4538 
4539     uniform mat4 transform;
4540 
4541     out vec3 color_varying;
4542 
4543     void main() {
4544         gl_Position = transform * vec4(pos, 0.0, 1.0);
4545         color_varying = (transform * vec4(color, 1.0)).xyz;
4546     }
4547     )";
4548 
4549     constexpr char fshaderSrcCore[] = R"(#version 330 core
4550     precision highp float;
4551 
4552     in vec3 color_varying;
4553 
4554     out vec4 fragColor;
4555 
4556     void main() {
4557         fragColor = vec4(color_varying, 1.0);
4558     }
4559     )";
4560 
4561     GLuint program;
4562 
4563     if (isGles2Gles()) {
4564         program = glperf::compileAndLinkShaderProgram(gl, vshaderSrcEs,
4565                                                       fshaderSrcEs);
4566     } else {
4567         program = glperf::compileAndLinkShaderProgram(gl, vshaderSrcCore,
4568                                                       fshaderSrcCore);
4569     }
4570 
4571     GLint transformLoc = gl->glGetUniformLocation(program, "transform");
4572 
4573     struct VertexAttributes {
4574         float position[2];
4575         float color[3];
4576     };
4577 
4578     const VertexAttributes vertexAttrs[] = {
4579         { { -0.5f, -0.5f,}, { 0.2, 0.1, 0.9, }, },
4580         { { 0.5f, -0.5f,}, { 0.8, 0.3, 0.1,}, },
4581         { { 0.0f, 0.5f,}, { 0.1, 0.9, 0.6,}, },
4582     };
4583 
4584     GLuint buffer;
4585     gl->glGenBuffers(1, &buffer);
4586     gl->glBindBuffer(GL_ARRAY_BUFFER, buffer);
4587     gl->glBufferData(GL_ARRAY_BUFFER, sizeof(vertexAttrs), vertexAttrs,
4588                      GL_STATIC_DRAW);
4589 
4590     gl->glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE,
4591                           sizeof(VertexAttributes), 0);
4592     gl->glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE,
4593                               sizeof(VertexAttributes),
4594                               (GLvoid*)offsetof(VertexAttributes, color));
4595 
4596     gl->glEnableVertexAttribArray(0);
4597     gl->glEnableVertexAttribArray(1);
4598 
4599     gl->glUseProgram(program);
4600 
4601     gl->glClearColor(0.2f, 0.2f, 0.3f, 0.0f);
4602     gl->glViewport(0, 0, 1, 1);
4603 
4604     float matrix[16] = {
4605         1.0f, 0.0f, 0.0f, 0.0f,
4606         0.0f, 1.0f, 0.0f, 0.0f,
4607         0.0f, 0.0f, 1.0f, 0.0f,
4608         0.0f, 0.0f, 0.0f, 1.0f,
4609     };
4610 
4611     gl->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
4612 
4613     uint32_t drawCount = 0;
4614 
4615     auto cpuTimeStart = android::base::cpuTime();
4616 
4617 fprintf(stderr, "%s: transform loc %d\n", __func__, transformLoc);
4618 fprintf(stderr, "%s: begin count %d\n", __func__, count);
4619     while (drawCount < count) {
4620         gl->glUniformMatrix4fv(transformLoc, 1, GL_FALSE, matrix);
4621         gl->glBindBuffer(GL_ARRAY_BUFFER, buffer);
4622         gl->glDrawArrays(GL_TRIANGLES, 0, 3);
4623         ++drawCount;
4624     }
4625 
4626     gl->glFinish();
4627 
4628     auto cpuTime = android::base::cpuTime() - cpuTimeStart;
4629 
4630     *duration_us = cpuTime.wall_time_us;
4631     *duration_cpu_us = cpuTime.usageUs();
4632 
4633     float ms = (*duration_us) / 1000.0f;
4634     float sec = (*duration_us) / 1000000.0f;
4635 
4636     printf("Drew %u times in %f ms. Rate: %f Hz\n", count, ms, count / sec);
4637 
4638     gl->glBindBuffer(GL_ARRAY_BUFFER, 0);
4639     gl->glUseProgram(0);
4640     gl->glDeleteProgram(program);
4641     gl->glDeleteBuffers(1, &buffer);
4642 }
4643 
4644 // Vulkan/GL interop
4645 // https://www.khronos.org/registry/OpenGL/extensions/EXT/EXT_external_objects.txt
4646 // Common between GL_EXT_memory_object and GL_EXT_semaphore
glGetUnsignedBytevEXT(GLenum pname,GLubyte * data)4647 GL_APICALL void GL_APIENTRY glGetUnsignedBytevEXT(GLenum pname, GLubyte* data) {
4648     GET_CTX_V2();
4649     if (!ctx->dispatcher().glGetUnsignedBytevEXT) {
4650         return;
4651     }
4652     ctx->dispatcher().glGetUnsignedBytevEXT(pname, data);
4653 }
4654 
glGetUnsignedBytei_vEXT(GLenum target,GLuint index,GLubyte * data)4655 GL_APICALL void GL_APIENTRY glGetUnsignedBytei_vEXT(GLenum target, GLuint index, GLubyte* data) {
4656     GET_CTX_V2();
4657     if (!ctx->dispatcher().glGetUnsignedBytei_vEXT) {
4658         return;
4659     }
4660     ctx->dispatcher().glGetUnsignedBytei_vEXT(target, index, data);
4661 }
4662 
4663 // GL_EXT_memory_object
glImportMemoryFdEXT(GLuint memory,GLuint64 size,GLenum handleType,GLint fd)4664 GL_APICALL void GL_APIENTRY glImportMemoryFdEXT(GLuint memory, GLuint64 size, GLenum handleType, GLint fd) {
4665     GET_CTX_V2();
4666     ctx->dispatcher().glImportMemoryFdEXT(memory, size, handleType, fd);
4667 }
4668 
glImportMemoryWin32HandleEXT(GLuint memory,GLuint64 size,GLenum handleType,void * handle)4669 GL_APICALL void GL_APIENTRY glImportMemoryWin32HandleEXT(GLuint memory, GLuint64 size, GLenum handleType, void* handle) {
4670     GET_CTX_V2();
4671     ctx->dispatcher().glImportMemoryWin32HandleEXT(memory, size, handleType, handle);
4672 }
4673 
glDeleteMemoryObjectsEXT(GLsizei n,const GLuint * memoryObjects)4674 GL_APICALL void GL_APIENTRY glDeleteMemoryObjectsEXT(GLsizei n, const GLuint *memoryObjects) {
4675     GET_CTX_V2();
4676     ctx->dispatcher().glDeleteMemoryObjectsEXT(n, memoryObjects);
4677 }
4678 
glIsMemoryObjectEXT(GLuint memoryObject)4679 GL_APICALL GLboolean GL_APIENTRY glIsMemoryObjectEXT(GLuint memoryObject) {
4680     GET_CTX_V2_RET(GL_FALSE);
4681     return ctx->dispatcher().glIsMemoryObjectEXT(memoryObject);
4682 }
4683 
glCreateMemoryObjectsEXT(GLsizei n,GLuint * memoryObjects)4684 GL_APICALL void GL_APIENTRY glCreateMemoryObjectsEXT(GLsizei n, GLuint *memoryObjects) {
4685     GET_CTX_V2();
4686     ctx->dispatcher().glCreateMemoryObjectsEXT(n, memoryObjects);
4687 }
4688 
glMemoryObjectParameterivEXT(GLuint memoryObject,GLenum pname,const GLint * params)4689 GL_APICALL void GL_APIENTRY glMemoryObjectParameterivEXT(GLuint memoryObject, GLenum pname, const GLint *params) {
4690     GET_CTX_V2();
4691     ctx->dispatcher().glMemoryObjectParameterivEXT(memoryObject, pname, params);
4692 }
4693 
glGetMemoryObjectParameterivEXT(GLuint memoryObject,GLenum pname,GLint * params)4694 GL_APICALL void GL_APIENTRY glGetMemoryObjectParameterivEXT(GLuint memoryObject, GLenum pname, GLint *params) {
4695     GET_CTX_V2();
4696     ctx->dispatcher().glGetMemoryObjectParameterivEXT(memoryObject, pname, params);
4697 }
4698 
glTexStorageMem2DEXT(GLenum target,GLsizei levels,GLenum internalFormat,GLsizei width,GLsizei height,GLuint memory,GLuint64 offset)4699 GL_APICALL void GL_APIENTRY glTexStorageMem2DEXT(GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLuint memory, GLuint64 offset) {
4700     GET_CTX_V2();
4701     GLint err = GL_NO_ERROR;
4702     GLenum format, type;
4703     GLESv2Validate::getCompatibleFormatTypeForInternalFormat(internalFormat, &format, &type);
4704     sPrepareTexImage2D(target, 0, (GLint)internalFormat, width, height, 0, format, type, 0, NULL, &type, (GLint*)&internalFormat, &err);
4705     SET_ERROR_IF(err != GL_NO_ERROR, err);
4706     TextureData *texData = getTextureTargetData(target);
4707     texData->texStorageLevels = levels;
4708     ctx->dispatcher().glTexStorageMem2DEXT(target, levels, internalFormat, width, height, memory, offset);
4709 }
4710 
glTexStorageMem2DMultisampleEXT(GLenum target,GLsizei samples,GLenum internalFormat,GLsizei width,GLsizei height,GLboolean fixedSampleLocations,GLuint memory,GLuint64 offset)4711 GL_APICALL void GL_APIENTRY glTexStorageMem2DMultisampleEXT(GLenum target, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset) {
4712     GET_CTX_V2();
4713     ctx->dispatcher().glTexStorageMem2DMultisampleEXT(target, samples, internalFormat, width, height, fixedSampleLocations, memory, offset);
4714 }
4715 
glTexStorageMem3DEXT(GLenum target,GLsizei levels,GLenum internalFormat,GLsizei width,GLsizei height,GLsizei depth,GLuint memory,GLuint64 offset)4716 GL_APICALL void GL_APIENTRY glTexStorageMem3DEXT(GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLuint memory, GLuint64 offset) {
4717     GET_CTX_V2();
4718     ctx->dispatcher().glTexStorageMem3DEXT(target, levels, internalFormat, width, height, depth, memory, offset);
4719 }
4720 
glTexStorageMem3DMultisampleEXT(GLenum target,GLsizei samples,GLenum internalFormat,GLsizei width,GLsizei height,GLsizei depth,GLboolean fixedSampleLocations,GLuint memory,GLuint64 offset)4721 GL_APICALL void GL_APIENTRY glTexStorageMem3DMultisampleEXT(GLenum target, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset) {
4722     GET_CTX_V2();
4723     ctx->dispatcher().glTexStorageMem3DMultisampleEXT(target, samples, internalFormat, width, height, depth, fixedSampleLocations, memory, offset);
4724 }
4725 
glBufferStorageMemEXT(GLenum target,GLsizeiptr size,GLuint memory,GLuint64 offset)4726 GL_APICALL void GL_APIENTRY glBufferStorageMemEXT(GLenum target, GLsizeiptr size, GLuint memory, GLuint64 offset) {
4727     GET_CTX_V2();
4728     ctx->dispatcher().glBufferStorageMemEXT(target, size, memory, offset);
4729 }
4730 
glTexParameteriHOST(GLenum target,GLenum pname,GLint param)4731 GL_APICALL void GL_APIENTRY glTexParameteriHOST(GLenum target, GLenum pname, GLint param) {
4732     GET_CTX_V2();
4733     ctx->dispatcher().glTexParameteri(target, pname, param);
4734 }
4735 
4736 // Not included: direct-state-access, 1D function pointers
4737 
4738 // GL_EXT_semaphore
glImportSemaphoreFdEXT(GLuint semaphore,GLenum handleType,GLint fd)4739 GL_APICALL void GL_APIENTRY glImportSemaphoreFdEXT(GLuint semaphore, GLenum handleType, GLint fd) {
4740     GET_CTX_V2();
4741     ctx->dispatcher().glImportSemaphoreFdEXT(semaphore, handleType, fd);
4742 }
4743 
glImportSemaphoreWin32HandleEXT(GLuint semaphore,GLenum handleType,void * handle)4744 GL_APICALL void GL_APIENTRY glImportSemaphoreWin32HandleEXT(GLuint semaphore, GLenum handleType, void* handle) {
4745     GET_CTX_V2();
4746     ctx->dispatcher().glImportSemaphoreWin32HandleEXT(semaphore, handleType, handle);
4747 }
4748 
glGenSemaphoresEXT(GLsizei n,GLuint * semaphores)4749 GL_APICALL void GL_APIENTRY glGenSemaphoresEXT(GLsizei n, GLuint *semaphores) {
4750     GET_CTX_V2();
4751     ctx->dispatcher().glGenSemaphoresEXT(n, semaphores);
4752 }
4753 
glDeleteSemaphoresEXT(GLsizei n,const GLuint * semaphores)4754 GL_APICALL void GL_APIENTRY glDeleteSemaphoresEXT(GLsizei n, const GLuint *semaphores) {
4755     GET_CTX_V2();
4756     ctx->dispatcher().glDeleteSemaphoresEXT(n, semaphores);
4757 }
4758 
glIsSemaphoreEXT(GLuint semaphore)4759 GL_APICALL GLboolean glIsSemaphoreEXT(GLuint semaphore) {
4760     GET_CTX_V2_RET(GL_FALSE);
4761     return ctx->dispatcher().glIsSemaphoreEXT(semaphore);
4762 }
4763 
glSemaphoreParameterui64vEXT(GLuint semaphore,GLenum pname,const GLuint64 * params)4764 GL_APICALL void GL_APIENTRY glSemaphoreParameterui64vEXT(GLuint semaphore, GLenum pname, const GLuint64 *params) {
4765     GET_CTX_V2();
4766     ctx->dispatcher().glSemaphoreParameterui64vEXT(semaphore, pname, params);
4767 }
4768 
glGetSemaphoreParameterui64vEXT(GLuint semaphore,GLenum pname,GLuint64 * params)4769 GL_APICALL void GL_APIENTRY glGetSemaphoreParameterui64vEXT(GLuint semaphore, GLenum pname, GLuint64 *params) {
4770     GET_CTX_V2();
4771     ctx->dispatcher().glGetSemaphoreParameterui64vEXT(semaphore, pname, params);
4772 }
4773 
glWaitSemaphoreEXT(GLuint semaphore,GLuint numBufferBarriers,const GLuint * buffers,GLuint numTextureBarriers,const GLuint * textures,const GLenum * srcLayouts)4774 GL_APICALL void GL_APIENTRY glWaitSemaphoreEXT(GLuint semaphore, GLuint numBufferBarriers, const GLuint *buffers, GLuint numTextureBarriers, const GLuint *textures, const GLenum *srcLayouts) {
4775     GET_CTX_V2();
4776     ctx->dispatcher().glWaitSemaphoreEXT(semaphore, numBufferBarriers, buffers, numTextureBarriers, textures, srcLayouts);
4777 }
4778 
glSignalSemaphoreEXT(GLuint semaphore,GLuint numBufferBarriers,const GLuint * buffers,GLuint numTextureBarriers,const GLuint * textures,const GLenum * dstLayouts)4779 GL_APICALL void GL_APIENTRY glSignalSemaphoreEXT(GLuint semaphore, GLuint numBufferBarriers, const GLuint *buffers, GLuint numTextureBarriers, const GLuint *textures, const GLenum *dstLayouts) {
4780     GET_CTX_V2();
4781     ctx->dispatcher().glSignalSemaphoreEXT(semaphore, numBufferBarriers, buffers, numTextureBarriers, textures, dstLayouts);
4782 }
4783 
glPrimitiveRestartIndex(GLuint index)4784 GL_APICALL void GL_APIENTRY glPrimitiveRestartIndex(GLuint index) {
4785     GET_CTX_V2();
4786     ctx->dispatcher().glPrimitiveRestartIndex(index);
4787 }
4788 
glGetGraphicsResetStatusEXT()4789 GL_APICALL GLenum GL_APIENTRY glGetGraphicsResetStatusEXT() {
4790     GET_CTX_V2_RET(GL_NO_ERROR);
4791     GLenum error = ctx->dispatcher().glGetError();
4792     if (error && !ctx->getGLerror()) {
4793         ctx->setGLerror(error);
4794     }
4795     auto fptr = ctx->dispatcher().glGetGraphicsResetStatusEXT;
4796     if (!fptr) {
4797         // If we're running on native OpenGL (not ANGLE) and glGetGraphicsResetStatusEXT
4798         // isn't supported by the driver, then default to no error. See b/185407409
4799         return GL_NO_ERROR;
4800     }
4801     GLenum res = fptr();
4802     // On some versions of SwANGLE it sets GL_INVALID_OPERATION after calling
4803     // glGetGraphicsResetStatusEXT. We should discard such error code.
4804     ctx->dispatcher().glGetError();
4805     return res;
4806 }
4807 
4808 } // namespace translator
4809 } // namespace gles2
4810