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