diff options
Diffstat (limited to 'xorg-server/hw')
-rwxr-xr-x | xorg-server/hw/xwin/glx/gen_gl_wrappers.py | 472 | ||||
-rw-r--r-- | xorg-server/hw/xwin/glx/glshim.c | 124 | ||||
-rw-r--r-- | xorg-server/hw/xwin/glx/glwindows.h | 7 | ||||
-rw-r--r-- | xorg-server/hw/xwin/glx/glwrap.c (renamed from xorg-server/hw/xwin/glx/glthunk.c) | 77 | ||||
-rw-r--r-- | xorg-server/hw/xwin/glx/indirect.c | 30 |
5 files changed, 287 insertions, 423 deletions
diff --git a/xorg-server/hw/xwin/glx/gen_gl_wrappers.py b/xorg-server/hw/xwin/glx/gen_gl_wrappers.py index 683b9d903..e5fa57142 100755 --- a/xorg-server/hw/xwin/glx/gen_gl_wrappers.py +++ b/xorg-server/hw/xwin/glx/gen_gl_wrappers.py @@ -1,8 +1,5 @@ #!/usr/bin/python3 # -# python script to generate cdecl to stdcall wrappers for GL functions -# adapted from genheaders.py -# # Copyright (c) 2013 The Khronos Group Inc. # # Permission is hereby granted, free of charge, to any person obtaining a @@ -27,23 +24,30 @@ import sys, time, pdb, string, cProfile from reg import * +# debug - start header generation in debugger +# dump - dump registry after loading +# profile - enable Python profiling +# protect - whether to use #ifndef protections +# registry <filename> - use specified XML registry instead of gl.xml +# timeit - time length of registry loading & header generation +# validate - validate return & parameter group tags against <group> +debug = False +dump = False +profile = False +protect = True +timeit = False +validate= False # Default input / log files errFilename = None diagFilename = 'diag.txt' regFilename = 'gl.xml' outFilename = 'gen_gl_wrappers.c' - -protect=True +dispatchheader=None prefix="gl" preresolve=False -wrapper=False -shim=False -thunk=False -thunkdefs=False staticwrappers=False -nodebug=False +nodebugcallcounting=False -#exclude base WGL API WinGDI={key: 1 for key in [ "wglCopyContext" ,"wglCreateContext" @@ -79,45 +83,110 @@ if __name__ == '__main__': while (i < len(sys.argv)): arg = sys.argv[i] i = i + 1 - if (arg == '-noprotect'): + if (arg == '-debug'): + print('Enabling debug (-debug)', file=sys.stderr) + debug = True + elif (arg == '-dump'): + print('Enabling dump (-dump)', file=sys.stderr) + dump = True + elif (arg == '-noprotect'): print('Disabling inclusion protection in output headers', file=sys.stderr) protect = False + elif (arg == '-profile'): + print('Enabling profiling (-profile)', file=sys.stderr) + profile = True elif (arg == '-registry'): regFilename = sys.argv[i] i = i+1 - print('Using registry', regFilename, file=sys.stderr) + print('Using registry ', regFilename, file=sys.stderr) + elif (arg == '-time'): + print('Enabling timing (-time)', file=sys.stderr) + timeit = True + elif (arg == '-validate'): + print('Enabling group validation (-validate)', file=sys.stderr) + validate = True elif (arg == '-outfile'): outFilename = sys.argv[i] i = i+1 elif (arg == '-preresolve'): preresolve=True - elif (arg == '-wrapper'): - wrapper=True - elif (arg == '-shim'): - shim=True - elif (arg == '-thunk'): - thunk=True - elif (arg == '-thunkdefs'): - thunkdefs=True elif (arg == '-staticwrappers'): staticwrappers=True + elif (arg == '-dispatchheader'): + dispatchheader = sys.argv[i] + i = i+1 elif (arg == '-prefix'): prefix = sys.argv[i] i = i+1 - elif (arg == '-nodebug'): - nodebug = True + elif (arg == '-nodbgcount'): + nodebugcallcounting = True elif (arg[0:1] == '-'): print('Unrecognized argument:', arg, file=sys.stderr) exit(1) - -print('Generating', outFilename, file=sys.stderr) +print('Generating ', outFilename, file=sys.stderr) + +# Simple timer functions +startTime = None +def startTimer(): + global startTime + startTime = time.clock() +def endTimer(msg): + global startTime + endTime = time.clock() + if (timeit): + print(msg, endTime - startTime) + startTime = None # Load & parse registry reg = Registry() + +startTimer() tree = etree.parse(regFilename) -reg.loadElementTree(tree) +endTimer('Time to make ElementTree =') -allVersions = '.*' +startTimer() +reg.loadElementTree(tree) +endTimer('Time to parse ElementTree =') + +if (validate): + reg.validateGroups() + +if (dump): + print('***************************************') + print('Performing Registry dump to regdump.txt') + print('***************************************') + reg.dumpReg(filehandle = open('regdump.txt','w')) + +# Turn a list of strings into a regexp string matching exactly those strings +def makeREstring(list): + return '^(' + '|'.join(list) + ')$' + +# These are "mandatory" OpenGL ES 1 extensions, to +# be included in the core GLES/gl.h header. +es1CoreList = [ + 'GL_OES_read_format', + 'GL_OES_compressed_paletted_texture', + 'GL_OES_point_size_array', + 'GL_OES_point_sprite' +] + +# Descriptive names for various regexp patterns used to select +# versions and extensions + +allVersions = allExtensions = '.*' +noVersions = noExtensions = None +gl12andLaterPat = '1\.[2-9]|[234]\.[0-9]' +gles2onlyPat = '2\.[0-9]' +gles2and3Pat = '[23]\.[0-9]' +es1CorePat = makeREstring(es1CoreList) +# Extensions in old glcorearb.h but not yet tagged accordingly in gl.xml +glCoreARBPat = None +glx13andLaterPat = '1\.[3-9]' + +# Defaults for generating re-inclusion protection wrappers (or not) +protectFile = protect +protectFeature = protect +protectProto = protect genOpts = CGeneratorOptions( apiname = prefix, @@ -125,9 +194,16 @@ genOpts = CGeneratorOptions( versions = allVersions, emitversions = allVersions, defaultExtensions = prefix, # Default extensions for GL - protectFile = protect, - protectFeature = protect, - protectProto = protect, +# addExtensions = None, +# removeExtensions = None, +# prefixText = prefixStrings + glExtPlatformStrings + glextVersionStrings, +# genFuncPointers = True, +# protectFile = protectFile, +# protectFeature = protectFeature, +# protectProto = protectProto, +# apicall = 'GLAPI ', +# apientry = 'APIENTRY ', +# apientryp = 'APIENTRYP '), ) # create error/warning & diagnostic files @@ -137,6 +213,28 @@ else: errWarn = sys.stderr diag = open(diagFilename, 'w') +# +# look for all the SET_ macros in dispatch.h, this is the set of functions +# we need to generate +# + +dispatch = {} + +if dispatchheader : + fh = open(dispatchheader) + dispatchh = fh.readlines() + + dispatch_regex = re.compile(r'(?:#define|static\s+INLINE\s+void)\s+SET_([^\()]+)\(') + + for line in dispatchh : + line = line.strip() + m1 = dispatch_regex.search(line) + + if m1 : + dispatch[prefix+m1.group(1)] = 1 + + del dispatch['glby_offset'] + class PreResolveOutputGenerator(OutputGenerator): def __init__(self, errFile = sys.stderr, @@ -145,7 +243,7 @@ class PreResolveOutputGenerator(OutputGenerator): OutputGenerator.__init__(self, errFile, warnFile, diagFile) self.wrappers={} def beginFile(self, genOpts): - self.outFile.write('/* Automatically generated from %s - DO NOT EDIT */\n\n'%regFilename) + pass def endFile(self): self.outFile.write('\nvoid ' + prefix + 'ResolveExtensionProcs(void)\n{\n') for funcname in self.wrappers.keys(): @@ -153,6 +251,7 @@ class PreResolveOutputGenerator(OutputGenerator): self.outFile.write('}\n\n') def beginFeature(self, interface, emit): OutputGenerator.beginFeature(self, interface, emit) + self.OldVersion = self.featureName.startswith('GL_VERSION_1_0') or self.featureName.startswith('GL_VERSION_1_1') def endFeature(self): OutputGenerator.endFeature(self) def genType(self, typeinfo, name): @@ -161,21 +260,21 @@ class PreResolveOutputGenerator(OutputGenerator): OutputGenerator.genEnum(self, enuminfo, name) def genCmd(self, cmd, name): OutputGenerator.genCmd(self, cmd, name) - if name in WinGDI: return self.outFile.write('RESOLVE_DECL(PFN' + name.upper() + 'PROC);\n') self.wrappers[name]=1 -class WrapperOutputGenerator(OutputGenerator): +class MyOutputGenerator(OutputGenerator): def __init__(self, errFile = sys.stderr, warnFile = sys.stderr, diagFile = sys.stdout): OutputGenerator.__init__(self, errFile, warnFile, diagFile) + self.wrappers={} def beginFile(self, genOpts): - self.outFile.write('/* Automatically generated from %s - DO NOT EDIT */\n\n'%regFilename) + pass def endFile(self): pass def beginFeature(self, interface, emit): @@ -189,18 +288,26 @@ class WrapperOutputGenerator(OutputGenerator): OutputGenerator.genEnum(self, enuminfo, name) def genCmd(self, cmd, name): OutputGenerator.genCmd(self, cmd, name) + # Avoid generating wrappers which aren't referenced by the dispatch table + if dispatchheader and not name in dispatch : + self.outFile.write('/* No wrapper for ' + name + ', not in dispatch table */\n') + return if name in WinGDI: return + self.wrappers[name]=1 + proto=noneStr(cmd.elem.find('proto')) rettype=noneStr(proto.text) if rettype.lower()!="void ": plist = ([t for t in proto.itertext()]) rettype = ''.join(plist[:-1]) - rettype=rettype.strip() + #ptype=proto.find("ptype") + #if ptype!=None: + # rettype = (noneStr(ptype.text))+" " if staticwrappers: self.outFile.write("static ") - self.outFile.write("%s %sWrapper("%(rettype, name)) + self.outFile.write("%s__stdcall %sWrapper("%(rettype, name)) params = cmd.elem.findall('param') plist=[] for param in params: @@ -215,230 +322,55 @@ class WrapperOutputGenerator(OutputGenerator): Comma=", " else: self.outFile.write("void") - - self.outFile.write(")\n{\n") - - # for GL 1.0 and 1.1 functions, generate stdcall wrappers which call the function directly if self.OldVersion: - if not nodebug: - self.outFile.write(' if (glxWinDebugSettings.enable%scallTrace) ErrorF("%s\\n");\n'%(prefix.upper(), name)) - self.outFile.write(" glWinDirectProcCalls++;\n") - self.outFile.write("\n") - - if rettype.lower()=="void": - self.outFile.write(" %s( "%(name)) + if nodebugcallcounting: + self.outFile.write(")\n{\n") else: - self.outFile.write(" return %s( "%(name)) - - Comma="" - for ptype, pname in plist: - self.outFile.write("%s%s_"%(Comma, pname)) - Comma=", " - - # for GL 1.2+ functions, generate stdcall wrappers which use wglGetProcAddress() - else: - if rettype.lower()=="void": - self.outFile.write(' RESOLVE(PFN%sPROC, "%s");\n'%(name.upper(), name)) - - if not nodebug: - self.outFile.write("\n") - self.outFile.write(' if (glxWinDebugSettings.enable%scallTrace) ErrorF("%s\\n");\n'%(prefix.upper(), name)) - self.outFile.write("\n") - - self.outFile.write(" RESOLVED_PROC(PFN%sPROC)( """%(name.upper())) - else: - self.outFile.write(' RESOLVE_RET(PFN%sPROC, "%s", FALSE);\n'%(name.upper(), name)) - - if not nodebug: - self.outFile.write("\n") - self.outFile.write(' if (glxWinDebugSettings.enable%scallTrace) ErrorF("%s\\n");\n'%(prefix.upper(), name)) - self.outFile.write("\n") - - self.outFile.write(" return RESOLVED_PROC(PFN%sPROC)("%(name.upper())) - - Comma="" - for ptype, pname in plist: - self.outFile.write("%s%s_"%(Comma, pname)) - Comma=", " - self.outFile.write(" );\n}\n\n") - -class ThunkOutputGenerator(OutputGenerator): - def __init__(self, - errFile = sys.stderr, - warnFile = sys.stderr, - diagFile = sys.stdout): - OutputGenerator.__init__(self, errFile, warnFile, diagFile) - def beginFile(self, genOpts): - self.outFile.write('/* Automatically generated from %s - DO NOT EDIT */\n\n'%regFilename) - def endFile(self): - pass - def beginFeature(self, interface, emit): - OutputGenerator.beginFeature(self, interface, emit) - self.OldVersion = self.featureName.startswith('GL_VERSION_1_0') or self.featureName.startswith('GL_VERSION_1_1') - def endFeature(self): - OutputGenerator.endFeature(self) - def genType(self, typeinfo, name): - OutputGenerator.genType(self, typeinfo, name) - def genEnum(self, enuminfo, name): - OutputGenerator.genEnum(self, enuminfo, name) - def genCmd(self, cmd, name): - OutputGenerator.genCmd(self, cmd, name) - - proto=noneStr(cmd.elem.find('proto')) - rettype=noneStr(proto.text) - if rettype.lower()!="void ": - plist = ([t for t in proto.itertext()]) - rettype = ''.join(plist[:-1]) - rettype=rettype.strip() - self.outFile.write("%s %sWrapper("%(rettype, name)) - params = cmd.elem.findall('param') - plist=[] - for param in params: - paramlist = ([t for t in param.itertext()]) - paramtype = ''.join(paramlist[:-1]) - paramname = paramlist[-1] - plist.append((paramtype, paramname)) - Comma="" - if len(plist): - for ptype, pname in plist: - self.outFile.write("%s%s%s_"%(Comma, ptype, pname)) - Comma=", " - else: - self.outFile.write("void") - - self.outFile.write(")\n{\n") - - # for GL 1.0 and 1.1 functions, generate stdcall thunk wrappers which call the function directly - if self.OldVersion: - if rettype.lower()=="void": + self.outFile.write( """) +{ +#ifdef _DEBUG + if (glxWinDebugSettings.enable%scallTrace) ErrorF("%s\\n"); + glWinDirectProcCalls++; +#endif +"""%(prefix.upper(), name)) + if rettype.lower()=="void ": self.outFile.write(" %s( "%(name)) else: self.outFile.write(" return %s( "%(name)) - Comma="" for ptype, pname in plist: self.outFile.write("%s%s_"%(Comma, pname)) Comma=", " - - # for GL 1.2+ functions, generate wrappers which use wglGetProcAddress() else: - if rettype.lower()=="void": - self.outFile.write(' RESOLVE(PFN%sPROC, "%s");\n'%(name.upper(), name)) - self.outFile.write(" RESOLVED_PROC(PFN%sPROC)( """%(name.upper())) + if rettype.lower()=="void ": + self.outFile.write(""") +{ + RESOLVE(PFN%sPROC, "%s");"""%(name.upper(), name)) + if not nodebugcallcounting: self.outFile.write(""" +#ifdef _DEBUG + if (glxWinDebugSettings.enable%scallTrace) ErrorF("%s\\n"); +#endif"""%(prefix.upper(), name)) + self.outFile.write(""" + RESOLVED_PROC(PFN%sPROC)( """%(name.upper())) else: - self.outFile.write(' RESOLVE_RET(PFN%sPROC, "%s", FALSE);\n'%(name.upper(), name)) - self.outFile.write(" return RESOLVED_PROC(PFN%sPROC)("%(name.upper())) - + self.outFile.write(""") +{ + RESOLVE_RET(PFN%sPROC, "%s", FALSE);"""%(name.upper(), name)) + if not nodebugcallcounting: self.outFile.write(""" +#ifdef _DEBUG + if (glxWinDebugSettings.enable%scallTrace) ErrorF("%s\\n"); +#endif"""%(prefix.upper(), name)) + self.outFile.write(""" + return RESOLVED_PROC(PFN%sPROC)( """%(name.upper())) Comma="" for ptype, pname in plist: self.outFile.write("%s%s_"%(Comma, pname)) Comma=", " self.outFile.write(" );\n}\n\n") -class ThunkDefsOutputGenerator(OutputGenerator): - def __init__(self, - errFile = sys.stderr, - warnFile = sys.stderr, - diagFile = sys.stdout): - OutputGenerator.__init__(self, errFile, warnFile, diagFile) - def beginFile(self, genOpts): - self.outFile.write("EXPORTS\n"); # this must be the first line for libtool to realize this is a .def file - self.outFile.write('; Automatically generated from %s - DO NOT EDIT\n\n'%regFilename) - def endFile(self): - pass - def beginFeature(self, interface, emit): - OutputGenerator.beginFeature(self, interface, emit) - def endFeature(self): - OutputGenerator.endFeature(self) - def genType(self, typeinfo, name): - OutputGenerator.genType(self, typeinfo, name) - def genEnum(self, enuminfo, name): - OutputGenerator.genEnum(self, enuminfo, name) - def genCmd(self, cmd, name): - OutputGenerator.genCmd(self, cmd, name) - - # export the wrapper function with the name of the function it wraps - self.outFile.write("%s = %sWrapper\n"%(name, name)) - -class ShimOutputGenerator(OutputGenerator): - def __init__(self, - errFile = sys.stderr, - warnFile = sys.stderr, - diagFile = sys.stdout): - OutputGenerator.__init__(self, errFile, warnFile, diagFile) - def beginFile(self, genOpts): - self.outFile.write('/* Automatically generated from %s - DO NOT EDIT */\n\n'%regFilename) - def endFile(self): - pass - def beginFeature(self, interface, emit): - OutputGenerator.beginFeature(self, interface, emit) - self.OldVersion = self.featureName.startswith('GL_VERSION_1_0') or self.featureName.startswith('GL_VERSION_1_1') or self.featureName.startswith('GL_VERSION_1_2') or self.featureName.startswith('GL_ARB_imaging') or self.featureName.startswith('GL_ARB_multitexture') or self.featureName.startswith('GL_ARB_texture_compression') - def endFeature(self): - OutputGenerator.endFeature(self) - def genType(self, typeinfo, name): - OutputGenerator.genType(self, typeinfo, name) - def genEnum(self, enuminfo, name): - OutputGenerator.genEnum(self, enuminfo, name) - def genCmd(self, cmd, name): - OutputGenerator.genCmd(self, cmd, name) - - if not self.OldVersion: - return - - # for GL functions which are in the ABI, generate a shim which calls the function via GetProcAddress - proto=noneStr(cmd.elem.find('proto')) - rettype=noneStr(proto.text) - if rettype.lower()!="void ": - plist = ([t for t in proto.itertext()]) - rettype = ''.join(plist[:-1]) - rettype=rettype.strip() - self.outFile.write("%s %s("%(rettype, name)) - params = cmd.elem.findall('param') - plist=[] - for param in params: - paramlist = ([t for t in param.itertext()]) - paramtype = ''.join(paramlist[:-1]) - paramname = paramlist[-1] - plist.append((paramtype, paramname)) - Comma="" - if len(plist): - for ptype, pname in plist: - self.outFile.write("%s%s%s_"%(Comma, ptype, pname)) - Comma=", " - else: - self.outFile.write("void") - - self.outFile.write(")\n{\n") - - self.outFile.write(' typedef %s (* PFN%sPROC)(' % (rettype, name.upper())) - - if len(plist): - Comma="" - for ptype, pname in plist: - self.outFile.write("%s %s %s_"%(Comma, ptype, pname)) - Comma=", " - else: - self.outFile.write("void") - - self.outFile.write(');\n') - - if rettype.lower()=="void": - self.outFile.write(' RESOLVE(PFN%sPROC, "%s");\n'%(name.upper(), name)) - self.outFile.write(' RESOLVED_PROC(') - else: - self.outFile.write(' RESOLVE_RET(PFN%sPROC, "%s", 0);\n'%(name.upper(), name)) - self.outFile.write(' return RESOLVED_PROC(') - - Comma="" - for ptype, pname in plist: - self.outFile.write("%s%s_"%(Comma, pname)) - Comma=", " - - self.outFile.write(" );\n}\n\n") - def genHeaders(): + startTimer() outFile = open(outFilename,"w") - if preresolve: gen = PreResolveOutputGenerator(errFile=errWarn, warnFile=errWarn, @@ -446,40 +378,40 @@ def genHeaders(): gen.outFile=outFile reg.setGenerator(gen) reg.apiGen(genOpts) + gen = MyOutputGenerator(errFile=errWarn, + warnFile=errWarn, + diagFile=diag) + gen.outFile=outFile + reg.setGenerator(gen) + reg.apiGen(genOpts) - if wrapper: - gen = WrapperOutputGenerator(errFile=errWarn, - warnFile=errWarn, - diagFile=diag) - gen.outFile=outFile - reg.setGenerator(gen) - reg.apiGen(genOpts) + # generate function to setup the dispatch table, which sets each + # dispatch table entry to point to it's wrapper function + # (assuming we were able to make one) - if shim: - gen = ShimOutputGenerator(errFile=errWarn, - warnFile=errWarn, - diagFile=diag) - gen.outFile=outFile - reg.setGenerator(gen) - reg.apiGen(genOpts) + if dispatchheader : + outFile.write( 'void glWinSetupDispatchTable(void)\n') + outFile.write( '{\n') + outFile.write( ' struct _glapi_table *disp = _glapi_get_dispatch();\n') - if thunk: - gen = ThunkOutputGenerator(errFile=errWarn, - warnFile=errWarn, - diagFile=diag) - gen.outFile=outFile - reg.setGenerator(gen) - reg.apiGen(genOpts) + for d in sorted(dispatch.keys()) : + if d in gen.wrappers : + outFile.write(' SET_'+ d[len(prefix):] + '(disp, (void *)' + d + 'Wrapper);\n') + else : + outFile.write('#pragma message("No wrapper for ' + d + ' !")\n') + + outFile.write('}\n') - if thunkdefs: - gen = ThunkDefsOutputGenerator(errFile=errWarn, - warnFile=errWarn, - diagFile=diag) - gen.outFile=outFile - reg.setGenerator(gen) - reg.apiGen(genOpts) outFile.close() -genHeaders() +if (debug): + pdb.run('genHeaders()') +elif (profile): + import cProfile, pstats + cProfile.run('genHeaders()', 'profile.txt') + p = pstats.Stats('profile.txt') + p.strip_dirs().sort_stats('time').print_stats(50) +else: + genHeaders() diff --git a/xorg-server/hw/xwin/glx/glshim.c b/xorg-server/hw/xwin/glx/glshim.c deleted file mode 100644 index 7109196c0..000000000 --- a/xorg-server/hw/xwin/glx/glshim.c +++ /dev/null @@ -1,124 +0,0 @@ -/* - * File: glshim.c - * Purpose: GL shim which redirects to a specified DLL - * - * Copyright (c) Jon TURNEY 2013 - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -/* - A GL shim which redirects to a specified DLL - - XWin is statically linked with this, rather than the system libGL, so that - GL calls can be directed to mesa cygGL-1.dll, or cygnativeGLthunk.dll - (which contains cdecl-to-stdcall thunks to the native openGL32.dll) -*/ - -#ifdef HAVE_XWIN_CONFIG_H -#include <xwin-config.h> -#endif - -#define GL_GLEXT_LEGACY -#include <GL/gl.h> -#undef GL_ARB_imaging -#undef GL_VERSION_1_3 -#include <GL/glext.h> - -#include <X11/Xwindows.h> -#include <os.h> -#include "glwindows.h" -#include <glx/glxserver.h> - -static HMODULE hMod = NULL; - -/* - Implement the __glGetProcAddress function by just using GetProcAddress() on the selected DLL -*/ -void *glXGetProcAddressARB(const char *symbol) -{ - void *proc; - - /* Default to the mesa GL implementation if one hasn't been selected yet */ - if (!hMod) - glWinSelectImplementation(0); - - proc = GetProcAddress(hMod, symbol); - - if (glxWinDebugSettings.enableGLcallTrace) - ErrorF("glXGetProcAddressARB: Resolved '%s' in %p to %p\n", symbol, hMod, proc); - - return proc; -} - -/* - Select a GL implementation DLL -*/ -int glWinSelectImplementation(int native) -{ - const char *dllname; - - if (native) { - dllname = "cygnativeGLthunk.dll"; - } - else { - dllname = "cygGL-1.dll"; - } - - hMod = LoadLibraryEx(dllname, NULL, 0); - if (hMod == NULL) { - ErrorF("glWinSelectGLimplementation: Could not load '%s'\n", dllname); - return -1; - } - - ErrorF("glWinSelectGLimplementation: Loaded '%s'\n", dllname); - - /* Connect __glGetProcAddress() to our implementation of glXGetProcAddressARB() above */ - __glXsetGetProcAddress((glx_gpa_proc)glXGetProcAddressARB); - - return 0; -} - -#define RESOLVE_RET(proctype, symbol, retval) \ - proctype proc = (proctype)glXGetProcAddressARB(symbol); \ - if (proc == NULL) return retval; - -#define RESOLVE(proctype, symbol) RESOLVE_RET(proctype, symbol,) -#define RESOLVED_PROC proc - -/* Include generated shims for direct linkage to GL functions which are in the ABI */ -#include "generated_gl_shim.c" - -/* - Special wrapper for glAddSwapHintRectWIN for copySubBuffers - - Only used with native GL if the GL_WIN_swap_hint extension is present, so we enable - GLX_MESA_copy_sub_buffer -*/ -typedef void (__stdcall * PFNGLADDSWAPHINTRECTWIN) (GLint x, GLint y, - GLsizei width, - GLsizei height); - -void -glAddSwapHintRectWINWrapper(GLint x, GLint y, GLsizei width, - GLsizei height) -{ - RESOLVE(PFNGLADDSWAPHINTRECTWIN, "glAddSwapHintRectWIN"); - RESOLVED_PROC(x, y, width, height); -} diff --git a/xorg-server/hw/xwin/glx/glwindows.h b/xorg-server/hw/xwin/glx/glwindows.h index 177dcf1bb..42adc5b60 100644 --- a/xorg-server/hw/xwin/glx/glwindows.h +++ b/xorg-server/hw/xwin/glx/glwindows.h @@ -42,9 +42,12 @@ typedef struct { extern glxWinDebugSettingsRec glxWinDebugSettings; +void glWinCallDelta(void); void glxWinPushNativeProvider(void); -void glAddSwapHintRectWINWrapper(GLint x, GLint y, GLsizei width, GLsizei height); -int glWinSelectImplementation(int native); +const GLubyte *glGetStringWrapperNonstatic(GLenum name); +void glAddSwapHintRectWINWrapperNonstatic(GLint x, GLint y, GLsizei width, + GLsizei height); +void glWinSetupDispatchTable(void); #ifdef _DEBUG #ifdef _MSC_VER diff --git a/xorg-server/hw/xwin/glx/glthunk.c b/xorg-server/hw/xwin/glx/glwrap.c index 565b63465..9733e7526 100644 --- a/xorg-server/hw/xwin/glx/glthunk.c +++ b/xorg-server/hw/xwin/glx/glwrap.c @@ -1,8 +1,13 @@ /* - * File: glthunk.c - * Purpose: cdecl thunk wrapper library for Win32 stdcall OpenGL library + * File: glwrap.c + * Purpose: Wrapper functions for Win32 OpenGL functions + * + * Authors: Alexander Gottwald + * Jon TURNEY + * + * Copyright (c) Jon TURNEY 2009 + * Copyright (c) Alexander Gottwald 2004 * - * Copyright (c) Jon TURNEY 2009,2013 * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -32,15 +37,37 @@ #endif #include <X11/Xwindows.h> - -#define GL_GLEXT_LEGACY #include <GL/gl.h> -#undef GL_ARB_imaging -#undef GL_VERSION_1_3 #include <GL/glext.h> #include <glx/glheader.h> +#include <glx/glxserver.h> +#include <glx/glxext.h> +#include <glx/glapi.h> +#include <glx/dispatch.h> +#include <glwindows.h> #include <winmsg.h> + #ifdef _DEBUG +static unsigned int glWinIndirectProcCalls = 0; +static unsigned int glWinDirectProcCalls = 0; + +void +glWinCallDelta(void) +{ + static unsigned int glWinIndirectProcCallsLast = 0; + static unsigned int glWinDirectProcCallsLast = 0; + + if ((glWinIndirectProcCalls != glWinIndirectProcCallsLast) || + (glWinDirectProcCalls != glWinDirectProcCallsLast)) { + if (glxWinDebugSettings.enableTrace) { + ErrorF("after %d direct and %d indirect GL calls\n", + glWinDirectProcCalls - glWinDirectProcCallsLast, + glWinIndirectProcCalls - glWinIndirectProcCallsLast); + } + glWinDirectProcCallsLast = glWinDirectProcCalls; + glWinIndirectProcCallsLast = glWinIndirectProcCalls; + } +} #endif static PROC @@ -52,9 +79,11 @@ glWinResolveHelper(PROC * cache, const char *symbol) if ((*cache) == NULL) { proc = wglGetProcAddress(symbol); if (proc == NULL) { + winDebug("glwrap: Can't resolve \"%s\"\n", symbol); (*cache) = (PROC) - 1; } else { + winDebug("glwrap: Resolved \"%s\"\n", symbol); (*cache) = proc; } } @@ -80,8 +109,10 @@ glWinResolveHelper(PROC * cache, const char *symbol) static PROC cache = NULL; \ proctype proc = (proctype)glWinResolveHelper(&cache, symbol); \ if (proc == NULL) { \ + __glXErrorCallBack(0); \ return retval; \ - } + } \ + INCPROCCALLS #define RESOLVE(proctype, symbol) RESOLVE_RET(proctype, symbol,) @@ -92,6 +123,34 @@ glWinResolveHelper(PROC * cache, const char *symbol) OpenGL 1.2 and upward is treated as extensions, function address must found using wglGetProcAddress(), but also stdcall so still need wrappers... + + Include generated dispatch table setup function */ -#include "generated_gl_thunks.c" +#include "generated_gl_wrappers.c" + +/* + Special non-static wrapper for glGetString for debug output +*/ + +const GLubyte * +glGetStringWrapperNonstatic(GLenum name) +{ + return glGetString(name); +} + +/* + Special non-static wrapper for glAddSwapHintRectWIN for copySubBuffers +*/ + +typedef void (__stdcall * PFNGLADDSWAPHINTRECTWIN) (GLint x, GLint y, + GLsizei width, + GLsizei height); + +void +glAddSwapHintRectWINWrapperNonstatic(GLint x, GLint y, GLsizei width, + GLsizei height) +{ + RESOLVE(PFNGLADDSWAPHINTRECTWIN, "glAddSwapHintRectWIN"); + proc(x, y, width, height); +} diff --git a/xorg-server/hw/xwin/glx/indirect.c b/xorg-server/hw/xwin/glx/indirect.c index 605f975c0..495e366ca 100644 --- a/xorg-server/hw/xwin/glx/indirect.c +++ b/xorg-server/hw/xwin/glx/indirect.c @@ -601,9 +601,7 @@ glxWinScreenProbe(ScreenPtr pScreen) if (NULL == screen) return NULL; - // Select the native GL implementation (WGL) - if (glWinSelectImplementation(1)) - return NULL; + /* Dump out some useful information about the native renderer */ // create window class { @@ -652,12 +650,11 @@ glxWinScreenProbe(ScreenPtr pScreen) // (but we need to have a current context for them to be resolvable) wglResolveExtensionProcs(); - /* Dump out some useful information about the native renderer */ - winDebug("GL_VERSION: %s\n", glGetString(GL_VERSION)); - winDebug("GL_VENDOR: %s\n", glGetString(GL_VENDOR)); - gl_renderer = (const char *) glGetString(GL_RENDERER); + winDebug("GL_VERSION: %s\n", glGetStringWrapperNonstatic(GL_VERSION)); + winDebug("GL_VENDOR: %s\n", glGetStringWrapperNonstatic(GL_VENDOR)); + gl_renderer = (const char *) glGetStringWrapperNonstatic(GL_RENDERER); winDebug("GL_RENDERER: %s\n", gl_renderer); - gl_extensions = (const char *) glGetString(GL_EXTENSIONS); + gl_extensions = (const char *) glGetStringWrapperNonstatic(GL_EXTENSIONS); wgl_extensions = wglGetExtensionsStringARBWrapper(hdc); if (!wgl_extensions) wgl_extensions = ""; @@ -671,7 +668,7 @@ glxWinScreenProbe(ScreenPtr pScreen) free(screen); LogMessage(X_ERROR, "AIGLX: Won't use generic native renderer as it is not accelerated\n"); - goto error; + return NULL; } // Can you see the problem here? The extensions string is DC specific @@ -782,7 +779,7 @@ glxWinScreenProbe(ScreenPtr pScreen) free(screen); LogMessage(X_ERROR, "AIGLX: No fbConfigs could be made from native OpenGL pixel formats\n"); - goto error; + return NULL; } /* These will be set by __glXScreenInit */ @@ -851,13 +848,6 @@ glxWinScreenProbe(ScreenPtr pScreen) pScreen->DestroyWindow = glxWinDestroyWindow; return &screen->base; - - error: - // Something went wrong and we can't use the native GL implementation - // so make sure the mesa GL implementation is selected instead - glWinSelectImplementation(0); - - return NULL; } /* ---------------------------------------------------------------------- */ @@ -1047,7 +1037,7 @@ static void glxWinDrawableCopySubBuffer(__GLXdrawable * drawable, int x, int y, int w, int h) { - glAddSwapHintRectWINWrapper(x, y, w, h); + glAddSwapHintRectWINWrapperNonstatic(x, y, w, h); glxWinDrawableSwapBuffers(NULL, drawable); } @@ -1629,6 +1619,7 @@ glxWinContextMakeCurrent(__GLXcontext * base) #ifdef _DEBUG GLWIN_TRACE_MSG("glxWinContextMakeCurrent context %p (native ctx %p)", gc, gc->ctx); + glWinCallDelta(); #endif /* Keep a note of the last active context in the drawable */ @@ -1700,6 +1691,7 @@ glxWinContextLoseCurrent(__GLXcontext * base) #ifdef _DEBUG GLWIN_TRACE_MSG("glxWinContextLoseCurrent context %p (native ctx %p)", gc, gc->ctx); + glWinCallDelta(); #endif /* Clear the last active context in the drawable */ @@ -1813,6 +1805,8 @@ glxWinCreateContext(__GLXscreen * screen, context->Dispatch=calloc(sizeof(void*), (sizeof(struct _glapi_table) / sizeof(void *) + MAX_EXTENSION_FUNCS)); _glapi_set_dispatch(context->Dispatch); + glWinSetupDispatchTable(); + GLWIN_DEBUG_MSG("GLXcontext %p created", context); return &(context->base); |