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