BUILT_SOURCES = api_tmp.h
CLEANFILES = api_tmp.h
-api_tmp.h: $(top_srcdir)/src/mapi/vgapi/vgapi.csv $(top_srcdir)/src/mapi/mapi/mapi_abi.py
- $(AM_V_GEN) $(PYTHON2) $(PYTHON_FLAGS) $(top_srcdir)/src/mapi/mapi/mapi_abi.py \
+api_tmp.h: $(top_srcdir)/src/mapi/vgapi/vgapi.csv $(top_srcdir)/src/mapi/mapi_abi.py
+ $(AM_V_GEN) $(PYTHON2) $(PYTHON_FLAGS) $(top_srcdir)/src/mapi/mapi_abi.py \
--printer vgapi --mode app $< > $@
api_tmp, = env.CodeGenerate(
target = 'api_tmp.h',
- script = '#src/mapi/mapi/mapi_abi.py',
+ script = '#src/mapi/mapi_abi.py',
source = '#src/mapi/vgapi/vgapi.csv',
command = python_cmd + ' $SCRIPT --printer vgapi --mode app $SOURCE > $TARGET'
)
* Chia-I Wu <olv@lunarg.com>
*/
-#include "mapi/mapi.h"
+#include "mapi.h"
/* define vega_spec and vega_procs for use with mapi */
#define API_TMP_DEFINE_SPEC
abi_header := shared-glapi/glapi_mapi_tmp.h
LOCAL_SRC_FILES := \
- mapi/entry.c \
- mapi/mapi_glapi.c \
- mapi/stub.c \
- mapi/table.c \
- mapi/u_current.c \
- mapi/u_execmem.c
+ entry.c \
+ mapi_glapi.c \
+ stub.c \
+ table.c \
+ u_current.c \
+ u_execmem.c
LOCAL_CFLAGS := \
-DMAPI_MODE_GLAPI \
mapi_abi_deps := \
$(wildcard $(LOCAL_PATH)/glapi/gen/*.py) \
$(wildcard $(LOCAL_PATH)/glapi/gen/*.xml) \
- $(LOCAL_PATH)/mapi/mapi_abi.py
+ $(LOCAL_PATH)/mapi_abi.py
-$(mapi_abi_headers): PRIVATE_SCRIPT := $(MESA_PYTHON2) $(LOCAL_PATH)/mapi/mapi_abi.py
+$(mapi_abi_headers): PRIVATE_SCRIPT := $(MESA_PYTHON2) $(LOCAL_PATH)/mapi_abi.py
$(mapi_abi_headers): PRIVATE_APIXML := $(LOCAL_PATH)/glapi/gen/gl_and_es_API.xml
$(mapi_abi_headers): $(mapi_abi_deps)
@mkdir -p $(dir $@)
--- /dev/null
+# src/mapi/Makefile.sources
+#
+# mapi may be used in several ways
+#
+# - In default mode, mapi implements the interface defined by mapi.h. To use
+# this mode, compile MAPI_FILES.
+#
+# - In util mode, mapi provides utility functions for use with glapi. To use
+# this mode, compile MAPI_UTIL_FILES with MAPI_MODE_UTIL defined.
+#
+# - In glapi mode, mapi implements the interface defined by glapi.h. To use
+# this mode, compile MAPI_GLAPI_FILES with MAPI_MODE_GLAPI defined.
+#
+# - In bridge mode, mapi provides entry points calling into glapi. To use
+# this mode, compile MAPI_BRIDGE_FILES with MAPI_MODE_BRIDGE defined.
+
+MAPI_UTIL_FILES = \
+ $(TOP)/src/mapi/u_current.c \
+ $(TOP)/src/mapi/u_execmem.c
+
+MAPI_FILES = \
+ $(TOP)/src/mapi/entry.c \
+ $(TOP)/src/mapi/mapi.c \
+ $(TOP)/src/mapi/stub.c \
+ $(TOP)/src/mapi/table.c \
+ $(MAPI_UTIL_FILES)
+
+MAPI_GLAPI_FILES = \
+ $(TOP)/src/mapi/entry.c \
+ $(TOP)/src/mapi/mapi_glapi.c \
+ $(TOP)/src/mapi/stub.c \
+ $(TOP)/src/mapi/table.c \
+ $(MAPI_UTIL_FILES)
+
+MAPI_BRIDGE_FILES = \
+ $(TOP)/src/mapi/entry.c
--- /dev/null
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.9
+ *
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS 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.
+ *
+ * Authors:
+ * Chia-I Wu <olv@lunarg.com>
+ */
+
+#include "entry.h"
+#include "u_current.h"
+#include "u_macros.h"
+
+/* define macros for use by assembly dispatchers */
+#define ENTRY_CURRENT_TABLE U_STRINGIFY(u_current_table)
+
+/* in bridge mode, mapi is a user of glapi */
+#ifdef MAPI_MODE_BRIDGE
+#define ENTRY_CURRENT_TABLE_GET "_glapi_get_dispatch"
+#else
+#define ENTRY_CURRENT_TABLE_GET U_STRINGIFY(u_current_get_internal)
+#endif
+
+#if defined(USE_X86_ASM) && defined(__GNUC__)
+# ifdef GLX_USE_TLS
+# include "entry_x86_tls.h"
+# else
+# include "entry_x86_tsd.h"
+# endif
+#elif defined(USE_X86_64_ASM) && defined(__GNUC__) && defined(GLX_USE_TLS)
+# include "entry_x86-64_tls.h"
+#else
+
+#include <stdlib.h>
+
+static INLINE const struct mapi_table *
+entry_current_get(void)
+{
+#ifdef MAPI_MODE_BRIDGE
+ return GET_DISPATCH();
+#else
+ return u_current_get();
+#endif
+}
+
+/* C version of the public entries */
+#define MAPI_TMP_DEFINES
+#define MAPI_TMP_PUBLIC_DECLARES
+#define MAPI_TMP_PUBLIC_ENTRIES
+#include "mapi_tmp.h"
+
+#ifndef MAPI_MODE_BRIDGE
+
+void
+entry_patch_public(void)
+{
+}
+
+mapi_func
+entry_get_public(int slot)
+{
+ /* pubic_entries are defined by MAPI_TMP_PUBLIC_ENTRIES */
+ return public_entries[slot];
+}
+
+mapi_func
+entry_generate(int slot)
+{
+ return NULL;
+}
+
+void
+entry_patch(mapi_func entry, int slot)
+{
+}
+
+#endif /* MAPI_MODE_BRIDGE */
+
+#endif /* asm */
--- /dev/null
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.9
+ *
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS 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.
+ *
+ * Authors:
+ * Chia-I Wu <olv@lunarg.com>
+ */
+
+#ifndef _ENTRY_H_
+#define _ENTRY_H_
+
+#include "u_compiler.h"
+
+typedef void (*mapi_func)(void);
+
+void
+entry_patch_public(void);
+
+mapi_func
+entry_get_public(int slot);
+
+mapi_func
+entry_generate(int slot);
+
+void
+entry_patch(mapi_func entry, int slot);
+
+#endif /* _ENTRY_H_ */
--- /dev/null
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.9
+ *
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS 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.
+ *
+ * Authors:
+ * Chia-I Wu <olv@lunarg.com>
+ */
+
+#include "u_macros.h"
+
+#ifdef __linux__
+__asm__(".section .note.ABI-tag, \"a\"\n\t"
+ ".p2align 2\n\t"
+ ".long 1f - 0f\n\t" /* name length */
+ ".long 3f - 2f\n\t" /* data length */
+ ".long 1\n\t" /* note length */
+ "0: .asciz \"GNU\"\n\t" /* vendor name */
+ "1: .p2align 2\n\t"
+ "2: .long 0\n\t" /* note data: the ABI tag */
+ ".long 2,4,20\n\t" /* Minimum kernel version w/TLS */
+ "3: .p2align 2\n\t"); /* pad out section */
+#endif /* __linux__ */
+
+__asm__(".text\n"
+ ".balign 32\n"
+ "x86_64_entry_start:");
+
+#define STUB_ASM_ENTRY(func) \
+ ".globl " func "\n" \
+ ".type " func ", @function\n" \
+ ".balign 32\n" \
+ func ":"
+
+#define STUB_ASM_CODE(slot) \
+ "movq " ENTRY_CURRENT_TABLE "@GOTTPOFF(%rip), %rax\n\t" \
+ "movq %fs:(%rax), %r11\n\t" \
+ "jmp *(8 * " slot ")(%r11)"
+
+#define MAPI_TMP_STUB_ASM_GCC
+#include "mapi_tmp.h"
+
+#ifndef MAPI_MODE_BRIDGE
+
+__asm__("x86_64_current_tls:\n\t"
+ "movq " ENTRY_CURRENT_TABLE "@GOTTPOFF(%rip), %rax\n\t"
+ "ret");
+
+extern unsigned long
+x86_64_current_tls();
+
+#include <string.h>
+#include "u_execmem.h"
+
+void
+entry_patch_public(void)
+{
+}
+
+static char
+x86_64_entry_start[];
+
+mapi_func
+entry_get_public(int slot)
+{
+ return (mapi_func) (x86_64_entry_start + slot * 32);
+}
+
+void
+entry_patch(mapi_func entry, int slot)
+{
+ char *code = (char *) entry;
+ *((unsigned int *) (code + 12)) = slot * sizeof(mapi_func);
+}
+
+mapi_func
+entry_generate(int slot)
+{
+ const char code_templ[16] = {
+ /* movq %fs:0, %r11 */
+ 0x64, 0x4c, 0x8b, 0x1c, 0x25, 0x00, 0x00, 0x00, 0x00,
+ /* jmp *0x1234(%r11) */
+ 0x41, 0xff, 0xa3, 0x34, 0x12, 0x00, 0x00,
+ };
+ unsigned long addr;
+ void *code;
+ mapi_func entry;
+
+ addr = x86_64_current_tls();
+ if ((addr >> 32) != 0xffffffff)
+ return NULL;
+ addr &= 0xffffffff;
+
+ code = u_execmem_alloc(sizeof(code_templ));
+ if (!code)
+ return NULL;
+
+ memcpy(code, code_templ, sizeof(code_templ));
+
+ *((unsigned int *) (code + 5)) = addr;
+ entry = (mapi_func) code;
+ entry_patch(entry, slot);
+
+ return entry;
+}
+
+#endif /* MAPI_MODE_BRIDGE */
--- /dev/null
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.9
+ *
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS 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.
+ *
+ * Authors:
+ * Chia-I Wu <olv@lunarg.com>
+ */
+
+#include <string.h>
+#include "u_macros.h"
+
+#ifdef __linux__
+__asm__(".section .note.ABI-tag, \"a\"\n\t"
+ ".p2align 2\n\t"
+ ".long 1f - 0f\n\t" /* name length */
+ ".long 3f - 2f\n\t" /* data length */
+ ".long 1\n\t" /* note length */
+ "0: .asciz \"GNU\"\n\t" /* vendor name */
+ "1: .p2align 2\n\t"
+ "2: .long 0\n\t" /* note data: the ABI tag */
+ ".long 2,4,20\n\t" /* Minimum kernel version w/TLS */
+ "3: .p2align 2\n\t"); /* pad out section */
+#endif /* __linux__ */
+
+__asm__(".text");
+
+__asm__("x86_current_tls:\n\t"
+ "call 1f\n"
+ "1:\n\t"
+ "popl %eax\n\t"
+ "addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %eax\n\t"
+ "movl " ENTRY_CURRENT_TABLE "@GOTNTPOFF(%eax), %eax\n\t"
+ "ret");
+
+#ifndef GLX_X86_READONLY_TEXT
+__asm__(".section wtext, \"awx\", @progbits");
+#endif /* GLX_X86_READONLY_TEXT */
+
+__asm__(".balign 16\n"
+ "x86_entry_start:");
+
+#define STUB_ASM_ENTRY(func) \
+ ".globl " func "\n" \
+ ".type " func ", @function\n" \
+ ".balign 16\n" \
+ func ":"
+
+#define STUB_ASM_CODE(slot) \
+ "call x86_current_tls\n\t" \
+ "movl %gs:(%eax), %eax\n\t" \
+ "jmp *(4 * " slot ")(%eax)"
+
+#define MAPI_TMP_STUB_ASM_GCC
+#include "mapi_tmp.h"
+
+#ifndef GLX_X86_READONLY_TEXT
+__asm__(".balign 16\n"
+ "x86_entry_end:");
+__asm__(".text");
+#endif /* GLX_X86_READONLY_TEXT */
+
+#ifndef MAPI_MODE_BRIDGE
+
+#include "u_execmem.h"
+
+extern unsigned long
+x86_current_tls();
+
+static char x86_entry_start[];
+static char x86_entry_end[];
+
+void
+entry_patch_public(void)
+{
+#ifndef GLX_X86_READONLY_TEXT
+ char patch[8] = {
+ 0x65, 0xa1, 0x00, 0x00, 0x00, 0x00, /* movl %gs:0x0, %eax */
+ 0x90, 0x90 /* nop's */
+ };
+ char *entry;
+
+ *((unsigned long *) (patch + 2)) = x86_current_tls();
+
+ for (entry = x86_entry_start; entry < x86_entry_end; entry += 16)
+ memcpy(entry, patch, sizeof(patch));
+#endif
+}
+
+mapi_func
+entry_get_public(int slot)
+{
+ return (mapi_func) (x86_entry_start + slot * 16);
+}
+
+void
+entry_patch(mapi_func entry, int slot)
+{
+ char *code = (char *) entry;
+ *((unsigned long *) (code + 8)) = slot * sizeof(mapi_func);
+}
+
+mapi_func
+entry_generate(int slot)
+{
+ const char code_templ[16] = {
+ 0x65, 0xa1, 0x00, 0x00, 0x00, 0x00, /* movl %gs:0x0, %eax */
+ 0xff, 0xa0, 0x34, 0x12, 0x00, 0x00, /* jmp *0x1234(%eax) */
+ 0x90, 0x90, 0x90, 0x90 /* nop's */
+ };
+ void *code;
+ mapi_func entry;
+
+ code = u_execmem_alloc(sizeof(code_templ));
+ if (!code)
+ return NULL;
+
+ memcpy(code, code_templ, sizeof(code_templ));
+
+ *((unsigned long *) (code + 2)) = x86_current_tls();
+ entry = (mapi_func) code;
+ entry_patch(entry, slot);
+
+ return entry;
+}
+
+#endif /* MAPI_MODE_BRIDGE */
--- /dev/null
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.9
+ *
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS 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.
+ *
+ * Authors:
+ * Chia-I Wu <olv@lunarg.com>
+ */
+
+#include "u_macros.h"
+
+#define X86_ENTRY_SIZE 32
+
+__asm__(".text\n"
+ ".balign 32\n"
+ "x86_entry_start:");
+
+#define STUB_ASM_ENTRY(func) \
+ ".globl " func "\n" \
+ ".type " func ", @function\n" \
+ ".balign 32\n" \
+ func ":"
+
+#define STUB_ASM_CODE(slot) \
+ "movl " ENTRY_CURRENT_TABLE ", %eax\n\t" \
+ "testl %eax, %eax\n\t" \
+ "je 1f\n\t" \
+ "jmp *(4 * " slot ")(%eax)\n" \
+ "1:\n\t" \
+ "call " ENTRY_CURRENT_TABLE_GET "\n\t" \
+ "jmp *(4 * " slot ")(%eax)"
+
+#define MAPI_TMP_STUB_ASM_GCC
+#include "mapi_tmp.h"
+
+#ifndef MAPI_MODE_BRIDGE
+
+__asm__(".balign 32\n"
+ "x86_entry_end:");
+
+#include <string.h>
+#include "u_execmem.h"
+
+static const char x86_entry_start[];
+static const char x86_entry_end[];
+
+void
+entry_patch_public(void)
+{
+}
+
+mapi_func
+entry_get_public(int slot)
+{
+ return (mapi_func) (x86_entry_start + slot * X86_ENTRY_SIZE);
+}
+
+void
+entry_patch(mapi_func entry, int slot)
+{
+ char *code = (char *) entry;
+
+ *((unsigned long *) (code + 11)) = slot * sizeof(mapi_func);
+ *((unsigned long *) (code + 22)) = slot * sizeof(mapi_func);
+}
+
+mapi_func
+entry_generate(int slot)
+{
+ const char *code_templ = x86_entry_end - X86_ENTRY_SIZE;
+ void *code;
+ mapi_func entry;
+
+ code = u_execmem_alloc(X86_ENTRY_SIZE);
+ if (!code)
+ return NULL;
+
+ memcpy(code, code_templ, X86_ENTRY_SIZE);
+ entry = (mapi_func) code;
+ entry_patch(entry, slot);
+
+ return entry;
+}
+
+#endif /* MAPI_MODE_BRIDGE */
lib_LTLIBRARIES = libGLESv1_CM.la
-libGLESv1_CM_la_SOURCES = ../mapi/entry.c glapi_mapi_tmp.h
+libGLESv1_CM_la_SOURCES = ../entry.c glapi_mapi_tmp.h
libGLESv1_CM_la_LIBADD = $(GLESv1_CM_LIB_DEPS)
libGLESv1_CM_la_LDFLAGS = -version-number 1:1 -no-undefined
lib_LTLIBRARIES = libGLESv2.la
-libGLESv2_la_SOURCES = ../mapi/entry.c glapi_mapi_tmp.h
+libGLESv2_la_SOURCES = ../entry.c glapi_mapi_tmp.h
libGLESv2_la_LIBADD = $(GLESv2_LIB_DEPS)
libGLESv2_la_LDFLAGS = -version-number 2 -no-undefined
TOP = $(top_srcdir)
include Makefile.sources
-include ../mapi/Makefile.sources
+include ../Makefile.sources
AM_CPPFLAGS = \
$(DEFINES) \
'u_execmem.c',
]
for s in mapi_sources:
- o = env.SharedObject(s[:-2], '../mapi/' + s)
+ o = env.SharedObject(s[:-2], '../' + s)
glapi_sources.append(o)
#
MESA_DIR = $(top_srcdir)/src/mesa
MESA_GLAPI_DIR = $(top_srcdir)/src/mapi/glapi
-MESA_MAPI_DIR = $(top_srcdir)/src/mapi/mapi
+MESA_MAPI_DIR = $(top_srcdir)/src/mapi
MESA_GLX_DIR = $(top_srcdir)/src/glx
MESA_GLAPI_OUTPUTS = \
$(wildcard $(top_srcdir)/src/mapi/glapi/gen/*.xml) \
$(wildcard $(top_srcdir)/src/mapi/glapi/gen/*.py)
-glapi_gen_mapi_script := $(top_srcdir)/src/mapi/mapi/mapi_abi.py
+glapi_gen_mapi_script := $(top_srcdir)/src/mapi/mapi_abi.py
glapi_gen_mapi_deps := \
$(glapi_gen_mapi_script) \
$(glapi_gen_common_deps)
*/
#include "glapi/glapi.h"
-#include "mapi/u_current.h"
+#include "u_current.h"
/*
* Global variables, _glapi_get_context, and _glapi_get_dispatch are defined in
#include "glapi/glapi_priv.h"
-#include "mapi/u_execmem.h"
+#include "u_execmem.h"
#ifdef USE_X86_ASM
#ifndef GLTHREAD_H
#define GLTHREAD_H
-#include "mapi/u_thread.h"
+#include "u_thread.h"
#ifdef __cplusplus
extern "C" {
--- /dev/null
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.9
+ *
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS 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.
+ *
+ * Authors:
+ * Chia-I Wu <olv@lunarg.com>
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "u_current.h"
+#include "u_thread.h"
+#include "mapi.h"
+#include "stub.h"
+#include "table.h"
+
+/* dynamic stubs will run out before this array */
+static const struct mapi_stub *mapi_stub_map[MAPI_TABLE_NUM_SLOTS];
+static int mapi_num_stubs;
+
+static const struct mapi_stub *
+get_stub(const char *name, const struct mapi_stub *alias)
+{
+ const struct mapi_stub *stub;
+
+ stub = stub_find_public(name);
+ if (!stub) {
+ struct mapi_stub *dyn = stub_find_dynamic(name, 1);
+ if (dyn) {
+ stub_fix_dynamic(dyn, alias);
+ stub = dyn;
+ }
+ }
+
+ return stub;
+}
+
+/**
+ * Initialize mapi. spec consists of NULL-separated strings. The first string
+ * denotes the version. It is followed by variable numbers of entries. Each
+ * entry can have multiple names. An empty name terminates an entry. An empty
+ * entry terminates the spec. A spec of two entries, Foo and Bar, is as
+ * follows
+ *
+ * "1\0"
+ * "Foo\0"
+ * "FooEXT\0"
+ * "\0"
+ * "Bar\0"
+ * "\0"
+ */
+void
+mapi_init(const char *spec)
+{
+ u_mutex_declare_static(mutex);
+ const char *p;
+ int ver, count;
+
+ u_mutex_lock(mutex);
+
+ /* already initialized */
+ if (mapi_num_stubs) {
+ u_mutex_unlock(mutex);
+ return;
+ }
+
+ count = 0;
+ p = spec;
+
+ /* parse version string */
+ ver = atoi(p);
+ if (ver != 1) {
+ u_mutex_unlock(mutex);
+ return;
+ }
+ p += strlen(p) + 1;
+
+ while (*p) {
+ const struct mapi_stub *stub;
+
+ stub = get_stub(p, NULL);
+ /* out of dynamic entries */
+ if (!stub)
+ break;
+ p += strlen(p) + 1;
+
+ while (*p) {
+ get_stub(p, stub);
+ p += strlen(p) + 1;
+ }
+
+ mapi_stub_map[count++] = stub;
+ p++;
+ }
+
+ mapi_num_stubs = count;
+
+ u_mutex_unlock(mutex);
+}
+
+/**
+ * Return the address of an entry. Optionally generate the entry if it does
+ * not exist.
+ */
+mapi_proc
+mapi_get_proc_address(const char *name)
+{
+ const struct mapi_stub *stub;
+
+ stub = stub_find_public(name);
+ if (!stub)
+ stub = stub_find_dynamic(name, 0);
+
+ return (stub) ? (mapi_proc) stub_get_addr(stub) : NULL;
+}
+
+/**
+ * Create a dispatch table.
+ */
+struct mapi_table *
+mapi_table_create(void)
+{
+ const struct mapi_table *noop = table_get_noop();
+ struct mapi_table *tbl;
+
+ tbl = malloc(MAPI_TABLE_SIZE);
+ if (tbl)
+ memcpy(tbl, noop, MAPI_TABLE_SIZE);
+
+ return tbl;
+}
+
+/**
+ * Destroy a dispatch table.
+ */
+void
+mapi_table_destroy(struct mapi_table *tbl)
+{
+ free(tbl);
+}
+
+/**
+ * Fill a dispatch table. The order of the procs is determined when mapi_init
+ * is called.
+ */
+void
+mapi_table_fill(struct mapi_table *tbl, const mapi_proc *procs)
+{
+ const struct mapi_table *noop = table_get_noop();
+ int i;
+
+ for (i = 0; i < mapi_num_stubs; i++) {
+ const struct mapi_stub *stub = mapi_stub_map[i];
+ int slot = stub_get_slot(stub);
+ mapi_func func = (mapi_func) procs[i];
+
+ if (!func)
+ func = table_get_func(noop, slot);
+ table_set_func(tbl, slot, func);
+ }
+}
+
+/**
+ * Make a dispatch table current.
+ */
+void
+mapi_table_make_current(const struct mapi_table *tbl)
+{
+ u_current_set(tbl);
+}
--- /dev/null
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.9
+ *
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS 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.
+ *
+ * Authors:
+ * Chia-I Wu <olv@lunarg.com>
+ */
+
+#ifndef _MAPI_H_
+#define _MAPI_H_
+
+#include "u_compiler.h"
+
+#ifdef _WIN32
+#ifdef MAPI_DLL_EXPORTS
+#define MAPI_EXPORT __declspec(dllexport)
+#else
+#define MAPI_EXPORT __declspec(dllimport)
+#endif
+#else /* _WIN32 */
+#define MAPI_EXPORT PUBLIC
+#endif
+
+typedef void (*mapi_proc)(void);
+
+struct mapi_table;
+
+MAPI_EXPORT void
+mapi_init(const char *spec);
+
+MAPI_EXPORT mapi_proc
+mapi_get_proc_address(const char *name);
+
+MAPI_EXPORT struct mapi_table *
+mapi_table_create(void);
+
+MAPI_EXPORT void
+mapi_table_destroy(struct mapi_table *tbl);
+
+MAPI_EXPORT void
+mapi_table_fill(struct mapi_table *tbl, const mapi_proc *procs);
+
+MAPI_EXPORT void
+mapi_table_make_current(const struct mapi_table *tbl);
+
+#endif /* _MAPI_H_ */
+++ /dev/null
-# src/mapi/mapi/Makefile.sources
-#
-# mapi may be used in several ways
-#
-# - In default mode, mapi implements the interface defined by mapi.h. To use
-# this mode, compile MAPI_FILES.
-#
-# - In util mode, mapi provides utility functions for use with glapi. To use
-# this mode, compile MAPI_UTIL_FILES with MAPI_MODE_UTIL defined.
-#
-# - In glapi mode, mapi implements the interface defined by glapi.h. To use
-# this mode, compile MAPI_GLAPI_FILES with MAPI_MODE_GLAPI defined.
-#
-# - In bridge mode, mapi provides entry points calling into glapi. To use
-# this mode, compile MAPI_BRIDGE_FILES with MAPI_MODE_BRIDGE defined.
-
-MAPI_UTIL_FILES = \
- $(TOP)/src/mapi/mapi/u_current.c \
- $(TOP)/src/mapi/mapi/u_execmem.c
-
-MAPI_FILES = \
- $(TOP)/src/mapi/mapi/entry.c \
- $(TOP)/src/mapi/mapi/mapi.c \
- $(TOP)/src/mapi/mapi/stub.c \
- $(TOP)/src/mapi/mapi/table.c \
- $(MAPI_UTIL_FILES)
-
-MAPI_GLAPI_FILES = \
- $(TOP)/src/mapi/mapi/entry.c \
- $(TOP)/src/mapi/mapi/mapi_glapi.c \
- $(TOP)/src/mapi/mapi/stub.c \
- $(TOP)/src/mapi/mapi/table.c \
- $(MAPI_UTIL_FILES)
-
-MAPI_BRIDGE_FILES = \
- $(TOP)/src/mapi/mapi/entry.c
+++ /dev/null
-/*
- * Mesa 3-D graphics library
- * Version: 7.9
- *
- * Copyright (C) 2010 LunarG Inc.
- *
- * 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 AUTHORS OR COPYRIGHT HOLDERS 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.
- *
- * Authors:
- * Chia-I Wu <olv@lunarg.com>
- */
-
-#include "entry.h"
-#include "u_current.h"
-#include "u_macros.h"
-
-/* define macros for use by assembly dispatchers */
-#define ENTRY_CURRENT_TABLE U_STRINGIFY(u_current_table)
-
-/* in bridge mode, mapi is a user of glapi */
-#ifdef MAPI_MODE_BRIDGE
-#define ENTRY_CURRENT_TABLE_GET "_glapi_get_dispatch"
-#else
-#define ENTRY_CURRENT_TABLE_GET U_STRINGIFY(u_current_get_internal)
-#endif
-
-#if defined(USE_X86_ASM) && defined(__GNUC__)
-# ifdef GLX_USE_TLS
-# include "entry_x86_tls.h"
-# else
-# include "entry_x86_tsd.h"
-# endif
-#elif defined(USE_X86_64_ASM) && defined(__GNUC__) && defined(GLX_USE_TLS)
-# include "entry_x86-64_tls.h"
-#else
-
-#include <stdlib.h>
-
-static INLINE const struct mapi_table *
-entry_current_get(void)
-{
-#ifdef MAPI_MODE_BRIDGE
- return GET_DISPATCH();
-#else
- return u_current_get();
-#endif
-}
-
-/* C version of the public entries */
-#define MAPI_TMP_DEFINES
-#define MAPI_TMP_PUBLIC_DECLARES
-#define MAPI_TMP_PUBLIC_ENTRIES
-#include "mapi_tmp.h"
-
-#ifndef MAPI_MODE_BRIDGE
-
-void
-entry_patch_public(void)
-{
-}
-
-mapi_func
-entry_get_public(int slot)
-{
- /* pubic_entries are defined by MAPI_TMP_PUBLIC_ENTRIES */
- return public_entries[slot];
-}
-
-mapi_func
-entry_generate(int slot)
-{
- return NULL;
-}
-
-void
-entry_patch(mapi_func entry, int slot)
-{
-}
-
-#endif /* MAPI_MODE_BRIDGE */
-
-#endif /* asm */
+++ /dev/null
-/*
- * Mesa 3-D graphics library
- * Version: 7.9
- *
- * Copyright (C) 2010 LunarG Inc.
- *
- * 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 AUTHORS OR COPYRIGHT HOLDERS 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.
- *
- * Authors:
- * Chia-I Wu <olv@lunarg.com>
- */
-
-#ifndef _ENTRY_H_
-#define _ENTRY_H_
-
-#include "u_compiler.h"
-
-typedef void (*mapi_func)(void);
-
-void
-entry_patch_public(void);
-
-mapi_func
-entry_get_public(int slot);
-
-mapi_func
-entry_generate(int slot);
-
-void
-entry_patch(mapi_func entry, int slot);
-
-#endif /* _ENTRY_H_ */
+++ /dev/null
-/*
- * Mesa 3-D graphics library
- * Version: 7.9
- *
- * Copyright (C) 2010 LunarG Inc.
- *
- * 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 AUTHORS OR COPYRIGHT HOLDERS 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.
- *
- * Authors:
- * Chia-I Wu <olv@lunarg.com>
- */
-
-#include "u_macros.h"
-
-#ifdef __linux__
-__asm__(".section .note.ABI-tag, \"a\"\n\t"
- ".p2align 2\n\t"
- ".long 1f - 0f\n\t" /* name length */
- ".long 3f - 2f\n\t" /* data length */
- ".long 1\n\t" /* note length */
- "0: .asciz \"GNU\"\n\t" /* vendor name */
- "1: .p2align 2\n\t"
- "2: .long 0\n\t" /* note data: the ABI tag */
- ".long 2,4,20\n\t" /* Minimum kernel version w/TLS */
- "3: .p2align 2\n\t"); /* pad out section */
-#endif /* __linux__ */
-
-__asm__(".text\n"
- ".balign 32\n"
- "x86_64_entry_start:");
-
-#define STUB_ASM_ENTRY(func) \
- ".globl " func "\n" \
- ".type " func ", @function\n" \
- ".balign 32\n" \
- func ":"
-
-#define STUB_ASM_CODE(slot) \
- "movq " ENTRY_CURRENT_TABLE "@GOTTPOFF(%rip), %rax\n\t" \
- "movq %fs:(%rax), %r11\n\t" \
- "jmp *(8 * " slot ")(%r11)"
-
-#define MAPI_TMP_STUB_ASM_GCC
-#include "mapi_tmp.h"
-
-#ifndef MAPI_MODE_BRIDGE
-
-__asm__("x86_64_current_tls:\n\t"
- "movq " ENTRY_CURRENT_TABLE "@GOTTPOFF(%rip), %rax\n\t"
- "ret");
-
-extern unsigned long
-x86_64_current_tls();
-
-#include <string.h>
-#include "u_execmem.h"
-
-void
-entry_patch_public(void)
-{
-}
-
-static char
-x86_64_entry_start[];
-
-mapi_func
-entry_get_public(int slot)
-{
- return (mapi_func) (x86_64_entry_start + slot * 32);
-}
-
-void
-entry_patch(mapi_func entry, int slot)
-{
- char *code = (char *) entry;
- *((unsigned int *) (code + 12)) = slot * sizeof(mapi_func);
-}
-
-mapi_func
-entry_generate(int slot)
-{
- const char code_templ[16] = {
- /* movq %fs:0, %r11 */
- 0x64, 0x4c, 0x8b, 0x1c, 0x25, 0x00, 0x00, 0x00, 0x00,
- /* jmp *0x1234(%r11) */
- 0x41, 0xff, 0xa3, 0x34, 0x12, 0x00, 0x00,
- };
- unsigned long addr;
- void *code;
- mapi_func entry;
-
- addr = x86_64_current_tls();
- if ((addr >> 32) != 0xffffffff)
- return NULL;
- addr &= 0xffffffff;
-
- code = u_execmem_alloc(sizeof(code_templ));
- if (!code)
- return NULL;
-
- memcpy(code, code_templ, sizeof(code_templ));
-
- *((unsigned int *) (code + 5)) = addr;
- entry = (mapi_func) code;
- entry_patch(entry, slot);
-
- return entry;
-}
-
-#endif /* MAPI_MODE_BRIDGE */
+++ /dev/null
-/*
- * Mesa 3-D graphics library
- * Version: 7.9
- *
- * Copyright (C) 2010 LunarG Inc.
- *
- * 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 AUTHORS OR COPYRIGHT HOLDERS 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.
- *
- * Authors:
- * Chia-I Wu <olv@lunarg.com>
- */
-
-#include <string.h>
-#include "u_macros.h"
-
-#ifdef __linux__
-__asm__(".section .note.ABI-tag, \"a\"\n\t"
- ".p2align 2\n\t"
- ".long 1f - 0f\n\t" /* name length */
- ".long 3f - 2f\n\t" /* data length */
- ".long 1\n\t" /* note length */
- "0: .asciz \"GNU\"\n\t" /* vendor name */
- "1: .p2align 2\n\t"
- "2: .long 0\n\t" /* note data: the ABI tag */
- ".long 2,4,20\n\t" /* Minimum kernel version w/TLS */
- "3: .p2align 2\n\t"); /* pad out section */
-#endif /* __linux__ */
-
-__asm__(".text");
-
-__asm__("x86_current_tls:\n\t"
- "call 1f\n"
- "1:\n\t"
- "popl %eax\n\t"
- "addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %eax\n\t"
- "movl " ENTRY_CURRENT_TABLE "@GOTNTPOFF(%eax), %eax\n\t"
- "ret");
-
-#ifndef GLX_X86_READONLY_TEXT
-__asm__(".section wtext, \"awx\", @progbits");
-#endif /* GLX_X86_READONLY_TEXT */
-
-__asm__(".balign 16\n"
- "x86_entry_start:");
-
-#define STUB_ASM_ENTRY(func) \
- ".globl " func "\n" \
- ".type " func ", @function\n" \
- ".balign 16\n" \
- func ":"
-
-#define STUB_ASM_CODE(slot) \
- "call x86_current_tls\n\t" \
- "movl %gs:(%eax), %eax\n\t" \
- "jmp *(4 * " slot ")(%eax)"
-
-#define MAPI_TMP_STUB_ASM_GCC
-#include "mapi_tmp.h"
-
-#ifndef GLX_X86_READONLY_TEXT
-__asm__(".balign 16\n"
- "x86_entry_end:");
-__asm__(".text");
-#endif /* GLX_X86_READONLY_TEXT */
-
-#ifndef MAPI_MODE_BRIDGE
-
-#include "u_execmem.h"
-
-extern unsigned long
-x86_current_tls();
-
-static char x86_entry_start[];
-static char x86_entry_end[];
-
-void
-entry_patch_public(void)
-{
-#ifndef GLX_X86_READONLY_TEXT
- char patch[8] = {
- 0x65, 0xa1, 0x00, 0x00, 0x00, 0x00, /* movl %gs:0x0, %eax */
- 0x90, 0x90 /* nop's */
- };
- char *entry;
-
- *((unsigned long *) (patch + 2)) = x86_current_tls();
-
- for (entry = x86_entry_start; entry < x86_entry_end; entry += 16)
- memcpy(entry, patch, sizeof(patch));
-#endif
-}
-
-mapi_func
-entry_get_public(int slot)
-{
- return (mapi_func) (x86_entry_start + slot * 16);
-}
-
-void
-entry_patch(mapi_func entry, int slot)
-{
- char *code = (char *) entry;
- *((unsigned long *) (code + 8)) = slot * sizeof(mapi_func);
-}
-
-mapi_func
-entry_generate(int slot)
-{
- const char code_templ[16] = {
- 0x65, 0xa1, 0x00, 0x00, 0x00, 0x00, /* movl %gs:0x0, %eax */
- 0xff, 0xa0, 0x34, 0x12, 0x00, 0x00, /* jmp *0x1234(%eax) */
- 0x90, 0x90, 0x90, 0x90 /* nop's */
- };
- void *code;
- mapi_func entry;
-
- code = u_execmem_alloc(sizeof(code_templ));
- if (!code)
- return NULL;
-
- memcpy(code, code_templ, sizeof(code_templ));
-
- *((unsigned long *) (code + 2)) = x86_current_tls();
- entry = (mapi_func) code;
- entry_patch(entry, slot);
-
- return entry;
-}
-
-#endif /* MAPI_MODE_BRIDGE */
+++ /dev/null
-/*
- * Mesa 3-D graphics library
- * Version: 7.9
- *
- * Copyright (C) 2010 LunarG Inc.
- *
- * 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 AUTHORS OR COPYRIGHT HOLDERS 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.
- *
- * Authors:
- * Chia-I Wu <olv@lunarg.com>
- */
-
-#include "u_macros.h"
-
-#define X86_ENTRY_SIZE 32
-
-__asm__(".text\n"
- ".balign 32\n"
- "x86_entry_start:");
-
-#define STUB_ASM_ENTRY(func) \
- ".globl " func "\n" \
- ".type " func ", @function\n" \
- ".balign 32\n" \
- func ":"
-
-#define STUB_ASM_CODE(slot) \
- "movl " ENTRY_CURRENT_TABLE ", %eax\n\t" \
- "testl %eax, %eax\n\t" \
- "je 1f\n\t" \
- "jmp *(4 * " slot ")(%eax)\n" \
- "1:\n\t" \
- "call " ENTRY_CURRENT_TABLE_GET "\n\t" \
- "jmp *(4 * " slot ")(%eax)"
-
-#define MAPI_TMP_STUB_ASM_GCC
-#include "mapi_tmp.h"
-
-#ifndef MAPI_MODE_BRIDGE
-
-__asm__(".balign 32\n"
- "x86_entry_end:");
-
-#include <string.h>
-#include "u_execmem.h"
-
-static const char x86_entry_start[];
-static const char x86_entry_end[];
-
-void
-entry_patch_public(void)
-{
-}
-
-mapi_func
-entry_get_public(int slot)
-{
- return (mapi_func) (x86_entry_start + slot * X86_ENTRY_SIZE);
-}
-
-void
-entry_patch(mapi_func entry, int slot)
-{
- char *code = (char *) entry;
-
- *((unsigned long *) (code + 11)) = slot * sizeof(mapi_func);
- *((unsigned long *) (code + 22)) = slot * sizeof(mapi_func);
-}
-
-mapi_func
-entry_generate(int slot)
-{
- const char *code_templ = x86_entry_end - X86_ENTRY_SIZE;
- void *code;
- mapi_func entry;
-
- code = u_execmem_alloc(X86_ENTRY_SIZE);
- if (!code)
- return NULL;
-
- memcpy(code, code_templ, X86_ENTRY_SIZE);
- entry = (mapi_func) code;
- entry_patch(entry, slot);
-
- return entry;
-}
-
-#endif /* MAPI_MODE_BRIDGE */
+++ /dev/null
-/*
- * Mesa 3-D graphics library
- * Version: 7.9
- *
- * Copyright (C) 2010 LunarG Inc.
- *
- * 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 AUTHORS OR COPYRIGHT HOLDERS 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.
- *
- * Authors:
- * Chia-I Wu <olv@lunarg.com>
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "u_current.h"
-#include "u_thread.h"
-#include "mapi.h"
-#include "stub.h"
-#include "table.h"
-
-/* dynamic stubs will run out before this array */
-static const struct mapi_stub *mapi_stub_map[MAPI_TABLE_NUM_SLOTS];
-static int mapi_num_stubs;
-
-static const struct mapi_stub *
-get_stub(const char *name, const struct mapi_stub *alias)
-{
- const struct mapi_stub *stub;
-
- stub = stub_find_public(name);
- if (!stub) {
- struct mapi_stub *dyn = stub_find_dynamic(name, 1);
- if (dyn) {
- stub_fix_dynamic(dyn, alias);
- stub = dyn;
- }
- }
-
- return stub;
-}
-
-/**
- * Initialize mapi. spec consists of NULL-separated strings. The first string
- * denotes the version. It is followed by variable numbers of entries. Each
- * entry can have multiple names. An empty name terminates an entry. An empty
- * entry terminates the spec. A spec of two entries, Foo and Bar, is as
- * follows
- *
- * "1\0"
- * "Foo\0"
- * "FooEXT\0"
- * "\0"
- * "Bar\0"
- * "\0"
- */
-void
-mapi_init(const char *spec)
-{
- u_mutex_declare_static(mutex);
- const char *p;
- int ver, count;
-
- u_mutex_lock(mutex);
-
- /* already initialized */
- if (mapi_num_stubs) {
- u_mutex_unlock(mutex);
- return;
- }
-
- count = 0;
- p = spec;
-
- /* parse version string */
- ver = atoi(p);
- if (ver != 1) {
- u_mutex_unlock(mutex);
- return;
- }
- p += strlen(p) + 1;
-
- while (*p) {
- const struct mapi_stub *stub;
-
- stub = get_stub(p, NULL);
- /* out of dynamic entries */
- if (!stub)
- break;
- p += strlen(p) + 1;
-
- while (*p) {
- get_stub(p, stub);
- p += strlen(p) + 1;
- }
-
- mapi_stub_map[count++] = stub;
- p++;
- }
-
- mapi_num_stubs = count;
-
- u_mutex_unlock(mutex);
-}
-
-/**
- * Return the address of an entry. Optionally generate the entry if it does
- * not exist.
- */
-mapi_proc
-mapi_get_proc_address(const char *name)
-{
- const struct mapi_stub *stub;
-
- stub = stub_find_public(name);
- if (!stub)
- stub = stub_find_dynamic(name, 0);
-
- return (stub) ? (mapi_proc) stub_get_addr(stub) : NULL;
-}
-
-/**
- * Create a dispatch table.
- */
-struct mapi_table *
-mapi_table_create(void)
-{
- const struct mapi_table *noop = table_get_noop();
- struct mapi_table *tbl;
-
- tbl = malloc(MAPI_TABLE_SIZE);
- if (tbl)
- memcpy(tbl, noop, MAPI_TABLE_SIZE);
-
- return tbl;
-}
-
-/**
- * Destroy a dispatch table.
- */
-void
-mapi_table_destroy(struct mapi_table *tbl)
-{
- free(tbl);
-}
-
-/**
- * Fill a dispatch table. The order of the procs is determined when mapi_init
- * is called.
- */
-void
-mapi_table_fill(struct mapi_table *tbl, const mapi_proc *procs)
-{
- const struct mapi_table *noop = table_get_noop();
- int i;
-
- for (i = 0; i < mapi_num_stubs; i++) {
- const struct mapi_stub *stub = mapi_stub_map[i];
- int slot = stub_get_slot(stub);
- mapi_func func = (mapi_func) procs[i];
-
- if (!func)
- func = table_get_func(noop, slot);
- table_set_func(tbl, slot, func);
- }
-}
-
-/**
- * Make a dispatch table current.
- */
-void
-mapi_table_make_current(const struct mapi_table *tbl)
-{
- u_current_set(tbl);
-}
+++ /dev/null
-/*
- * Mesa 3-D graphics library
- * Version: 7.9
- *
- * Copyright (C) 2010 LunarG Inc.
- *
- * 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 AUTHORS OR COPYRIGHT HOLDERS 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.
- *
- * Authors:
- * Chia-I Wu <olv@lunarg.com>
- */
-
-#ifndef _MAPI_H_
-#define _MAPI_H_
-
-#include "u_compiler.h"
-
-#ifdef _WIN32
-#ifdef MAPI_DLL_EXPORTS
-#define MAPI_EXPORT __declspec(dllexport)
-#else
-#define MAPI_EXPORT __declspec(dllimport)
-#endif
-#else /* _WIN32 */
-#define MAPI_EXPORT PUBLIC
-#endif
-
-typedef void (*mapi_proc)(void);
-
-struct mapi_table;
-
-MAPI_EXPORT void
-mapi_init(const char *spec);
-
-MAPI_EXPORT mapi_proc
-mapi_get_proc_address(const char *name);
-
-MAPI_EXPORT struct mapi_table *
-mapi_table_create(void);
-
-MAPI_EXPORT void
-mapi_table_destroy(struct mapi_table *tbl);
-
-MAPI_EXPORT void
-mapi_table_fill(struct mapi_table *tbl, const mapi_proc *procs);
-
-MAPI_EXPORT void
-mapi_table_make_current(const struct mapi_table *tbl);
-
-#endif /* _MAPI_H_ */
+++ /dev/null
-#!/usr/bin/env python
-
-# Mesa 3-D graphics library
-# Version: 7.9
-#
-# Copyright (C) 2010 LunarG Inc.
-#
-# 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 AUTHORS OR COPYRIGHT HOLDERS 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.
-#
-# Authors:
-# Chia-I Wu <olv@lunarg.com>
-
-import sys
-# make it possible to import glapi
-import os
-GLAPI = os.path.join(".", os.path.dirname(sys.argv[0]), "../glapi/gen")
-sys.path.append(GLAPI)
-
-import re
-from optparse import OptionParser
-import gl_XML
-import glX_XML
-
-
-# number of dynamic entries
-ABI_NUM_DYNAMIC_ENTRIES = 256
-
-class ABIEntry(object):
- """Represent an ABI entry."""
-
- _match_c_param = re.compile(
- '^(?P<type>[\w\s*]+?)(?P<name>\w+)(\[(?P<array>\d+)\])?$')
-
- def __init__(self, cols, attrs, xml_data = None):
- self._parse(cols)
-
- self.slot = attrs['slot']
- self.hidden = attrs['hidden']
- self.alias = attrs['alias']
- self.handcode = attrs['handcode']
- self.xml_data = xml_data
-
- def c_prototype(self):
- return '%s %s(%s)' % (self.c_return(), self.name, self.c_params())
-
- def c_return(self):
- ret = self.ret
- if not ret:
- ret = 'void'
-
- return ret
-
- def c_params(self):
- """Return the parameter list used in the entry prototype."""
- c_params = []
- for t, n, a in self.params:
- sep = '' if t.endswith('*') else ' '
- arr = '[%d]' % a if a else ''
- c_params.append(t + sep + n + arr)
- if not c_params:
- c_params.append('void')
-
- return ", ".join(c_params)
-
- def c_args(self):
- """Return the argument list used in the entry invocation."""
- c_args = []
- for t, n, a in self.params:
- c_args.append(n)
-
- return ", ".join(c_args)
-
- def _parse(self, cols):
- ret = cols.pop(0)
- if ret == 'void':
- ret = None
-
- name = cols.pop(0)
-
- params = []
- if not cols:
- raise Exception(cols)
- elif len(cols) == 1 and cols[0] == 'void':
- pass
- else:
- for val in cols:
- params.append(self._parse_param(val))
-
- self.ret = ret
- self.name = name
- self.params = params
-
- def _parse_param(self, c_param):
- m = self._match_c_param.match(c_param)
- if not m:
- raise Exception('unrecognized param ' + c_param)
-
- c_type = m.group('type').strip()
- c_name = m.group('name')
- c_array = m.group('array')
- c_array = int(c_array) if c_array else 0
-
- return (c_type, c_name, c_array)
-
- def __str__(self):
- return self.c_prototype()
-
- def __cmp__(self, other):
- # compare slot, alias, and then name
- res = cmp(self.slot, other.slot)
- if not res:
- if not self.alias:
- res = -1
- elif not other.alias:
- res = 1
-
- if not res:
- res = cmp(self.name, other.name)
-
- return res
-
-def abi_parse_xml(xml):
- """Parse a GLAPI XML file for ABI entries."""
- api = gl_XML.parse_GL_API(xml, glX_XML.glx_item_factory())
-
- entry_dict = {}
- for func in api.functionIterateByOffset():
- # make sure func.name appear first
- entry_points = func.entry_points[:]
- entry_points.remove(func.name)
- entry_points.insert(0, func.name)
-
- for name in entry_points:
- attrs = {
- 'slot': func.offset,
- 'hidden': not func.is_static_entry_point(name),
- 'alias': None if name == func.name else func.name,
- 'handcode': bool(func.has_different_protocol(name)),
- }
-
- # post-process attrs
- if attrs['alias']:
- try:
- alias = entry_dict[attrs['alias']]
- except KeyError:
- raise Exception('failed to alias %s' % attrs['alias'])
- if alias.alias:
- raise Exception('recursive alias %s' % ent.name)
- attrs['alias'] = alias
- if attrs['handcode']:
- attrs['handcode'] = func.static_glx_name(name)
- else:
- attrs['handcode'] = None
-
- if entry_dict.has_key(name):
- raise Exception('%s is duplicated' % (name))
-
- cols = []
- cols.append(func.return_type)
- cols.append(name)
- params = func.get_parameter_string(name)
- cols.extend([p.strip() for p in params.split(',')])
-
- ent = ABIEntry(cols, attrs, func)
- entry_dict[ent.name] = ent
-
- entries = entry_dict.values()
- entries.sort()
-
- return entries
-
-def abi_parse_line(line):
- cols = [col.strip() for col in line.split(',')]
-
- attrs = {
- 'slot': -1,
- 'hidden': False,
- 'alias': None,
- 'handcode': None,
- }
-
- # extract attributes from the first column
- vals = cols[0].split(':')
- while len(vals) > 1:
- val = vals.pop(0)
- if val.startswith('slot='):
- attrs['slot'] = int(val[5:])
- elif val == 'hidden':
- attrs['hidden'] = True
- elif val.startswith('alias='):
- attrs['alias'] = val[6:]
- elif val.startswith('handcode='):
- attrs['handcode'] = val[9:]
- elif not val:
- pass
- else:
- raise Exception('unknown attribute %s' % val)
- cols[0] = vals[0]
-
- return (attrs, cols)
-
-def abi_parse(filename):
- """Parse a CSV file for ABI entries."""
- fp = open(filename) if filename != '-' else sys.stdin
- lines = [line.strip() for line in fp.readlines()
- if not line.startswith('#') and line.strip()]
-
- entry_dict = {}
- next_slot = 0
- for line in lines:
- attrs, cols = abi_parse_line(line)
-
- # post-process attributes
- if attrs['alias']:
- try:
- alias = entry_dict[attrs['alias']]
- except KeyError:
- raise Exception('failed to alias %s' % attrs['alias'])
- if alias.alias:
- raise Exception('recursive alias %s' % ent.name)
- slot = alias.slot
- attrs['alias'] = alias
- else:
- slot = next_slot
- next_slot += 1
-
- if attrs['slot'] < 0:
- attrs['slot'] = slot
- elif attrs['slot'] != slot:
- raise Exception('invalid slot in %s' % (line))
-
- ent = ABIEntry(cols, attrs)
- if entry_dict.has_key(ent.name):
- raise Exception('%s is duplicated' % (ent.name))
- entry_dict[ent.name] = ent
-
- entries = entry_dict.values()
- entries.sort()
-
- return entries
-
-def abi_sanity_check(entries):
- if not entries:
- return
-
- all_names = []
- last_slot = entries[-1].slot
- i = 0
- for slot in xrange(last_slot + 1):
- if entries[i].slot != slot:
- raise Exception('entries are not ordered by slots')
- if entries[i].alias:
- raise Exception('first entry of slot %d aliases %s'
- % (slot, entries[i].alias.name))
- handcode = None
- while i < len(entries) and entries[i].slot == slot:
- ent = entries[i]
- if not handcode and ent.handcode:
- handcode = ent.handcode
- elif ent.handcode != handcode:
- raise Exception('two aliases with handcode %s != %s',
- ent.handcode, handcode)
-
- if ent.name in all_names:
- raise Exception('%s is duplicated' % (ent.name))
- if ent.alias and ent.alias.name not in all_names:
- raise Exception('failed to alias %s' % (ent.alias.name))
- all_names.append(ent.name)
- i += 1
- if i < len(entries):
- raise Exception('there are %d invalid entries' % (len(entries) - 1))
-
-class ABIPrinter(object):
- """MAPI Printer"""
-
- def __init__(self, entries):
- self.entries = entries
-
- # sort entries by their names
- self.entries_sorted_by_names = self.entries[:]
- self.entries_sorted_by_names.sort(lambda x, y: cmp(x.name, y.name))
-
- self.indent = ' ' * 3
- self.noop_warn = 'noop_warn'
- self.noop_generic = 'noop_generic'
- self.current_get = 'entry_current_get'
-
- self.api_defines = []
- self.api_headers = ['"KHR/khrplatform.h"']
- self.api_call = 'KHRONOS_APICALL'
- self.api_entry = 'KHRONOS_APIENTRY'
- self.api_attrs = 'KHRONOS_APIATTRIBUTES'
-
- self.c_header = ''
-
- self.lib_need_table_size = True
- self.lib_need_noop_array = True
- self.lib_need_stubs = True
- self.lib_need_all_entries = True
- self.lib_need_non_hidden_entries = False
-
- def c_notice(self):
- return '/* This file is automatically generated by mapi_abi.py. Do not modify. */'
-
- def c_public_includes(self):
- """Return includes of the client API headers."""
- defines = ['#define ' + d for d in self.api_defines]
- includes = ['#include ' + h for h in self.api_headers]
- return "\n".join(defines + includes)
-
- def need_entry_point(self, ent):
- """Return True if an entry point is needed for the entry."""
- # non-handcode hidden aliases may share the entry they alias
- use_alias = (ent.hidden and ent.alias and not ent.handcode)
- return not use_alias
-
- def c_public_declarations(self, prefix):
- """Return the declarations of public entry points."""
- decls = []
- for ent in self.entries:
- if not self.need_entry_point(ent):
- continue
- export = self.api_call if not ent.hidden else ''
- decls.append(self._c_decl(ent, prefix, True, export) + ';')
-
- return "\n".join(decls)
-
- def c_mapi_table(self):
- """Return defines of the dispatch table size."""
- num_static_entries = self.entries[-1].slot + 1
- return ('#define MAPI_TABLE_NUM_STATIC %d\n' + \
- '#define MAPI_TABLE_NUM_DYNAMIC %d') % (
- num_static_entries, ABI_NUM_DYNAMIC_ENTRIES)
-
- def c_mapi_table_initializer(self, prefix):
- """Return the array initializer for mapi_table_fill."""
- entries = [self._c_function(ent, prefix)
- for ent in self.entries if not ent.alias]
- pre = self.indent + '(mapi_proc) '
- return pre + (',\n' + pre).join(entries)
-
- def c_mapi_table_spec(self):
- """Return the spec for mapi_init."""
- specv1 = []
- line = '"1'
- for ent in self.entries:
- if not ent.alias:
- line += '\\0"\n'
- specv1.append(line)
- line = '"'
- line += '%s\\0' % ent.name
- line += '";'
- specv1.append(line)
-
- return self.indent + self.indent.join(specv1)
-
- def _c_function(self, ent, prefix, mangle=False, stringify=False):
- """Return the function name of an entry."""
- formats = {
- True: { True: '%s_STR(%s)', False: '%s(%s)' },
- False: { True: '"%s%s"', False: '%s%s' },
- }
- fmt = formats[prefix.isupper()][stringify]
- name = ent.name
- if mangle and ent.hidden:
- name = '_dispatch_stub_' + str(ent.slot)
- return fmt % (prefix, name)
-
- def _c_function_call(self, ent, prefix):
- """Return the function name used for calling."""
- if ent.handcode:
- # _c_function does not handle this case
- formats = { True: '%s(%s)', False: '%s%s' }
- fmt = formats[prefix.isupper()]
- name = fmt % (prefix, ent.handcode)
- elif self.need_entry_point(ent):
- name = self._c_function(ent, prefix, True)
- else:
- name = self._c_function(ent.alias, prefix, True)
- return name
-
- def _c_decl(self, ent, prefix, mangle=False, export=''):
- """Return the C declaration for the entry."""
- decl = '%s %s %s(%s)' % (ent.c_return(), self.api_entry,
- self._c_function(ent, prefix, mangle), ent.c_params())
- if export:
- decl = export + ' ' + decl
- if self.api_attrs:
- decl += ' ' + self.api_attrs
-
- return decl
-
- def _c_cast(self, ent):
- """Return the C cast for the entry."""
- cast = '%s (%s *)(%s)' % (
- ent.c_return(), self.api_entry, ent.c_params())
-
- return cast
-
- def c_private_declarations(self, prefix):
- """Return the declarations of private functions."""
- decls = [self._c_decl(ent, prefix) + ';'
- for ent in self.entries if not ent.alias]
-
- return "\n".join(decls)
-
- def c_public_dispatches(self, prefix, no_hidden):
- """Return the public dispatch functions."""
- dispatches = []
- for ent in self.entries:
- if ent.hidden and no_hidden:
- continue
-
- if not self.need_entry_point(ent):
- continue
-
- export = self.api_call if not ent.hidden else ''
-
- proto = self._c_decl(ent, prefix, True, export)
- cast = self._c_cast(ent)
-
- ret = ''
- if ent.ret:
- ret = 'return '
- stmt1 = self.indent
- stmt1 += 'const struct mapi_table *_tbl = %s();' % (
- self.current_get)
- stmt2 = self.indent
- stmt2 += 'mapi_func _func = ((const mapi_func *) _tbl)[%d];' % (
- ent.slot)
- stmt3 = self.indent
- stmt3 += '%s((%s) _func)(%s);' % (ret, cast, ent.c_args())
-
- disp = '%s\n{\n%s\n%s\n%s\n}' % (proto, stmt1, stmt2, stmt3)
-
- if ent.handcode:
- disp = '#if 0\n' + disp + '\n#endif'
-
- dispatches.append(disp)
-
- return '\n\n'.join(dispatches)
-
- def c_public_initializer(self, prefix):
- """Return the initializer for public dispatch functions."""
- names = []
- for ent in self.entries:
- if ent.alias:
- continue
-
- name = '%s(mapi_func) %s' % (self.indent,
- self._c_function_call(ent, prefix))
- names.append(name)
-
- return ',\n'.join(names)
-
- def c_stub_string_pool(self):
- """Return the string pool for use by stubs."""
- # sort entries by their names
- sorted_entries = self.entries[:]
- sorted_entries.sort(lambda x, y: cmp(x.name, y.name))
-
- pool = []
- offsets = {}
- count = 0
- for ent in sorted_entries:
- offsets[ent] = count
- pool.append('%s' % (ent.name))
- count += len(ent.name) + 1
-
- pool_str = self.indent + '"' + \
- ('\\0"\n' + self.indent + '"').join(pool) + '";'
- return (pool_str, offsets)
-
- def c_stub_initializer(self, prefix, pool_offsets):
- """Return the initializer for struct mapi_stub array."""
- stubs = []
- for ent in self.entries_sorted_by_names:
- stubs.append('%s{ (void *) %d, %d, NULL }' % (
- self.indent, pool_offsets[ent], ent.slot))
-
- return ',\n'.join(stubs)
-
- def c_noop_functions(self, prefix, warn_prefix):
- """Return the noop functions."""
- noops = []
- for ent in self.entries:
- if ent.alias:
- continue
-
- proto = self._c_decl(ent, prefix, False, 'static')
-
- stmt1 = self.indent;
- space = ''
- for t, n, a in ent.params:
- stmt1 += "%s(void) %s;" % (space, n)
- space = ' '
-
- if ent.params:
- stmt1 += '\n';
-
- stmt1 += self.indent + '%s(%s);' % (self.noop_warn,
- self._c_function(ent, warn_prefix, False, True))
-
- if ent.ret:
- stmt2 = self.indent + 'return (%s) 0;' % (ent.ret)
- noop = '%s\n{\n%s\n%s\n}' % (proto, stmt1, stmt2)
- else:
- noop = '%s\n{\n%s\n}' % (proto, stmt1)
-
- noops.append(noop)
-
- return '\n\n'.join(noops)
-
- def c_noop_initializer(self, prefix, use_generic):
- """Return an initializer for the noop dispatch table."""
- entries = [self._c_function(ent, prefix)
- for ent in self.entries if not ent.alias]
- if use_generic:
- entries = [self.noop_generic] * len(entries)
-
- entries.extend([self.noop_generic] * ABI_NUM_DYNAMIC_ENTRIES)
-
- pre = self.indent + '(mapi_func) '
- return pre + (',\n' + pre).join(entries)
-
- def c_asm_gcc(self, prefix, no_hidden):
- asm = []
-
- for ent in self.entries:
- if ent.hidden and no_hidden:
- continue
-
- if not self.need_entry_point(ent):
- continue
-
- name = self._c_function(ent, prefix, True, True)
-
- if ent.handcode:
- asm.append('#if 0')
-
- if ent.hidden:
- asm.append('".hidden "%s"\\n"' % (name))
-
- if ent.alias and not (ent.alias.hidden and no_hidden):
- asm.append('".globl "%s"\\n"' % (name))
- asm.append('".set "%s", "%s"\\n"' % (name,
- self._c_function(ent.alias, prefix, True, True)))
- else:
- asm.append('STUB_ASM_ENTRY(%s)"\\n"' % (name))
- asm.append('"\\t"STUB_ASM_CODE("%d")"\\n"' % (ent.slot))
-
- if ent.handcode:
- asm.append('#endif')
- asm.append('')
-
- return "\n".join(asm)
-
- def output_for_lib(self):
- print self.c_notice()
-
- if self.c_header:
- print
- print self.c_header
-
- print
- print '#ifdef MAPI_TMP_DEFINES'
- print self.c_public_includes()
- print
- print self.c_public_declarations(self.prefix_lib)
- print '#undef MAPI_TMP_DEFINES'
- print '#endif /* MAPI_TMP_DEFINES */'
-
- if self.lib_need_table_size:
- print
- print '#ifdef MAPI_TMP_TABLE'
- print self.c_mapi_table()
- print '#undef MAPI_TMP_TABLE'
- print '#endif /* MAPI_TMP_TABLE */'
-
- if self.lib_need_noop_array:
- print
- print '#ifdef MAPI_TMP_NOOP_ARRAY'
- print '#ifdef DEBUG'
- print
- print self.c_noop_functions(self.prefix_noop, self.prefix_warn)
- print
- print 'const mapi_func table_%s_array[] = {' % (self.prefix_noop)
- print self.c_noop_initializer(self.prefix_noop, False)
- print '};'
- print
- print '#else /* DEBUG */'
- print
- print 'const mapi_func table_%s_array[] = {' % (self.prefix_noop)
- print self.c_noop_initializer(self.prefix_noop, True)
- print '};'
- print
- print '#endif /* DEBUG */'
- print '#undef MAPI_TMP_NOOP_ARRAY'
- print '#endif /* MAPI_TMP_NOOP_ARRAY */'
-
- if self.lib_need_stubs:
- pool, pool_offsets = self.c_stub_string_pool()
- print
- print '#ifdef MAPI_TMP_PUBLIC_STUBS'
- print 'static const char public_string_pool[] ='
- print pool
- print
- print 'static const struct mapi_stub public_stubs[] = {'
- print self.c_stub_initializer(self.prefix_lib, pool_offsets)
- print '};'
- print '#undef MAPI_TMP_PUBLIC_STUBS'
- print '#endif /* MAPI_TMP_PUBLIC_STUBS */'
-
- if self.lib_need_all_entries:
- print
- print '#ifdef MAPI_TMP_PUBLIC_ENTRIES'
- print self.c_public_dispatches(self.prefix_lib, False)
- print
- print 'static const mapi_func public_entries[] = {'
- print self.c_public_initializer(self.prefix_lib)
- print '};'
- print '#undef MAPI_TMP_PUBLIC_ENTRIES'
- print '#endif /* MAPI_TMP_PUBLIC_ENTRIES */'
-
- print
- print '#ifdef MAPI_TMP_STUB_ASM_GCC'
- print '__asm__('
- print self.c_asm_gcc(self.prefix_lib, False)
- print ');'
- print '#undef MAPI_TMP_STUB_ASM_GCC'
- print '#endif /* MAPI_TMP_STUB_ASM_GCC */'
-
- if self.lib_need_non_hidden_entries:
- all_hidden = True
- for ent in self.entries:
- if not ent.hidden:
- all_hidden = False
- break
- if not all_hidden:
- print
- print '#ifdef MAPI_TMP_PUBLIC_ENTRIES_NO_HIDDEN'
- print self.c_public_dispatches(self.prefix_lib, True)
- print
- print '/* does not need public_entries */'
- print '#undef MAPI_TMP_PUBLIC_ENTRIES_NO_HIDDEN'
- print '#endif /* MAPI_TMP_PUBLIC_ENTRIES_NO_HIDDEN */'
-
- print
- print '#ifdef MAPI_TMP_STUB_ASM_GCC_NO_HIDDEN'
- print '__asm__('
- print self.c_asm_gcc(self.prefix_lib, True)
- print ');'
- print '#undef MAPI_TMP_STUB_ASM_GCC_NO_HIDDEN'
- print '#endif /* MAPI_TMP_STUB_ASM_GCC_NO_HIDDEN */'
-
- def output_for_app(self):
- print self.c_notice()
- print
- print self.c_private_declarations(self.prefix_app)
- print
- print '#ifdef API_TMP_DEFINE_SPEC'
- print
- print 'static const char %s_spec[] =' % (self.prefix_app)
- print self.c_mapi_table_spec()
- print
- print 'static const mapi_proc %s_procs[] = {' % (self.prefix_app)
- print self.c_mapi_table_initializer(self.prefix_app)
- print '};'
- print
- print '#endif /* API_TMP_DEFINE_SPEC */'
-
-class GLAPIPrinter(ABIPrinter):
- """OpenGL API Printer"""
-
- def __init__(self, entries):
- for ent in entries:
- self._override_for_api(ent)
- super(GLAPIPrinter, self).__init__(entries)
-
- self.api_defines = ['GL_GLEXT_PROTOTYPES']
- self.api_headers = ['"GL/gl.h"', '"GL/glext.h"']
- self.api_call = 'GLAPI'
- self.api_entry = 'APIENTRY'
- self.api_attrs = ''
-
- self.lib_need_table_size = False
- self.lib_need_noop_array = False
- self.lib_need_stubs = False
- self.lib_need_all_entries = False
- self.lib_need_non_hidden_entries = True
-
- self.prefix_lib = 'GLAPI_PREFIX'
- self.prefix_app = '_mesa_'
- self.prefix_noop = 'noop'
- self.prefix_warn = self.prefix_lib
-
- self.c_header = self._get_c_header()
-
- def _override_for_api(self, ent):
- """Override attributes of an entry if necessary for this
- printer."""
- # By default, no override is necessary.
- pass
-
- def _get_c_header(self):
- header = """#ifndef _GLAPI_TMP_H_
-#define _GLAPI_TMP_H_
-#ifdef USE_MGL_NAMESPACE
-#define GLAPI_PREFIX(func) mgl##func
-#define GLAPI_PREFIX_STR(func) "mgl"#func
-#else
-#define GLAPI_PREFIX(func) gl##func
-#define GLAPI_PREFIX_STR(func) "gl"#func
-#endif /* USE_MGL_NAMESPACE */
-
-typedef int GLfixed;
-typedef int GLclampx;
-#endif /* _GLAPI_TMP_H_ */"""
-
- return header
-
-class ES1APIPrinter(GLAPIPrinter):
- """OpenGL ES 1.x API Printer"""
-
- def __init__(self, entries):
- super(ES1APIPrinter, self).__init__(entries)
- self.prefix_lib = 'gl'
- self.prefix_warn = 'gl'
-
- def _override_for_api(self, ent):
- if ent.xml_data is None:
- raise Exception('ES2 API printer requires XML input')
- ent.hidden = ent.name not in \
- ent.xml_data.entry_points_for_api_version('es1')
- ent.handcode = False
-
- def _get_c_header(self):
- header = """#ifndef _GLAPI_TMP_H_
-#define _GLAPI_TMP_H_
-typedef int GLfixed;
-typedef int GLclampx;
-#endif /* _GLAPI_TMP_H_ */"""
-
- return header
-
-class ES2APIPrinter(GLAPIPrinter):
- """OpenGL ES 2.x API Printer"""
-
- def __init__(self, entries):
- super(ES2APIPrinter, self).__init__(entries)
- self.prefix_lib = 'gl'
- self.prefix_warn = 'gl'
-
- def _override_for_api(self, ent):
- if ent.xml_data is None:
- raise Exception('ES2 API printer requires XML input')
- ent.hidden = ent.name not in \
- ent.xml_data.entry_points_for_api_version('es2')
- ent.handcode = False
-
- def _get_c_header(self):
- header = """#ifndef _GLAPI_TMP_H_
-#define _GLAPI_TMP_H_
-typedef int GLfixed;
-typedef int GLclampx;
-#endif /* _GLAPI_TMP_H_ */"""
-
- return header
-
-class SharedGLAPIPrinter(GLAPIPrinter):
- """Shared GLAPI API Printer"""
-
- def __init__(self, entries):
- super(SharedGLAPIPrinter, self).__init__(entries)
-
- self.lib_need_table_size = True
- self.lib_need_noop_array = True
- self.lib_need_stubs = True
- self.lib_need_all_entries = True
- self.lib_need_non_hidden_entries = False
-
- self.prefix_lib = 'shared'
- self.prefix_warn = 'gl'
-
- def _override_for_api(self, ent):
- ent.hidden = True
- ent.handcode = False
-
- def _get_c_header(self):
- header = """#ifndef _GLAPI_TMP_H_
-#define _GLAPI_TMP_H_
-typedef int GLfixed;
-typedef int GLclampx;
-#endif /* _GLAPI_TMP_H_ */"""
-
- return header
-
-class VGAPIPrinter(ABIPrinter):
- """OpenVG API Printer"""
-
- def __init__(self, entries):
- super(VGAPIPrinter, self).__init__(entries)
-
- self.api_defines = ['VG_VGEXT_PROTOTYPES']
- self.api_headers = ['"VG/openvg.h"', '"VG/vgext.h"']
- self.api_call = 'VG_API_CALL'
- self.api_entry = 'VG_API_ENTRY'
- self.api_attrs = 'VG_API_EXIT'
-
- self.prefix_lib = 'vg'
- self.prefix_app = 'vega'
- self.prefix_noop = 'noop'
- self.prefix_warn = 'vg'
-
-def parse_args():
- printers = ['vgapi', 'glapi', 'es1api', 'es2api', 'shared-glapi']
- modes = ['lib', 'app']
-
- parser = OptionParser(usage='usage: %prog [options] <filename>')
- parser.add_option('-p', '--printer', dest='printer',
- help='printer to use: %s' % (", ".join(printers)))
- parser.add_option('-m', '--mode', dest='mode',
- help='target user: %s' % (", ".join(modes)))
-
- options, args = parser.parse_args()
- if not args or options.printer not in printers or \
- options.mode not in modes:
- parser.print_help()
- sys.exit(1)
-
- return (args[0], options)
-
-def main():
- printers = {
- 'vgapi': VGAPIPrinter,
- 'glapi': GLAPIPrinter,
- 'es1api': ES1APIPrinter,
- 'es2api': ES2APIPrinter,
- 'shared-glapi': SharedGLAPIPrinter,
- }
-
- filename, options = parse_args()
-
- if filename.endswith('.xml'):
- entries = abi_parse_xml(filename)
- else:
- entries = abi_parse(filename)
- abi_sanity_check(entries)
-
- printer = printers[options.printer](entries)
- if options.mode == 'lib':
- printer.output_for_lib()
- else:
- printer.output_for_app()
-
-if __name__ == '__main__':
- main()
+++ /dev/null
-/*
- * Mesa 3-D graphics library
- * Version: 7.9
- *
- * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
- * Copyright (C) 2010 LunarG Inc.
- *
- * 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 AUTHORS OR COPYRIGHT HOLDERS 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.
- *
- * Authors:
- * Chia-I Wu <olv@lunarg.com>
- */
-
-#include <string.h>
-#include "glapi/glapi.h"
-#include "mapi/u_current.h"
-#include "mapi/table.h" /* for MAPI_TABLE_NUM_SLOTS */
-#include "mapi/stub.h"
-
-/*
- * Global variables, _glapi_get_context, and _glapi_get_dispatch are defined in
- * u_current.c.
- */
-
-#ifdef GLX_USE_TLS
-/* not used, but defined for compatibility */
-const struct _glapi_table *_glapi_Dispatch;
-const void *_glapi_Context;
-#endif /* GLX_USE_TLS */
-
-void
-_glapi_destroy_multithread(void)
-{
- u_current_destroy();
-}
-
-void
-_glapi_check_multithread(void)
-{
- u_current_init();
-}
-
-void
-_glapi_set_context(void *context)
-{
- u_current_set_user((const void *) context);
-}
-
-void
-_glapi_set_dispatch(struct _glapi_table *dispatch)
-{
- u_current_set((const struct mapi_table *) dispatch);
-}
-
-/**
- * Return size of dispatch table struct as number of functions (or
- * slots).
- */
-unsigned int
-_glapi_get_dispatch_table_size(void)
-{
- return MAPI_TABLE_NUM_SLOTS;
-}
-
-/**
- * Fill-in the dispatch stub for the named function.
- *
- * This function is intended to be called by a hardware driver. When called,
- * a dispatch stub may be created created for the function. A pointer to this
- * dispatch function will be returned by glXGetProcAddress.
- *
- * \param function_names Array of pointers to function names that should
- * share a common dispatch offset.
- * \param parameter_signature String representing the types of the parameters
- * passed to the named function. Parameter types
- * are converted to characters using the following
- * rules:
- * - 'i' for \c GLint, \c GLuint, and \c GLenum
- * - 'p' for any pointer type
- * - 'f' for \c GLfloat and \c GLclampf
- * - 'd' for \c GLdouble and \c GLclampd
- *
- * \returns
- * The offset in the dispatch table of the named function. A pointer to the
- * driver's implementation of the named function should be stored at
- * \c dispatch_table[\c offset]. Return -1 if error/problem.
- *
- * \sa glXGetProcAddress
- *
- * \warning
- * This function can only handle up to 8 names at a time. As far as I know,
- * the maximum number of names ever associated with an existing GL function is
- * 4 (\c glPointParameterfSGIS, \c glPointParameterfEXT,
- * \c glPointParameterfARB, and \c glPointParameterf), so this should not be
- * too painful of a limitation.
- *
- * \todo
- * Check parameter_signature.
- */
-int
-_glapi_add_dispatch( const char * const * function_names,
- const char * parameter_signature )
-{
- const struct mapi_stub *function_stubs[8];
- const struct mapi_stub *alias = NULL;
- unsigned i;
-
- (void) memset(function_stubs, 0, sizeof(function_stubs));
-
- /* find the missing stubs, and decide the alias */
- for (i = 0; function_names[i] != NULL && i < 8; i++) {
- const char * funcName = function_names[i];
- const struct mapi_stub *stub;
- int slot;
-
- if (!funcName || funcName[0] != 'g' || funcName[1] != 'l')
- return -1;
- funcName += 2;
-
- stub = stub_find_public(funcName);
- if (!stub)
- stub = stub_find_dynamic(funcName, 0);
-
- slot = (stub) ? stub_get_slot(stub) : -1;
- if (slot >= 0) {
- if (alias && stub_get_slot(alias) != slot)
- return -1;
- /* use the first existing stub as the alias */
- if (!alias)
- alias = stub;
-
- function_stubs[i] = stub;
- }
- }
-
- /* generate missing stubs */
- for (i = 0; function_names[i] != NULL && i < 8; i++) {
- const char * funcName = function_names[i] + 2;
- struct mapi_stub *stub;
-
- if (function_stubs[i])
- continue;
-
- stub = stub_find_dynamic(funcName, 1);
- if (!stub)
- return -1;
-
- stub_fix_dynamic(stub, alias);
- if (!alias)
- alias = stub;
- }
-
- return (alias) ? stub_get_slot(alias) : -1;
-}
-
-static const struct mapi_stub *
-_glapi_get_stub(const char *name, int generate)
-{
- const struct mapi_stub *stub;
-
-#ifdef USE_MGL_NAMESPACE
- if (name)
- name++;
-#endif
-
- if (!name || name[0] != 'g' || name[1] != 'l')
- return NULL;
- name += 2;
-
- stub = stub_find_public(name);
- if (!stub)
- stub = stub_find_dynamic(name, generate);
-
- return stub;
-}
-
-/**
- * Return offset of entrypoint for named function within dispatch table.
- */
-int
-_glapi_get_proc_offset(const char *funcName)
-{
- const struct mapi_stub *stub = _glapi_get_stub(funcName, 0);
- return (stub) ? stub_get_slot(stub) : -1;
-}
-
-/**
- * Return pointer to the named function. If the function name isn't found
- * in the name of static functions, try generating a new API entrypoint on
- * the fly with assembly language.
- */
-_glapi_proc
-_glapi_get_proc_address(const char *funcName)
-{
- const struct mapi_stub *stub = _glapi_get_stub(funcName, 1);
- return (stub) ? (_glapi_proc) stub_get_addr(stub) : NULL;
-}
-
-/**
- * Return the name of the function at the given dispatch offset.
- * This is only intended for debugging.
- */
-const char *
-_glapi_get_proc_name(unsigned int offset)
-{
- const struct mapi_stub *stub = stub_find_by_slot(offset);
- return stub ? stub_get_name(stub) : NULL;
-}
-
-unsigned long
-_glthread_GetID(void)
-{
- return u_thread_self();
-}
-
-void
-_glapi_noop_enable_warnings(unsigned char enable)
-{
-}
-
-void
-_glapi_set_warning_func(_glapi_proc func)
-{
-}
+++ /dev/null
-/*
- * Mesa 3-D graphics library
- * Version: 7.9
- *
- * Copyright (C) 2010 LunarG Inc.
- *
- * 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 AUTHORS OR COPYRIGHT HOLDERS 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.
- *
- * Authors:
- * Chia-I Wu <olv@lunarg.com>
- */
-
-#ifndef MAPI_ABI_HEADER
-#error "MAPI_ABI_HEADER must be defined"
-#endif
-
-/* does not need hidden entries in bridge mode */
-#ifdef MAPI_MODE_BRIDGE
-
-#ifdef MAPI_TMP_PUBLIC_ENTRIES
-#undef MAPI_TMP_PUBLIC_ENTRIES
-#define MAPI_TMP_PUBLIC_ENTRIES_NO_HIDDEN
-#endif
-
-#ifdef MAPI_TMP_STUB_ASM_GCC
-#undef MAPI_TMP_STUB_ASM_GCC
-#define MAPI_TMP_STUB_ASM_GCC_NO_HIDDEN
-#endif
-
-#endif /* MAPI_MODE_BRIDGE */
-
-#include MAPI_ABI_HEADER
+++ /dev/null
-/*
- * Mesa 3-D graphics library
- * Version: 7.9
- *
- * Copyright (C) 2010 LunarG Inc.
- *
- * 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 AUTHORS OR COPYRIGHT HOLDERS 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.
- *
- * Authors:
- * Chia-I Wu <olv@lunarg.com>
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-
-#include "u_current.h"
-#include "u_thread.h"
-#include "entry.h"
-#include "stub.h"
-#include "table.h"
-
-#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))
-
-struct mapi_stub {
- const void *name;
- int slot;
- mapi_func addr;
-};
-
-/* define public_string_pool and public_stubs */
-#define MAPI_TMP_PUBLIC_STUBS
-#include "mapi_tmp.h"
-
-static struct mapi_stub dynamic_stubs[MAPI_TABLE_NUM_DYNAMIC];
-static int num_dynamic_stubs;
-static int next_dynamic_slot = MAPI_TABLE_NUM_STATIC;
-
-void
-stub_init_once(void)
-{
-#ifdef HAVE_PTHREAD
- static pthread_once_t once = PTHREAD_ONCE_INIT;
- pthread_once(&once, entry_patch_public);
-#else
- static int first = 1;
- if (first) {
- first = 0;
- entry_patch_public();
- }
-#endif
-}
-
-static int
-stub_compare(const void *key, const void *elem)
-{
- const char *name = (const char *) key;
- const struct mapi_stub *stub = (const struct mapi_stub *) elem;
- const char *stub_name;
-
- stub_name = &public_string_pool[(unsigned long) stub->name];
-
- return strcmp(name, stub_name);
-}
-
-/**
- * Return the public stub with the given name.
- */
-const struct mapi_stub *
-stub_find_public(const char *name)
-{
- return (const struct mapi_stub *) bsearch(name, public_stubs,
- ARRAY_SIZE(public_stubs), sizeof(public_stubs[0]), stub_compare);
-}
-
-/**
- * Add a dynamic stub.
- */
-static struct mapi_stub *
-stub_add_dynamic(const char *name)
-{
- struct mapi_stub *stub;
- int idx;
-
- idx = num_dynamic_stubs;
- /* minus 1 to make sure we can never reach the last slot */
- if (idx >= MAPI_TABLE_NUM_DYNAMIC - 1)
- return NULL;
-
- stub = &dynamic_stubs[idx];
-
- /* dispatch to the last slot, which is reserved for no-op */
- stub->addr = entry_generate(
- MAPI_TABLE_NUM_STATIC + MAPI_TABLE_NUM_DYNAMIC - 1);
- if (!stub->addr)
- return NULL;
-
- stub->name = (const void *) name;
- /* to be fixed later */
- stub->slot = -1;
-
- num_dynamic_stubs = idx + 1;
-
- return stub;
-}
-
-/**
- * Return the dynamic stub with the given name. If no such stub exists and
- * generate is true, a new stub is generated.
- */
-struct mapi_stub *
-stub_find_dynamic(const char *name, int generate)
-{
- u_mutex_declare_static(dynamic_mutex);
- struct mapi_stub *stub = NULL;
- int count, i;
-
- u_mutex_lock(dynamic_mutex);
-
- if (generate)
- assert(!stub_find_public(name));
-
- count = num_dynamic_stubs;
- for (i = 0; i < count; i++) {
- if (strcmp(name, (const char *) dynamic_stubs[i].name) == 0) {
- stub = &dynamic_stubs[i];
- break;
- }
- }
-
- /* generate a dynamic stub */
- if (generate && !stub)
- stub = stub_add_dynamic(name);
-
- u_mutex_unlock(dynamic_mutex);
-
- return stub;
-}
-
-static const struct mapi_stub *
-search_table_by_slot(const struct mapi_stub *table, size_t num_entries,
- int slot)
-{
- size_t i;
- for (i = 0; i < num_entries; ++i) {
- if (table[i].slot == slot)
- return &table[i];
- }
- return NULL;
-}
-
-const struct mapi_stub *
-stub_find_by_slot(int slot)
-{
- const struct mapi_stub *stub =
- search_table_by_slot(public_stubs, ARRAY_SIZE(public_stubs), slot);
- if (stub)
- return stub;
- return search_table_by_slot(dynamic_stubs, num_dynamic_stubs, slot);
-}
-
-void
-stub_fix_dynamic(struct mapi_stub *stub, const struct mapi_stub *alias)
-{
- int slot;
-
- if (stub->slot >= 0)
- return;
-
- if (alias)
- slot = alias->slot;
- else
- slot = next_dynamic_slot++;
-
- entry_patch(stub->addr, slot);
- stub->slot = slot;
-}
-
-/**
- * Return the name of a stub.
- */
-const char *
-stub_get_name(const struct mapi_stub *stub)
-{
- const char *name;
-
- if (stub >= public_stubs &&
- stub < public_stubs + ARRAY_SIZE(public_stubs))
- name = &public_string_pool[(unsigned long) stub->name];
- else
- name = (const char *) stub->name;
-
- return name;
-}
-
-/**
- * Return the slot of a stub.
- */
-int
-stub_get_slot(const struct mapi_stub *stub)
-{
- return stub->slot;
-}
-
-/**
- * Return the address of a stub.
- */
-mapi_func
-stub_get_addr(const struct mapi_stub *stub)
-{
- assert(stub->addr || (unsigned int) stub->slot < MAPI_TABLE_NUM_STATIC);
- return (stub->addr) ? stub->addr : entry_get_public(stub->slot);
-}
+++ /dev/null
-/*
- * Mesa 3-D graphics library
- * Version: 7.9
- *
- * Copyright (C) 2010 LunarG Inc.
- *
- * 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 AUTHORS OR COPYRIGHT HOLDERS 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.
- *
- * Authors:
- * Chia-I Wu <olv@lunarg.com>
- */
-
-#ifndef _STUB_H_
-#define _STUB_H_
-
-#include "entry.h"
-
-struct mapi_stub;
-
-void
-stub_init_once(void);
-
-const struct mapi_stub *
-stub_find_public(const char *name);
-
-struct mapi_stub *
-stub_find_dynamic(const char *name, int generate);
-
-const struct mapi_stub *
-stub_find_by_slot(int slot);
-
-void
-stub_fix_dynamic(struct mapi_stub *stub, const struct mapi_stub *alias);
-
-const char *
-stub_get_name(const struct mapi_stub *stub);
-
-int
-stub_get_slot(const struct mapi_stub *stub);
-
-mapi_func
-stub_get_addr(const struct mapi_stub *stub);
-
-#endif /* _STUB_H_ */
+++ /dev/null
-/*
- * Mesa 3-D graphics library
- * Version: 7.9
- *
- * Copyright (C) 2010 LunarG Inc.
- *
- * 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 AUTHORS OR COPYRIGHT HOLDERS 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.
- *
- * Authors:
- * Chia-I Wu <olv@lunarg.com>
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-
-#include "table.h"
-
-static void
-noop_warn(const char *name)
-{
- static int debug = -1;
-
- if (debug < 0)
- debug = (getenv("MESA_DEBUG") || getenv("LIBGL_DEBUG"));
-
- if (debug)
- fprintf(stderr, "%s is no-op\n", name);
-}
-
-static int
-noop_generic(void)
-{
- noop_warn("function");
- return 0;
-}
-
-/* define noop_array */
-#define MAPI_TMP_DEFINES
-#define MAPI_TMP_NOOP_ARRAY
-#include "mapi_tmp.h"
+++ /dev/null
-/*
- * Mesa 3-D graphics library
- * Version: 7.9
- *
- * Copyright (C) 2010 LunarG Inc.
- *
- * 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 AUTHORS OR COPYRIGHT HOLDERS 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.
- *
- * Authors:
- * Chia-I Wu <olv@lunarg.com>
- */
-
-#ifndef _TABLE_H_
-#define _TABLE_H_
-
-#include "u_compiler.h"
-#include "entry.h"
-
-#define MAPI_TMP_TABLE
-#include "mapi_tmp.h"
-
-#define MAPI_TABLE_NUM_SLOTS (MAPI_TABLE_NUM_STATIC + MAPI_TABLE_NUM_DYNAMIC)
-#define MAPI_TABLE_SIZE (MAPI_TABLE_NUM_SLOTS * sizeof(mapi_func))
-
-extern const mapi_func table_noop_array[];
-
-/**
- * Get the no-op dispatch table.
- */
-static INLINE const struct mapi_table *
-table_get_noop(void)
-{
- return (const struct mapi_table *) table_noop_array;
-}
-
-/**
- * Set the function of a slot.
- */
-static INLINE void
-table_set_func(struct mapi_table *tbl, int slot, mapi_func func)
-{
- mapi_func *funcs = (mapi_func *) tbl;
- funcs[slot] = func;
-}
-
-/**
- * Return the function of a slot.
- */
-static INLINE mapi_func
-table_get_func(const struct mapi_table *tbl, int slot)
-{
- const mapi_func *funcs = (const mapi_func *) tbl;
- return funcs[slot];
-}
-
-#endif /* _TABLE_H_ */
+++ /dev/null
-#ifndef _U_COMPILER_H_
-#define _U_COMPILER_H_
-
-#include "c99_compat.h" /* inline, __func__, etc. */
-
-
-/* XXX: Use standard `inline` keyword instead */
-#ifndef INLINE
-# define INLINE inline
-#endif
-
-/* Function visibility */
-#ifndef PUBLIC
-# if defined(__GNUC__) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590))
-# define PUBLIC __attribute__((visibility("default")))
-# elif defined(_MSC_VER)
-# define PUBLIC __declspec(dllexport)
-# else
-# define PUBLIC
-# endif
-#endif
-
-#ifndef likely
-# if defined(__GNUC__)
-# define likely(x) __builtin_expect(!!(x), 1)
-# define unlikely(x) __builtin_expect(!!(x), 0)
-# else
-# define likely(x) (x)
-# define unlikely(x) (x)
-# endif
-#endif
-
-#endif /* _U_COMPILER_H_ */
+++ /dev/null
-/*
- * Mesa 3-D graphics library
- * Version: 7.1
- *
- * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
- *
- * 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
- * BRIAN PAUL 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.
- */
-
-
-/*
- * This file manages the OpenGL API dispatch layer.
- * The dispatch table (struct _glapi_table) is basically just a list
- * of function pointers.
- * There are functions to set/get the current dispatch table for the
- * current thread and to manage registration/dispatch of dynamically
- * added extension functions.
- *
- * It's intended that this file and the other glapi*.[ch] files are
- * flexible enough to be reused in several places: XFree86, DRI-
- * based libGL.so, and perhaps the SGI SI.
- *
- * NOTE: There are no dependencies on Mesa in this code.
- *
- * Versions (API changes):
- * 2000/02/23 - original version for Mesa 3.3 and XFree86 4.0
- * 2001/01/16 - added dispatch override feature for Mesa 3.5
- * 2002/06/28 - added _glapi_set_warning_func(), Mesa 4.1.
- * 2002/10/01 - _glapi_get_proc_address() will now generate new entrypoints
- * itself (using offset ~0). _glapi_add_entrypoint() can be
- * called afterward and it'll fill in the correct dispatch
- * offset. This allows DRI libGL to avoid probing for DRI
- * drivers! No changes to the public glapi interface.
- */
-
-#include "u_current.h"
-#include "u_thread.h"
-
-#ifndef MAPI_MODE_UTIL
-
-#include "table.h"
-#include "stub.h"
-
-#else
-
-extern void init_glapi_relocs_once(void);
-extern void (*__glapi_noop_table[])(void);
-
-#define table_noop_array __glapi_noop_table
-#define stub_init_once() init_glapi_relocs_once()
-
-#endif
-
-/**
- * \name Current dispatch and current context control variables
- *
- * Depending on whether or not multithreading is support, and the type of
- * support available, several variables are used to store the current context
- * pointer and the current dispatch table pointer. In the non-threaded case,
- * the variables \c _glapi_Dispatch and \c _glapi_Context are used for this
- * purpose.
- *
- * In the "normal" threaded case, the variables \c _glapi_Dispatch and
- * \c _glapi_Context will be \c NULL if an application is detected as being
- * multithreaded. Single-threaded applications will use \c _glapi_Dispatch
- * and \c _glapi_Context just like the case without any threading support.
- * When \c _glapi_Dispatch and \c _glapi_Context are \c NULL, the thread state
- * data \c _gl_DispatchTSD and \c ContextTSD are used. Drivers and the
- * static dispatch functions access these variables via \c _glapi_get_dispatch
- * and \c _glapi_get_context.
- *
- * There is a race condition in setting \c _glapi_Dispatch to \c NULL. It is
- * possible for the original thread to be setting it at the same instant a new
- * thread, perhaps running on a different processor, is clearing it. Because
- * of that, \c ThreadSafe, which can only ever be changed to \c GL_TRUE, is
- * used to determine whether or not the application is multithreaded.
- *
- * In the TLS case, the variables \c _glapi_Dispatch and \c _glapi_Context are
- * hardcoded to \c NULL. Instead the TLS variables \c _glapi_tls_Dispatch and
- * \c _glapi_tls_Context are used. Having \c _glapi_Dispatch and
- * \c _glapi_Context be hardcoded to \c NULL maintains binary compatability
- * between TLS enabled loaders and non-TLS DRI drivers.
- */
-/*@{*/
-#if defined(GLX_USE_TLS)
-
-__thread struct mapi_table *u_current_table
- __attribute__((tls_model("initial-exec")))
- = (struct mapi_table *) table_noop_array;
-
-__thread void *u_current_user
- __attribute__((tls_model("initial-exec")));
-
-#else
-
-struct mapi_table *u_current_table =
- (struct mapi_table *) table_noop_array;
-void *u_current_user;
-
-#ifdef THREADS
-struct u_tsd u_current_table_tsd;
-static struct u_tsd u_current_user_tsd;
-static int ThreadSafe;
-#endif /* THREADS */
-
-#endif /* defined(GLX_USE_TLS) */
-/*@}*/
-
-
-void
-u_current_destroy(void)
-{
-#if defined(THREADS) && defined(_WIN32)
- u_tsd_destroy(&u_current_table_tsd);
- u_tsd_destroy(&u_current_user_tsd);
-#endif
-}
-
-
-#if defined(THREADS) && !defined(GLX_USE_TLS)
-
-static void
-u_current_init_tsd(void)
-{
- u_tsd_init(&u_current_table_tsd);
- u_tsd_init(&u_current_user_tsd);
-}
-
-/**
- * Mutex for multithread check.
- */
-u_mutex_declare_static(ThreadCheckMutex);
-
-/**
- * We should call this periodically from a function such as glXMakeCurrent
- * in order to test if multiple threads are being used.
- */
-void
-u_current_init(void)
-{
- static unsigned long knownID;
- static int firstCall = 1;
-
- if (ThreadSafe)
- return;
-
- u_mutex_lock(ThreadCheckMutex);
- if (firstCall) {
- u_current_init_tsd();
-
- knownID = u_thread_self();
- firstCall = 0;
- }
- else if (knownID != u_thread_self()) {
- ThreadSafe = 1;
- u_current_set(NULL);
- u_current_set_user(NULL);
- }
- u_mutex_unlock(ThreadCheckMutex);
-}
-
-#else
-
-void
-u_current_init(void)
-{
-}
-
-#endif
-
-
-
-/**
- * Set the current context pointer for this thread.
- * The context pointer is an opaque type which should be cast to
- * void from the real context pointer type.
- */
-void
-u_current_set_user(const void *ptr)
-{
- u_current_init();
-
-#if defined(GLX_USE_TLS)
- u_current_user = (void *) ptr;
-#elif defined(THREADS)
- u_tsd_set(&u_current_user_tsd, (void *) ptr);
- u_current_user = (ThreadSafe) ? NULL : (void *) ptr;
-#else
- u_current_user = (void *) ptr;
-#endif
-}
-
-/**
- * Get the current context pointer for this thread.
- * The context pointer is an opaque type which should be cast from
- * void to the real context pointer type.
- */
-void *
-u_current_get_user_internal(void)
-{
-#if defined(GLX_USE_TLS)
- return u_current_user;
-#elif defined(THREADS)
- return (ThreadSafe)
- ? u_tsd_get(&u_current_user_tsd)
- : u_current_user;
-#else
- return u_current_user;
-#endif
-}
-
-/**
- * Set the global or per-thread dispatch table pointer.
- * If the dispatch parameter is NULL we'll plug in the no-op dispatch
- * table (__glapi_noop_table).
- */
-void
-u_current_set(const struct mapi_table *tbl)
-{
- u_current_init();
-
- stub_init_once();
-
- if (!tbl)
- tbl = (const struct mapi_table *) table_noop_array;
-
-#if defined(GLX_USE_TLS)
- u_current_table = (struct mapi_table *) tbl;
-#elif defined(THREADS)
- u_tsd_set(&u_current_table_tsd, (void *) tbl);
- u_current_table = (ThreadSafe) ? NULL : (void *) tbl;
-#else
- u_current_table = (struct mapi_table *) tbl;
-#endif
-}
-
-/**
- * Return pointer to current dispatch table for calling thread.
- */
-struct mapi_table *
-u_current_get_internal(void)
-{
-#if defined(GLX_USE_TLS)
- return u_current_table;
-#elif defined(THREADS)
- return (struct mapi_table *) ((ThreadSafe) ?
- u_tsd_get(&u_current_table_tsd) : (void *) u_current_table);
-#else
- return u_current_table;
-#endif
-}
+++ /dev/null
-#ifndef _U_CURRENT_H_
-#define _U_CURRENT_H_
-
-#if defined(MAPI_MODE_UTIL) || defined(MAPI_MODE_GLAPI) || \
- defined(MAPI_MODE_BRIDGE)
-
-#include "glapi/glapi.h"
-
-/* ugly renames to match glapi.h */
-#define mapi_table _glapi_table
-
-#ifdef GLX_USE_TLS
-#define u_current_table _glapi_tls_Dispatch
-#define u_current_user _glapi_tls_Context
-#else
-#define u_current_table _glapi_Dispatch
-#define u_current_user _glapi_Context
-#endif
-
-#define u_current_get_internal _glapi_get_dispatch
-#define u_current_get_user_internal _glapi_get_context
-
-#define u_current_table_tsd _gl_DispatchTSD
-
-#else /* MAPI_MODE_UTIL || MAPI_MODE_GLAPI || MAPI_MODE_BRIDGE */
-
-#include "u_compiler.h"
-
-struct mapi_table;
-
-#ifdef GLX_USE_TLS
-
-extern __thread struct mapi_table *u_current_table
- __attribute__((tls_model("initial-exec")));
-
-extern __thread void *u_current_user
- __attribute__((tls_model("initial-exec")));
-
-#else /* GLX_USE_TLS */
-
-extern struct mapi_table *u_current_table;
-extern void *u_current_user;
-
-#endif /* GLX_USE_TLS */
-
-#endif /* MAPI_MODE_UTIL || MAPI_MODE_GLAPI || MAPI_MODE_BRIDGE */
-
-void
-u_current_init(void);
-
-void
-u_current_destroy(void);
-
-void
-u_current_set(const struct mapi_table *tbl);
-
-struct mapi_table *
-u_current_get_internal(void);
-
-void
-u_current_set_user(const void *ptr);
-
-void *
-u_current_get_user_internal(void);
-
-static INLINE const struct mapi_table *
-u_current_get(void)
-{
-#ifdef GLX_USE_TLS
- return u_current_table;
-#else
- return (likely(u_current_table) ?
- u_current_table : u_current_get_internal());
-#endif
-}
-
-static INLINE const void *
-u_current_get_user(void)
-{
-#ifdef GLX_USE_TLS
- return u_current_user;
-#else
- return likely(u_current_user) ? u_current_user : u_current_get_user_internal();
-#endif
-}
-
-#endif /* _U_CURRENT_H_ */
+++ /dev/null
-/*
- * Mesa 3-D graphics library
- * Version: 6.5
- *
- * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
- *
- * 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
- * BRIAN PAUL 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.
- */
-
-
-/**
- * \file glapi_execmem.c
- *
- * Function for allocating executable memory for dispatch stubs.
- *
- * Copied from main/execmem.c and simplified for dispatch stubs.
- */
-
-
-#include "u_compiler.h"
-#include "u_thread.h"
-#include "u_execmem.h"
-
-
-#define EXEC_MAP_SIZE (4*1024)
-
-u_mutex_declare_static(exec_mutex);
-
-static unsigned int head = 0;
-
-static unsigned char *exec_mem = (unsigned char *)0;
-
-
-#if defined(__linux__) || defined(__OpenBSD__) || defined(_NetBSD__) || defined(__sun)
-
-#include <unistd.h>
-#include <sys/mman.h>
-
-#ifdef MESA_SELINUX
-#include <selinux/selinux.h>
-#endif
-
-
-#ifndef MAP_ANONYMOUS
-#define MAP_ANONYMOUS MAP_ANON
-#endif
-
-
-/*
- * Dispatch stubs are of fixed size and never freed. Thus, we do not need to
- * overlay a heap, we just mmap a page and manage through an index.
- */
-
-static int
-init_map(void)
-{
-#ifdef MESA_SELINUX
- if (is_selinux_enabled()) {
- if (!security_get_boolean_active("allow_execmem") ||
- !security_get_boolean_pending("allow_execmem"))
- return 0;
- }
-#endif
-
- if (!exec_mem)
- exec_mem = mmap(NULL, EXEC_MAP_SIZE, PROT_EXEC | PROT_READ | PROT_WRITE,
- MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
-
- return (exec_mem != MAP_FAILED);
-}
-
-
-#elif defined(_WIN32)
-
-#include <windows.h>
-
-
-/*
- * Avoid Data Execution Prevention.
- */
-
-static int
-init_map(void)
-{
- exec_mem = VirtualAlloc(NULL, EXEC_MAP_SIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
-
- return (exec_mem != NULL);
-}
-
-
-#else
-
-#include <stdlib.h>
-
-static int
-init_map(void)
-{
- exec_mem = malloc(EXEC_MAP_SIZE);
-
- return (exec_mem != NULL);
-}
-
-
-#endif
-
-void *
-u_execmem_alloc(unsigned int size)
-{
- void *addr = NULL;
-
- u_mutex_lock(exec_mutex);
-
- if (!init_map())
- goto bail;
-
- /* free space check, assumes no integer overflow */
- if (head + size > EXEC_MAP_SIZE)
- goto bail;
-
- /* allocation, assumes proper addr and size alignement */
- addr = exec_mem + head;
- head += size;
-
-bail:
- u_mutex_unlock(exec_mutex);
-
- return addr;
-}
-
-
+++ /dev/null
-#ifndef _U_EXECMEM_H_
-#define _U_EXECMEM_H_
-
-void *
-u_execmem_alloc(unsigned int size);
-
-#endif /* _U_EXECMEM_H_ */
+++ /dev/null
-#ifndef _U_MACROS_
-#define _U_MACROS_
-
-#define _U_STRINGIFY(x) #x
-#define _U_CONCAT(x, y) x ## y
-#define _U_CONCAT_STR(x, y) #x#y
-
-#define U_STRINGIFY(x) _U_STRINGIFY(x)
-#define U_CONCAT(x, y) _U_CONCAT(x, y)
-#define U_CONCAT_STR(x, y) _U_CONCAT_STR(x, y)
-
-#endif /* _U_MACROS_ */
+++ /dev/null
-/*
- * Mesa 3-D graphics library
- * Version: 6.5.2
- *
- * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
- *
- * 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
- * BRIAN PAUL 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.
- */
-
-
-/*
- * Thread support for gl dispatch.
- *
- * Initial version by John Stone (j.stone@acm.org) (johns@cs.umr.edu)
- * and Christoph Poliwoda (poliwoda@volumegraphics.com)
- * Revised by Keith Whitwell
- * Adapted for new gl dispatcher by Brian Paul
- * Modified for use in mapi by Chia-I Wu
- */
-
-/*
- * If this file is accidentally included by a non-threaded build,
- * it should not cause the build to fail, or otherwise cause problems.
- * In general, it should only be included when needed however.
- */
-
-#ifndef _U_THREAD_H_
-#define _U_THREAD_H_
-
-#include <stdio.h>
-#include <stdlib.h>
-#include "u_compiler.h"
-
-#if defined(HAVE_PTHREAD)
-#include <pthread.h> /* POSIX threads headers */
-#endif
-#ifdef _WIN32
-#include <windows.h>
-#endif
-
-#if defined(HAVE_PTHREAD) || defined(_WIN32)
-#ifndef THREADS
-#define THREADS
-#endif
-#endif
-
-/*
- * Error messages
- */
-#define INIT_TSD_ERROR "_glthread_: failed to allocate key for thread specific data"
-#define GET_TSD_ERROR "_glthread_: failed to get thread specific data"
-#define SET_TSD_ERROR "_glthread_: thread failed to set thread specific data"
-
-
-/*
- * Magic number to determine if a TSD object has been initialized.
- * Kind of a hack but there doesn't appear to be a better cross-platform
- * solution.
- */
-#define INIT_MAGIC 0xff8adc98
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/*
- * POSIX threads. This should be your choice in the Unix world
- * whenever possible. When building with POSIX threads, be sure
- * to enable any compiler flags which will cause the MT-safe
- * libc (if one exists) to be used when linking, as well as any
- * header macros for MT-safe errno, etc. For Solaris, this is the -mt
- * compiler flag. On Solaris with gcc, use -D_REENTRANT to enable
- * proper compiling for MT-safe libc etc.
- */
-#if defined(HAVE_PTHREAD)
-
-struct u_tsd {
- pthread_key_t key;
- unsigned initMagic;
-};
-
-typedef pthread_mutex_t u_mutex;
-
-#define u_mutex_declare_static(name) \
- static u_mutex name = PTHREAD_MUTEX_INITIALIZER
-
-#define u_mutex_init(name) pthread_mutex_init(&(name), NULL)
-#define u_mutex_destroy(name) pthread_mutex_destroy(&(name))
-#define u_mutex_lock(name) (void) pthread_mutex_lock(&(name))
-#define u_mutex_unlock(name) (void) pthread_mutex_unlock(&(name))
-
-static INLINE unsigned long
-u_thread_self(void)
-{
- return (unsigned long) pthread_self();
-}
-
-
-static INLINE void
-u_tsd_init(struct u_tsd *tsd)
-{
- if (pthread_key_create(&tsd->key, NULL/*free*/) != 0) {
- perror(INIT_TSD_ERROR);
- exit(-1);
- }
- tsd->initMagic = INIT_MAGIC;
-}
-
-
-static INLINE void *
-u_tsd_get(struct u_tsd *tsd)
-{
- if (tsd->initMagic != INIT_MAGIC) {
- u_tsd_init(tsd);
- }
- return pthread_getspecific(tsd->key);
-}
-
-
-static INLINE void
-u_tsd_set(struct u_tsd *tsd, void *ptr)
-{
- if (tsd->initMagic != INIT_MAGIC) {
- u_tsd_init(tsd);
- }
- if (pthread_setspecific(tsd->key, ptr) != 0) {
- perror(SET_TSD_ERROR);
- exit(-1);
- }
-}
-
-#endif /* HAVE_PTHREAD */
-
-
-/*
- * Windows threads. Should work with Windows NT and 95.
- * IMPORTANT: Link with multithreaded runtime library when THREADS are
- * used!
- */
-#ifdef _WIN32
-
-struct u_tsd {
- DWORD key;
- unsigned initMagic;
-};
-
-typedef CRITICAL_SECTION u_mutex;
-
-/* http://locklessinc.com/articles/pthreads_on_windows/ */
-#define u_mutex_declare_static(name) \
- static u_mutex name = {(PCRITICAL_SECTION_DEBUG)-1, -1, 0, 0, 0, 0}
-
-#define u_mutex_init(name) InitializeCriticalSection(&name)
-#define u_mutex_destroy(name) DeleteCriticalSection(&name)
-#define u_mutex_lock(name) EnterCriticalSection(&name)
-#define u_mutex_unlock(name) LeaveCriticalSection(&name)
-
-static INLINE unsigned long
-u_thread_self(void)
-{
- return GetCurrentThreadId();
-}
-
-
-static INLINE void
-u_tsd_init(struct u_tsd *tsd)
-{
- tsd->key = TlsAlloc();
- if (tsd->key == TLS_OUT_OF_INDEXES) {
- perror(INIT_TSD_ERROR);
- exit(-1);
- }
- tsd->initMagic = INIT_MAGIC;
-}
-
-
-static INLINE void
-u_tsd_destroy(struct u_tsd *tsd)
-{
- if (tsd->initMagic != INIT_MAGIC) {
- return;
- }
- TlsFree(tsd->key);
- tsd->initMagic = 0x0;
-}
-
-
-static INLINE void *
-u_tsd_get(struct u_tsd *tsd)
-{
- if (tsd->initMagic != INIT_MAGIC) {
- u_tsd_init(tsd);
- }
- return TlsGetValue(tsd->key);
-}
-
-
-static INLINE void
-u_tsd_set(struct u_tsd *tsd, void *ptr)
-{
- /* the following code assumes that the struct u_tsd has been initialized
- to zero at creation */
- if (tsd->initMagic != INIT_MAGIC) {
- u_tsd_init(tsd);
- }
- if (TlsSetValue(tsd->key, ptr) == 0) {
- perror(SET_TSD_ERROR);
- exit(-1);
- }
-}
-
-#endif /* _WIN32 */
-
-
-/*
- * THREADS not defined
- */
-#ifndef THREADS
-
-struct u_tsd {
- unsigned initMagic;
-};
-
-typedef unsigned u_mutex;
-
-#define u_mutex_declare_static(name) static u_mutex name = 0
-#define u_mutex_init(name) (void) name
-#define u_mutex_destroy(name) (void) name
-#define u_mutex_lock(name) (void) name
-#define u_mutex_unlock(name) (void) name
-
-/*
- * no-op functions
- */
-
-static INLINE unsigned long
-u_thread_self(void)
-{
- return 0;
-}
-
-
-static INLINE void
-u_tsd_init(struct u_tsd *tsd)
-{
- (void) tsd;
-}
-
-
-static INLINE void *
-u_tsd_get(struct u_tsd *tsd)
-{
- (void) tsd;
- return NULL;
-}
-
-
-static INLINE void
-u_tsd_set(struct u_tsd *tsd, void *ptr)
-{
- (void) tsd;
- (void) ptr;
-}
-#endif /* THREADS */
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _U_THREAD_H_ */
--- /dev/null
+#!/usr/bin/env python
+
+# Mesa 3-D graphics library
+# Version: 7.9
+#
+# Copyright (C) 2010 LunarG Inc.
+#
+# 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 AUTHORS OR COPYRIGHT HOLDERS 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.
+#
+# Authors:
+# Chia-I Wu <olv@lunarg.com>
+
+import sys
+# make it possible to import glapi
+import os
+GLAPI = os.path.join(".", os.path.dirname(sys.argv[0]), "glapi/gen")
+sys.path.append(GLAPI)
+
+import re
+from optparse import OptionParser
+import gl_XML
+import glX_XML
+
+
+# number of dynamic entries
+ABI_NUM_DYNAMIC_ENTRIES = 256
+
+class ABIEntry(object):
+ """Represent an ABI entry."""
+
+ _match_c_param = re.compile(
+ '^(?P<type>[\w\s*]+?)(?P<name>\w+)(\[(?P<array>\d+)\])?$')
+
+ def __init__(self, cols, attrs, xml_data = None):
+ self._parse(cols)
+
+ self.slot = attrs['slot']
+ self.hidden = attrs['hidden']
+ self.alias = attrs['alias']
+ self.handcode = attrs['handcode']
+ self.xml_data = xml_data
+
+ def c_prototype(self):
+ return '%s %s(%s)' % (self.c_return(), self.name, self.c_params())
+
+ def c_return(self):
+ ret = self.ret
+ if not ret:
+ ret = 'void'
+
+ return ret
+
+ def c_params(self):
+ """Return the parameter list used in the entry prototype."""
+ c_params = []
+ for t, n, a in self.params:
+ sep = '' if t.endswith('*') else ' '
+ arr = '[%d]' % a if a else ''
+ c_params.append(t + sep + n + arr)
+ if not c_params:
+ c_params.append('void')
+
+ return ", ".join(c_params)
+
+ def c_args(self):
+ """Return the argument list used in the entry invocation."""
+ c_args = []
+ for t, n, a in self.params:
+ c_args.append(n)
+
+ return ", ".join(c_args)
+
+ def _parse(self, cols):
+ ret = cols.pop(0)
+ if ret == 'void':
+ ret = None
+
+ name = cols.pop(0)
+
+ params = []
+ if not cols:
+ raise Exception(cols)
+ elif len(cols) == 1 and cols[0] == 'void':
+ pass
+ else:
+ for val in cols:
+ params.append(self._parse_param(val))
+
+ self.ret = ret
+ self.name = name
+ self.params = params
+
+ def _parse_param(self, c_param):
+ m = self._match_c_param.match(c_param)
+ if not m:
+ raise Exception('unrecognized param ' + c_param)
+
+ c_type = m.group('type').strip()
+ c_name = m.group('name')
+ c_array = m.group('array')
+ c_array = int(c_array) if c_array else 0
+
+ return (c_type, c_name, c_array)
+
+ def __str__(self):
+ return self.c_prototype()
+
+ def __cmp__(self, other):
+ # compare slot, alias, and then name
+ res = cmp(self.slot, other.slot)
+ if not res:
+ if not self.alias:
+ res = -1
+ elif not other.alias:
+ res = 1
+
+ if not res:
+ res = cmp(self.name, other.name)
+
+ return res
+
+def abi_parse_xml(xml):
+ """Parse a GLAPI XML file for ABI entries."""
+ api = gl_XML.parse_GL_API(xml, glX_XML.glx_item_factory())
+
+ entry_dict = {}
+ for func in api.functionIterateByOffset():
+ # make sure func.name appear first
+ entry_points = func.entry_points[:]
+ entry_points.remove(func.name)
+ entry_points.insert(0, func.name)
+
+ for name in entry_points:
+ attrs = {
+ 'slot': func.offset,
+ 'hidden': not func.is_static_entry_point(name),
+ 'alias': None if name == func.name else func.name,
+ 'handcode': bool(func.has_different_protocol(name)),
+ }
+
+ # post-process attrs
+ if attrs['alias']:
+ try:
+ alias = entry_dict[attrs['alias']]
+ except KeyError:
+ raise Exception('failed to alias %s' % attrs['alias'])
+ if alias.alias:
+ raise Exception('recursive alias %s' % ent.name)
+ attrs['alias'] = alias
+ if attrs['handcode']:
+ attrs['handcode'] = func.static_glx_name(name)
+ else:
+ attrs['handcode'] = None
+
+ if entry_dict.has_key(name):
+ raise Exception('%s is duplicated' % (name))
+
+ cols = []
+ cols.append(func.return_type)
+ cols.append(name)
+ params = func.get_parameter_string(name)
+ cols.extend([p.strip() for p in params.split(',')])
+
+ ent = ABIEntry(cols, attrs, func)
+ entry_dict[ent.name] = ent
+
+ entries = entry_dict.values()
+ entries.sort()
+
+ return entries
+
+def abi_parse_line(line):
+ cols = [col.strip() for col in line.split(',')]
+
+ attrs = {
+ 'slot': -1,
+ 'hidden': False,
+ 'alias': None,
+ 'handcode': None,
+ }
+
+ # extract attributes from the first column
+ vals = cols[0].split(':')
+ while len(vals) > 1:
+ val = vals.pop(0)
+ if val.startswith('slot='):
+ attrs['slot'] = int(val[5:])
+ elif val == 'hidden':
+ attrs['hidden'] = True
+ elif val.startswith('alias='):
+ attrs['alias'] = val[6:]
+ elif val.startswith('handcode='):
+ attrs['handcode'] = val[9:]
+ elif not val:
+ pass
+ else:
+ raise Exception('unknown attribute %s' % val)
+ cols[0] = vals[0]
+
+ return (attrs, cols)
+
+def abi_parse(filename):
+ """Parse a CSV file for ABI entries."""
+ fp = open(filename) if filename != '-' else sys.stdin
+ lines = [line.strip() for line in fp.readlines()
+ if not line.startswith('#') and line.strip()]
+
+ entry_dict = {}
+ next_slot = 0
+ for line in lines:
+ attrs, cols = abi_parse_line(line)
+
+ # post-process attributes
+ if attrs['alias']:
+ try:
+ alias = entry_dict[attrs['alias']]
+ except KeyError:
+ raise Exception('failed to alias %s' % attrs['alias'])
+ if alias.alias:
+ raise Exception('recursive alias %s' % ent.name)
+ slot = alias.slot
+ attrs['alias'] = alias
+ else:
+ slot = next_slot
+ next_slot += 1
+
+ if attrs['slot'] < 0:
+ attrs['slot'] = slot
+ elif attrs['slot'] != slot:
+ raise Exception('invalid slot in %s' % (line))
+
+ ent = ABIEntry(cols, attrs)
+ if entry_dict.has_key(ent.name):
+ raise Exception('%s is duplicated' % (ent.name))
+ entry_dict[ent.name] = ent
+
+ entries = entry_dict.values()
+ entries.sort()
+
+ return entries
+
+def abi_sanity_check(entries):
+ if not entries:
+ return
+
+ all_names = []
+ last_slot = entries[-1].slot
+ i = 0
+ for slot in xrange(last_slot + 1):
+ if entries[i].slot != slot:
+ raise Exception('entries are not ordered by slots')
+ if entries[i].alias:
+ raise Exception('first entry of slot %d aliases %s'
+ % (slot, entries[i].alias.name))
+ handcode = None
+ while i < len(entries) and entries[i].slot == slot:
+ ent = entries[i]
+ if not handcode and ent.handcode:
+ handcode = ent.handcode
+ elif ent.handcode != handcode:
+ raise Exception('two aliases with handcode %s != %s',
+ ent.handcode, handcode)
+
+ if ent.name in all_names:
+ raise Exception('%s is duplicated' % (ent.name))
+ if ent.alias and ent.alias.name not in all_names:
+ raise Exception('failed to alias %s' % (ent.alias.name))
+ all_names.append(ent.name)
+ i += 1
+ if i < len(entries):
+ raise Exception('there are %d invalid entries' % (len(entries) - 1))
+
+class ABIPrinter(object):
+ """MAPI Printer"""
+
+ def __init__(self, entries):
+ self.entries = entries
+
+ # sort entries by their names
+ self.entries_sorted_by_names = self.entries[:]
+ self.entries_sorted_by_names.sort(lambda x, y: cmp(x.name, y.name))
+
+ self.indent = ' ' * 3
+ self.noop_warn = 'noop_warn'
+ self.noop_generic = 'noop_generic'
+ self.current_get = 'entry_current_get'
+
+ self.api_defines = []
+ self.api_headers = ['"KHR/khrplatform.h"']
+ self.api_call = 'KHRONOS_APICALL'
+ self.api_entry = 'KHRONOS_APIENTRY'
+ self.api_attrs = 'KHRONOS_APIATTRIBUTES'
+
+ self.c_header = ''
+
+ self.lib_need_table_size = True
+ self.lib_need_noop_array = True
+ self.lib_need_stubs = True
+ self.lib_need_all_entries = True
+ self.lib_need_non_hidden_entries = False
+
+ def c_notice(self):
+ return '/* This file is automatically generated by mapi_abi.py. Do not modify. */'
+
+ def c_public_includes(self):
+ """Return includes of the client API headers."""
+ defines = ['#define ' + d for d in self.api_defines]
+ includes = ['#include ' + h for h in self.api_headers]
+ return "\n".join(defines + includes)
+
+ def need_entry_point(self, ent):
+ """Return True if an entry point is needed for the entry."""
+ # non-handcode hidden aliases may share the entry they alias
+ use_alias = (ent.hidden and ent.alias and not ent.handcode)
+ return not use_alias
+
+ def c_public_declarations(self, prefix):
+ """Return the declarations of public entry points."""
+ decls = []
+ for ent in self.entries:
+ if not self.need_entry_point(ent):
+ continue
+ export = self.api_call if not ent.hidden else ''
+ decls.append(self._c_decl(ent, prefix, True, export) + ';')
+
+ return "\n".join(decls)
+
+ def c_mapi_table(self):
+ """Return defines of the dispatch table size."""
+ num_static_entries = self.entries[-1].slot + 1
+ return ('#define MAPI_TABLE_NUM_STATIC %d\n' + \
+ '#define MAPI_TABLE_NUM_DYNAMIC %d') % (
+ num_static_entries, ABI_NUM_DYNAMIC_ENTRIES)
+
+ def c_mapi_table_initializer(self, prefix):
+ """Return the array initializer for mapi_table_fill."""
+ entries = [self._c_function(ent, prefix)
+ for ent in self.entries if not ent.alias]
+ pre = self.indent + '(mapi_proc) '
+ return pre + (',\n' + pre).join(entries)
+
+ def c_mapi_table_spec(self):
+ """Return the spec for mapi_init."""
+ specv1 = []
+ line = '"1'
+ for ent in self.entries:
+ if not ent.alias:
+ line += '\\0"\n'
+ specv1.append(line)
+ line = '"'
+ line += '%s\\0' % ent.name
+ line += '";'
+ specv1.append(line)
+
+ return self.indent + self.indent.join(specv1)
+
+ def _c_function(self, ent, prefix, mangle=False, stringify=False):
+ """Return the function name of an entry."""
+ formats = {
+ True: { True: '%s_STR(%s)', False: '%s(%s)' },
+ False: { True: '"%s%s"', False: '%s%s' },
+ }
+ fmt = formats[prefix.isupper()][stringify]
+ name = ent.name
+ if mangle and ent.hidden:
+ name = '_dispatch_stub_' + str(ent.slot)
+ return fmt % (prefix, name)
+
+ def _c_function_call(self, ent, prefix):
+ """Return the function name used for calling."""
+ if ent.handcode:
+ # _c_function does not handle this case
+ formats = { True: '%s(%s)', False: '%s%s' }
+ fmt = formats[prefix.isupper()]
+ name = fmt % (prefix, ent.handcode)
+ elif self.need_entry_point(ent):
+ name = self._c_function(ent, prefix, True)
+ else:
+ name = self._c_function(ent.alias, prefix, True)
+ return name
+
+ def _c_decl(self, ent, prefix, mangle=False, export=''):
+ """Return the C declaration for the entry."""
+ decl = '%s %s %s(%s)' % (ent.c_return(), self.api_entry,
+ self._c_function(ent, prefix, mangle), ent.c_params())
+ if export:
+ decl = export + ' ' + decl
+ if self.api_attrs:
+ decl += ' ' + self.api_attrs
+
+ return decl
+
+ def _c_cast(self, ent):
+ """Return the C cast for the entry."""
+ cast = '%s (%s *)(%s)' % (
+ ent.c_return(), self.api_entry, ent.c_params())
+
+ return cast
+
+ def c_private_declarations(self, prefix):
+ """Return the declarations of private functions."""
+ decls = [self._c_decl(ent, prefix) + ';'
+ for ent in self.entries if not ent.alias]
+
+ return "\n".join(decls)
+
+ def c_public_dispatches(self, prefix, no_hidden):
+ """Return the public dispatch functions."""
+ dispatches = []
+ for ent in self.entries:
+ if ent.hidden and no_hidden:
+ continue
+
+ if not self.need_entry_point(ent):
+ continue
+
+ export = self.api_call if not ent.hidden else ''
+
+ proto = self._c_decl(ent, prefix, True, export)
+ cast = self._c_cast(ent)
+
+ ret = ''
+ if ent.ret:
+ ret = 'return '
+ stmt1 = self.indent
+ stmt1 += 'const struct mapi_table *_tbl = %s();' % (
+ self.current_get)
+ stmt2 = self.indent
+ stmt2 += 'mapi_func _func = ((const mapi_func *) _tbl)[%d];' % (
+ ent.slot)
+ stmt3 = self.indent
+ stmt3 += '%s((%s) _func)(%s);' % (ret, cast, ent.c_args())
+
+ disp = '%s\n{\n%s\n%s\n%s\n}' % (proto, stmt1, stmt2, stmt3)
+
+ if ent.handcode:
+ disp = '#if 0\n' + disp + '\n#endif'
+
+ dispatches.append(disp)
+
+ return '\n\n'.join(dispatches)
+
+ def c_public_initializer(self, prefix):
+ """Return the initializer for public dispatch functions."""
+ names = []
+ for ent in self.entries:
+ if ent.alias:
+ continue
+
+ name = '%s(mapi_func) %s' % (self.indent,
+ self._c_function_call(ent, prefix))
+ names.append(name)
+
+ return ',\n'.join(names)
+
+ def c_stub_string_pool(self):
+ """Return the string pool for use by stubs."""
+ # sort entries by their names
+ sorted_entries = self.entries[:]
+ sorted_entries.sort(lambda x, y: cmp(x.name, y.name))
+
+ pool = []
+ offsets = {}
+ count = 0
+ for ent in sorted_entries:
+ offsets[ent] = count
+ pool.append('%s' % (ent.name))
+ count += len(ent.name) + 1
+
+ pool_str = self.indent + '"' + \
+ ('\\0"\n' + self.indent + '"').join(pool) + '";'
+ return (pool_str, offsets)
+
+ def c_stub_initializer(self, prefix, pool_offsets):
+ """Return the initializer for struct mapi_stub array."""
+ stubs = []
+ for ent in self.entries_sorted_by_names:
+ stubs.append('%s{ (void *) %d, %d, NULL }' % (
+ self.indent, pool_offsets[ent], ent.slot))
+
+ return ',\n'.join(stubs)
+
+ def c_noop_functions(self, prefix, warn_prefix):
+ """Return the noop functions."""
+ noops = []
+ for ent in self.entries:
+ if ent.alias:
+ continue
+
+ proto = self._c_decl(ent, prefix, False, 'static')
+
+ stmt1 = self.indent;
+ space = ''
+ for t, n, a in ent.params:
+ stmt1 += "%s(void) %s;" % (space, n)
+ space = ' '
+
+ if ent.params:
+ stmt1 += '\n';
+
+ stmt1 += self.indent + '%s(%s);' % (self.noop_warn,
+ self._c_function(ent, warn_prefix, False, True))
+
+ if ent.ret:
+ stmt2 = self.indent + 'return (%s) 0;' % (ent.ret)
+ noop = '%s\n{\n%s\n%s\n}' % (proto, stmt1, stmt2)
+ else:
+ noop = '%s\n{\n%s\n}' % (proto, stmt1)
+
+ noops.append(noop)
+
+ return '\n\n'.join(noops)
+
+ def c_noop_initializer(self, prefix, use_generic):
+ """Return an initializer for the noop dispatch table."""
+ entries = [self._c_function(ent, prefix)
+ for ent in self.entries if not ent.alias]
+ if use_generic:
+ entries = [self.noop_generic] * len(entries)
+
+ entries.extend([self.noop_generic] * ABI_NUM_DYNAMIC_ENTRIES)
+
+ pre = self.indent + '(mapi_func) '
+ return pre + (',\n' + pre).join(entries)
+
+ def c_asm_gcc(self, prefix, no_hidden):
+ asm = []
+
+ for ent in self.entries:
+ if ent.hidden and no_hidden:
+ continue
+
+ if not self.need_entry_point(ent):
+ continue
+
+ name = self._c_function(ent, prefix, True, True)
+
+ if ent.handcode:
+ asm.append('#if 0')
+
+ if ent.hidden:
+ asm.append('".hidden "%s"\\n"' % (name))
+
+ if ent.alias and not (ent.alias.hidden and no_hidden):
+ asm.append('".globl "%s"\\n"' % (name))
+ asm.append('".set "%s", "%s"\\n"' % (name,
+ self._c_function(ent.alias, prefix, True, True)))
+ else:
+ asm.append('STUB_ASM_ENTRY(%s)"\\n"' % (name))
+ asm.append('"\\t"STUB_ASM_CODE("%d")"\\n"' % (ent.slot))
+
+ if ent.handcode:
+ asm.append('#endif')
+ asm.append('')
+
+ return "\n".join(asm)
+
+ def output_for_lib(self):
+ print self.c_notice()
+
+ if self.c_header:
+ print
+ print self.c_header
+
+ print
+ print '#ifdef MAPI_TMP_DEFINES'
+ print self.c_public_includes()
+ print
+ print self.c_public_declarations(self.prefix_lib)
+ print '#undef MAPI_TMP_DEFINES'
+ print '#endif /* MAPI_TMP_DEFINES */'
+
+ if self.lib_need_table_size:
+ print
+ print '#ifdef MAPI_TMP_TABLE'
+ print self.c_mapi_table()
+ print '#undef MAPI_TMP_TABLE'
+ print '#endif /* MAPI_TMP_TABLE */'
+
+ if self.lib_need_noop_array:
+ print
+ print '#ifdef MAPI_TMP_NOOP_ARRAY'
+ print '#ifdef DEBUG'
+ print
+ print self.c_noop_functions(self.prefix_noop, self.prefix_warn)
+ print
+ print 'const mapi_func table_%s_array[] = {' % (self.prefix_noop)
+ print self.c_noop_initializer(self.prefix_noop, False)
+ print '};'
+ print
+ print '#else /* DEBUG */'
+ print
+ print 'const mapi_func table_%s_array[] = {' % (self.prefix_noop)
+ print self.c_noop_initializer(self.prefix_noop, True)
+ print '};'
+ print
+ print '#endif /* DEBUG */'
+ print '#undef MAPI_TMP_NOOP_ARRAY'
+ print '#endif /* MAPI_TMP_NOOP_ARRAY */'
+
+ if self.lib_need_stubs:
+ pool, pool_offsets = self.c_stub_string_pool()
+ print
+ print '#ifdef MAPI_TMP_PUBLIC_STUBS'
+ print 'static const char public_string_pool[] ='
+ print pool
+ print
+ print 'static const struct mapi_stub public_stubs[] = {'
+ print self.c_stub_initializer(self.prefix_lib, pool_offsets)
+ print '};'
+ print '#undef MAPI_TMP_PUBLIC_STUBS'
+ print '#endif /* MAPI_TMP_PUBLIC_STUBS */'
+
+ if self.lib_need_all_entries:
+ print
+ print '#ifdef MAPI_TMP_PUBLIC_ENTRIES'
+ print self.c_public_dispatches(self.prefix_lib, False)
+ print
+ print 'static const mapi_func public_entries[] = {'
+ print self.c_public_initializer(self.prefix_lib)
+ print '};'
+ print '#undef MAPI_TMP_PUBLIC_ENTRIES'
+ print '#endif /* MAPI_TMP_PUBLIC_ENTRIES */'
+
+ print
+ print '#ifdef MAPI_TMP_STUB_ASM_GCC'
+ print '__asm__('
+ print self.c_asm_gcc(self.prefix_lib, False)
+ print ');'
+ print '#undef MAPI_TMP_STUB_ASM_GCC'
+ print '#endif /* MAPI_TMP_STUB_ASM_GCC */'
+
+ if self.lib_need_non_hidden_entries:
+ all_hidden = True
+ for ent in self.entries:
+ if not ent.hidden:
+ all_hidden = False
+ break
+ if not all_hidden:
+ print
+ print '#ifdef MAPI_TMP_PUBLIC_ENTRIES_NO_HIDDEN'
+ print self.c_public_dispatches(self.prefix_lib, True)
+ print
+ print '/* does not need public_entries */'
+ print '#undef MAPI_TMP_PUBLIC_ENTRIES_NO_HIDDEN'
+ print '#endif /* MAPI_TMP_PUBLIC_ENTRIES_NO_HIDDEN */'
+
+ print
+ print '#ifdef MAPI_TMP_STUB_ASM_GCC_NO_HIDDEN'
+ print '__asm__('
+ print self.c_asm_gcc(self.prefix_lib, True)
+ print ');'
+ print '#undef MAPI_TMP_STUB_ASM_GCC_NO_HIDDEN'
+ print '#endif /* MAPI_TMP_STUB_ASM_GCC_NO_HIDDEN */'
+
+ def output_for_app(self):
+ print self.c_notice()
+ print
+ print self.c_private_declarations(self.prefix_app)
+ print
+ print '#ifdef API_TMP_DEFINE_SPEC'
+ print
+ print 'static const char %s_spec[] =' % (self.prefix_app)
+ print self.c_mapi_table_spec()
+ print
+ print 'static const mapi_proc %s_procs[] = {' % (self.prefix_app)
+ print self.c_mapi_table_initializer(self.prefix_app)
+ print '};'
+ print
+ print '#endif /* API_TMP_DEFINE_SPEC */'
+
+class GLAPIPrinter(ABIPrinter):
+ """OpenGL API Printer"""
+
+ def __init__(self, entries):
+ for ent in entries:
+ self._override_for_api(ent)
+ super(GLAPIPrinter, self).__init__(entries)
+
+ self.api_defines = ['GL_GLEXT_PROTOTYPES']
+ self.api_headers = ['"GL/gl.h"', '"GL/glext.h"']
+ self.api_call = 'GLAPI'
+ self.api_entry = 'APIENTRY'
+ self.api_attrs = ''
+
+ self.lib_need_table_size = False
+ self.lib_need_noop_array = False
+ self.lib_need_stubs = False
+ self.lib_need_all_entries = False
+ self.lib_need_non_hidden_entries = True
+
+ self.prefix_lib = 'GLAPI_PREFIX'
+ self.prefix_app = '_mesa_'
+ self.prefix_noop = 'noop'
+ self.prefix_warn = self.prefix_lib
+
+ self.c_header = self._get_c_header()
+
+ def _override_for_api(self, ent):
+ """Override attributes of an entry if necessary for this
+ printer."""
+ # By default, no override is necessary.
+ pass
+
+ def _get_c_header(self):
+ header = """#ifndef _GLAPI_TMP_H_
+#define _GLAPI_TMP_H_
+#ifdef USE_MGL_NAMESPACE
+#define GLAPI_PREFIX(func) mgl##func
+#define GLAPI_PREFIX_STR(func) "mgl"#func
+#else
+#define GLAPI_PREFIX(func) gl##func
+#define GLAPI_PREFIX_STR(func) "gl"#func
+#endif /* USE_MGL_NAMESPACE */
+
+typedef int GLfixed;
+typedef int GLclampx;
+#endif /* _GLAPI_TMP_H_ */"""
+
+ return header
+
+class ES1APIPrinter(GLAPIPrinter):
+ """OpenGL ES 1.x API Printer"""
+
+ def __init__(self, entries):
+ super(ES1APIPrinter, self).__init__(entries)
+ self.prefix_lib = 'gl'
+ self.prefix_warn = 'gl'
+
+ def _override_for_api(self, ent):
+ if ent.xml_data is None:
+ raise Exception('ES2 API printer requires XML input')
+ ent.hidden = ent.name not in \
+ ent.xml_data.entry_points_for_api_version('es1')
+ ent.handcode = False
+
+ def _get_c_header(self):
+ header = """#ifndef _GLAPI_TMP_H_
+#define _GLAPI_TMP_H_
+typedef int GLfixed;
+typedef int GLclampx;
+#endif /* _GLAPI_TMP_H_ */"""
+
+ return header
+
+class ES2APIPrinter(GLAPIPrinter):
+ """OpenGL ES 2.x API Printer"""
+
+ def __init__(self, entries):
+ super(ES2APIPrinter, self).__init__(entries)
+ self.prefix_lib = 'gl'
+ self.prefix_warn = 'gl'
+
+ def _override_for_api(self, ent):
+ if ent.xml_data is None:
+ raise Exception('ES2 API printer requires XML input')
+ ent.hidden = ent.name not in \
+ ent.xml_data.entry_points_for_api_version('es2')
+ ent.handcode = False
+
+ def _get_c_header(self):
+ header = """#ifndef _GLAPI_TMP_H_
+#define _GLAPI_TMP_H_
+typedef int GLfixed;
+typedef int GLclampx;
+#endif /* _GLAPI_TMP_H_ */"""
+
+ return header
+
+class SharedGLAPIPrinter(GLAPIPrinter):
+ """Shared GLAPI API Printer"""
+
+ def __init__(self, entries):
+ super(SharedGLAPIPrinter, self).__init__(entries)
+
+ self.lib_need_table_size = True
+ self.lib_need_noop_array = True
+ self.lib_need_stubs = True
+ self.lib_need_all_entries = True
+ self.lib_need_non_hidden_entries = False
+
+ self.prefix_lib = 'shared'
+ self.prefix_warn = 'gl'
+
+ def _override_for_api(self, ent):
+ ent.hidden = True
+ ent.handcode = False
+
+ def _get_c_header(self):
+ header = """#ifndef _GLAPI_TMP_H_
+#define _GLAPI_TMP_H_
+typedef int GLfixed;
+typedef int GLclampx;
+#endif /* _GLAPI_TMP_H_ */"""
+
+ return header
+
+class VGAPIPrinter(ABIPrinter):
+ """OpenVG API Printer"""
+
+ def __init__(self, entries):
+ super(VGAPIPrinter, self).__init__(entries)
+
+ self.api_defines = ['VG_VGEXT_PROTOTYPES']
+ self.api_headers = ['"VG/openvg.h"', '"VG/vgext.h"']
+ self.api_call = 'VG_API_CALL'
+ self.api_entry = 'VG_API_ENTRY'
+ self.api_attrs = 'VG_API_EXIT'
+
+ self.prefix_lib = 'vg'
+ self.prefix_app = 'vega'
+ self.prefix_noop = 'noop'
+ self.prefix_warn = 'vg'
+
+def parse_args():
+ printers = ['vgapi', 'glapi', 'es1api', 'es2api', 'shared-glapi']
+ modes = ['lib', 'app']
+
+ parser = OptionParser(usage='usage: %prog [options] <filename>')
+ parser.add_option('-p', '--printer', dest='printer',
+ help='printer to use: %s' % (", ".join(printers)))
+ parser.add_option('-m', '--mode', dest='mode',
+ help='target user: %s' % (", ".join(modes)))
+
+ options, args = parser.parse_args()
+ if not args or options.printer not in printers or \
+ options.mode not in modes:
+ parser.print_help()
+ sys.exit(1)
+
+ return (args[0], options)
+
+def main():
+ printers = {
+ 'vgapi': VGAPIPrinter,
+ 'glapi': GLAPIPrinter,
+ 'es1api': ES1APIPrinter,
+ 'es2api': ES2APIPrinter,
+ 'shared-glapi': SharedGLAPIPrinter,
+ }
+
+ filename, options = parse_args()
+
+ if filename.endswith('.xml'):
+ entries = abi_parse_xml(filename)
+ else:
+ entries = abi_parse(filename)
+ abi_sanity_check(entries)
+
+ printer = printers[options.printer](entries)
+ if options.mode == 'lib':
+ printer.output_for_lib()
+ else:
+ printer.output_for_app()
+
+if __name__ == '__main__':
+ main()
--- /dev/null
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.9
+ *
+ * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS 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.
+ *
+ * Authors:
+ * Chia-I Wu <olv@lunarg.com>
+ */
+
+#include <string.h>
+#include "glapi/glapi.h"
+#include "u_current.h"
+#include "table.h" /* for MAPI_TABLE_NUM_SLOTS */
+#include "stub.h"
+
+/*
+ * Global variables, _glapi_get_context, and _glapi_get_dispatch are defined in
+ * u_current.c.
+ */
+
+#ifdef GLX_USE_TLS
+/* not used, but defined for compatibility */
+const struct _glapi_table *_glapi_Dispatch;
+const void *_glapi_Context;
+#endif /* GLX_USE_TLS */
+
+void
+_glapi_destroy_multithread(void)
+{
+ u_current_destroy();
+}
+
+void
+_glapi_check_multithread(void)
+{
+ u_current_init();
+}
+
+void
+_glapi_set_context(void *context)
+{
+ u_current_set_user((const void *) context);
+}
+
+void
+_glapi_set_dispatch(struct _glapi_table *dispatch)
+{
+ u_current_set((const struct mapi_table *) dispatch);
+}
+
+/**
+ * Return size of dispatch table struct as number of functions (or
+ * slots).
+ */
+unsigned int
+_glapi_get_dispatch_table_size(void)
+{
+ return MAPI_TABLE_NUM_SLOTS;
+}
+
+/**
+ * Fill-in the dispatch stub for the named function.
+ *
+ * This function is intended to be called by a hardware driver. When called,
+ * a dispatch stub may be created created for the function. A pointer to this
+ * dispatch function will be returned by glXGetProcAddress.
+ *
+ * \param function_names Array of pointers to function names that should
+ * share a common dispatch offset.
+ * \param parameter_signature String representing the types of the parameters
+ * passed to the named function. Parameter types
+ * are converted to characters using the following
+ * rules:
+ * - 'i' for \c GLint, \c GLuint, and \c GLenum
+ * - 'p' for any pointer type
+ * - 'f' for \c GLfloat and \c GLclampf
+ * - 'd' for \c GLdouble and \c GLclampd
+ *
+ * \returns
+ * The offset in the dispatch table of the named function. A pointer to the
+ * driver's implementation of the named function should be stored at
+ * \c dispatch_table[\c offset]. Return -1 if error/problem.
+ *
+ * \sa glXGetProcAddress
+ *
+ * \warning
+ * This function can only handle up to 8 names at a time. As far as I know,
+ * the maximum number of names ever associated with an existing GL function is
+ * 4 (\c glPointParameterfSGIS, \c glPointParameterfEXT,
+ * \c glPointParameterfARB, and \c glPointParameterf), so this should not be
+ * too painful of a limitation.
+ *
+ * \todo
+ * Check parameter_signature.
+ */
+int
+_glapi_add_dispatch( const char * const * function_names,
+ const char * parameter_signature )
+{
+ const struct mapi_stub *function_stubs[8];
+ const struct mapi_stub *alias = NULL;
+ unsigned i;
+
+ (void) memset(function_stubs, 0, sizeof(function_stubs));
+
+ /* find the missing stubs, and decide the alias */
+ for (i = 0; function_names[i] != NULL && i < 8; i++) {
+ const char * funcName = function_names[i];
+ const struct mapi_stub *stub;
+ int slot;
+
+ if (!funcName || funcName[0] != 'g' || funcName[1] != 'l')
+ return -1;
+ funcName += 2;
+
+ stub = stub_find_public(funcName);
+ if (!stub)
+ stub = stub_find_dynamic(funcName, 0);
+
+ slot = (stub) ? stub_get_slot(stub) : -1;
+ if (slot >= 0) {
+ if (alias && stub_get_slot(alias) != slot)
+ return -1;
+ /* use the first existing stub as the alias */
+ if (!alias)
+ alias = stub;
+
+ function_stubs[i] = stub;
+ }
+ }
+
+ /* generate missing stubs */
+ for (i = 0; function_names[i] != NULL && i < 8; i++) {
+ const char * funcName = function_names[i] + 2;
+ struct mapi_stub *stub;
+
+ if (function_stubs[i])
+ continue;
+
+ stub = stub_find_dynamic(funcName, 1);
+ if (!stub)
+ return -1;
+
+ stub_fix_dynamic(stub, alias);
+ if (!alias)
+ alias = stub;
+ }
+
+ return (alias) ? stub_get_slot(alias) : -1;
+}
+
+static const struct mapi_stub *
+_glapi_get_stub(const char *name, int generate)
+{
+ const struct mapi_stub *stub;
+
+#ifdef USE_MGL_NAMESPACE
+ if (name)
+ name++;
+#endif
+
+ if (!name || name[0] != 'g' || name[1] != 'l')
+ return NULL;
+ name += 2;
+
+ stub = stub_find_public(name);
+ if (!stub)
+ stub = stub_find_dynamic(name, generate);
+
+ return stub;
+}
+
+/**
+ * Return offset of entrypoint for named function within dispatch table.
+ */
+int
+_glapi_get_proc_offset(const char *funcName)
+{
+ const struct mapi_stub *stub = _glapi_get_stub(funcName, 0);
+ return (stub) ? stub_get_slot(stub) : -1;
+}
+
+/**
+ * Return pointer to the named function. If the function name isn't found
+ * in the name of static functions, try generating a new API entrypoint on
+ * the fly with assembly language.
+ */
+_glapi_proc
+_glapi_get_proc_address(const char *funcName)
+{
+ const struct mapi_stub *stub = _glapi_get_stub(funcName, 1);
+ return (stub) ? (_glapi_proc) stub_get_addr(stub) : NULL;
+}
+
+/**
+ * Return the name of the function at the given dispatch offset.
+ * This is only intended for debugging.
+ */
+const char *
+_glapi_get_proc_name(unsigned int offset)
+{
+ const struct mapi_stub *stub = stub_find_by_slot(offset);
+ return stub ? stub_get_name(stub) : NULL;
+}
+
+unsigned long
+_glthread_GetID(void)
+{
+ return u_thread_self();
+}
+
+void
+_glapi_noop_enable_warnings(unsigned char enable)
+{
+}
+
+void
+_glapi_set_warning_func(_glapi_proc func)
+{
+}
--- /dev/null
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.9
+ *
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS 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.
+ *
+ * Authors:
+ * Chia-I Wu <olv@lunarg.com>
+ */
+
+#ifndef MAPI_ABI_HEADER
+#error "MAPI_ABI_HEADER must be defined"
+#endif
+
+/* does not need hidden entries in bridge mode */
+#ifdef MAPI_MODE_BRIDGE
+
+#ifdef MAPI_TMP_PUBLIC_ENTRIES
+#undef MAPI_TMP_PUBLIC_ENTRIES
+#define MAPI_TMP_PUBLIC_ENTRIES_NO_HIDDEN
+#endif
+
+#ifdef MAPI_TMP_STUB_ASM_GCC
+#undef MAPI_TMP_STUB_ASM_GCC
+#define MAPI_TMP_STUB_ASM_GCC_NO_HIDDEN
+#endif
+
+#endif /* MAPI_MODE_BRIDGE */
+
+#include MAPI_ABI_HEADER
TOP = $(top_srcdir)
GLAPI = $(top_srcdir)/src/mapi/glapi
-include $(top_srcdir)/src/mapi/mapi/Makefile.sources
+include $(top_srcdir)/src/mapi/Makefile.sources
lib_LTLIBRARIES = libglapi.la
libglapi_la_SOURCES = $(MAPI_GLAPI_FILES)
# generate ABI header
header = env.CodeGenerate(
target = header_name,
- script = '../mapi/mapi_abi.py',
+ script = '../mapi_abi.py',
source = '../glapi/gen/gl_and_es_API.xml',
command = python_cmd + ' $SCRIPT ' + \
'--printer %s --mode lib $SOURCE > $TARGET' % (printer),
for s in mapi_sources[mode]:
o = env.SharedObject(
target = '%s-%s' % (printer, s[:-2]),
- source = '../mapi/' + s,
+ source = '../' + s,
CPPPATH = cpppath,
CPPDEFINES = cppdefines,
)
--- /dev/null
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.9
+ *
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS 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.
+ *
+ * Authors:
+ * Chia-I Wu <olv@lunarg.com>
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "u_current.h"
+#include "u_thread.h"
+#include "entry.h"
+#include "stub.h"
+#include "table.h"
+
+#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))
+
+struct mapi_stub {
+ const void *name;
+ int slot;
+ mapi_func addr;
+};
+
+/* define public_string_pool and public_stubs */
+#define MAPI_TMP_PUBLIC_STUBS
+#include "mapi_tmp.h"
+
+static struct mapi_stub dynamic_stubs[MAPI_TABLE_NUM_DYNAMIC];
+static int num_dynamic_stubs;
+static int next_dynamic_slot = MAPI_TABLE_NUM_STATIC;
+
+void
+stub_init_once(void)
+{
+#ifdef HAVE_PTHREAD
+ static pthread_once_t once = PTHREAD_ONCE_INIT;
+ pthread_once(&once, entry_patch_public);
+#else
+ static int first = 1;
+ if (first) {
+ first = 0;
+ entry_patch_public();
+ }
+#endif
+}
+
+static int
+stub_compare(const void *key, const void *elem)
+{
+ const char *name = (const char *) key;
+ const struct mapi_stub *stub = (const struct mapi_stub *) elem;
+ const char *stub_name;
+
+ stub_name = &public_string_pool[(unsigned long) stub->name];
+
+ return strcmp(name, stub_name);
+}
+
+/**
+ * Return the public stub with the given name.
+ */
+const struct mapi_stub *
+stub_find_public(const char *name)
+{
+ return (const struct mapi_stub *) bsearch(name, public_stubs,
+ ARRAY_SIZE(public_stubs), sizeof(public_stubs[0]), stub_compare);
+}
+
+/**
+ * Add a dynamic stub.
+ */
+static struct mapi_stub *
+stub_add_dynamic(const char *name)
+{
+ struct mapi_stub *stub;
+ int idx;
+
+ idx = num_dynamic_stubs;
+ /* minus 1 to make sure we can never reach the last slot */
+ if (idx >= MAPI_TABLE_NUM_DYNAMIC - 1)
+ return NULL;
+
+ stub = &dynamic_stubs[idx];
+
+ /* dispatch to the last slot, which is reserved for no-op */
+ stub->addr = entry_generate(
+ MAPI_TABLE_NUM_STATIC + MAPI_TABLE_NUM_DYNAMIC - 1);
+ if (!stub->addr)
+ return NULL;
+
+ stub->name = (const void *) name;
+ /* to be fixed later */
+ stub->slot = -1;
+
+ num_dynamic_stubs = idx + 1;
+
+ return stub;
+}
+
+/**
+ * Return the dynamic stub with the given name. If no such stub exists and
+ * generate is true, a new stub is generated.
+ */
+struct mapi_stub *
+stub_find_dynamic(const char *name, int generate)
+{
+ u_mutex_declare_static(dynamic_mutex);
+ struct mapi_stub *stub = NULL;
+ int count, i;
+
+ u_mutex_lock(dynamic_mutex);
+
+ if (generate)
+ assert(!stub_find_public(name));
+
+ count = num_dynamic_stubs;
+ for (i = 0; i < count; i++) {
+ if (strcmp(name, (const char *) dynamic_stubs[i].name) == 0) {
+ stub = &dynamic_stubs[i];
+ break;
+ }
+ }
+
+ /* generate a dynamic stub */
+ if (generate && !stub)
+ stub = stub_add_dynamic(name);
+
+ u_mutex_unlock(dynamic_mutex);
+
+ return stub;
+}
+
+static const struct mapi_stub *
+search_table_by_slot(const struct mapi_stub *table, size_t num_entries,
+ int slot)
+{
+ size_t i;
+ for (i = 0; i < num_entries; ++i) {
+ if (table[i].slot == slot)
+ return &table[i];
+ }
+ return NULL;
+}
+
+const struct mapi_stub *
+stub_find_by_slot(int slot)
+{
+ const struct mapi_stub *stub =
+ search_table_by_slot(public_stubs, ARRAY_SIZE(public_stubs), slot);
+ if (stub)
+ return stub;
+ return search_table_by_slot(dynamic_stubs, num_dynamic_stubs, slot);
+}
+
+void
+stub_fix_dynamic(struct mapi_stub *stub, const struct mapi_stub *alias)
+{
+ int slot;
+
+ if (stub->slot >= 0)
+ return;
+
+ if (alias)
+ slot = alias->slot;
+ else
+ slot = next_dynamic_slot++;
+
+ entry_patch(stub->addr, slot);
+ stub->slot = slot;
+}
+
+/**
+ * Return the name of a stub.
+ */
+const char *
+stub_get_name(const struct mapi_stub *stub)
+{
+ const char *name;
+
+ if (stub >= public_stubs &&
+ stub < public_stubs + ARRAY_SIZE(public_stubs))
+ name = &public_string_pool[(unsigned long) stub->name];
+ else
+ name = (const char *) stub->name;
+
+ return name;
+}
+
+/**
+ * Return the slot of a stub.
+ */
+int
+stub_get_slot(const struct mapi_stub *stub)
+{
+ return stub->slot;
+}
+
+/**
+ * Return the address of a stub.
+ */
+mapi_func
+stub_get_addr(const struct mapi_stub *stub)
+{
+ assert(stub->addr || (unsigned int) stub->slot < MAPI_TABLE_NUM_STATIC);
+ return (stub->addr) ? stub->addr : entry_get_public(stub->slot);
+}
--- /dev/null
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.9
+ *
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS 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.
+ *
+ * Authors:
+ * Chia-I Wu <olv@lunarg.com>
+ */
+
+#ifndef _STUB_H_
+#define _STUB_H_
+
+#include "entry.h"
+
+struct mapi_stub;
+
+void
+stub_init_once(void);
+
+const struct mapi_stub *
+stub_find_public(const char *name);
+
+struct mapi_stub *
+stub_find_dynamic(const char *name, int generate);
+
+const struct mapi_stub *
+stub_find_by_slot(int slot);
+
+void
+stub_fix_dynamic(struct mapi_stub *stub, const struct mapi_stub *alias);
+
+const char *
+stub_get_name(const struct mapi_stub *stub);
+
+int
+stub_get_slot(const struct mapi_stub *stub);
+
+mapi_func
+stub_get_addr(const struct mapi_stub *stub);
+
+#endif /* _STUB_H_ */
--- /dev/null
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.9
+ *
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS 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.
+ *
+ * Authors:
+ * Chia-I Wu <olv@lunarg.com>
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "table.h"
+
+static void
+noop_warn(const char *name)
+{
+ static int debug = -1;
+
+ if (debug < 0)
+ debug = (getenv("MESA_DEBUG") || getenv("LIBGL_DEBUG"));
+
+ if (debug)
+ fprintf(stderr, "%s is no-op\n", name);
+}
+
+static int
+noop_generic(void)
+{
+ noop_warn("function");
+ return 0;
+}
+
+/* define noop_array */
+#define MAPI_TMP_DEFINES
+#define MAPI_TMP_NOOP_ARRAY
+#include "mapi_tmp.h"
--- /dev/null
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.9
+ *
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS 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.
+ *
+ * Authors:
+ * Chia-I Wu <olv@lunarg.com>
+ */
+
+#ifndef _TABLE_H_
+#define _TABLE_H_
+
+#include "u_compiler.h"
+#include "entry.h"
+
+#define MAPI_TMP_TABLE
+#include "mapi_tmp.h"
+
+#define MAPI_TABLE_NUM_SLOTS (MAPI_TABLE_NUM_STATIC + MAPI_TABLE_NUM_DYNAMIC)
+#define MAPI_TABLE_SIZE (MAPI_TABLE_NUM_SLOTS * sizeof(mapi_func))
+
+extern const mapi_func table_noop_array[];
+
+/**
+ * Get the no-op dispatch table.
+ */
+static INLINE const struct mapi_table *
+table_get_noop(void)
+{
+ return (const struct mapi_table *) table_noop_array;
+}
+
+/**
+ * Set the function of a slot.
+ */
+static INLINE void
+table_set_func(struct mapi_table *tbl, int slot, mapi_func func)
+{
+ mapi_func *funcs = (mapi_func *) tbl;
+ funcs[slot] = func;
+}
+
+/**
+ * Return the function of a slot.
+ */
+static INLINE mapi_func
+table_get_func(const struct mapi_table *tbl, int slot)
+{
+ const mapi_func *funcs = (const mapi_func *) tbl;
+ return funcs[slot];
+}
+
+#endif /* _TABLE_H_ */
--- /dev/null
+#ifndef _U_COMPILER_H_
+#define _U_COMPILER_H_
+
+#include "c99_compat.h" /* inline, __func__, etc. */
+
+
+/* XXX: Use standard `inline` keyword instead */
+#ifndef INLINE
+# define INLINE inline
+#endif
+
+/* Function visibility */
+#ifndef PUBLIC
+# if defined(__GNUC__) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590))
+# define PUBLIC __attribute__((visibility("default")))
+# elif defined(_MSC_VER)
+# define PUBLIC __declspec(dllexport)
+# else
+# define PUBLIC
+# endif
+#endif
+
+#ifndef likely
+# if defined(__GNUC__)
+# define likely(x) __builtin_expect(!!(x), 1)
+# define unlikely(x) __builtin_expect(!!(x), 0)
+# else
+# define likely(x) (x)
+# define unlikely(x) (x)
+# endif
+#endif
+
+#endif /* _U_COMPILER_H_ */
--- /dev/null
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.1
+ *
+ * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
+ *
+ * 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
+ * BRIAN PAUL 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.
+ */
+
+
+/*
+ * This file manages the OpenGL API dispatch layer.
+ * The dispatch table (struct _glapi_table) is basically just a list
+ * of function pointers.
+ * There are functions to set/get the current dispatch table for the
+ * current thread and to manage registration/dispatch of dynamically
+ * added extension functions.
+ *
+ * It's intended that this file and the other glapi*.[ch] files are
+ * flexible enough to be reused in several places: XFree86, DRI-
+ * based libGL.so, and perhaps the SGI SI.
+ *
+ * NOTE: There are no dependencies on Mesa in this code.
+ *
+ * Versions (API changes):
+ * 2000/02/23 - original version for Mesa 3.3 and XFree86 4.0
+ * 2001/01/16 - added dispatch override feature for Mesa 3.5
+ * 2002/06/28 - added _glapi_set_warning_func(), Mesa 4.1.
+ * 2002/10/01 - _glapi_get_proc_address() will now generate new entrypoints
+ * itself (using offset ~0). _glapi_add_entrypoint() can be
+ * called afterward and it'll fill in the correct dispatch
+ * offset. This allows DRI libGL to avoid probing for DRI
+ * drivers! No changes to the public glapi interface.
+ */
+
+#include "u_current.h"
+#include "u_thread.h"
+
+#ifndef MAPI_MODE_UTIL
+
+#include "table.h"
+#include "stub.h"
+
+#else
+
+extern void init_glapi_relocs_once(void);
+extern void (*__glapi_noop_table[])(void);
+
+#define table_noop_array __glapi_noop_table
+#define stub_init_once() init_glapi_relocs_once()
+
+#endif
+
+/**
+ * \name Current dispatch and current context control variables
+ *
+ * Depending on whether or not multithreading is support, and the type of
+ * support available, several variables are used to store the current context
+ * pointer and the current dispatch table pointer. In the non-threaded case,
+ * the variables \c _glapi_Dispatch and \c _glapi_Context are used for this
+ * purpose.
+ *
+ * In the "normal" threaded case, the variables \c _glapi_Dispatch and
+ * \c _glapi_Context will be \c NULL if an application is detected as being
+ * multithreaded. Single-threaded applications will use \c _glapi_Dispatch
+ * and \c _glapi_Context just like the case without any threading support.
+ * When \c _glapi_Dispatch and \c _glapi_Context are \c NULL, the thread state
+ * data \c _gl_DispatchTSD and \c ContextTSD are used. Drivers and the
+ * static dispatch functions access these variables via \c _glapi_get_dispatch
+ * and \c _glapi_get_context.
+ *
+ * There is a race condition in setting \c _glapi_Dispatch to \c NULL. It is
+ * possible for the original thread to be setting it at the same instant a new
+ * thread, perhaps running on a different processor, is clearing it. Because
+ * of that, \c ThreadSafe, which can only ever be changed to \c GL_TRUE, is
+ * used to determine whether or not the application is multithreaded.
+ *
+ * In the TLS case, the variables \c _glapi_Dispatch and \c _glapi_Context are
+ * hardcoded to \c NULL. Instead the TLS variables \c _glapi_tls_Dispatch and
+ * \c _glapi_tls_Context are used. Having \c _glapi_Dispatch and
+ * \c _glapi_Context be hardcoded to \c NULL maintains binary compatability
+ * between TLS enabled loaders and non-TLS DRI drivers.
+ */
+/*@{*/
+#if defined(GLX_USE_TLS)
+
+__thread struct mapi_table *u_current_table
+ __attribute__((tls_model("initial-exec")))
+ = (struct mapi_table *) table_noop_array;
+
+__thread void *u_current_user
+ __attribute__((tls_model("initial-exec")));
+
+#else
+
+struct mapi_table *u_current_table =
+ (struct mapi_table *) table_noop_array;
+void *u_current_user;
+
+#ifdef THREADS
+struct u_tsd u_current_table_tsd;
+static struct u_tsd u_current_user_tsd;
+static int ThreadSafe;
+#endif /* THREADS */
+
+#endif /* defined(GLX_USE_TLS) */
+/*@}*/
+
+
+void
+u_current_destroy(void)
+{
+#if defined(THREADS) && defined(_WIN32)
+ u_tsd_destroy(&u_current_table_tsd);
+ u_tsd_destroy(&u_current_user_tsd);
+#endif
+}
+
+
+#if defined(THREADS) && !defined(GLX_USE_TLS)
+
+static void
+u_current_init_tsd(void)
+{
+ u_tsd_init(&u_current_table_tsd);
+ u_tsd_init(&u_current_user_tsd);
+}
+
+/**
+ * Mutex for multithread check.
+ */
+u_mutex_declare_static(ThreadCheckMutex);
+
+/**
+ * We should call this periodically from a function such as glXMakeCurrent
+ * in order to test if multiple threads are being used.
+ */
+void
+u_current_init(void)
+{
+ static unsigned long knownID;
+ static int firstCall = 1;
+
+ if (ThreadSafe)
+ return;
+
+ u_mutex_lock(ThreadCheckMutex);
+ if (firstCall) {
+ u_current_init_tsd();
+
+ knownID = u_thread_self();
+ firstCall = 0;
+ }
+ else if (knownID != u_thread_self()) {
+ ThreadSafe = 1;
+ u_current_set(NULL);
+ u_current_set_user(NULL);
+ }
+ u_mutex_unlock(ThreadCheckMutex);
+}
+
+#else
+
+void
+u_current_init(void)
+{
+}
+
+#endif
+
+
+
+/**
+ * Set the current context pointer for this thread.
+ * The context pointer is an opaque type which should be cast to
+ * void from the real context pointer type.
+ */
+void
+u_current_set_user(const void *ptr)
+{
+ u_current_init();
+
+#if defined(GLX_USE_TLS)
+ u_current_user = (void *) ptr;
+#elif defined(THREADS)
+ u_tsd_set(&u_current_user_tsd, (void *) ptr);
+ u_current_user = (ThreadSafe) ? NULL : (void *) ptr;
+#else
+ u_current_user = (void *) ptr;
+#endif
+}
+
+/**
+ * Get the current context pointer for this thread.
+ * The context pointer is an opaque type which should be cast from
+ * void to the real context pointer type.
+ */
+void *
+u_current_get_user_internal(void)
+{
+#if defined(GLX_USE_TLS)
+ return u_current_user;
+#elif defined(THREADS)
+ return (ThreadSafe)
+ ? u_tsd_get(&u_current_user_tsd)
+ : u_current_user;
+#else
+ return u_current_user;
+#endif
+}
+
+/**
+ * Set the global or per-thread dispatch table pointer.
+ * If the dispatch parameter is NULL we'll plug in the no-op dispatch
+ * table (__glapi_noop_table).
+ */
+void
+u_current_set(const struct mapi_table *tbl)
+{
+ u_current_init();
+
+ stub_init_once();
+
+ if (!tbl)
+ tbl = (const struct mapi_table *) table_noop_array;
+
+#if defined(GLX_USE_TLS)
+ u_current_table = (struct mapi_table *) tbl;
+#elif defined(THREADS)
+ u_tsd_set(&u_current_table_tsd, (void *) tbl);
+ u_current_table = (ThreadSafe) ? NULL : (void *) tbl;
+#else
+ u_current_table = (struct mapi_table *) tbl;
+#endif
+}
+
+/**
+ * Return pointer to current dispatch table for calling thread.
+ */
+struct mapi_table *
+u_current_get_internal(void)
+{
+#if defined(GLX_USE_TLS)
+ return u_current_table;
+#elif defined(THREADS)
+ return (struct mapi_table *) ((ThreadSafe) ?
+ u_tsd_get(&u_current_table_tsd) : (void *) u_current_table);
+#else
+ return u_current_table;
+#endif
+}
--- /dev/null
+#ifndef _U_CURRENT_H_
+#define _U_CURRENT_H_
+
+#if defined(MAPI_MODE_UTIL) || defined(MAPI_MODE_GLAPI) || \
+ defined(MAPI_MODE_BRIDGE)
+
+#include "glapi/glapi.h"
+
+/* ugly renames to match glapi.h */
+#define mapi_table _glapi_table
+
+#ifdef GLX_USE_TLS
+#define u_current_table _glapi_tls_Dispatch
+#define u_current_user _glapi_tls_Context
+#else
+#define u_current_table _glapi_Dispatch
+#define u_current_user _glapi_Context
+#endif
+
+#define u_current_get_internal _glapi_get_dispatch
+#define u_current_get_user_internal _glapi_get_context
+
+#define u_current_table_tsd _gl_DispatchTSD
+
+#else /* MAPI_MODE_UTIL || MAPI_MODE_GLAPI || MAPI_MODE_BRIDGE */
+
+#include "u_compiler.h"
+
+struct mapi_table;
+
+#ifdef GLX_USE_TLS
+
+extern __thread struct mapi_table *u_current_table
+ __attribute__((tls_model("initial-exec")));
+
+extern __thread void *u_current_user
+ __attribute__((tls_model("initial-exec")));
+
+#else /* GLX_USE_TLS */
+
+extern struct mapi_table *u_current_table;
+extern void *u_current_user;
+
+#endif /* GLX_USE_TLS */
+
+#endif /* MAPI_MODE_UTIL || MAPI_MODE_GLAPI || MAPI_MODE_BRIDGE */
+
+void
+u_current_init(void);
+
+void
+u_current_destroy(void);
+
+void
+u_current_set(const struct mapi_table *tbl);
+
+struct mapi_table *
+u_current_get_internal(void);
+
+void
+u_current_set_user(const void *ptr);
+
+void *
+u_current_get_user_internal(void);
+
+static INLINE const struct mapi_table *
+u_current_get(void)
+{
+#ifdef GLX_USE_TLS
+ return u_current_table;
+#else
+ return (likely(u_current_table) ?
+ u_current_table : u_current_get_internal());
+#endif
+}
+
+static INLINE const void *
+u_current_get_user(void)
+{
+#ifdef GLX_USE_TLS
+ return u_current_user;
+#else
+ return likely(u_current_user) ? u_current_user : u_current_get_user_internal();
+#endif
+}
+
+#endif /* _U_CURRENT_H_ */
--- /dev/null
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.5
+ *
+ * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
+ *
+ * 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
+ * BRIAN PAUL 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.
+ */
+
+
+/**
+ * \file glapi_execmem.c
+ *
+ * Function for allocating executable memory for dispatch stubs.
+ *
+ * Copied from main/execmem.c and simplified for dispatch stubs.
+ */
+
+
+#include "u_compiler.h"
+#include "u_thread.h"
+#include "u_execmem.h"
+
+
+#define EXEC_MAP_SIZE (4*1024)
+
+u_mutex_declare_static(exec_mutex);
+
+static unsigned int head = 0;
+
+static unsigned char *exec_mem = (unsigned char *)0;
+
+
+#if defined(__linux__) || defined(__OpenBSD__) || defined(_NetBSD__) || defined(__sun)
+
+#include <unistd.h>
+#include <sys/mman.h>
+
+#ifdef MESA_SELINUX
+#include <selinux/selinux.h>
+#endif
+
+
+#ifndef MAP_ANONYMOUS
+#define MAP_ANONYMOUS MAP_ANON
+#endif
+
+
+/*
+ * Dispatch stubs are of fixed size and never freed. Thus, we do not need to
+ * overlay a heap, we just mmap a page and manage through an index.
+ */
+
+static int
+init_map(void)
+{
+#ifdef MESA_SELINUX
+ if (is_selinux_enabled()) {
+ if (!security_get_boolean_active("allow_execmem") ||
+ !security_get_boolean_pending("allow_execmem"))
+ return 0;
+ }
+#endif
+
+ if (!exec_mem)
+ exec_mem = mmap(NULL, EXEC_MAP_SIZE, PROT_EXEC | PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+
+ return (exec_mem != MAP_FAILED);
+}
+
+
+#elif defined(_WIN32)
+
+#include <windows.h>
+
+
+/*
+ * Avoid Data Execution Prevention.
+ */
+
+static int
+init_map(void)
+{
+ exec_mem = VirtualAlloc(NULL, EXEC_MAP_SIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
+
+ return (exec_mem != NULL);
+}
+
+
+#else
+
+#include <stdlib.h>
+
+static int
+init_map(void)
+{
+ exec_mem = malloc(EXEC_MAP_SIZE);
+
+ return (exec_mem != NULL);
+}
+
+
+#endif
+
+void *
+u_execmem_alloc(unsigned int size)
+{
+ void *addr = NULL;
+
+ u_mutex_lock(exec_mutex);
+
+ if (!init_map())
+ goto bail;
+
+ /* free space check, assumes no integer overflow */
+ if (head + size > EXEC_MAP_SIZE)
+ goto bail;
+
+ /* allocation, assumes proper addr and size alignement */
+ addr = exec_mem + head;
+ head += size;
+
+bail:
+ u_mutex_unlock(exec_mutex);
+
+ return addr;
+}
+
+
--- /dev/null
+#ifndef _U_EXECMEM_H_
+#define _U_EXECMEM_H_
+
+void *
+u_execmem_alloc(unsigned int size);
+
+#endif /* _U_EXECMEM_H_ */
--- /dev/null
+#ifndef _U_MACROS_
+#define _U_MACROS_
+
+#define _U_STRINGIFY(x) #x
+#define _U_CONCAT(x, y) x ## y
+#define _U_CONCAT_STR(x, y) #x#y
+
+#define U_STRINGIFY(x) _U_STRINGIFY(x)
+#define U_CONCAT(x, y) _U_CONCAT(x, y)
+#define U_CONCAT_STR(x, y) _U_CONCAT_STR(x, y)
+
+#endif /* _U_MACROS_ */
--- /dev/null
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.5.2
+ *
+ * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
+ *
+ * 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
+ * BRIAN PAUL 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.
+ */
+
+
+/*
+ * Thread support for gl dispatch.
+ *
+ * Initial version by John Stone (j.stone@acm.org) (johns@cs.umr.edu)
+ * and Christoph Poliwoda (poliwoda@volumegraphics.com)
+ * Revised by Keith Whitwell
+ * Adapted for new gl dispatcher by Brian Paul
+ * Modified for use in mapi by Chia-I Wu
+ */
+
+/*
+ * If this file is accidentally included by a non-threaded build,
+ * it should not cause the build to fail, or otherwise cause problems.
+ * In general, it should only be included when needed however.
+ */
+
+#ifndef _U_THREAD_H_
+#define _U_THREAD_H_
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "u_compiler.h"
+
+#if defined(HAVE_PTHREAD)
+#include <pthread.h> /* POSIX threads headers */
+#endif
+#ifdef _WIN32
+#include <windows.h>
+#endif
+
+#if defined(HAVE_PTHREAD) || defined(_WIN32)
+#ifndef THREADS
+#define THREADS
+#endif
+#endif
+
+/*
+ * Error messages
+ */
+#define INIT_TSD_ERROR "_glthread_: failed to allocate key for thread specific data"
+#define GET_TSD_ERROR "_glthread_: failed to get thread specific data"
+#define SET_TSD_ERROR "_glthread_: thread failed to set thread specific data"
+
+
+/*
+ * Magic number to determine if a TSD object has been initialized.
+ * Kind of a hack but there doesn't appear to be a better cross-platform
+ * solution.
+ */
+#define INIT_MAGIC 0xff8adc98
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/*
+ * POSIX threads. This should be your choice in the Unix world
+ * whenever possible. When building with POSIX threads, be sure
+ * to enable any compiler flags which will cause the MT-safe
+ * libc (if one exists) to be used when linking, as well as any
+ * header macros for MT-safe errno, etc. For Solaris, this is the -mt
+ * compiler flag. On Solaris with gcc, use -D_REENTRANT to enable
+ * proper compiling for MT-safe libc etc.
+ */
+#if defined(HAVE_PTHREAD)
+
+struct u_tsd {
+ pthread_key_t key;
+ unsigned initMagic;
+};
+
+typedef pthread_mutex_t u_mutex;
+
+#define u_mutex_declare_static(name) \
+ static u_mutex name = PTHREAD_MUTEX_INITIALIZER
+
+#define u_mutex_init(name) pthread_mutex_init(&(name), NULL)
+#define u_mutex_destroy(name) pthread_mutex_destroy(&(name))
+#define u_mutex_lock(name) (void) pthread_mutex_lock(&(name))
+#define u_mutex_unlock(name) (void) pthread_mutex_unlock(&(name))
+
+static INLINE unsigned long
+u_thread_self(void)
+{
+ return (unsigned long) pthread_self();
+}
+
+
+static INLINE void
+u_tsd_init(struct u_tsd *tsd)
+{
+ if (pthread_key_create(&tsd->key, NULL/*free*/) != 0) {
+ perror(INIT_TSD_ERROR);
+ exit(-1);
+ }
+ tsd->initMagic = INIT_MAGIC;
+}
+
+
+static INLINE void *
+u_tsd_get(struct u_tsd *tsd)
+{
+ if (tsd->initMagic != INIT_MAGIC) {
+ u_tsd_init(tsd);
+ }
+ return pthread_getspecific(tsd->key);
+}
+
+
+static INLINE void
+u_tsd_set(struct u_tsd *tsd, void *ptr)
+{
+ if (tsd->initMagic != INIT_MAGIC) {
+ u_tsd_init(tsd);
+ }
+ if (pthread_setspecific(tsd->key, ptr) != 0) {
+ perror(SET_TSD_ERROR);
+ exit(-1);
+ }
+}
+
+#endif /* HAVE_PTHREAD */
+
+
+/*
+ * Windows threads. Should work with Windows NT and 95.
+ * IMPORTANT: Link with multithreaded runtime library when THREADS are
+ * used!
+ */
+#ifdef _WIN32
+
+struct u_tsd {
+ DWORD key;
+ unsigned initMagic;
+};
+
+typedef CRITICAL_SECTION u_mutex;
+
+/* http://locklessinc.com/articles/pthreads_on_windows/ */
+#define u_mutex_declare_static(name) \
+ static u_mutex name = {(PCRITICAL_SECTION_DEBUG)-1, -1, 0, 0, 0, 0}
+
+#define u_mutex_init(name) InitializeCriticalSection(&name)
+#define u_mutex_destroy(name) DeleteCriticalSection(&name)
+#define u_mutex_lock(name) EnterCriticalSection(&name)
+#define u_mutex_unlock(name) LeaveCriticalSection(&name)
+
+static INLINE unsigned long
+u_thread_self(void)
+{
+ return GetCurrentThreadId();
+}
+
+
+static INLINE void
+u_tsd_init(struct u_tsd *tsd)
+{
+ tsd->key = TlsAlloc();
+ if (tsd->key == TLS_OUT_OF_INDEXES) {
+ perror(INIT_TSD_ERROR);
+ exit(-1);
+ }
+ tsd->initMagic = INIT_MAGIC;
+}
+
+
+static INLINE void
+u_tsd_destroy(struct u_tsd *tsd)
+{
+ if (tsd->initMagic != INIT_MAGIC) {
+ return;
+ }
+ TlsFree(tsd->key);
+ tsd->initMagic = 0x0;
+}
+
+
+static INLINE void *
+u_tsd_get(struct u_tsd *tsd)
+{
+ if (tsd->initMagic != INIT_MAGIC) {
+ u_tsd_init(tsd);
+ }
+ return TlsGetValue(tsd->key);
+}
+
+
+static INLINE void
+u_tsd_set(struct u_tsd *tsd, void *ptr)
+{
+ /* the following code assumes that the struct u_tsd has been initialized
+ to zero at creation */
+ if (tsd->initMagic != INIT_MAGIC) {
+ u_tsd_init(tsd);
+ }
+ if (TlsSetValue(tsd->key, ptr) == 0) {
+ perror(SET_TSD_ERROR);
+ exit(-1);
+ }
+}
+
+#endif /* _WIN32 */
+
+
+/*
+ * THREADS not defined
+ */
+#ifndef THREADS
+
+struct u_tsd {
+ unsigned initMagic;
+};
+
+typedef unsigned u_mutex;
+
+#define u_mutex_declare_static(name) static u_mutex name = 0
+#define u_mutex_init(name) (void) name
+#define u_mutex_destroy(name) (void) name
+#define u_mutex_lock(name) (void) name
+#define u_mutex_unlock(name) (void) name
+
+/*
+ * no-op functions
+ */
+
+static INLINE unsigned long
+u_thread_self(void)
+{
+ return 0;
+}
+
+
+static INLINE void
+u_tsd_init(struct u_tsd *tsd)
+{
+ (void) tsd;
+}
+
+
+static INLINE void *
+u_tsd_get(struct u_tsd *tsd)
+{
+ (void) tsd;
+ return NULL;
+}
+
+
+static INLINE void
+u_tsd_set(struct u_tsd *tsd, void *ptr)
+{
+ (void) tsd;
+ (void) ptr;
+}
+#endif /* THREADS */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _U_THREAD_H_ */
lib_LTLIBRARIES = libOpenVG.la
TOP=$(top_srcdir)
-include ../mapi/Makefile.sources
+include ../Makefile.sources
libOpenVG_la_SOURCES = $(MAPI_FILES) vgapi_tmp.h
libOpenVG_la_LIBADD = $(VG_LIB_DEPS)
libOpenVG_la_LDFLAGS = -version-number 1 -no-undefined
-vgapi_tmp.h: $(srcdir)/vgapi.csv $(top_srcdir)/src/mapi/mapi/mapi_abi.py
- $(AM_V_GEN) $(PYTHON2) $(PYTHON_FLAGS) $(top_srcdir)/src/mapi/mapi/mapi_abi.py \
+vgapi_tmp.h: $(srcdir)/vgapi.csv $(top_srcdir)/src/mapi/mapi_abi.py
+ $(AM_V_GEN) $(PYTHON2) $(PYTHON_FLAGS) $(top_srcdir)/src/mapi/mapi_abi.py \
--printer vgapi --mode lib $< > $@
BUILT_SOURCES = vgapi_tmp.h
vgapi_header, = env.CodeGenerate(
target = 'vgapi_tmp.h',
- script = '../mapi/mapi_abi.py',
+ script = '../mapi_abi.py',
source = 'vgapi.csv',
command = python_cmd + ' $SCRIPT --printer vgapi --mode lib $SOURCE > $TARGET'
)
vgapi_objects = []
for s in mapi_sources:
- o = env.SharedObject(s[:-2], '../mapi/' + s)
+ o = env.SharedObject(s[:-2], '../' + s)
vgapi_objects.append(o)
env.Depends(vgapi_objects, vgapi_header)