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.
This commit is contained in:
Matthias Bentrup 2015-02-04 15:27:59 +01:00
parent 9e3e40d974
commit f64f38f5bb
8 changed files with 125 additions and 14 deletions

View File

@ -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 $@ 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 >> $@ 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 "--------------------------------------------------------------------"
@echo "Creating glew.c" @echo "Creating glew.c"
@echo "--------------------------------------------------------------------" @echo "--------------------------------------------------------------------"
@ -200,8 +209,10 @@ $(S.DEST)/glew.c: $(EXT)/.dummy
echo -e "\n#endif /* !GLEW_MX */\n" >> $@; echo -e "\n#endif /* !GLEW_MX */\n" >> $@;
$(BIN)/make_init.pl GL $(GL_CORE_SPEC) >> $@ $(BIN)/make_init.pl GL $(GL_CORE_SPEC) >> $@
$(BIN)/make_init.pl GL $(GL_EXT_SPEC) >> $@ $(BIN)/make_init.pl GL $(GL_EXT_SPEC) >> $@
cat $(SRC)/glew_init_hash.c | grep -v '^#line' >> $@
cat $(SRC)/glew_init_gl.c >> $@ 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) >> $@ $(BIN)/make_list.pl $(GL_EXT_SPEC) >> $@
echo -e "\n return GLEW_OK;\n}\n" >> $@ echo -e "\n return GLEW_OK;\n}\n" >> $@
echo -e "\n#if defined(_WIN32)" >> $@ echo -e "\n#if defined(_WIN32)" >> $@

41
auto/bin/make_gperf.pl Executable file
View File

@ -0,0 +1,41 @@
#!/usr/bin/perl
##
## Copyright (C) 2002-2008, Marcelo E. Magallon <mmagallo[]debian org>
## Copyright (C) 2002-2008, Milan Ikits <milan ikits[]ieee org>
##
## 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";
}
}

View File

@ -44,11 +44,6 @@ if (@ARGV)
print "#ifdef $extname\n"; print "#ifdef $extname\n";
if (length($extstring))
{
print " " . $extvar . " = _glewSearchExtension(\"$extstring\", extStart, extEnd);\n";
}
if (keys %$functions) if (keys %$functions)
{ {
if ($extname =~ /WGL_.*/) if ($extname =~ /WGL_.*/)

View File

@ -7,6 +7,7 @@
#endif #endif
#include <stddef.h> /* For size_t */ #include <stddef.h> /* For size_t */
extern int memcmp(const void *, const void *, size_t);
/* /*
* Define glewGetContext and related helper macros. * Define glewGetContext and related helper macros.
@ -158,28 +159,41 @@ void* NSGLGetProcAddress (const GLubyte *name)
*/ */
#undef GLEW_GET_VAR #undef GLEW_GET_VAR
#undef GLEW_GET_REF
#ifdef GLEW_MX #ifdef GLEW_MX
# define GLEW_GET_VAR(x) (glewGetContext()->x) # define GLEW_GET_VAR(x) (glewGetContext()->x)
# define GLEW_GET_REF(x) (&((GLEWContext *)0)->x)
#else /* GLEW_MX */ #else /* GLEW_MX */
# define GLEW_GET_VAR(x) (x) # define GLEW_GET_VAR(x) (x)
# define GLEW_GET_REF(x) (&(x))
#endif /* GLEW_MX */ #endif /* GLEW_MX */
#ifdef WGLEW_GET_VAR #ifdef WGLEW_GET_VAR
# undef WGLEW_GET_VAR # undef WGLEW_GET_VAR
# undef WGLEW_GET_REF
# ifdef GLEW_MX # ifdef GLEW_MX
# define WGLEW_GET_VAR(x) (wglewGetContext()->x) # define WGLEW_GET_VAR(x) (wglewGetContext()->x)
# define WGLEW_GET_REF(x) (&((WGLEWContext *)0)->x)
# else /* GLEW_MX */ # else /* GLEW_MX */
# define WGLEW_GET_VAR(x) (x) # define WGLEW_GET_VAR(x) (x)
# define WGLEW_GET_REF(x) (&(x))
# endif /* GLEW_MX */ # endif /* GLEW_MX */
#else
# define WGLEW_GET_REF(x) (NULL)
#endif /* WGLEW_GET_VAR */ #endif /* WGLEW_GET_VAR */
#ifdef GLXEW_GET_VAR #ifdef GLXEW_GET_VAR
# undef GLXEW_GET_VAR # undef GLXEW_GET_VAR
# undef GLXEW_GET_REF
# ifdef GLEW_MX # ifdef GLEW_MX
# define GLXEW_GET_VAR(x) (glxewGetContext()->x) # define GLXEW_GET_VAR(x) (glxewGetContext()->x)
# define GLXEW_GET_REF(x) (&((GLXEWContext *)0)->x)
# else /* GLEW_MX */ # else /* GLEW_MX */
# define GLXEW_GET_VAR(x) (x) # define GLXEW_GET_VAR(x) (x)
# define GLXEW_GET_REF(x) (&(x))
# endif /* GLEW_MX */ # endif /* GLEW_MX */
#else
# define GLXEW_GET_REF(x) (NULL)
#endif /* GLXEW_GET_VAR */ #endif /* GLXEW_GET_VAR */
/* /*

View File

@ -23,6 +23,7 @@ GLenum GLEWAPIENTRY glewContextInit (GLEW_CONTEXT_ARG_DEF_LIST)
GLint major, minor; GLint major, minor;
const GLubyte* extStart; const GLubyte* extStart;
const GLubyte* extEnd; const GLubyte* extEnd;
/* query opengl version */ /* query opengl version */
s = glGetString(GL_VERSION); s = glGetString(GL_VERSION);
dot = _glewStrCLen(s, '.'); 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; GLEW_VERSION_1_1 = GLEW_VERSION_1_2 == GL_TRUE || ( major == 1 && minor >= 1 ) ? GL_TRUE : GL_FALSE;
} }
/* query opengl extensions string */ /* initialize core functions */
extStart = glGetString(GL_EXTENSIONS);
if (extStart == 0)
extStart = (const GLubyte*)"";
extEnd = extStart + _glewStrLen(extStart);
/* initialize extensions */

View File

@ -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 */

View File

@ -54,4 +54,20 @@ GLenum glxewInit (GLXEW_CONTEXT_ARG_DEF_LIST)
if (extStart == 0) if (extStart == 0)
extStart = (const GLubyte *)""; extStart = (const GLubyte *)"";
extEnd = extStart + _glewStrLen(extStart); 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 */ /* initialize extensions */

View File

@ -41,5 +41,21 @@ GLenum GLEWAPIENTRY wglewInit (WGLEW_CONTEXT_ARG_DEF_LIST)
else else
extStart = (const GLubyte*)_wglewGetExtensionsStringARB(wglGetCurrentDC()); extStart = (const GLubyte*)_wglewGetExtensionsStringARB(wglGetCurrentDC());
extEnd = extStart + _glewStrLen(extStart); 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 */ /* initialize extensions */
crippled = _wglewGetExtensionsStringARB == NULL && _wglewGetExtensionsStringEXT == NULL; crippled = _wglewGetExtensionsStringARB == NULL && _wglewGetExtensionsStringEXT == NULL;