Implement EGL_KHR_get_all_proc_addresses. This also improves GetProcAddress performance by using binary search instead of linear search. Fixes bug b/20110899 Change-Id: I6c58e17f0580904338e4d806e310cccbec398f28 Reviewed-on: https://swiftshader-review.googlesource.com/15748 Tested-by: Krzysztof Kosiński <krzysio@google.com> Reviewed-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/OpenGL/libEGL/libEGL.cpp b/src/OpenGL/libEGL/libEGL.cpp index 21ef933..08861c2 100644 --- a/src/OpenGL/libEGL/libEGL.cpp +++ b/src/OpenGL/libEGL/libEGL.cpp
@@ -29,6 +29,7 @@ #include "Main/libX11.hpp" #endif +#include <algorithm> #include <string.h> using namespace egl; @@ -174,6 +175,7 @@ if(dpy == EGL_NO_DISPLAY && name == EGL_EXTENSIONS) { return success( + "EGL_KHR_client_get_all_proc_addresses " #if defined(__linux__) && !defined(__ANDROID__) "EGL_KHR_platform_gbm " "EGL_KHR_platform_x11 " @@ -195,6 +197,7 @@ return success("OpenGL_ES"); case EGL_EXTENSIONS: return success("EGL_KHR_create_context " + "EGL_KHR_get_all_proc_addresses " "EGL_KHR_gl_texture_2D_image " "EGL_KHR_gl_texture_cubemap_image " "EGL_KHR_gl_renderbuffer_image " @@ -1241,34 +1244,85 @@ { TRACE("(const char *procname = \"%s\")", procname); - struct Extension + struct Function { const char *name; __eglMustCastToProperFunctionPointerType address; }; - static const Extension eglExtensions[] = + struct CompareFunctor { - #define EXTENSION(name) {#name, (__eglMustCastToProperFunctionPointerType)name} - - EXTENSION(eglCreateImageKHR), - EXTENSION(eglDestroyImageKHR), - EXTENSION(eglGetPlatformDisplayEXT), - EXTENSION(eglCreatePlatformWindowSurfaceEXT), - EXTENSION(eglCreatePlatformPixmapSurfaceEXT), - EXTENSION(eglCreateSyncKHR), - EXTENSION(eglDestroySyncKHR), - EXTENSION(eglClientWaitSyncKHR), - EXTENSION(eglGetSyncAttribKHR), - - #undef EXTENSION + bool operator()(const Function &a, const Function &b) const + { + return strcmp(a.name, b.name) < 0; + } }; - for(unsigned int ext = 0; ext < sizeof(eglExtensions) / sizeof(Extension); ext++) + // This array must be kept sorted with respect to strcmp(), so that binary search works correctly. + // The Unix command "LC_COLLATE=C sort" will generate the correct order. + static const Function eglFunctions[] = { - if(strcmp(procname, eglExtensions[ext].name) == 0) + #define FUNCTION(name) {#name, (__eglMustCastToProperFunctionPointerType)name} + + FUNCTION(eglBindAPI), + FUNCTION(eglBindTexImage), + FUNCTION(eglChooseConfig), + FUNCTION(eglClientWaitSyncKHR), + FUNCTION(eglCopyBuffers), + FUNCTION(eglCreateContext), + FUNCTION(eglCreateImageKHR), + FUNCTION(eglCreatePbufferFromClientBuffer), + FUNCTION(eglCreatePbufferSurface), + FUNCTION(eglCreatePixmapSurface), + FUNCTION(eglCreatePlatformPixmapSurfaceEXT), + FUNCTION(eglCreatePlatformWindowSurfaceEXT), + FUNCTION(eglCreateSyncKHR), + FUNCTION(eglCreateWindowSurface), + FUNCTION(eglDestroyContext), + FUNCTION(eglDestroyImageKHR), + FUNCTION(eglDestroySurface), + FUNCTION(eglDestroySyncKHR), + FUNCTION(eglGetConfigAttrib), + FUNCTION(eglGetConfigs), + FUNCTION(eglGetCurrentContext), + FUNCTION(eglGetCurrentDisplay), + FUNCTION(eglGetCurrentSurface), + FUNCTION(eglGetDisplay), + FUNCTION(eglGetError), + FUNCTION(eglGetPlatformDisplayEXT), + FUNCTION(eglGetProcAddress), + FUNCTION(eglGetSyncAttribKHR), + FUNCTION(eglInitialize), + FUNCTION(eglMakeCurrent), + FUNCTION(eglQueryAPI), + FUNCTION(eglQueryContext), + FUNCTION(eglQueryString), + FUNCTION(eglQuerySurface), + FUNCTION(eglReleaseTexImage), + FUNCTION(eglReleaseThread), + FUNCTION(eglSurfaceAttrib), + FUNCTION(eglSwapBuffers), + FUNCTION(eglSwapInterval), + FUNCTION(eglTerminate), + FUNCTION(eglWaitClient), + FUNCTION(eglWaitGL), + FUNCTION(eglWaitNative), + + #undef FUNCTION + }; + + static const size_t numFunctions = sizeof eglFunctions / sizeof(Function); + static const Function *const eglFunctionsEnd = eglFunctions + numFunctions; + + Function needle; + needle.name = procname; + + if(procname && strncmp("egl", procname, 3) == 0) + { + const Function *result = std::lower_bound(eglFunctions, eglFunctionsEnd, needle, CompareFunctor()); + if (result != eglFunctionsEnd && strcmp(procname, result->name) == 0) { - return success((__eglMustCastToProperFunctionPointerType)eglExtensions[ext].address); + return success((__eglMustCastToProperFunctionPointerType)result->address); } }
diff --git a/src/OpenGL/libGLES_CM/libGLES_CM.cpp b/src/OpenGL/libGLES_CM/libGLES_CM.cpp index 62acae1..88a19e8 100644 --- a/src/OpenGL/libGLES_CM/libGLES_CM.cpp +++ b/src/OpenGL/libGLES_CM/libGLES_CM.cpp
@@ -32,6 +32,7 @@ #include <GLES/gl.h> #include <GLES/glext.h> +#include <algorithm> #include <limits> namespace es1 @@ -4727,46 +4728,215 @@ extern "C" __eglMustCastToProperFunctionPointerType es1GetProcAddress(const char *procname) { - struct Extension + struct Function { const char *name; __eglMustCastToProperFunctionPointerType address; }; - static const Extension glExtensions[] = + struct CompareFunctor { - #define EXTENSION(name) {#name, (__eglMustCastToProperFunctionPointerType)name} - - EXTENSION(glEGLImageTargetTexture2DOES), - EXTENSION(glEGLImageTargetRenderbufferStorageOES), - EXTENSION(glIsRenderbufferOES), - EXTENSION(glBindRenderbufferOES), - EXTENSION(glDeleteRenderbuffersOES), - EXTENSION(glGenRenderbuffersOES), - EXTENSION(glRenderbufferStorageOES), - EXTENSION(glGetRenderbufferParameterivOES), - EXTENSION(glIsFramebufferOES), - EXTENSION(glBindFramebufferOES), - EXTENSION(glDeleteFramebuffersOES), - EXTENSION(glGenFramebuffersOES), - EXTENSION(glCheckFramebufferStatusOES), - EXTENSION(glFramebufferRenderbufferOES), - EXTENSION(glFramebufferTexture2DOES), - EXTENSION(glGetFramebufferAttachmentParameterivOES), - EXTENSION(glGenerateMipmapOES), - EXTENSION(glBlendEquationOES), - EXTENSION(glBlendEquationSeparateOES), - EXTENSION(glBlendFuncSeparateOES), - EXTENSION(glPointSizePointerOES), - - #undef EXTENSION + bool operator()(const Function &a, const Function &b) const + { + return strcmp(a.name, b.name) < 0; + } }; - for(unsigned int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++) + // This array must be kept sorted with respect to strcmp(), so that binary search works correctly. + // The Unix command "LC_COLLATE=C sort" will generate the correct order. + static const Function glFunctions[] = { - if(strcmp(procname, glExtensions[ext].name) == 0) + #define FUNCTION(name) {#name, (__eglMustCastToProperFunctionPointerType)name} + + FUNCTION(glActiveTexture), + FUNCTION(glAlphaFunc), + FUNCTION(glAlphaFuncx), + FUNCTION(glBindBuffer), + FUNCTION(glBindFramebufferOES), + FUNCTION(glBindRenderbufferOES), + FUNCTION(glBindTexture), + FUNCTION(glBlendEquationOES), + FUNCTION(glBlendEquationSeparateOES), + FUNCTION(glBlendFunc), + FUNCTION(glBlendFuncSeparateOES), + FUNCTION(glBufferData), + FUNCTION(glBufferSubData), + FUNCTION(glCheckFramebufferStatusOES), + FUNCTION(glClear), + FUNCTION(glClearColor), + FUNCTION(glClearColorx), + FUNCTION(glClearDepthf), + FUNCTION(glClearDepthx), + FUNCTION(glClearStencil), + FUNCTION(glClientActiveTexture), + FUNCTION(glClipPlanef), + FUNCTION(glClipPlanex), + FUNCTION(glColor4f), + FUNCTION(glColor4ub), + FUNCTION(glColor4x), + FUNCTION(glColorMask), + FUNCTION(glColorPointer), + FUNCTION(glCompressedTexImage2D), + FUNCTION(glCompressedTexSubImage2D), + FUNCTION(glCopyTexImage2D), + FUNCTION(glCopyTexSubImage2D), + FUNCTION(glCullFace), + FUNCTION(glDeleteBuffers), + FUNCTION(glDeleteFramebuffersOES), + FUNCTION(glDeleteRenderbuffersOES), + FUNCTION(glDeleteTextures), + FUNCTION(glDepthFunc), + FUNCTION(glDepthMask), + FUNCTION(glDepthRangef), + FUNCTION(glDepthRangex), + FUNCTION(glDisable), + FUNCTION(glDisableClientState), + FUNCTION(glDrawArrays), + FUNCTION(glDrawElements), + FUNCTION(glDrawTexfOES), + FUNCTION(glDrawTexfvOES), + FUNCTION(glDrawTexiOES), + FUNCTION(glDrawTexivOES), + FUNCTION(glDrawTexsOES), + FUNCTION(glDrawTexsvOES), + FUNCTION(glDrawTexxOES), + FUNCTION(glDrawTexxvOES), + FUNCTION(glEGLImageTargetRenderbufferStorageOES), + FUNCTION(glEGLImageTargetTexture2DOES), + FUNCTION(glEnable), + FUNCTION(glEnableClientState), + FUNCTION(glFinish), + FUNCTION(glFlush), + FUNCTION(glFogf), + FUNCTION(glFogfv), + FUNCTION(glFogx), + FUNCTION(glFogxv), + FUNCTION(glFramebufferRenderbufferOES), + FUNCTION(glFramebufferTexture2DOES), + FUNCTION(glFrontFace), + FUNCTION(glFrustumf), + FUNCTION(glFrustumx), + FUNCTION(glGenBuffers), + FUNCTION(glGenFramebuffersOES), + FUNCTION(glGenRenderbuffersOES), + FUNCTION(glGenTextures), + FUNCTION(glGenerateMipmapOES), + FUNCTION(glGetBooleanv), + FUNCTION(glGetBufferParameteriv), + FUNCTION(glGetClipPlanef), + FUNCTION(glGetClipPlanex), + FUNCTION(glGetError), + FUNCTION(glGetFixedv), + FUNCTION(glGetFloatv), + FUNCTION(glGetFramebufferAttachmentParameterivOES), + FUNCTION(glGetIntegerv), + FUNCTION(glGetLightfv), + FUNCTION(glGetLightxv), + FUNCTION(glGetMaterialfv), + FUNCTION(glGetMaterialxv), + FUNCTION(glGetPointerv), + FUNCTION(glGetRenderbufferParameterivOES), + FUNCTION(glGetString), + FUNCTION(glGetTexEnvfv), + FUNCTION(glGetTexEnviv), + FUNCTION(glGetTexEnvxv), + FUNCTION(glGetTexParameterfv), + FUNCTION(glGetTexParameteriv), + FUNCTION(glGetTexParameterxv), + FUNCTION(glHint), + FUNCTION(glIsBuffer), + FUNCTION(glIsEnabled), + FUNCTION(glIsFramebufferOES), + FUNCTION(glIsRenderbufferOES), + FUNCTION(glIsTexture), + FUNCTION(glLightModelf), + FUNCTION(glLightModelfv), + FUNCTION(glLightModelx), + FUNCTION(glLightModelxv), + FUNCTION(glLightf), + FUNCTION(glLightfv), + FUNCTION(glLightx), + FUNCTION(glLightxv), + FUNCTION(glLineWidth), + FUNCTION(glLineWidthx), + FUNCTION(glLoadIdentity), + FUNCTION(glLoadMatrixf), + FUNCTION(glLoadMatrixx), + FUNCTION(glLogicOp), + FUNCTION(glMaterialf), + FUNCTION(glMaterialfv), + FUNCTION(glMaterialx), + FUNCTION(glMaterialxv), + FUNCTION(glMatrixMode), + FUNCTION(glMultMatrixf), + FUNCTION(glMultMatrixx), + FUNCTION(glMultiTexCoord4f), + FUNCTION(glMultiTexCoord4x), + FUNCTION(glNormal3f), + FUNCTION(glNormal3x), + FUNCTION(glNormalPointer), + FUNCTION(glOrthof), + FUNCTION(glOrthox), + FUNCTION(glPixelStorei), + FUNCTION(glPointParameterf), + FUNCTION(glPointParameterfv), + FUNCTION(glPointParameterx), + FUNCTION(glPointParameterxv), + FUNCTION(glPointSize), + FUNCTION(glPointSizePointerOES), + FUNCTION(glPointSizex), + FUNCTION(glPolygonOffset), + FUNCTION(glPolygonOffsetx), + FUNCTION(glPopMatrix), + FUNCTION(glPushMatrix), + FUNCTION(glReadPixels), + FUNCTION(glRenderbufferStorageOES), + FUNCTION(glRotatef), + FUNCTION(glRotatex), + FUNCTION(glSampleCoverage), + FUNCTION(glSampleCoveragex), + FUNCTION(glScalef), + FUNCTION(glScalex), + FUNCTION(glScissor), + FUNCTION(glShadeModel), + FUNCTION(glStencilFunc), + FUNCTION(glStencilMask), + FUNCTION(glStencilOp), + FUNCTION(glTexCoordPointer), + FUNCTION(glTexEnvf), + FUNCTION(glTexEnvfv), + FUNCTION(glTexEnvi), + FUNCTION(glTexEnviv), + FUNCTION(glTexEnvx), + FUNCTION(glTexEnvxv), + FUNCTION(glTexImage2D), + FUNCTION(glTexParameterf), + FUNCTION(glTexParameterfv), + FUNCTION(glTexParameteri), + FUNCTION(glTexParameteriv), + FUNCTION(glTexParameterx), + FUNCTION(glTexParameterxv), + FUNCTION(glTexSubImage2D), + FUNCTION(glTranslatef), + FUNCTION(glTranslatex), + FUNCTION(glVertexPointer), + FUNCTION(glViewport), + + #undef FUNCTION + }; + + static const size_t numFunctions = sizeof glFunctions / sizeof(Function); + static const Function *const glFunctionsEnd = glFunctions + numFunctions; + + Function needle; + needle.name = procname; + + if(procname && strncmp("gl", procname, 2) == 0) + { + const Function *result = std::lower_bound(glFunctions, glFunctionsEnd, needle, CompareFunctor()); + if(result != glFunctionsEnd && strcmp(procname, result->name) == 0) { - return (__eglMustCastToProperFunctionPointerType)glExtensions[ext].address; + return (__eglMustCastToProperFunctionPointerType)result->address; } }
diff --git a/src/OpenGL/libGLESv2/libGLESv2.cpp b/src/OpenGL/libGLESv2/libGLESv2.cpp index 9f96d47..f9fe511 100644 --- a/src/OpenGL/libGLESv2/libGLESv2.cpp +++ b/src/OpenGL/libGLESv2/libGLESv2.cpp
@@ -34,6 +34,7 @@ #include <GLES2/gl2ext.h> #include <GLES3/gl3.h> +#include <algorithm> #include <limits> #ifdef __ANDROID__ @@ -6872,71 +6873,327 @@ extern "C" NO_SANITIZE_FUNCTION __eglMustCastToProperFunctionPointerType es2GetProcAddress(const char *procname) { - struct Extension + struct Function { const char *name; __eglMustCastToProperFunctionPointerType address; }; - static const Extension glExtensions[] = + struct CompareFunctor { - #define EXTENSION(name) {#name, (__eglMustCastToProperFunctionPointerType)name} - - EXTENSION(glTexImage3DOES), - EXTENSION(glBlitFramebufferANGLE), - EXTENSION(glBlitFramebufferNV), - EXTENSION(glRenderbufferStorageMultisampleANGLE), - EXTENSION(glDeleteFencesNV), - EXTENSION(glGenFencesNV), - EXTENSION(glIsFenceNV), - EXTENSION(glTestFenceNV), - EXTENSION(glGetFenceivNV), - EXTENSION(glFinishFenceNV), - EXTENSION(glSetFenceNV), - EXTENSION(glGetGraphicsResetStatusEXT), - EXTENSION(glReadnPixelsEXT), - EXTENSION(glGetnUniformfvEXT), - EXTENSION(glGetnUniformivEXT), - EXTENSION(glGenQueriesEXT), - EXTENSION(glDeleteQueriesEXT), - EXTENSION(glIsQueryEXT), - EXTENSION(glBeginQueryEXT), - EXTENSION(glEndQueryEXT), - EXTENSION(glGetQueryivEXT), - EXTENSION(glGetQueryObjectuivEXT), - EXTENSION(glEGLImageTargetTexture2DOES), - EXTENSION(glEGLImageTargetRenderbufferStorageOES), - EXTENSION(glDrawElementsInstancedEXT), - EXTENSION(glDrawArraysInstancedEXT), - EXTENSION(glVertexAttribDivisorEXT), - EXTENSION(glDrawArraysInstancedANGLE), - EXTENSION(glDrawElementsInstancedANGLE), - EXTENSION(glVertexAttribDivisorANGLE), - EXTENSION(glIsRenderbufferOES), - EXTENSION(glBindRenderbufferOES), - EXTENSION(glDeleteRenderbuffersOES), - EXTENSION(glGenRenderbuffersOES), - EXTENSION(glRenderbufferStorageOES), - EXTENSION(glGetRenderbufferParameterivOES), - EXTENSION(glIsFramebufferOES), - EXTENSION(glBindFramebufferOES), - EXTENSION(glDeleteFramebuffersOES), - EXTENSION(glGenFramebuffersOES), - EXTENSION(glCheckFramebufferStatusOES), - EXTENSION(glFramebufferRenderbufferOES), - EXTENSION(glFramebufferTexture2DOES), - EXTENSION(glGetFramebufferAttachmentParameterivOES), - EXTENSION(glGenerateMipmapOES), - EXTENSION(glDrawBuffersEXT), - - #undef EXTENSION + bool operator()(const Function &a, const Function &b) const + { + return strcmp(a.name, b.name) < 0; + } }; - for(unsigned int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++) + // This array must be kept sorted with respect to strcmp(), so that binary search works correctly. + // The Unix command "LC_COLLATE=C sort" will generate the correct order. + static const Function glFunctions[] = { - if(strcmp(procname, glExtensions[ext].name) == 0) + #define FUNCTION(name) {#name, (__eglMustCastToProperFunctionPointerType)name} + + FUNCTION(glActiveTexture), + FUNCTION(glAttachShader), + FUNCTION(glBeginQuery), + FUNCTION(glBeginQueryEXT), + FUNCTION(glBeginTransformFeedback), + FUNCTION(glBindAttribLocation), + FUNCTION(glBindBuffer), + FUNCTION(glBindBufferBase), + FUNCTION(glBindBufferRange), + FUNCTION(glBindFramebuffer), + FUNCTION(glBindFramebufferOES), + FUNCTION(glBindRenderbuffer), + FUNCTION(glBindRenderbufferOES), + FUNCTION(glBindSampler), + FUNCTION(glBindTexture), + FUNCTION(glBindTransformFeedback), + FUNCTION(glBindVertexArray), + FUNCTION(glBlendColor), + FUNCTION(glBlendEquation), + FUNCTION(glBlendEquationSeparate), + FUNCTION(glBlendFunc), + FUNCTION(glBlendFuncSeparate), + FUNCTION(glBlitFramebuffer), + FUNCTION(glBlitFramebufferANGLE), + FUNCTION(glBufferData), + FUNCTION(glBufferSubData), + FUNCTION(glCheckFramebufferStatus), + FUNCTION(glCheckFramebufferStatusOES), + FUNCTION(glClear), + FUNCTION(glClearBufferfi), + FUNCTION(glClearBufferfv), + FUNCTION(glClearBufferiv), + FUNCTION(glClearBufferuiv), + FUNCTION(glClearColor), + FUNCTION(glClearDepthf), + FUNCTION(glClearStencil), + FUNCTION(glClientWaitSync), + FUNCTION(glColorMask), + FUNCTION(glCompileShader), + FUNCTION(glCompressedTexImage2D), + FUNCTION(glCompressedTexImage3D), + FUNCTION(glCompressedTexSubImage2D), + FUNCTION(glCompressedTexSubImage3D), + FUNCTION(glCopyBufferSubData), + FUNCTION(glCopyTexImage2D), + FUNCTION(glCopyTexSubImage2D), + FUNCTION(glCopyTexSubImage3D), + FUNCTION(glCreateProgram), + FUNCTION(glCreateShader), + FUNCTION(glCullFace), + FUNCTION(glDeleteBuffers), + FUNCTION(glDeleteFencesNV), + FUNCTION(glDeleteFramebuffers), + FUNCTION(glDeleteFramebuffersOES), + FUNCTION(glDeleteProgram), + FUNCTION(glDeleteQueries), + FUNCTION(glDeleteQueriesEXT), + FUNCTION(glDeleteRenderbuffers), + FUNCTION(glDeleteRenderbuffersOES), + FUNCTION(glDeleteSamplers), + FUNCTION(glDeleteShader), + FUNCTION(glDeleteSync), + FUNCTION(glDeleteTextures), + FUNCTION(glDeleteTransformFeedbacks), + FUNCTION(glDeleteVertexArrays), + FUNCTION(glDepthFunc), + FUNCTION(glDepthMask), + FUNCTION(glDepthRangef), + FUNCTION(glDetachShader), + FUNCTION(glDisable), + FUNCTION(glDisableVertexAttribArray), + FUNCTION(glDrawArrays), + FUNCTION(glDrawArraysInstanced), + FUNCTION(glDrawBuffers), + FUNCTION(glDrawBuffersEXT), + FUNCTION(glDrawElements), + FUNCTION(glDrawElementsInstanced), + FUNCTION(glDrawRangeElements), + FUNCTION(glEGLImageTargetRenderbufferStorageOES), + FUNCTION(glEGLImageTargetTexture2DOES), + FUNCTION(glEnable), + FUNCTION(glEnableVertexAttribArray), + FUNCTION(glEndQuery), + FUNCTION(glEndQueryEXT), + FUNCTION(glEndTransformFeedback), + FUNCTION(glFenceSync), + FUNCTION(glFinish), + FUNCTION(glFinishFenceNV), + FUNCTION(glFlush), + FUNCTION(glFlushMappedBufferRange), + FUNCTION(glFramebufferRenderbuffer), + FUNCTION(glFramebufferRenderbufferOES), + FUNCTION(glFramebufferTexture2D), + FUNCTION(glFramebufferTexture2DOES), + FUNCTION(glFramebufferTextureLayer), + FUNCTION(glFrontFace), + FUNCTION(glGenBuffers), + FUNCTION(glGenFencesNV), + FUNCTION(glGenFramebuffers), + FUNCTION(glGenFramebuffersOES), + FUNCTION(glGenQueries), + FUNCTION(glGenQueriesEXT), + FUNCTION(glGenRenderbuffers), + FUNCTION(glGenRenderbuffersOES), + FUNCTION(glGenSamplers), + FUNCTION(glGenTextures), + FUNCTION(glGenTransformFeedbacks), + FUNCTION(glGenVertexArrays), + FUNCTION(glGenerateMipmap), + FUNCTION(glGenerateMipmapOES), + FUNCTION(glGetActiveAttrib), + FUNCTION(glGetActiveUniform), + FUNCTION(glGetActiveUniformBlockName), + FUNCTION(glGetActiveUniformBlockiv), + FUNCTION(glGetActiveUniformsiv), + FUNCTION(glGetAttachedShaders), + FUNCTION(glGetAttribLocation), + FUNCTION(glGetBooleanv), + FUNCTION(glGetBufferParameteri64v), + FUNCTION(glGetBufferParameteriv), + FUNCTION(glGetBufferPointerv), + FUNCTION(glGetError), + FUNCTION(glGetFenceivNV), + FUNCTION(glGetFloatv), + FUNCTION(glGetFragDataLocation), + FUNCTION(glGetFramebufferAttachmentParameteriv), + FUNCTION(glGetFramebufferAttachmentParameterivOES), + FUNCTION(glGetGraphicsResetStatusEXT), + FUNCTION(glGetInteger64i_v), + FUNCTION(glGetInteger64v), + FUNCTION(glGetIntegeri_v), + FUNCTION(glGetIntegerv), + FUNCTION(glGetInternalformativ), + FUNCTION(glGetProgramBinary), + FUNCTION(glGetProgramInfoLog), + FUNCTION(glGetProgramiv), + FUNCTION(glGetQueryObjectuiv), + FUNCTION(glGetQueryObjectuivEXT), + FUNCTION(glGetQueryiv), + FUNCTION(glGetQueryivEXT), + FUNCTION(glGetRenderbufferParameteriv), + FUNCTION(glGetRenderbufferParameterivOES), + FUNCTION(glGetSamplerParameterfv), + FUNCTION(glGetSamplerParameteriv), + FUNCTION(glGetShaderInfoLog), + FUNCTION(glGetShaderPrecisionFormat), + FUNCTION(glGetShaderSource), + FUNCTION(glGetShaderiv), + FUNCTION(glGetString), + FUNCTION(glGetStringi), + FUNCTION(glGetSynciv), + FUNCTION(glGetTexParameterfv), + FUNCTION(glGetTexParameteriv), + FUNCTION(glGetTransformFeedbackVarying), + FUNCTION(glGetUniformBlockIndex), + FUNCTION(glGetUniformIndices), + FUNCTION(glGetUniformLocation), + FUNCTION(glGetUniformfv), + FUNCTION(glGetUniformiv), + FUNCTION(glGetUniformuiv), + FUNCTION(glGetVertexAttribIiv), + FUNCTION(glGetVertexAttribIuiv), + FUNCTION(glGetVertexAttribPointerv), + FUNCTION(glGetVertexAttribfv), + FUNCTION(glGetVertexAttribiv), + FUNCTION(glGetnUniformfvEXT), + FUNCTION(glGetnUniformivEXT), + FUNCTION(glHint), + FUNCTION(glInvalidateFramebuffer), + FUNCTION(glInvalidateSubFramebuffer), + FUNCTION(glIsBuffer), + FUNCTION(glIsEnabled), + FUNCTION(glIsFenceNV), + FUNCTION(glIsFramebuffer), + FUNCTION(glIsFramebufferOES), + FUNCTION(glIsProgram), + FUNCTION(glIsQuery), + FUNCTION(glIsQueryEXT), + FUNCTION(glIsRenderbuffer), + FUNCTION(glIsRenderbufferOES), + FUNCTION(glIsSampler), + FUNCTION(glIsShader), + FUNCTION(glIsSync), + FUNCTION(glIsTexture), + FUNCTION(glIsTransformFeedback), + FUNCTION(glIsVertexArray), + FUNCTION(glLineWidth), + FUNCTION(glLinkProgram), + FUNCTION(glMapBufferRange), + FUNCTION(glPauseTransformFeedback), + FUNCTION(glPixelStorei), + FUNCTION(glPolygonOffset), + FUNCTION(glProgramBinary), + FUNCTION(glProgramParameteri), + FUNCTION(glReadBuffer), + FUNCTION(glReadPixels), + FUNCTION(glReadnPixelsEXT), + FUNCTION(glReleaseShaderCompiler), + FUNCTION(glRenderbufferStorage), + FUNCTION(glRenderbufferStorageMultisample), + FUNCTION(glRenderbufferStorageMultisampleANGLE), + FUNCTION(glRenderbufferStorageOES), + FUNCTION(glResumeTransformFeedback), + FUNCTION(glSampleCoverage), + FUNCTION(glSamplerParameterf), + FUNCTION(glSamplerParameterfv), + FUNCTION(glSamplerParameteri), + FUNCTION(glSamplerParameteriv), + FUNCTION(glScissor), + FUNCTION(glSetFenceNV), + FUNCTION(glShaderBinary), + FUNCTION(glShaderSource), + FUNCTION(glStencilFunc), + FUNCTION(glStencilFuncSeparate), + FUNCTION(glStencilMask), + FUNCTION(glStencilMaskSeparate), + FUNCTION(glStencilOp), + FUNCTION(glStencilOpSeparate), + FUNCTION(glTestFenceNV), + FUNCTION(glTexImage2D), + FUNCTION(glTexImage3D), + FUNCTION(glTexImage3DOES), + FUNCTION(glTexParameterf), + FUNCTION(glTexParameterfv), + FUNCTION(glTexParameteri), + FUNCTION(glTexParameteriv), + FUNCTION(glTexStorage2D), + FUNCTION(glTexStorage3D), + FUNCTION(glTexSubImage2D), + FUNCTION(glTexSubImage3D), + FUNCTION(glTransformFeedbackVaryings), + FUNCTION(glUniform1f), + FUNCTION(glUniform1fv), + FUNCTION(glUniform1i), + FUNCTION(glUniform1iv), + FUNCTION(glUniform1ui), + FUNCTION(glUniform1uiv), + FUNCTION(glUniform2f), + FUNCTION(glUniform2fv), + FUNCTION(glUniform2i), + FUNCTION(glUniform2iv), + FUNCTION(glUniform2ui), + FUNCTION(glUniform2uiv), + FUNCTION(glUniform3f), + FUNCTION(glUniform3fv), + FUNCTION(glUniform3i), + FUNCTION(glUniform3iv), + FUNCTION(glUniform3ui), + FUNCTION(glUniform3uiv), + FUNCTION(glUniform4f), + FUNCTION(glUniform4fv), + FUNCTION(glUniform4i), + FUNCTION(glUniform4iv), + FUNCTION(glUniform4ui), + FUNCTION(glUniform4uiv), + FUNCTION(glUniformBlockBinding), + FUNCTION(glUniformMatrix2fv), + FUNCTION(glUniformMatrix2x3fv), + FUNCTION(glUniformMatrix2x4fv), + FUNCTION(glUniformMatrix3fv), + FUNCTION(glUniformMatrix3x2fv), + FUNCTION(glUniformMatrix3x4fv), + FUNCTION(glUniformMatrix4fv), + FUNCTION(glUniformMatrix4x2fv), + FUNCTION(glUniformMatrix4x3fv), + FUNCTION(glUnmapBuffer), + FUNCTION(glUseProgram), + FUNCTION(glValidateProgram), + FUNCTION(glVertexAttrib1f), + FUNCTION(glVertexAttrib1fv), + FUNCTION(glVertexAttrib2f), + FUNCTION(glVertexAttrib2fv), + FUNCTION(glVertexAttrib3f), + FUNCTION(glVertexAttrib3fv), + FUNCTION(glVertexAttrib4f), + FUNCTION(glVertexAttrib4fv), + FUNCTION(glVertexAttribDivisor), + FUNCTION(glVertexAttribI4i), + FUNCTION(glVertexAttribI4iv), + FUNCTION(glVertexAttribI4ui), + FUNCTION(glVertexAttribI4uiv), + FUNCTION(glVertexAttribIPointer), + FUNCTION(glVertexAttribPointer), + FUNCTION(glViewport), + FUNCTION(glWaitSync), + + #undef FUNCTION + }; + + static const size_t numFunctions = sizeof glFunctions / sizeof(Function); + static const Function *const glFunctionsEnd = glFunctions + numFunctions; + + Function needle; + needle.name = procname; + + if(procname && strncmp("gl", procname, 2) == 0) + { + const Function *result = std::lower_bound(glFunctions, glFunctionsEnd, needle, CompareFunctor()); + if(result != glFunctionsEnd && strcmp(procname, result->name) == 0) { - return (__eglMustCastToProperFunctionPointerType)glExtensions[ext].address; + return (__eglMustCastToProperFunctionPointerType)result->address; } }