glapi: Fix OpenGL and OpenGL ES interop.

When --enable-shared-glapi is specified, libGL will share libglapi with
OpenGL ES instead of defining its own copy of glapi.  This makes sure an
app will get only one copy of glapi in its address space.

The new option is disabled by default.  When enabled, libGL and libglapi
must be built from the same source tree and distributed together.  This
requirement comes from the fact that the dispatch offsets used by these
libraries are re-assigned whenever GLAPI XMLs are changed.

For GLX, indirect rendering for has_different_protocol() functions is
tricky.  A has_different_protocol() function is assigned only one
dispatch offset, yet each entry point needs a different protocol opcode.
It cannot be supported by the shared glapi.  The fix to this is to make
glXGetProcAddress handle such functions specially before calling
_glapi_get_proc_address.

Note that these files are automatically generated/re-generated

 src/glx/indirect.c
 src/glx/indirect.h
 src/mapi/glapi/glapi_mapi_tmp.h
This commit is contained in:
Chia-I Wu 2010-12-26 18:24:13 +08:00
parent 9767d3b5ad
commit e8c7d7598f
14 changed files with 13306 additions and 29 deletions

View File

@ -15,6 +15,7 @@ ASM_FLAGS = @ASM_FLAGS@
PIC_FLAGS = @PIC_FLAGS@
DEFINES = @DEFINES@
API_DEFINES = @API_DEFINES@
SHARED_GLAPI = @SHARED_GLAPI@
CFLAGS = @CPPFLAGS@ @CFLAGS@ \
$(OPT_FLAGS) $(PIC_FLAGS) $(ARCH_FLAGS) $(ASM_FLAGS) $(DEFINES)
CXXFLAGS = @CPPFLAGS@ @CXXFLAGS@ \

View File

@ -528,6 +528,18 @@ if test "x$enable_gles2" = xyes; then
fi
AC_SUBST([API_DEFINES])
AC_ARG_ENABLE([shared-glapi],
[AS_HELP_STRING([--enable-shared-glapi],
[EXPERIMENTAL. Enable shared glapi for OpenGL @<:@default=no@:>@])],
[enable_shared_glapi="$enableval"],
[enable_shared_glapi=no])
SHARED_GLAPI="0"
if test "x$enable_shared_glapi" = xyes; then
SHARED_GLAPI="1"
fi
AC_SUBST([SHARED_GLAPI])
dnl
dnl Driver configuration. Options are xlib, dri and osmesa right now.
dnl More later: fbdev, ...
@ -589,8 +601,8 @@ GALLIUM_WINSYS_DIRS="sw"
GALLIUM_DRIVERS_DIRS="softpipe failover galahad trace rbug noop identity"
GALLIUM_STATE_TRACKERS_DIRS=""
# build shared-glapi if OpenGL ES is enabled
case "x$enable_gles1$enable_gles2" in
# build shared-glapi if enabled for OpenGL or if OpenGL ES is enabled
case "x$enabled_shared_glapi$enable_gles1$enable_gles2" in
x*yes*)
CORE_DIRS="$CORE_DIRS mapi/shared-glapi"
;;

View File

@ -123,8 +123,12 @@ endif
# OpenGL state tracker
GL_CPPFLAGS := -I$(TOP)/src/mesa $(API_DEFINES)
# cannot not link to $(GL_LIB) as the app might want GLES
ifeq ($(SHARED_GLAPI),1)
GL_SYS := $(DRI_LIB_DEPS) -l$(GLAPI_LIB)
else
# cannot link to $(GL_LIB) as the app might want GL or GLES
GL_SYS := $(DRI_LIB_DEPS)
endif
GL_LIBS := $(TOP)/src/mesa/libmesagallium.a
# OpenVG state tracker

View File

@ -60,6 +60,10 @@ GL_LIB_DEPS += $(LLVM_LIBS)
LDFLAGS += $(LLVM_LDFLAGS)
endif
ifeq ($(SHARED_GLAPI),1)
GL_LIB_DEPS := -L$(TOP)/$(LIB_DIR) -l$(GLAPI_LIB) $(GL_LIB_DEPS)
endif
.SUFFIXES : .cpp

View File

