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/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;
}
}