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