From f64f38f5bb69ad20ac7c077353cf5cdf28c067cb Mon Sep 17 00:00:00 2001 From: Matthias Bentrup Date: Wed, 4 Feb 2015 15:27:59 +0100 Subject: [PATCH] Load core function pointers before checking the extension string. For GL versions since 3.0 the glGetString() function is deprecated or removed, and the right way to query extensions is glGetStringi(), but that has to be loaded first. Also instead of searching the whole extension string n times lookup the known extensions in a static hash table. The hash table is built with the gperf utility. --- auto/Makefile | 15 ++++++++++++-- auto/bin/make_gperf.pl | 41 ++++++++++++++++++++++++++++++++++++++ auto/bin/make_list.pl | 5 ----- auto/src/glew_head.c | 14 +++++++++++++ auto/src/glew_init_gl.c | 9 ++------- auto/src/glew_init_glext.c | 23 +++++++++++++++++++++ auto/src/glew_init_glx.c | 16 +++++++++++++++ auto/src/glew_init_wgl.c | 16 +++++++++++++++ 8 files changed, 125 insertions(+), 14 deletions(-) create mode 100755 auto/bin/make_gperf.pl create mode 100644 auto/src/glew_init_glext.c diff --git a/auto/Makefile b/auto/Makefile index 91b68ed..70606d1 100644 --- a/auto/Makefile +++ b/auto/Makefile @@ -183,7 +183,16 @@ $(I.DEST)/glxew.h: $(EXT)/.dummy perl -e "s/GLXEW_VAR_EXPORT GLboolean __GLXEW_VERSION_1_2;/GLXEW_VAR_EXPORT GLboolean __GLXEW_VERSION_1_0;\nGLXEW_VAR_EXPORT GLboolean __GLXEW_VERSION_1_1;\nGLXEW_VAR_EXPORT GLboolean __GLXEW_VERSION_1_2;/" -pi $@ cat $(SRC)/glxew_tail.h >> $@ -$(S.DEST)/glew.c: $(EXT)/.dummy +$(SRC)/glew.gperf: $(EXT)/.dummy + @echo "--------------------------------------------------------------------" + @echo "Creating glew.gperf" + @echo "--------------------------------------------------------------------" + $(BIN)/make_gperf.pl $(GL_EXT_SPEC) $(WGL_EXT_SPEC) $(GLX_EXT_SPEC) > $@ + +$(SRC)/glew_init_hash.c: $(SRC)/glew.gperf + gperf -m 10 --output-file=$@ $(SRC)/glew.gperf + +$(S.DEST)/glew.c: $(EXT)/.dummy $(SRC)/glew_init_hash.c @echo "--------------------------------------------------------------------" @echo "Creating glew.c" @echo "--------------------------------------------------------------------" @@ -200,8 +209,10 @@ $(S.DEST)/glew.c: $(EXT)/.dummy echo -e "\n#endif /* !GLEW_MX */\n" >> $@; $(BIN)/make_init.pl GL $(GL_CORE_SPEC) >> $@ $(BIN)/make_init.pl GL $(GL_EXT_SPEC) >> $@ + cat $(SRC)/glew_init_hash.c | grep -v '^#line' >> $@ cat $(SRC)/glew_init_gl.c >> $@ - $(BIN)/make_list.pl $(GL_CORE_SPEC) | grep -v '\"GL_VERSION' >> $@ + $(BIN)/make_list.pl $(GL_CORE_SPEC) >> $@ + cat $(SRC)/glew_init_glext.c >> $@ $(BIN)/make_list.pl $(GL_EXT_SPEC) >> $@ echo -e "\n return GLEW_OK;\n}\n" >> $@ echo -e "\n#if defined(_WIN32)" >> $@ diff --git a/auto/bin/make_gperf.pl b/auto/bin/make_gperf.pl new file mode 100755 index 0000000..8578f39 --- /dev/null +++ b/auto/bin/make_gperf.pl @@ -0,0 +1,41 @@ +#!/usr/bin/perl +## +## Copyright (C) 2002-2008, Marcelo E. Magallon +## Copyright (C) 2002-2008, Milan Ikits +## +## This program is distributed under the terms and conditions of the GNU +## General Public License Version 2 as published by the Free Software +## Foundation or, at your option, any later version. + +use strict; +use warnings; + +do 'bin/make.pl'; + +my @extlist = (); +my %extensions = (); + +our $type = shift; + +if (@ARGV) +{ + @extlist = @ARGV; + + print "%struct-type\n"; + print "%compare-lengths\n"; + print "%define initializer-suffix ,NULL\n"; + print "%7bit\n"; + print "struct initflag { const char *name; GLboolean *flag; };\n"; + print "%%\n"; + + foreach my $ext (sort @extlist) + { + my ($extname, $exturl, $extstring, $types, $tokens, $functions, $exacts) = parse_ext($ext); + + my $extvar = $extname; + $extvar =~ s/GL(X*)_/GL$1EW_/; + my $prefix = $extvar; + $prefix =~ s/_.*//; + print $extname . ", " . $prefix . "_GET_REF(__" . $extvar . ")\n"; + } +} diff --git a/auto/bin/make_list.pl b/auto/bin/make_list.pl index 75dc060..ccbf0c3 100755 --- a/auto/bin/make_list.pl +++ b/auto/bin/make_list.pl @@ -44,11 +44,6 @@ if (@ARGV) print "#ifdef $extname\n"; - if (length($extstring)) - { - print " " . $extvar . " = _glewSearchExtension(\"$extstring\", extStart, extEnd);\n"; - } - if (keys %$functions) { if ($extname =~ /WGL_.*/) diff --git a/auto/src/glew_head.c b/auto/src/glew_head.c index e945bcd..7d119c4 100644 --- a/auto/src/glew_head.c +++ b/auto/src/glew_head.c @@ -7,6 +7,7 @@ #endif #include /* For size_t */ +extern int memcmp(const void *, const void *, size_t); /* * Define glewGetContext and related helper macros. @@ -158,28 +159,41 @@ void* NSGLGetProcAddress (const GLubyte *name) */ #undef GLEW_GET_VAR +#undef GLEW_GET_REF #ifdef GLEW_MX # define GLEW_GET_VAR(x) (glewGetContext()->x) +# define GLEW_GET_REF(x) (&((GLEWContext *)0)->x) #else /* GLEW_MX */ # define GLEW_GET_VAR(x) (x) +# define GLEW_GET_REF(x) (&(x)) #endif /* GLEW_MX */ #ifdef WGLEW_GET_VAR # undef WGLEW_GET_VAR +# undef WGLEW_GET_REF # ifdef GLEW_MX # define WGLEW_GET_VAR(x) (wglewGetContext()->x) +# define WGLEW_GET_REF(x) (&((WGLEWContext *)0)->x) # else /* GLEW_MX */ # define WGLEW_GET_VAR(x) (x) +# define WGLEW_GET_REF(x) (&(x)) # endif /* GLEW_MX */ +#else +# define WGLEW_GET_REF(x) (NULL) #endif /* WGLEW_GET_VAR */ #ifdef GLXEW_GET_VAR # undef GLXEW_GET_VAR +# undef GLXEW_GET_REF # ifdef GLEW_MX # define GLXEW_GET_VAR(x) (glxewGetContext()->x) +# define GLXEW_GET_REF(x) (&((GLXEWContext *)0)->x) # else /* GLEW_MX */ # define GLXEW_GET_VAR(x) (x) +# define GLXEW_GET_REF(x) (&(x)) # endif /* GLEW_MX */ +#else +# define GLXEW_GET_REF(x) (NULL) #endif /* GLXEW_GET_VAR */ /* diff --git a/auto/src/glew_init_gl.c b/auto/src/glew_init_gl.c index c438792..27a38e9 100644 --- a/auto/src/glew_init_gl.c +++ b/auto/src/glew_init_gl.c @@ -23,6 +23,7 @@ GLenum GLEWAPIENTRY glewContextInit (GLEW_CONTEXT_ARG_DEF_LIST) GLint major, minor; const GLubyte* extStart; const GLubyte* extEnd; + /* query opengl version */ s = glGetString(GL_VERSION); dot = _glewStrCLen(s, '.'); @@ -64,10 +65,4 @@ GLenum GLEWAPIENTRY glewContextInit (GLEW_CONTEXT_ARG_DEF_LIST) GLEW_VERSION_1_1 = GLEW_VERSION_1_2 == GL_TRUE || ( major == 1 && minor >= 1 ) ? GL_TRUE : GL_FALSE; } - /* query opengl extensions string */ - extStart = glGetString(GL_EXTENSIONS); - if (extStart == 0) - extStart = (const GLubyte*)""; - extEnd = extStart + _glewStrLen(extStart); - - /* initialize extensions */ + /* initialize core functions */ diff --git a/auto/src/glew_init_glext.c b/auto/src/glew_init_glext.c new file mode 100644 index 0000000..103e551 --- /dev/null +++ b/auto/src/glew_init_glext.c @@ -0,0 +1,23 @@ + + /* query opengl extensions string */ + extStart = glGetString(GL_EXTENSIONS); + if (extStart == 0) + extStart = (const GLubyte*)""; + extEnd = extStart + _glewStrLen(extStart); + + while (extStart < extEnd) + { + GLuint len = _glewStrCLen(extStart, ' '); + struct initflag *ptr = in_word_set(extStart, len); + + if (ptr != NULL && ptr->flag != NULL) { +#ifdef GLEW_MX + *(GLboolean *)((char *)ctx + (size_t)(ptr->flag)) = GL_TRUE; +#else + *ptr->flag = GL_TRUE; +#endif + } + extStart += len + 1; + } + + /* initialize extensions */ diff --git a/auto/src/glew_init_glx.c b/auto/src/glew_init_glx.c index b54cca3..6b4d7b7 100644 --- a/auto/src/glew_init_glx.c +++ b/auto/src/glew_init_glx.c @@ -54,4 +54,20 @@ GLenum glxewInit (GLXEW_CONTEXT_ARG_DEF_LIST) if (extStart == 0) extStart = (const GLubyte *)""; extEnd = extStart + _glewStrLen(extStart); + + while (extStart < extEnd) + { + GLuint len = _glewStrCLen(extStart, ' '); + struct initflag *ptr = in_word_set(extStart, len); + + if (ptr != NULL && ptr->flag != NULL) { +#ifdef GLEW_MX + *(GLboolean *)((char *)ctx + (size_t)(ptr->flag)) = GL_TRUE; +#else + *ptr->flag = GL_TRUE; +#endif + } + extStart += len + 1; + } + /* initialize extensions */ diff --git a/auto/src/glew_init_wgl.c b/auto/src/glew_init_wgl.c index cc731fe..f8c5116 100644 --- a/auto/src/glew_init_wgl.c +++ b/auto/src/glew_init_wgl.c @@ -41,5 +41,21 @@ GLenum GLEWAPIENTRY wglewInit (WGLEW_CONTEXT_ARG_DEF_LIST) else extStart = (const GLubyte*)_wglewGetExtensionsStringARB(wglGetCurrentDC()); extEnd = extStart + _glewStrLen(extStart); + + while (extStart < extEnd) + { + GLuint len = _glewStrCLen(extStart, ' '); + struct initflag *ptr = in_word_set(extStart, len); + + if (ptr != NULL && ptr->flag != NULL) { +#ifdef GLEW_MX + *(GLboolean *)((char *)ctx + (size_t)(ptr->flag)) = GL_TRUE; +#else + *ptr->flag = GL_TRUE; +#endif + } + extStart += len + 1; + } + /* initialize extensions */ crippled = _wglewGetExtensionsStringARB == NULL && _wglewGetExtensionsStringEXT == NULL;