From bb770af3a59e5935c108c05ee45490fc5668d4a3 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Fri, 14 Jan 2011 17:50:29 +0800 Subject: [PATCH] scons: Add support for GLES. GLES can be enabled by running scons with $ scons gles=yes When gles=yes is given, the build is changed in three ways. First, libmesa.a will be built with FEATURE_ES1 and FEATURE_ES2. This makes DRI drivers and libEGL support and advertise GLES support. Second, GLES libraries will be created. They are libGLESv1_CM, libGLESv2, and libglapi. Last, libGL or opengl32 will link to libglapi. This change is required as _glapi_* will be declared as __declspec(dllimport) in libmesa.a on windows. libmesa.a expects those symbols to be defined in another DLL. Due to this change to GL, GLES support is marked experimental. Note that GLES requires libxml2-python to generate some of its sources. --- SConstruct | 6 + common.py | 1 + src/SConscript | 7 ++ src/gallium/state_trackers/wgl/SConscript | 3 + src/gallium/state_trackers/wgl/stw_device.c | 3 + src/gallium/targets/egl-static/SConscript | 16 ++- src/gallium/targets/libgl-gdi/SConscript | 6 + src/gallium/targets/libgl-xlib/SConscript | 6 + src/mapi/glapi/SConscript | 5 + src/mapi/glapi/glapi.h | 5 - src/mapi/shared-glapi/SConscript | 116 ++++++++++++++++++++ src/mesa/SConscript | 63 +++++++++++ 12 files changed, 228 insertions(+), 9 deletions(-) create mode 100644 src/mapi/shared-glapi/SConscript diff --git a/SConstruct b/SConstruct index 368ad83edf3..a2c20471f7a 100644 --- a/SConstruct +++ b/SConstruct @@ -56,6 +56,12 @@ else: Help(opts.GenerateHelpText(env)) +# fail early for a common error on windows +if env['gles']: + try: + import libxml2 + except ImportError: + raise SCons.Errors.UserError, "GLES requires libxml2-python to build" ####################################################################### # Environment setup diff --git a/common.py b/common.py index 76184d577a3..cbb61629d27 100644 --- a/common.py +++ b/common.py @@ -90,6 +90,7 @@ def AddOptions(opts): opts.Add(EnumOption('platform', 'target platform', host_platform, allowed_values=('linux', 'cell', 'windows', 'winddk', 'wince', 'darwin', 'embedded', 'cygwin', 'sunos5', 'freebsd8'))) opts.Add('toolchain', 'compiler toolchain', default_toolchain) + opts.Add(BoolOption('gles', 'EXPERIMENTAL: enable OpenGL ES support', 'no')) opts.Add(BoolOption('llvm', 'use LLVM', default_llvm)) opts.Add(BoolOption('debug', 'DEPRECATED: debug build', 'yes')) opts.Add(BoolOption('profile', 'DEPRECATED: profile build', 'no')) diff --git a/src/SConscript b/src/SConscript index 201812c5ac3..06c6f94bf0c 100644 --- a/src/SConscript +++ b/src/SConscript @@ -8,6 +8,10 @@ else: Export('talloc') SConscript('glsl/SConscript') +# When env['gles'] is set, the targets defined in mapi/glapi/SConscript are not +# used. libgl-xlib and libgl-gdi adapt themselves to use the targets defined +# in mapi/glapi-shared/SConscript. mesa/SConscript also adapts itself to +# enable OpenGL ES support. SConscript('mapi/glapi/SConscript') SConscript('mesa/SConscript') @@ -17,5 +21,8 @@ if env['platform'] != 'embedded': SConscript('egl/main/SConscript') SConscript('glut/glx/SConscript') + if env['gles']: + SConscript('mapi/shared-glapi/SConscript') + SConscript('gallium/SConscript') diff --git a/src/gallium/state_trackers/wgl/SConscript b/src/gallium/state_trackers/wgl/SConscript index 1b7597de440..7cb953ba742 100644 --- a/src/gallium/state_trackers/wgl/SConscript +++ b/src/gallium/state_trackers/wgl/SConscript @@ -15,6 +15,9 @@ env.AppendUnique(CPPDEFINES = [ 'BUILD_GL32', # declare gl* as __declspec(dllexport) in Mesa headers 'WIN32_LEAN_AND_MEAN', # http://msdn2.microsoft.com/en-us/library/6dwk3a1z.aspx ]) +if not env['gles']: + # prevent _glapi_* from being declared __declspec(dllimport) + env.Append(CPPDEFINES = ['_GLAPI_NO_EXPORTS']) sources = [ 'stw_context.c', diff --git a/src/gallium/state_trackers/wgl/stw_device.c b/src/gallium/state_trackers/wgl/stw_device.c index c4822d4d8aa..4ece4e4979a 100644 --- a/src/gallium/state_trackers/wgl/stw_device.c +++ b/src/gallium/state_trackers/wgl/stw_device.c @@ -170,7 +170,10 @@ stw_cleanup(void) _glthread_DESTROY_MUTEX(OneTimeLock); + /* glapi is statically linked: we can call the local destroy function. */ +#ifdef _GLAPI_NO_EXPORTS _glapi_destroy_multithread(); +#endif #ifdef DEBUG debug_memory_end(stw_dev->memdbg_no); diff --git a/src/gallium/targets/egl-static/SConscript b/src/gallium/targets/egl-static/SConscript index 381ef4e862d..c978934a0c8 100644 --- a/src/gallium/targets/egl-static/SConscript +++ b/src/gallium/targets/egl-static/SConscript @@ -58,10 +58,18 @@ if env['platform'] == 'windows': env.Prepend(LIBS = [ ws_gdi, ]) -else: - # OpenGL - env.Append(CPPDEFINES = ['FEATURE_GL=1']) - env.Prepend(LIBS = ['GL', 'talloc', glsl, mesa]) + +# OpenGL ES and OpenGL +if env['gles']: + env.Append(CPPDEFINES = [ + 'FEATURE_GL=1', + 'FEATURE_ES1=1', + 'FEATURE_ES2=1' + ]) + env.Prepend(LIBPATH = [shared_glapi.dir]) + # manually add LIBPREFIX on windows + glapi_name = 'glapi' if env['platform'] != 'windows' else 'libglapi' + env.Prepend(LIBS = [glapi_name, talloc, glsl, mesa]) # OpenVG if True: diff --git a/src/gallium/targets/libgl-gdi/SConscript b/src/gallium/targets/libgl-gdi/SConscript index 6fa0851a1ab..c088d4c2ae6 100644 --- a/src/gallium/targets/libgl-gdi/SConscript +++ b/src/gallium/targets/libgl-gdi/SConscript @@ -37,6 +37,12 @@ drivers += [trace, rbug] env['no_import_lib'] = 1 +# when GLES is enabled, gl* and _glapi_* belong to bridge_glapi and +# shared_glapi respectively +if env['gles']: + env.Prepend(LIBPATH = [shared_glapi.dir]) + glapi = [bridge_glapi, 'libglapi'] + opengl32 = env.SharedLibrary( target ='opengl32', source = sources, diff --git a/src/gallium/targets/libgl-xlib/SConscript b/src/gallium/targets/libgl-xlib/SConscript index d932736be78..9bb0a56525e 100644 --- a/src/gallium/targets/libgl-xlib/SConscript +++ b/src/gallium/targets/libgl-xlib/SConscript @@ -16,6 +16,12 @@ env.Append(CPPDEFINES = ['USE_XSHM']) env.Prepend(LIBS = env['X11_LIBS']) +# when GLES is enabled, gl* and _glapi_* belong to bridge_glapi and +# shared_glapi respectively +if env['gles']: + env.Prepend(LIBPATH = [shared_glapi.dir]) + glapi = [bridge_glapi, 'glapi'] + env.Prepend(LIBS = [ st_xlib, ws_xlib, diff --git a/src/mapi/glapi/SConscript b/src/mapi/glapi/SConscript index 4057991ec8d..276b2160246 100644 --- a/src/mapi/glapi/SConscript +++ b/src/mapi/glapi/SConscript @@ -17,6 +17,11 @@ if env['platform'] != 'winddk': '_GDI32_', # prevent gl* being declared __declspec(dllimport) in MS headers 'BUILD_GL32', # declare gl* as __declspec(dllexport) in Mesa headers ]) + if env['gles']: + env.Append(CPPDEFINES = ['_GLAPI_DLL_EXPORTS']) + else: + # prevent _glapi_* from being declared __declspec(dllimport) + env.Append(CPPDEFINES = ['_GLAPI_NO_EXPORTS']) env.Append(CPPPATH = [ '#/src/mapi', diff --git a/src/mapi/glapi/glapi.h b/src/mapi/glapi/glapi.h index 8cca50487c4..e909cf892ab 100644 --- a/src/mapi/glapi/glapi.h +++ b/src/mapi/glapi/glapi.h @@ -45,11 +45,6 @@ #define _GLAPI_H -/* opengl.dll does not export _glapi_* */ -#if defined(_WIN32) -#define _GLAPI_NO_EXPORTS -#endif - #ifdef _GLAPI_NO_EXPORTS # define _GLAPI_EXPORT #else /* _GLAPI_NO_EXPORTS */ diff --git a/src/mapi/shared-glapi/SConscript b/src/mapi/shared-glapi/SConscript new file mode 100644 index 00000000000..b7c43a73476 --- /dev/null +++ b/src/mapi/shared-glapi/SConscript @@ -0,0 +1,116 @@ +####################################################################### +# SConscript for shared-glapi/es1api/es2api + +from sys import executable as python_cmd + +Import('*') + +def mapi_objects(env, printer, mode): + """Return mapi objects built for the given printer and mode.""" + mapi_sources = { + 'glapi': ['entry.c', 'mapi_glapi.c', 'stub.c', 'table.c', + 'u_current.c', 'u_execmem.c', 'u_thread.c'], + 'bridge': ['entry.c'], + } + mapi_defines = { + 'glapi': ['MAPI_MODE_GLAPI'], + 'bridge': ['MAPI_MODE_BRIDGE'], + } + + header_name = '%s-tmp.h' % (printer) + + # generate ABI header + header = env.CodeGenerate( + target = header_name, + script = '../mapi/mapi_abi.py', + source = '../glapi/gen/gl_and_es_API.xml', + command = python_cmd + ' $SCRIPT ' + \ + '--printer %s --mode lib $SOURCE > $TARGET' % (printer), + ) + + cpppath = [ + header[0].dir, + '#/include', + '#/src/mapi', + ] + + cppdefines = mapi_defines[mode] + [ + 'MAPI_ABI_HEADER=\\"%s\\"' % (header_name), + ] + + if env['platform'] == 'windows': + if mode == 'glapi': + cppdefines += [ + '_GLAPI_DLL_EXPORTS', # declare _glapi_* as __declspec(dllexport) in glapi.h + ] + else: + cppdefines += [ + '_GDI32_', # prevent gl* being declared __declspec(dllimport) in MS headers + 'BUILD_GL32', # declare gl* as __declspec(dllexport) in Mesa headers + ] + + objects = [] + for s in mapi_sources[mode]: + o = env.SharedObject( + target = '%s-%s' % (printer, s[:-2]), + source = '../mapi/' + s, + CPPPATH = cpppath, + CPPDEFINES = cppdefines, + ) + objects.append(o[0]) + + env.Depends(objects, header) + + return objects + +if env['platform'] != 'winddk': + env = env.Clone() + + env['SHLIBPREFIX'] = 'lib' + env['LIBPREFIX'] = 'lib' + + shared_glapi_objects = mapi_objects(env, 'shared-glapi', 'glapi') + shared_glapi = env.SharedLibrary( + target = 'glapi', + source = shared_glapi_objects, + ) + + # manually add LIBPREFIX on windows + if env['platform'] == 'windows': + libs = ['libglapi'] + else: + libs = ['glapi'] + + es1api_objects = mapi_objects(env, 'es1api', 'bridge') + es1api = env.SharedLibrary( + target = 'GLESv1_CM', + source = es1api_objects, + LIBPATH = ['.'], + LIBS = libs, + ) + + es2api_objects = mapi_objects(env, 'es2api', 'bridge') + es2api = env.SharedLibrary( + target = 'GLESv2', + source = es2api_objects, + LIBPATH = ['.'], + LIBS = libs, + ) + + env.InstallSharedLibrary(shared_glapi, version=(0, 0, 0)) + env.InstallSharedLibrary(es1api, version=(1, 0, 0)) + env.InstallSharedLibrary(es2api, version=(2, 0, 0)) + + if env['platform'] == 'windows': + shared_glapi = env.FindIxes(shared_glapi, 'LIBPREFIX', 'LIBSUFFIX') + else: + shared_glapi = env.FindIxes(shared_glapi, 'SHLIBPREFIX', 'SHLIBSUFFIX') + + # build glapi bridge as a convenience libarary for libgl-xlib/libgl-gdi + bridge_glapi_objects = mapi_objects(env, 'glapi', 'bridge') + bridge_glapi = env.ConvenienceLibrary( + target = 'glapi_bridge', + source = bridge_glapi_objects, + ) + + Export(['shared_glapi', 'bridge_glapi']) diff --git a/src/mesa/SConscript b/src/mesa/SConscript index cc4ad09fa33..7c7c7c37c83 100644 --- a/src/mesa/SConscript +++ b/src/mesa/SConscript @@ -12,11 +12,19 @@ env.Append(CPPPATH = [ '#/src/mesa', ]) +env.Append(CPPDEFINES = [ + 'FEATURE_GL=1', +]) + if env['platform'] == 'windows': env.Append(CPPDEFINES = [ '_GDI32_', # prevent gl* being declared __declspec(dllimport) in MS headers 'BUILD_GL32', # declare gl* as __declspec(dllexport) in Mesa headers ]) + if not env['gles']: + # prevent _glapi_* from being declared __declspec(dllimport) + env.Append(CPPDEFINES = ['_GLAPI_NO_EXPORTS']) + env.Prepend(CPPPATH = ['#src/talloc']) else: env.Append(CPPDEFINES = [ @@ -240,6 +248,61 @@ mesa_sources = ( statetracker_sources ) +if env['gles']: + from sys import executable as python_cmd + + env.Append(CPPDEFINES = ['FEATURE_ES1=1', 'FEATURE_ES2=1']) + + # generate GLES sources + gles_sources = [] + gles_sources += env.CodeGenerate( + target = 'main/api_exec_es1.c', + script = 'main/es_generator.py', + source = 'main/APIspec.xml', + command = python_cmd + ' $SCRIPT -S $SOURCE -V GLES1.1 > $TARGET' + ) + gles_sources += env.CodeGenerate( + target = 'main/api_exec_es2.c', + script = 'main/es_generator.py', + source = 'main/APIspec.xml', + command = python_cmd + ' $SCRIPT -S $SOURCE -V GLES2.0 > $TARGET' + ) + + # generate GLES headers + GLAPI = '#src/mapi/glapi/' + gles_headers = [] + gles_headers += env.CodeGenerate( + target = 'es1api/main/glapidispatch.h', + script = GLAPI + 'gen/gl_table.py', + source = GLAPI + 'gen-es/es1_API.xml', + command = python_cmd + ' $SCRIPT -c -m remap_table -f $SOURCE > $TARGET', + ) + gles_headers += env.CodeGenerate( + target = 'es1api/main/remap_helper.h', + script = GLAPI + 'gen/remap_helper.py', + source = GLAPI + 'gen-es/es1_API.xml', + command = python_cmd + ' $SCRIPT -f $SOURCE > $TARGET', + ) + gles_headers += env.CodeGenerate( + target = 'es2api/main/glapidispatch.h', + script = GLAPI + 'gen/gl_table.py', + source = GLAPI + 'gen-es/es2_API.xml', + command = python_cmd + ' $SCRIPT -c -m remap_table -f $SOURCE > $TARGET', + ) + gles_headers += env.CodeGenerate( + target = 'es2api/main/remap_helper.h', + script = GLAPI + 'gen/remap_helper.py', + source = GLAPI + 'gen-es/es2_API.xml', + command = python_cmd + ' $SCRIPT -f $SOURCE > $TARGET', + ) + + env.Depends(gles_sources, gles_headers) + + # gles_sources #include gles_headers with full path + env.Append(CPPPATH = [gles_headers[0].dir.up().up()]) + + mesa_sources += gles_sources + # # Assembly sources # -- 2.30.2