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, ¶m);
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