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