From e935fcad83772ae5ab9ee6ecbe2967b8be230f3f 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 | 2 ++ auto/src/glew_init_glext.c | 23 +++++++++++++++++++++ auto/src/glew_init_glx.c | 16 +++++++++++++++ auto/src/glew_init_wgl.c | 16 +++++++++++++++ 7 files changed, 111 insertions(+), 7 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 33663ac..f6d9e4a 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 "--------------------------------------------------------------------" @@ -209,8 +218,10 @@ $(S.DEST)/glew.c: $(EXT)/.dummy echo -e "" >> $@; $(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) && ! defined(GLEW_OSMESA)" >> $@ 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 3d0ddce..98fa227 100755 --- a/auto/bin/make_list.pl +++ b/auto/bin/make_list.pl @@ -47,11 +47,6 @@ if (@ARGV) print "#ifdef $extname\n"; } - if (length($extstring) && $extstring !~ /^GL_/) - { - 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 e8672cb..98867d4 100644 --- a/auto/src/glew_head.c +++ b/auto/src/glew_head.c @@ -13,6 +13,8 @@ #include /* For malloc, free */ #include /* For memset */ +extern int memcmp(const void *, const void *, size_t); + #if defined(GLEW_REGAL) /* In GLEW_REGAL mode we call direcly into the linked 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 159e45d..d241e92 100644 --- a/auto/src/glew_init_glx.c +++ b/auto/src/glew_init_glx.c @@ -50,4 +50,20 @@ GLenum glxewInit () 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 978cf3c..bd161be 100644 --- a/auto/src/glew_init_wgl.c +++ b/auto/src/glew_init_wgl.c @@ -37,5 +37,21 @@ GLenum GLEWAPIENTRY wglewInit () 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;