aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/hw/xwin/glx
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/hw/xwin/glx')
-rw-r--r--xorg-server/hw/xwin/glx/Makefile.am32
-rwxr-xr-xxorg-server/hw/xwin/glx/gen_gl_wrappers.py472
-rw-r--r--xorg-server/hw/xwin/glx/glshim.c124
-rw-r--r--xorg-server/hw/xwin/glx/glthunk.c (renamed from xorg-server/hw/xwin/glx/glwrap.c)77
-rw-r--r--xorg-server/hw/xwin/glx/glwindows.h7
-rw-r--r--xorg-server/hw/xwin/glx/indirect.c30
-rw-r--r--[-rwxr-xr-x]xorg-server/hw/xwin/glx/makefile0
7 files changed, 449 insertions, 293 deletions
diff --git a/xorg-server/hw/xwin/glx/Makefile.am b/xorg-server/hw/xwin/glx/Makefile.am
index 067ee5b3c..f2dffbffb 100644
--- a/xorg-server/hw/xwin/glx/Makefile.am
+++ b/xorg-server/hw/xwin/glx/Makefile.am
@@ -1,14 +1,18 @@
noinst_LTLIBRARIES = libXwinGLX.la
+lib_LTLIBRARIES = libnativeGLthunk.la
libXwinGLX_la_SOURCES = \
winpriv.c \
winpriv.h \
glwindows.h \
- glwrap.c \
+ glshim.c \
indirect.c \
wgl_ext_api.c \
wgl_ext_api.h
+libnativeGLthunk_la_SOURCES = \
+ glthunk.c
+
if XWIN_MULTIWINDOW
DEFS_MULTIWINDOW = -DXWIN_MULTIWINDOW
endif
@@ -30,16 +34,32 @@ AM_CFLAGS = -DHAVE_XWIN_CONFIG_H $(DIX_CFLAGS) \
-I$(top_srcdir) \
-I$(top_srcdir)/hw/xwin/
+libnativeGLthunk_la_CFLAGS = $(AM_CFLAGS) -Wno-unused-function -Wno-missing-prototypes -Wno-missing-declarations
+libnativeGLthunk_la_LDFLAGS = -shared -no-undefined -avoid-version -lopengl32 -export-symbols generated_gl_thunks.def
+EXTRA_libnativeGLthunk_la_DEPENDENCIES = generated_gl_thunks.def
+
if XWIN_GLX_WINDOWS
-generated_gl_wrappers.c: gen_gl_wrappers.py $(KHRONOS_SPEC_DIR)/gl.spec $(KHRONOS_SPEC_DIR)/gl.tm
- $(AM_V_GEN)$(PYTHON) $(srcdir)/gen_gl_wrappers.py --spec=$(KHRONOS_SPEC_DIR)/gl.spec --typemap=$(KHRONOS_SPEC_DIR)/gl.tm --dispatch-header=$(top_srcdir)/glx/dispatch.h --staticwrappers >generated_gl_wrappers.c
+if DEBUG
+GENGLWRAPPERSOPTS=""
+else
+GENGLWRAPPERSOPTS="-nodebug"
+endif
+
+generated_wgl_wrappers.c: $(srcdir)/gen_gl_wrappers.py $(KHRONOS_SPEC_DIR)/wgl.xml $(KHRONOS_SPEC_DIR)/reg.py
+ $(AM_V_GEN)PYTHONPATH=$(KHRONOS_SPEC_DIR) $(PYTHON3) $(srcdir)/gen_gl_wrappers.py -registry $(KHRONOS_SPEC_DIR)/wgl.xml -prefix wgl -wrapper -preresolve $(GENGLWRAPPERSOPTS) -outfile $@
+
+generated_gl_shim.c: $(srcdir)/gen_gl_wrappers.py $(KHRONOS_SPEC_DIR)/gl.xml $(KHRONOS_SPEC_DIR)/reg.py
+ $(AM_V_GEN)PYTHONPATH=$(KHRONOS_SPEC_DIR) $(PYTHON3) $(srcdir)/gen_gl_wrappers.py -registry $(KHRONOS_SPEC_DIR)/gl.xml -shim $(GENGLWRAPPERSOPTS) -outfile $@
+
+generated_gl_thunks.c: $(srcdir)/gen_gl_wrappers.py $(KHRONOS_SPEC_DIR)/gl.xml $(KHRONOS_SPEC_DIR)/reg.py
+ $(AM_V_GEN)PYTHONPATH=$(KHRONOS_SPEC_DIR) $(PYTHON3) $(srcdir)/gen_gl_wrappers.py -registry $(KHRONOS_SPEC_DIR)/gl.xml -thunk $(GENGLWRAPPERSOPTS) -outfile $@
-generated_wgl_wrappers.c: gen_gl_wrappers.py $(KHRONOS_SPEC_DIR)/wglext.spec $(KHRONOS_SPEC_DIR)/wgl.tm
- $(AM_V_GEN)$(PYTHON) $(srcdir)/gen_gl_wrappers.py --spec=$(KHRONOS_SPEC_DIR)/wglext.spec --typemap=$(KHRONOS_SPEC_DIR)/wgl.tm --prefix=wgl --preresolve >generated_wgl_wrappers.c
+generated_gl_thunks.def: $(srcdir)/gen_gl_wrappers.py $(KHRONOS_SPEC_DIR)/gl.xml $(KHRONOS_SPEC_DIR)/reg.py
+ $(AM_V_GEN)PYTHONPATH=$(KHRONOS_SPEC_DIR) $(PYTHON3) $(srcdir)/gen_gl_wrappers.py -registry $(KHRONOS_SPEC_DIR)/gl.xml -thunkdefs $(GENGLWRAPPERSOPTS) -outfile $@
endif
-BUILT_SOURCES = generated_gl_wrappers.c generated_wgl_wrappers.c
+BUILT_SOURCES = generated_gl_shim.c generated_gl_thunks.c generated_gl_thunks.def generated_wgl_wrappers.c
CLEANFILES = $(BUILT_SOURCES)
EXTRA_DIST = gen_gl_wrappers.py
diff --git a/xorg-server/hw/xwin/glx/gen_gl_wrappers.py b/xorg-server/hw/xwin/glx/gen_gl_wrappers.py
index e5fa57142..683b9d903 100755
--- a/xorg-server/hw/xwin/glx/gen_gl_wrappers.py
+++ b/xorg-server/hw/xwin/glx/gen_gl_wrappers.py
@@ -1,5 +1,8 @@
#!/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
@@ -24,30 +27,23 @@
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'
-dispatchheader=None
+
+protect=True
prefix="gl"
preresolve=False
+wrapper=False
+shim=False
+thunk=False
+thunkdefs=False
staticwrappers=False
-nodebugcallcounting=False
+nodebug=False
+#exclude base WGL API
WinGDI={key: 1 for key in [
"wglCopyContext"
,"wglCreateContext"
@@ -83,110 +79,45 @@ if __name__ == '__main__':
while (i < len(sys.argv)):
arg = sys.argv[i]
i = i + 1
- 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'):
+ if (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)
- 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
+ print('Using registry', regFilename, file=sys.stderr)
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 == '-nodbgcount'):
- nodebugcallcounting = True
+ elif (arg == '-nodebug'):
+ nodebug = True
elif (arg[0:1] == '-'):
print('Unrecognized argument:', arg, file=sys.stderr)
exit(1)
-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
+
+print('Generating', outFilename, file=sys.stderr)
# Load & parse registry
reg = Registry()
-
-startTimer()
tree = etree.parse(regFilename)
-endTimer('Time to make ElementTree =')
-
-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
+
+allVersions = '.*'
genOpts = CGeneratorOptions(
apiname = prefix,
@@ -194,16 +125,9 @@ genOpts = CGeneratorOptions(
versions = allVersions,
emitversions = allVersions,
defaultExtensions = prefix, # Default extensions for GL
-# addExtensions = None,
-# removeExtensions = None,
-# prefixText = prefixStrings + glExtPlatformStrings + glextVersionStrings,
-# genFuncPointers = True,
-# protectFile = protectFile,
-# protectFeature = protectFeature,
-# protectProto = protectProto,
-# apicall = 'GLAPI ',
-# apientry = 'APIENTRY ',
-# apientryp = 'APIENTRYP '),
+ protectFile = protect,
+ protectFeature = protect,
+ protectProto = protect,
)
# create error/warning & diagnostic files
@@ -213,28 +137,6 @@ 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,
@@ -243,7 +145,7 @@ class PreResolveOutputGenerator(OutputGenerator):
OutputGenerator.__init__(self, errFile, warnFile, diagFile)
self.wrappers={}
def beginFile(self, genOpts):
- pass
+ self.outFile.write('/* Automatically generated from %s - DO NOT EDIT */\n\n'%regFilename)
def endFile(self):
self.outFile.write('\nvoid ' + prefix + 'ResolveExtensionProcs(void)\n{\n')
for funcname in self.wrappers.keys():
@@ -251,7 +153,6 @@ 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):
@@ -260,21 +161,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 MyOutputGenerator(OutputGenerator):
+class WrapperOutputGenerator(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):
- pass
+ self.outFile.write('/* Automatically generated from %s - DO NOT EDIT */\n\n'%regFilename)
def endFile(self):
pass
def beginFeature(self, interface, emit):
@@ -288,26 +189,18 @@ class MyOutputGenerator(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])
- #ptype=proto.find("ptype")
- #if ptype!=None:
- # rettype = (noneStr(ptype.text))+" "
+ rettype=rettype.strip()
if staticwrappers: self.outFile.write("static ")
- self.outFile.write("%s__stdcall %sWrapper("%(rettype, name))
+ self.outFile.write("%s %sWrapper("%(rettype, name))
params = cmd.elem.findall('param')
plist=[]
for param in params:
@@ -322,55 +215,230 @@ class MyOutputGenerator(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 nodebugcallcounting:
- self.outFile.write(")\n{\n")
+ 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))
else:
- self.outFile.write( """)
-{
-#ifdef _DEBUG
- if (glxWinDebugSettings.enable%scallTrace) ErrorF("%s\\n");
- glWinDirectProcCalls++;
-#endif
-"""%(prefix.upper(), name))
- if rettype.lower()=="void ":
+ 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(" %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");"""%(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()))
+ if rettype.lower()=="void":
+ self.outFile.write(' RESOLVE(PFN%sPROC, "%s");\n'%(name.upper(), name))
+ self.outFile.write(" RESOLVED_PROC(PFN%sPROC)( """%(name.upper()))
else:
- 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()))
+ self.outFile.write(' RESOLVE_RET(PFN%sPROC, "%s", FALSE);\n'%(name.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,
@@ -378,40 +446,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)
- # 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 dispatchheader :
- outFile.write( 'void glWinSetupDispatchTable(void)\n')
- outFile.write( '{\n')
- outFile.write( ' struct _glapi_table *disp = _glapi_get_dispatch();\n')
+ if wrapper:
+ gen = WrapperOutputGenerator(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')
+ if shim:
+ gen = ShimOutputGenerator(errFile=errWarn,
+ warnFile=errWarn,
+ diagFile=diag)
+ gen.outFile=outFile
+ reg.setGenerator(gen)
+ reg.apiGen(genOpts)
- outFile.write('}\n')
+ if thunk:
+ gen = ThunkOutputGenerator(errFile=errWarn,
+ warnFile=errWarn,
+ diagFile=diag)
+ gen.outFile=outFile
+ reg.setGenerator(gen)
+ reg.apiGen(genOpts)
+ if thunkdefs:
+ gen = ThunkDefsOutputGenerator(errFile=errWarn,
+ warnFile=errWarn,
+ diagFile=diag)
+ gen.outFile=outFile
+ reg.setGenerator(gen)
+ reg.apiGen(genOpts)
outFile.close()
-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()
+genHeaders()
diff --git a/xorg-server/hw/xwin/glx/glshim.c b/xorg-server/hw/xwin/glx/glshim.c
new file mode 100644
index 000000000..7109196c0
--- /dev/null
+++ b/xorg-server/hw/xwin/glx/glshim.c
@@ -0,0 +1,124 @@
+/*
+ * 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/glwrap.c b/xorg-server/hw/xwin/glx/glthunk.c
index 9733e7526..565b63465 100644
--- a/xorg-server/hw/xwin/glx/glwrap.c
+++ b/xorg-server/hw/xwin/glx/glthunk.c
@@ -1,13 +1,8 @@
/*
- * 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
+ * File: glthunk.c
+ * Purpose: cdecl thunk wrapper library for Win32 stdcall OpenGL library
*
+ * 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"),
@@ -37,37 +32,15 @@
#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
@@ -79,11 +52,9 @@ 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;
}
}
@@ -109,10 +80,8 @@ 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,)
@@ -123,34 +92,6 @@ 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_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);
-}
+#include "generated_gl_thunks.c"
diff --git a/xorg-server/hw/xwin/glx/glwindows.h b/xorg-server/hw/xwin/glx/glwindows.h
index 42adc5b60..177dcf1bb 100644
--- a/xorg-server/hw/xwin/glx/glwindows.h
+++ b/xorg-server/hw/xwin/glx/glwindows.h
@@ -42,12 +42,9 @@ typedef struct {
extern glxWinDebugSettingsRec glxWinDebugSettings;
-void glWinCallDelta(void);
void glxWinPushNativeProvider(void);
-const GLubyte *glGetStringWrapperNonstatic(GLenum name);
-void glAddSwapHintRectWINWrapperNonstatic(GLint x, GLint y, GLsizei width,
- GLsizei height);
-void glWinSetupDispatchTable(void);
+void glAddSwapHintRectWINWrapper(GLint x, GLint y, GLsizei width, GLsizei height);
+int glWinSelectImplementation(int native);
#ifdef _DEBUG
#ifdef _MSC_VER
diff --git a/xorg-server/hw/xwin/glx/indirect.c b/xorg-server/hw/xwin/glx/indirect.c
index 495e366ca..605f975c0 100644
--- a/xorg-server/hw/xwin/glx/indirect.c
+++ b/xorg-server/hw/xwin/glx/indirect.c
@@ -601,7 +601,9 @@ glxWinScreenProbe(ScreenPtr pScreen)
if (NULL == screen)
return NULL;
- /* Dump out some useful information about the native renderer */
+ // Select the native GL implementation (WGL)
+ if (glWinSelectImplementation(1))
+ return NULL;
// create window class
{
@@ -650,11 +652,12 @@ glxWinScreenProbe(ScreenPtr pScreen)
// (but we need to have a current context for them to be resolvable)
wglResolveExtensionProcs();
- winDebug("GL_VERSION: %s\n", glGetStringWrapperNonstatic(GL_VERSION));
- winDebug("GL_VENDOR: %s\n", glGetStringWrapperNonstatic(GL_VENDOR));
- gl_renderer = (const char *) glGetStringWrapperNonstatic(GL_RENDERER);
+ /* 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_RENDERER: %s\n", gl_renderer);
- gl_extensions = (const char *) glGetStringWrapperNonstatic(GL_EXTENSIONS);
+ gl_extensions = (const char *) glGetString(GL_EXTENSIONS);
wgl_extensions = wglGetExtensionsStringARBWrapper(hdc);
if (!wgl_extensions)
wgl_extensions = "";
@@ -668,7 +671,7 @@ glxWinScreenProbe(ScreenPtr pScreen)
free(screen);
LogMessage(X_ERROR,
"AIGLX: Won't use generic native renderer as it is not accelerated\n");
- return NULL;
+ goto error;
}
// Can you see the problem here? The extensions string is DC specific
@@ -779,7 +782,7 @@ glxWinScreenProbe(ScreenPtr pScreen)
free(screen);
LogMessage(X_ERROR,
"AIGLX: No fbConfigs could be made from native OpenGL pixel formats\n");
- return NULL;
+ goto error;
}
/* These will be set by __glXScreenInit */
@@ -848,6 +851,13 @@ 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;
}
/* ---------------------------------------------------------------------- */
@@ -1037,7 +1047,7 @@ static void
glxWinDrawableCopySubBuffer(__GLXdrawable * drawable,
int x, int y, int w, int h)
{
- glAddSwapHintRectWINWrapperNonstatic(x, y, w, h);
+ glAddSwapHintRectWINWrapper(x, y, w, h);
glxWinDrawableSwapBuffers(NULL, drawable);
}
@@ -1619,7 +1629,6 @@ 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 */
@@ -1691,7 +1700,6 @@ 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 */
@@ -1805,8 +1813,6 @@ 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);
diff --git a/xorg-server/hw/xwin/glx/makefile b/xorg-server/hw/xwin/glx/makefile
index 3b0413312..3b0413312 100755..100644
--- a/xorg-server/hw/xwin/glx/makefile
+++ b/xorg-server/hw/xwin/glx/makefile