@ -46,6 +46,12 @@ SOURCES = \
applegl_glx.c
ifeq ($(SHARED_GLAPI),1)
GL_LIB_DEPS := -L$(TOP)/$(LIB_DIR) -l$(GLAPI_LIB) $(GL_LIB_DEPS)
EXTRA_DEFINES += -DGLX_SHARED_GLAPI
endif
# override GLAPI_LIB
GLAPI_LIB = $(TOP)/src/mapi/glapi/libglapi.a
OBJECTS = $(SOURCES:.c=.o)

View File

@ -36,6 +36,7 @@
#include "glxclient.h"
#include "glapi.h"
#include "glxextensions.h"
#include "indirect.h"
#ifdef GLX_DIRECT_RENDERING
#ifdef GLX_USE_APPLEGL
@ -2514,7 +2515,11 @@ _X_EXPORT void (*glXGetProcAddressARB(const GLubyte * procName)) (void)
f = (gl_function) get_glx_proc_address((const char *) procName);
if ((f == NULL) && (procName[0] == 'g') && (procName[1] == 'l')
&& (procName[2] != 'X')) {
f = (gl_function) _glapi_get_proc_address((const char *) procName);
#ifdef GLX_SHARED_GLAPI
f = (gl_function) __indirect_get_proc_address((const char *) procName);
#endif
if (!f)
f = (gl_function) _glapi_get_proc_address((const char *) procName);
}
#endif
return f;

View File

@ -10657,5 +10657,65 @@ __indirect_glFramebufferTextureLayerEXT(GLenum target, GLenum attachment,
}
# undef FASTCALL
# undef NOINLINE
#ifdef GLX_SHARED_GLAPI
static const struct proc_pair {
const char *name;
_glapi_proc proc;
} proc_pairs[20] = {
{
"AreTexturesResidentEXT", (_glapi_proc) glAreTexturesResidentEXT}, {
"DeleteTexturesEXT", (_glapi_proc) glDeleteTexturesEXT}, {
"GenTexturesEXT", (_glapi_proc) glGenTexturesEXT}, {
"GetColorTableEXT", (_glapi_proc) glGetColorTableEXT}, {
"GetColorTableParameterfvEXT",
(_glapi_proc) glGetColorTableParameterfvEXT}, {
"GetColorTableParameterfvSGI",
(_glapi_proc) glGetColorTableParameterfvEXT}, {
"GetColorTableParameterivEXT",
(_glapi_proc) glGetColorTableParameterivEXT}, {
"GetColorTableParameterivSGI",
(_glapi_proc) glGetColorTableParameterivEXT}, {
"GetColorTableSGI", (_glapi_proc) glGetColorTableEXT}, {
"GetConvolutionFilterEXT", (_glapi_proc) gl_dispatch_stub_356}, {
"GetConvolutionParameterfvEXT", (_glapi_proc) gl_dispatch_stub_357}, {
"GetConvolutionParameterivEXT", (_glapi_proc) gl_dispatch_stub_358}, {
"GetHistogramEXT", (_glapi_proc) gl_dispatch_stub_361}, {
"GetHistogramParameterfvEXT", (_glapi_proc) gl_dispatch_stub_362}, {
"GetHistogramParameterivEXT", (_glapi_proc) gl_dispatch_stub_363}, {
"GetMinmaxEXT", (_glapi_proc) gl_dispatch_stub_364}, {
"GetMinmaxParameterfvEXT", (_glapi_proc) gl_dispatch_stub_365}, {
"GetMinmaxParameterivEXT", (_glapi_proc) gl_dispatch_stub_366}, {
"GetSeparableFilterEXT", (_glapi_proc) gl_dispatch_stub_359}, {
"IsTextureEXT", (_glapi_proc) glIsTextureEXT}
};
static int
__indirect_get_proc_compare(const void *key, const void *memb)
{
const struct proc_pair *pair = (const struct proc_pair *) memb;
return strcmp((const char *) key, pair->name);
}
_glapi_proc
__indirect_get_proc_address(const char *name)
{
const struct proc_pair *pair;
/* skip "gl" */
name += 2;
pair = (const struct proc_pair *) bsearch((const void *) name,
(const void *) proc_pairs,
ARRAY_SIZE(proc_pairs),
sizeof(proc_pairs[0]),
__indirect_get_proc_compare);
return (pair) ? pair->proc : NULL;
}
#endif /* GLX_SHARED_GLAPI */
#undef FASTCALL
#undef NOINLINE

View File

@ -715,6 +715,10 @@ extern HIDDEN void __indirect_glRenderbufferStorageEXT(GLenum target, GLenum int
extern HIDDEN void __indirect_glBlitFramebufferEXT(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
extern HIDDEN void __indirect_glFramebufferTextureLayerEXT(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
#ifdef GLX_SHARED_GLAPI
extern HIDDEN void (*__indirect_get_proc_address(const char *name))(void);
#endif
# undef HIDDEN
# undef FASTCALL
# undef NOINLINE

View File

@ -8,46 +8,60 @@ TARGET = glapi
MAPI = $(TOP)/src/mapi/mapi
include sources.mak
GLAPI_OBJECTS = $(GLAPI_SOURCES:.c=.o)
GLAPI_ASM_OBJECTS = $(GLAPI_ASM_SOURCES:.S=.o)
include $(MAPI)/sources.mak
MAPI_UTIL_OBJECTS := $(MAPI_UTIL_SOURCES:.c=.o)
MAPI_UTIL_SOURCES := $(addprefix $(MAPI)/, $(MAPI_UTIL_SOURCES))
TARGET_OBJECTS = $(GLAPI_OBJECTS) $(GLAPI_ASM_OBJECTS) $(MAPI_UTIL_OBJECTS)
INCLUDE_DIRS = \
glapi_CPPFLAGS := \
-I$(TOP)/include \
-I$(TOP)/src/mapi \
-I$(TOP)/src/mesa
-I$(TOP)/src/mesa \
-DMAPI_ABI_HEADER=\"glapi/glapi_mapi_tmp.h\"
ifeq ($(SHARED_GLAPI),1)
glapi_CPPFLAGS += -DMAPI_MODE_BRIDGE
glapi_SOURCES := $(addprefix $(MAPI)/, $(MAPI_BRIDGE_SOURCES))
glapi_GLAPI_OBJECTS :=
glapi_ASM_OBJECTS :=
glapi_MAPI_OBJECTS := $(MAPI_BRIDGE_SOURCES:.c=.o)
else
glapi_CPPFLAGS += -DMAPI_MODE_UTIL
glapi_SOURCES := $(GLAPI_SOURCES) $(addprefix $(MAPI)/, $(MAPI_UTIL_SOURCES))
glapi_GLAPI_OBJECTS := $(GLAPI_SOURCES:.c=.o)
glapi_ASM_OBJECTS := $(GLAPI_ASM_SOURCES:.S=.o)
glapi_MAPI_OBJECTS := $(MAPI_UTIL_SOURCES:.c=.o)
endif # SHARED_GLAPI
glapi_OBJECTS := \
$(glapi_GLAPI_OBJECTS) \
$(glapi_ASM_OBJECTS) \
$(glapi_MAPI_OBJECTS)
default: depend lib$(TARGET).a
lib$(TARGET).a: $(TARGET_OBJECTS)
@$(MKLIB) -o $(TARGET) -static $(TARGET_OBJECTS)
lib$(TARGET).a: $(glapi_OBJECTS)
@$(MKLIB) -o $(TARGET) -static $(glapi_OBJECTS)
$(GLAPI_OBJECTS): %.o: %.c
$(CC) -c $(INCLUDE_DIRS) $(CFLAGS) -DMAPI_MODE_UTIL $< -o $@
$(glapi_GLAPI_OBJECTS): %.o: %.c
$(CC) -c $(glapi_CPPFLAGS) $(CFLAGS) $< -o $@
$(GLAPI_ASM_OBJECTS): %.o: %.S
$(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@
$(glapi_ASM_OBJECTS): %.o: %.S
$(CC) -c $(glapi_CPPFLAGS) $(CFLAGS) $< -o $@
$(MAPI_UTIL_OBJECTS): %.o: $(MAPI)/%.c
$(CC) -c $(INCLUDE_DIRS) $(CFLAGS) -DMAPI_MODE_UTIL $< -o $@
$(glapi_MAPI_OBJECTS): %.o: $(MAPI)/%.c
$(CC) -c $(glapi_CPPFLAGS) $(CFLAGS) $< -o $@
install:
clean:
-rm -f $(TARGET_OBJECTS)
-rm -f $(glapi_OBJECTS)
-rm -f lib$(TARGET).a
-rm -f depend depend.bak
depend: $(GLAPI_SOURCES) $(MAPI_UTIL_SOURCES)
depend: $(glapi_SOURCES)
@ echo "running $(MKDEP)"
@ touch depend
@$(MKDEP) $(MKDEP_OPTIONS) -f- $(DEFINES) $(INCLUDE_DIRS) \
-DMAPI_MODE_UTIL $(GLAPI_SOURCES) $(MAPI_UTIL_SOURCES) \
2>/dev/null | sed -e 's,^$(MAPI)/,,' > depend
@$(MKDEP) $(MKDEP_OPTIONS) -f- $(DEFINES) $(glapi_CPPFLAGS) \
$(glapi_SOURCES) 2>/dev/null | sed -e 's,^$(MAPI)/,,' > depend
-include depend

View File

@ -9,9 +9,11 @@ include $(TOP)/configs/current
MESA_DIR = $(TOP)/src/mesa
MESA_GLAPI_DIR = $(TOP)/src/mapi/glapi
MESA_MAPI_DIR = $(TOP)/src/mapi/mapi
MESA_GLX_DIR = $(TOP)/src/glx
MESA_GLAPI_OUTPUTS = \
$(MESA_GLAPI_DIR)/glapi_mapi_tmp.h \
$(MESA_GLAPI_DIR)/glprocs.h \
$(MESA_GLAPI_DIR)/glapitemp.h \
$(MESA_GLAPI_DIR)/glapitable.h
@ -141,6 +143,10 @@ $(XORG_GLAPI_DIR)/%.h: $(MESA_GLAPI_DIR)/%.h
######################################################################
$(MESA_GLAPI_DIR)/glapi_mapi_tmp.h: $(MESA_MAPI_DIR)/mapi_abi.py $(COMMON_ES)
$(PYTHON2) $(PYTHON_FLAGS) $< \
--printer glapi --mode lib gl_and_es_API.xml > $@
$(MESA_GLAPI_DIR)/glprocs.h: gl_procs.py $(COMMON)
$(PYTHON2) $(PYTHON_FLAGS) $< > $@

View File

@ -350,6 +350,55 @@ const GLuint __glXDefaultPixelStore[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 1 };
if func.glx_sop and func.glx_vendorpriv:
self.printFunction(func, func.glx_vendorpriv_names[0])
self.printGetProcAddress(api)
return
def printGetProcAddress(self, api):
procs = {}
for func in api.functionIterateGlx():
for n in func.entry_points:
if func.has_different_protocol(n):
procs[n] = func.static_glx_name(n)
print """
#ifdef GLX_SHARED_GLAPI
static const struct proc_pair
{
const char *name;
_glapi_proc proc;
} proc_pairs[%d] = {""" % len(procs)
names = procs.keys()
names.sort()
for i in xrange(len(names)):
comma = ',' if i < len(names) - 1 else ''
print ' { "%s", (_glapi_proc) gl%s }%s' % (names[i], procs[names[i]], comma)
print """};
static int
__indirect_get_proc_compare(const void *key, const void *memb)
{
const struct proc_pair *pair = (const struct proc_pair *) memb;
return strcmp((const char *) key, pair->name);
}
_glapi_proc
__indirect_get_proc_address(const char *name)
{
const struct proc_pair *pair;
/* skip "gl" */
name += 2;
pair = (const struct proc_pair *) bsearch((const void *) name,
(const void *) proc_pairs, ARRAY_SIZE(proc_pairs), sizeof(proc_pairs[0]),
__indirect_get_proc_compare);
return (pair) ? pair->proc : NULL;
}
#endif /* GLX_SHARED_GLAPI */
"""
return
@ -1001,6 +1050,10 @@ extern HIDDEN NOINLINE FASTCALL GLubyte * __glXSetupVendorRequest(
break
print ''
print '#ifdef GLX_SHARED_GLAPI'
print 'extern HIDDEN void (*__indirect_get_proc_address(const char *name))(void);'
print '#endif'
def show_usage():

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
# src/mapi/shared-glapi/Makefile
#
# Used by OpenGL ES
# Used by OpenGL ES or when --enable-shared-glapi is specified
#
TOP := ../../..

View File

@ -47,6 +47,9 @@ INCLUDE_DIRS = \
CORE_MESA = $(TOP)/src/mesa/libmesa.a $(TOP)/src/mapi/glapi/libglapi.a
ifeq ($(SHARED_GLAPI),1)
GL_LIB_DEPS := -L$(TOP)/$(LIB_DIR) -l$(GLAPI_LIB) $(GL_LIB_DEPS)
endif
.c.o: