summaryrefslogtreecommitdiffstats
path: root/src/egl
diff options
context:
space:
mode:
Diffstat (limited to 'src/egl')
-rw-r--r--src/egl/drivers/Makefile.template7
-rw-r--r--src/egl/drivers/dri/Makefile2
-rw-r--r--src/egl/drivers/dri2/Makefile2
-rw-r--r--src/egl/drivers/dri2/egl_dri2.c101
-rw-r--r--src/egl/drivers/glx/egl_glx.c2
-rw-r--r--src/egl/main/Makefile19
-rw-r--r--src/egl/main/egl.pc.in12
-rw-r--r--src/egl/main/eglapi.c48
-rw-r--r--src/egl/main/eglapi.h7
-rw-r--r--src/egl/main/eglconfig.c62
-rw-r--r--src/egl/main/eglconfig.h23
-rw-r--r--src/egl/main/egldefines.h1
-rw-r--r--src/egl/main/egldisplay.h2
-rw-r--r--src/egl/main/egldriver.c103
-rw-r--r--src/egl/main/egldriver.h9
-rw-r--r--src/egl/main/eglglobals.c3
-rw-r--r--src/egl/main/eglmisc.c2
-rw-r--r--src/egl/main/eglsurface.c23
-rw-r--r--src/egl/main/eglsurface.h2
19 files changed, 289 insertions, 141 deletions
diff --git a/src/egl/drivers/Makefile.template b/src/egl/drivers/Makefile.template
index e9a614ce62d..08e82c65e9b 100644
--- a/src/egl/drivers/Makefile.template
+++ b/src/egl/drivers/Makefile.template
@@ -12,20 +12,21 @@
#
-EGL_DRIVER_PATH = $(TOP)/$(LIB_DIR)/$(EGL_DRIVER)
+EGL_DRIVER_PATH = $(TOP)/$(LIB_DIR)/egl/$(EGL_DRIVER)
EGL_OBJECTS = $(EGL_SOURCES:.c=.o)
default: depend $(EGL_DRIVER_PATH)
$(EGL_DRIVER_PATH): $(EGL_DRIVER)
- $(INSTALL) $< $(TOP)/$(LIB_DIR)
+ @$(INSTALL) -d $(TOP)/$(LIB_DIR)/egl
+ $(INSTALL) $< $(TOP)/$(LIB_DIR)/egl
$(EGL_DRIVER): $(EGL_OBJECTS) Makefile $(TOP)/src/egl/drivers/Makefile.template
@$(MKLIB) -o $(EGL_DRIVER) -noprefix \
-linker '$(CC)' -ldflags '$(LDFLAGS)' \
-L$(TOP)/$(LIB_DIR) $(MKLIB_OPTIONS) \
- $(EGL_OBJECTS) $(EGL_LIBS)
+ $(EGL_OBJECTS) $(EGL_LIBS) -l$(EGL_LIB)
.c.o:
$(CC) -c $(EGL_INCLUDES) $(CFLAGS) $(EGL_CFLAGS) $< -o $@
diff --git a/src/egl/drivers/dri/Makefile b/src/egl/drivers/dri/Makefile
index 7339c97c77d..c3aacff1cfe 100644
--- a/src/egl/drivers/dri/Makefile
+++ b/src/egl/drivers/dri/Makefile
@@ -11,9 +11,9 @@ INCLUDE_DIRS = \
$(shell pkg-config --cflags-only-I libdrm) \
-I$(TOP)/include \
-I$(TOP)/include/GL/internal \
+ -I$(TOP)/src/mapi \
-I$(TOP)/src/mesa \
-I$(TOP)/src/mesa/main \
- -I$(TOP)/src/mesa/glapi \
-I$(TOP)/src/mesa/math \
-I$(TOP)/src/mesa/transform \
-I$(TOP)/src/mesa/shader \
diff --git a/src/egl/drivers/dri2/Makefile b/src/egl/drivers/dri2/Makefile
index 129e67b8c66..4e760aec4c8 100644
--- a/src/egl/drivers/dri2/Makefile
+++ b/src/egl/drivers/dri2/Makefile
@@ -9,7 +9,7 @@ EGL_SOURCES = egl_dri2.c
EGL_INCLUDES = \
-I$(TOP)/include \
-I$(TOP)/src/egl/main \
- -I$(TOP)/src/mesa \
+ -I$(TOP)/src/mapi \
-DDEFAULT_DRIVER_DIR=\"$(DRI_DRIVER_SEARCH_DIR)\" \
$(EGL_DRI2_CFLAGS)
diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
index 69f3c28c9e4..eb9a6510ed0 100644
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -51,6 +51,8 @@
#include "eglsurface.h"
#include "eglimage.h"
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
+
struct dri2_egl_driver
{
_EGLDriver base;
@@ -163,7 +165,7 @@ EGLint dri2_to_egl_attribute_map[] = {
0, /* __DRI_ATTRIB_BIND_TO_TEXTURE_RGBA */
0, /* __DRI_ATTRIB_BIND_TO_MIPMAP_TEXTURE */
0, /* __DRI_ATTRIB_BIND_TO_TEXTURE_TARGETS */
- 0, /* __DRI_ATTRIB_YINVERTED */
+ EGL_Y_INVERTED_NOK, /* __DRI_ATTRIB_YINVERTED */
};
static void
@@ -415,12 +417,6 @@ dri2_get_buffers_with_format(__DRIdrawable * driDrawable,
return dri2_surf->buffers;
}
-#ifdef GLX_USE_TLS
-static const char dri_driver_format[] = "%.*s/tls/%s_dri.so";
-#else
-static const char dri_driver_format[] = "%.*s/%s_dri.so";
-#endif
-
static const char dri_driver_path[] = DEFAULT_DRIVER_DIR;
struct dri2_extension_match {
@@ -678,19 +674,28 @@ dri2_initialize(_EGLDriver *drv, _EGLDisplay *disp,
dri2_dpy->driver = NULL;
end = search_paths + strlen(search_paths);
for (p = search_paths; p < end && dri2_dpy->driver == NULL; p = next + 1) {
+ int len;
next = strchr(p, ':');
if (next == NULL)
next = end;
+ len = next - p;
+#if GLX_USE_TLS
snprintf(path, sizeof path,
- dri_driver_format, (int) (next - p), p, dri2_dpy->driver_name);
+ "%.*s/tls/%s_dri.so", len, p, dri2_dpy->driver_name);
dri2_dpy->driver = dlopen(path, RTLD_NOW | RTLD_GLOBAL);
- if (dri2_dpy->driver == NULL)
- _eglLog(_EGL_DEBUG, "failed to open %s: %s\n", path, dlerror());
+#endif
+ if (dri2_dpy->driver == NULL) {
+ snprintf(path, sizeof path,
+ "%.*s/%s_dri.so", len, p, dri2_dpy->driver_name);
+ dri2_dpy->driver = dlopen(path, RTLD_NOW | RTLD_GLOBAL);
+ if (dri2_dpy->driver == NULL)
+ _eglLog(_EGL_DEBUG, "failed to open %s: %s\n", path, dlerror());
+ }
}
if (dri2_dpy->driver == NULL) {
- _eglLog(_EGL_FATAL,
+ _eglLog(_EGL_WARNING,
"DRI2: failed to open any driver (search paths %s)",
search_paths);
goto cleanup_conn;
@@ -699,7 +704,7 @@ dri2_initialize(_EGLDriver *drv, _EGLDisplay *disp,
_eglLog(_EGL_DEBUG, "DRI2: dlopen(%s)", path);
extensions = dlsym(dri2_dpy->driver, __DRI_DRIVER_EXTENSIONS);
if (extensions == NULL) {
- _eglLog(_EGL_FATAL,
+ _eglLog(_EGL_WARNING,
"DRI2: driver exports no extensions (%s)", dlerror());
goto cleanup_driver;
}
@@ -709,7 +714,7 @@ dri2_initialize(_EGLDriver *drv, _EGLDisplay *disp,
dri2_dpy->fd = open(dri2_dpy->device_name, O_RDWR);
if (dri2_dpy->fd == -1) {
- _eglLog(_EGL_FATAL,
+ _eglLog(_EGL_WARNING,
"DRI2: could not open %s (%s)", dri2_dpy->device_name,
strerror(errno));
goto cleanup_driver;
@@ -748,7 +753,7 @@ dri2_initialize(_EGLDriver *drv, _EGLDisplay *disp,
&dri2_dpy->driver_configs, dri2_dpy);
if (dri2_dpy->dri_screen == NULL) {
- _eglLog(_EGL_FATAL, "DRI2: failed to create dri screen");
+ _eglLog(_EGL_WARNING, "DRI2: failed to create dri screen");
goto cleanup_fd;
}
@@ -778,6 +783,8 @@ dri2_initialize(_EGLDriver *drv, _EGLDisplay *disp,
disp->Extensions.KHR_image_pixmap = EGL_TRUE;
disp->Extensions.KHR_gl_renderbuffer_image = EGL_TRUE;
disp->Extensions.KHR_gl_texture_2D_image = EGL_TRUE;
+ disp->Extensions.NOK_swap_region = EGL_TRUE;
+ disp->Extensions.NOK_texture_from_pixmap = EGL_TRUE;
/* we're supporting EGL 1.4 */
*major = 1;
@@ -1067,7 +1074,8 @@ dri2_create_pbuffer_surface(_EGLDriver *drv, _EGLDisplay *disp,
}
static EGLBoolean
-dri2_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
+dri2_copy_region(_EGLDriver *drv, _EGLDisplay *disp,
+ _EGLSurface *draw, xcb_xfixes_region_t region)
{
struct dri2_egl_driver *dri2_drv = dri2_egl_driver(drv);
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
@@ -1099,7 +1107,7 @@ dri2_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
cookie = xcb_dri2_copy_region_unchecked(dri2_dpy->conn,
dri2_surf->drawable,
- dri2_surf->region,
+ region,
XCB_DRI2_ATTACHMENT_BUFFER_FRONT_LEFT,
XCB_DRI2_ATTACHMENT_BUFFER_FAKE_FRONT_LEFT);
free(xcb_dri2_copy_region_reply(dri2_dpy->conn, cookie, NULL));
@@ -1107,6 +1115,44 @@ dri2_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
return EGL_TRUE;
}
+static EGLBoolean
+dri2_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
+{
+ struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
+
+ return dri2_copy_region(drv, disp, draw, dri2_surf->region);
+}
+
+static EGLBoolean
+dri2_swap_buffers_region(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw,
+ EGLint numRects, const EGLint *rects)
+{
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+ struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
+ EGLBoolean ret;
+ xcb_xfixes_region_t region;
+ xcb_rectangle_t rectangles[16];
+ int i;
+
+ if (numRects > ARRAY_SIZE(rectangles))
+ return dri2_copy_region(drv, disp, draw, dri2_surf->region);
+
+ /* FIXME: Invert y here? */
+ for (i = 0; i < numRects; i++) {
+ rectangles[i].x = rects[i * 4];
+ rectangles[i].y = rects[i * 4 + 1];
+ rectangles[i].width = rects[i * 4 + 2];
+ rectangles[i].height = rects[i * 4 + 3];
+ }
+
+ region = xcb_generate_id(dri2_dpy->conn);
+ xcb_xfixes_create_region(dri2_dpy->conn, region, numRects, rectangles);
+ ret = dri2_copy_region(drv, disp, draw, region);
+ xcb_xfixes_destroy_region(dri2_dpy->conn, region);
+
+ return ret;
+}
+
/*
* Called from eglGetProcAddress() via drv->API.GetProcAddress().
*/
@@ -1187,19 +1233,8 @@ dri2_bind_tex_image(_EGLDriver *drv,
ctx = _eglGetCurrentContext();
dri2_ctx = dri2_egl_context(ctx);
- if (buffer != EGL_BACK_BUFFER) {
- _eglError(EGL_BAD_PARAMETER, "eglBindTexImage");
- return EGL_FALSE;
- }
-
- /* We allow binding pixmaps too... Not conformat, but we can do it
- * for free and it's useful for X compositors. Supposedly there's
- * a EGL_NOKIA_texture_from_pixmap extension that allows that, but
- * I couldn't find it at this time. */
- if ((dri2_surf->base.Type & (EGL_PBUFFER_BIT | EGL_PIXMAP_BIT)) == 0) {
- _eglError(EGL_BAD_SURFACE, "eglBindTexImage");
+ if (!_eglBindTexImage(drv, disp, surf, buffer))
return EGL_FALSE;
- }
switch (dri2_surf->base.TextureFormat) {
case EGL_TEXTURE_RGB:
@@ -1209,8 +1244,7 @@ dri2_bind_tex_image(_EGLDriver *drv,
format = __DRI_TEXTURE_FORMAT_RGBA;
break;
default:
- _eglError(EGL_BAD_MATCH, "eglBindTexImage");
- return EGL_FALSE;
+ assert(0);
}
switch (dri2_surf->base.TextureTarget) {
@@ -1218,15 +1252,14 @@ dri2_bind_tex_image(_EGLDriver *drv,
target = GL_TEXTURE_2D;
break;
default:
- _eglError(EGL_BAD_PARAMETER, "eglBindTexImage");
- return EGL_FALSE;
+ assert(0);
}
(*dri2_dpy->tex_buffer->setTexBuffer2)(dri2_ctx->dri_context,
target, format,
dri2_surf->dri_drawable);
- return dri2_surf->base.BoundToTexture = EGL_TRUE;
+ return EGL_TRUE;
}
static EGLBoolean
@@ -1396,6 +1429,7 @@ _eglMain(const char *args)
if (!dri2_drv)
return NULL;
+ memset(dri2_drv, 0, sizeof *dri2_drv);
_eglInitDriverFallbacks(&dri2_drv->base);
dri2_drv->base.API.Initialize = dri2_initialize;
dri2_drv->base.API.Terminate = dri2_terminate;
@@ -1414,6 +1448,7 @@ _eglMain(const char *args)
dri2_drv->base.API.ReleaseTexImage = dri2_release_tex_image;
dri2_drv->base.API.CreateImageKHR = dri2_create_image_khr;
dri2_drv->base.API.DestroyImageKHR = dri2_destroy_image_khr;
+ dri2_drv->base.API.SwapBuffersRegionNOK = dri2_swap_buffers_region;
dri2_drv->base.Name = "DRI2";
dri2_drv->base.Unload = dri2_unload;
diff --git a/src/egl/drivers/glx/egl_glx.c b/src/egl/drivers/glx/egl_glx.c
index 3cbfebe4881..e08ef5f2228 100644
--- a/src/egl/drivers/glx/egl_glx.c
+++ b/src/egl/drivers/glx/egl_glx.c
@@ -41,6 +41,7 @@
#include "eglconfigutil.h"
#include "eglconfig.h"
#include "eglcontext.h"
+#include "egldefines.h"
#include "egldisplay.h"
#include "egldriver.h"
#include "eglcurrent.h"
@@ -48,7 +49,6 @@
#include "eglsurface.h"
#define CALLOC_STRUCT(T) (struct T *) calloc(1, sizeof(struct T))
-#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
#ifndef GLX_VERSION_1_4
#error "GL/glx.h must be equal to or greater than GLX 1.4"
diff --git a/src/egl/main/Makefile b/src/egl/main/Makefile
index 3b4ebf7fec4..82fd855b1d5 100644
--- a/src/egl/main/Makefile
+++ b/src/egl/main/Makefile
@@ -82,10 +82,27 @@ install-headers:
$(INSTALL) -m 644 $(TOP)/include/EGL/*.h \
$(DESTDIR)$(INSTALL_INC_DIR)/EGL
-install: default install-headers
+PKG_CONFIG_DIR = $(INSTALL_LIB_DIR)/pkgconfig
+
+gl_pcedit = sed \
+ -e 's,@INSTALL_DIR@,$(INSTALL_DIR),' \
+ -e 's,@INSTALL_LIB_DIR@,$(INSTALL_LIB_DIR),' \
+ -e 's,@INSTALL_INC_DIR@,$(INSTALL_INC_DIR),' \
+ -e 's,@VERSION@,$(MESA_MAJOR).$(MESA_MINOR).$(MESA_TINY),' \
+ -e 's,@EGL_PC_REQ_PRIV@,$(EGL_PC_REQ_PRIV),' \
+ -e 's,@EGL_PC_LIB_PRIV@,$(EGL_PC_LIB_PRIV),' \
+ -e 's,@EGL_PC_CFLAGS@,$(EGL_PC_CFLAGS),' \
+ -e 's,@EGL_LIB@,$(EGL_LIB),'
+
+egl.pc: egl.pc.in
+ $(gl_pcedit) $< > $@
+
+install: default install-headers egl.pc
$(INSTALL) -d $(DESTDIR)$(INSTALL_LIB_DIR)
$(MINSTALL) $(TOP)/$(LIB_DIR)/$(EGL_LIB_GLOB) \
$(DESTDIR)$(INSTALL_LIB_DIR)
+ $(INSTALL) -d $(DESTDIR)$(PKG_CONFIG_DIR)
+ $(INSTALL) -m 644 egl.pc $(DESTDIR)$(PKG_CONFIG_DIR)
clean:
-rm -f *.o
diff --git a/src/egl/main/egl.pc.in b/src/egl/main/egl.pc.in
new file mode 100644
index 00000000000..2855a4980a0
--- /dev/null
+++ b/src/egl/main/egl.pc.in
@@ -0,0 +1,12 @@
+prefix=@INSTALL_DIR@
+exec_prefix=${prefix}
+libdir=@INSTALL_LIB_DIR@
+includedir=@INSTALL_INC_DIR@
+
+Name: egl
+Description: Mesa EGL library
+Requires.private: @EGL_PC_REQ_PRIV@
+Version: @VERSION@
+Libs: -L${libdir} -l@EGL_LIB@
+Libs.private: @EGL_PC_LIB_PRIV@
+Cflags: -I${includedir} @EGL_PC_CFLAGS@
diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c
index 647be652207..1a533e0880b 100644
--- a/src/egl/main/eglapi.c
+++ b/src/egl/main/eglapi.c
@@ -261,7 +261,7 @@ EGLBoolean EGLAPIENTRY
eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
{
_EGLDisplay *disp = _eglLockDisplay(dpy);
- EGLint major_int, minor_int;
+ EGLint major_int = 0, minor_int = 0;
if (!disp)
RETURN_EGL_ERROR(NULL, EGL_BAD_DISPLAY, EGL_FALSE);
@@ -272,13 +272,15 @@ eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
if (!drv) {
_eglPreloadDrivers();
drv = _eglMatchDriver(disp);
- if (!drv)
- RETURN_EGL_ERROR(disp, EGL_NOT_INITIALIZED, EGL_FALSE);
+ /* Initialize the particular display now */
+ if (drv && !drv->API.Initialize(drv, disp, &major_int, &minor_int))
+ RETURN_EGL_ERROR(disp, EGL_NOT_INITIALIZED, EGL_FALSE);
}
-
- /* Initialize the particular display now */
- if (!drv->API.Initialize(drv, disp, &major_int, &minor_int))
- RETURN_EGL_ERROR(disp, EGL_NOT_INITIALIZED, EGL_FALSE);
+ if (!drv)
+ /* Load and initialize the first default driver that works */
+ drv = _eglLoadDefaultDriver(disp, &major_int, &minor_int);
+ if (!drv)
+ RETURN_EGL_ERROR(disp, EGL_NOT_INITIALIZED, EGL_FALSE);
disp->APImajor = major_int;
disp->APIminor = minor_int;
@@ -836,6 +838,9 @@ eglGetProcAddress(const char *procname)
{ "eglCreateImageKHR", (_EGLProc) eglCreateImageKHR },
{ "eglDestroyImageKHR", (_EGLProc) eglDestroyImageKHR },
#endif /* EGL_KHR_image_base */
+#ifdef EGL_NOK_swap_region
+ { "eglSwapBuffersRegionNOK", (_EGLProc) eglSwapBuffersRegionNOK },
+#endif
{ NULL, NULL }
};
EGLint i;
@@ -1244,3 +1249,32 @@ eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image)
#endif /* EGL_KHR_image_base */
+
+
+#ifdef EGL_NOK_swap_region
+
+EGLBoolean
+eglSwapBuffersRegionNOK(EGLDisplay dpy, EGLSurface surface,
+ EGLint numRects, const EGLint *rects)
+{
+ _EGLContext *ctx = _eglGetCurrentContext();
+ _EGLDisplay *disp = _eglLockDisplay(dpy);
+ _EGLSurface *surf = _eglLookupSurface(surface, disp);
+ _EGLDriver *drv;
+ EGLBoolean ret;
+
+ _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
+
+ /* surface must be bound to current context in EGL 1.4 */
+ if (!ctx || !_eglIsContextLinked(ctx) || surf != ctx->DrawSurface)
+ RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
+
+ if (drv->API.SwapBuffersRegionNOK)
+ ret = drv->API.SwapBuffersRegionNOK(drv, disp, surf, numRects, rects);
+ else
+ ret = drv->API.SwapBuffers(drv, disp, surf);
+
+ RETURN_EGL_EVAL(disp, ret);
+}
+
+#endif /* EGL_NOK_swap_region */
diff --git a/src/egl/main/eglapi.h b/src/egl/main/eglapi.h
index 3e2ba8dd415..d8c8b49a49d 100644
--- a/src/egl/main/eglapi.h
+++ b/src/egl/main/eglapi.h
@@ -76,6 +76,9 @@ typedef _EGLImage *(*CreateImageKHR_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLCo
typedef EGLBoolean (*DestroyImageKHR_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLImage *image);
#endif /* EGL_KHR_image_base */
+#ifdef EGL_NOK_swap_region
+typedef EGLBoolean (*SwapBuffersRegionNOK_t)(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf, EGLint numRects, const EGLint *rects);
+#endif
/**
* The API dispatcher jumps through these functions
@@ -134,6 +137,10 @@ struct _egl_api
CreateImageKHR_t CreateImageKHR;
DestroyImageKHR_t DestroyImageKHR;
#endif /* EGL_KHR_image_base */
+
+#ifdef EGL_NOK_swap_region
+ SwapBuffersRegionNOK_t SwapBuffersRegionNOK;
+#endif
};
#endif /* EGLAPI_INCLUDED */
diff --git a/src/egl/main/eglconfig.c b/src/egl/main/eglconfig.c
index 21d13cba904..fa947d76887 100644
--- a/src/egl/main/eglconfig.c
+++ b/src/egl/main/eglconfig.c
@@ -13,7 +13,6 @@
#define MIN2(A, B) (((A) < (B)) ? (A) : (B))
-#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
/**
@@ -224,7 +223,12 @@ static const struct {
0 },
{ EGL_NONE, ATTRIB_TYPE_PSEUDO,
ATTRIB_CRITERION_IGNORE,
- 0 }
+ 0 },
+
+ { EGL_Y_INVERTED_NOK, ATTRIB_TYPE_BOOLEAN,
+ ATTRIB_CRITERION_EXACT,
+ EGL_DONT_CARE },
+
};
@@ -479,6 +483,28 @@ _eglMatchConfig(const _EGLConfig *conf, const _EGLConfig *criteria)
return matched;
}
+static INLINE EGLBoolean
+_eglIsConfigAttribValid(_EGLConfig *conf, EGLint attr)
+{
+ if (_eglIndexConfig(conf, attr) < 0)
+ return EGL_FALSE;
+
+ /* there are some holes in the range */
+ switch (attr) {
+ case 0x3030 /* a gap before EGL_SAMPLES */:
+ case EGL_NONE:
+#ifdef EGL_VERSION_1_4
+ case EGL_MATCH_NATIVE_PIXMAP:
+#endif
+ return EGL_FALSE;
+ case EGL_Y_INVERTED_NOK:
+ return conf->Display->Extensions.NOK_texture_from_pixmap;
+ default:
+ break;
+ }
+
+ return EGL_TRUE;
+}
/**
* Initialize a criteria config from the given attribute list.
@@ -501,15 +527,13 @@ _eglParseConfigAttribList(_EGLConfig *conf, const EGLint *attrib_list)
/* parse the list */
for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i += 2) {
- EGLint idx;
-
attr = attrib_list[i];
val = attrib_list[i + 1];
- idx = _eglIndexConfig(conf, attr);
- if (idx < 0)
- return EGL_FALSE;
- conf->Storage[idx] = val;
+ if (!_eglIsConfigAttribValid(conf, attr))
+ return EGL_FALSE;
+
+ SET_CONFIG_ATTRIB(conf, attr, val);
/* rememeber some attributes for post-processing */
switch (attr) {
@@ -782,28 +806,6 @@ _eglChooseConfig(_EGLDriver *drv, _EGLDisplay *disp, const EGLint *attrib_list,
}
-static INLINE EGLBoolean
-_eglIsConfigAttribValid(_EGLConfig *conf, EGLint attr)
-{
- if (_eglIndexConfig(conf, attr) < 0)
- return EGL_FALSE;
-
- /* there are some holes in the range */
- switch (attr) {
- case 0x3030 /* a gap before EGL_SAMPLES */:
- case EGL_NONE:
-#ifdef EGL_VERSION_1_4
- case EGL_MATCH_NATIVE_PIXMAP:
-#endif
- return EGL_FALSE;
- default:
- break;
- }
-
- return EGL_TRUE;
-}
-
-
/**
* Fallback for eglGetConfigAttrib.
*/
diff --git a/src/egl/main/eglconfig.h b/src/egl/main/eglconfig.h
index ced060f7797..ca63c40d3d7 100644
--- a/src/egl/main/eglconfig.h
+++ b/src/egl/main/eglconfig.h
@@ -8,16 +8,24 @@
#define _EGL_CONFIG_FIRST_ATTRIB EGL_BUFFER_SIZE
#define _EGL_CONFIG_LAST_ATTRIB EGL_CONFORMANT
-#define _EGL_CONFIG_NUM_ATTRIBS \
+#define _EGL_CONFIG_NUM_CONTIGUOUS_ATTRIBS \
(_EGL_CONFIG_LAST_ATTRIB - _EGL_CONFIG_FIRST_ATTRIB + 1)
-#define _EGL_CONFIG_STORAGE_SIZE _EGL_CONFIG_NUM_ATTRIBS
+/* Attributes outside the contiguous block:
+ *
+ * EGL_Y_INVERTED_NOK
+ */
+#define _EGL_CONFIG_FIRST_EXTRA_ATTRIB _EGL_CONFIG_NUM_CONTIGUOUS_ATTRIBS
+#define _EGL_CONFIG_NUM_EXTRA_ATTRIBS 1
+
+#define _EGL_CONFIG_NUM_ATTRIBS \
+ _EGL_CONFIG_NUM_CONTIGUOUS_ATTRIBS + _EGL_CONFIG_NUM_EXTRA_ATTRIBS
struct _egl_config
{
_EGLDisplay *Display;
- EGLint Storage[_EGL_CONFIG_STORAGE_SIZE];
+ EGLint Storage[_EGL_CONFIG_NUM_ATTRIBS];
};
@@ -37,10 +45,15 @@ _eglIndexConfig(const _EGLConfig *conf, EGLint key)
{
(void) conf;
if (key >= _EGL_CONFIG_FIRST_ATTRIB &&
- key < _EGL_CONFIG_FIRST_ATTRIB + _EGL_CONFIG_NUM_ATTRIBS)
+ key < _EGL_CONFIG_FIRST_ATTRIB + _EGL_CONFIG_NUM_CONTIGUOUS_ATTRIBS)
return key - _EGL_CONFIG_FIRST_ATTRIB;
- else
+
+ switch (key) {
+ case EGL_Y_INVERTED_NOK:
+ return _EGL_CONFIG_FIRST_EXTRA_ATTRIB;
+ default:
return -1;
+ }
}
diff --git a/src/egl/main/egldefines.h b/src/egl/main/egldefines.h
index 8fc2301b795..4ecd4c1420c 100644
--- a/src/egl/main/egldefines.h
+++ b/src/egl/main/egldefines.h
@@ -40,6 +40,7 @@
#define _EGL_VENDOR_STRING "Mesa Project"
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
#endif /* EGLDEFINES_INCLUDED */
diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h
index 21bf22b5fee..42e305f91ac 100644
--- a/src/egl/main/egldisplay.h
+++ b/src/egl/main/egldisplay.h
@@ -46,6 +46,8 @@ struct _egl_extensions
EGLBoolean KHR_gl_texture_cubemap_image;
EGLBoolean KHR_gl_texture_3D_image;
EGLBoolean KHR_gl_renderbuffer_image;
+ EGLBoolean NOK_swap_region;
+ EGLBoolean NOK_texture_from_pixmap;
char String[_EGL_MAX_EXTENSIONS_LEN];
};
diff --git a/src/egl/main/egldriver.c b/src/egl/main/egldriver.c
index 6384242b093..566554d51dc 100644
--- a/src/egl/main/egldriver.c
+++ b/src/egl/main/egldriver.c
@@ -36,7 +36,9 @@
/* XXX Need to decide how to do dynamic name lookup on Windows */
-static const char DefaultDriverName[] = "TBD";
+static const char DefaultDriverNames[] = {
+ "TBD",
+};
typedef HMODULE lib_handle;
@@ -63,7 +65,10 @@ library_suffix(void)
#elif defined(_EGL_PLATFORM_POSIX)
-static const char DefaultDriverName[] = "egl_glx";
+static const char *DefaultDriverNames[] = {
+ "egl_dri2",
+ "egl_glx"
+};
typedef void * lib_handle;
@@ -87,32 +92,6 @@ library_suffix(void)
}
-#else /* _EGL_PLATFORM_NO_OS */
-
-
-static const char DefaultDriverName[] = "builtin";
-
-typedef void *lib_handle;
-
-static INLINE void *
-open_library(const char *filename)
-{
- return (void *) filename;
-}
-
-static INLINE void
-close_library(void *lib)
-{
-}
-
-
-static const char *
-library_suffix(void)
-{
- return NULL;
-}
-
-
#endif
@@ -157,12 +136,6 @@ _eglOpenLibrary(const char *driverPath, lib_handle *handle)
else {
error = dlerror();
}
-#else /* _EGL_PLATFORM_NO_OS */
- /* must be the default driver name */
- if (strcmp(driverPath, DefaultDriverName) == 0)
- mainFunc = (_EGLMain_t) _eglMain;
- else
- error = "not builtin driver";
#endif
if (!lib) {
@@ -293,9 +266,9 @@ _eglLoaderFile(const char *dir, size_t len, void *loader_data)
len += flen;
path[len] = '\0';
- drv = _eglLoadDriver(path, NULL);
- /* fix the path and load again */
- if (!drv && library_suffix()) {
+ if (library_suffix() == NULL || strstr(path, library_suffix()))
+ drv = _eglLoadDriver(path, NULL);
+ else {
const char *suffix = library_suffix();
size_t slen = strlen(suffix);
const char *p;
@@ -306,6 +279,8 @@ _eglLoaderFile(const char *dir, size_t len, void *loader_data)
if (need_suffix && len + slen + 1 <= sizeof(path)) {
strcpy(path + len, suffix);
drv = _eglLoadDriver(path, NULL);
+ } else {
+ drv = NULL;
}
}
if (!drv)
@@ -518,17 +493,6 @@ _eglPreloadDisplayDrivers(void)
/**
- * Preload the default driver.
- */
-static EGLBoolean
-_eglPreloadDefaultDriver(void)
-{
- return (_eglPreloadForEach(_eglGetSearchPath(),
- _eglLoaderFile, (void *) DefaultDriverName) > 0);
-}
-
-
-/**
* Preload drivers.
*
* This function loads the driver modules and creates the corresponding
@@ -549,15 +513,13 @@ _eglPreloadDrivers(void)
}
loaded = (_eglPreloadUserDriver() ||
- _eglPreloadDisplayDrivers() ||
- _eglPreloadDefaultDriver());
+ _eglPreloadDisplayDrivers());
_eglUnlockMutex(_eglGlobal.Mutex);
return loaded;
}
-
/**
* Unload preloaded drivers.
*/
@@ -588,6 +550,30 @@ _eglUnloadDrivers(void)
_eglGlobal.NumDrivers = 0;
}
+_EGLDriver *
+_eglLoadDefaultDriver(EGLDisplay dpy, EGLint *major, EGLint *minor)
+{
+ _EGLDriver *drv = NULL;
+ int i;
+
+ _eglLockMutex(_eglGlobal.Mutex);
+
+ for (i = 0; i < ARRAY_SIZE(DefaultDriverNames); i++) {
+ _eglPreloadForEach(_eglGetSearchPath(),
+ _eglLoaderFile, (void *) DefaultDriverNames[i]);
+ if (_eglGlobal.NumDrivers == 0)
+ continue;
+ drv = _eglGlobal.Drivers[0];
+ if (drv->API.Initialize(drv, dpy, major, minor))
+ break;
+ _eglUnloadDrivers();
+ }
+
+ _eglUnlockMutex(_eglGlobal.Mutex);
+
+ return drv;
+}
+
/**
* Plug all the available fallback routines into the given driver's
@@ -653,6 +639,21 @@ _eglInitDriverFallbacks(_EGLDriver *drv)
/**
+ * Invoke a callback function on each EGL search path.
+ *
+ * The first argument of the callback function is the name of the search path.
+ * The second argument is the length of the name.
+ */
+void
+_eglSearchPathForEach(EGLBoolean (*callback)(const char *, size_t, void *),
+ void *callback_data)
+{
+ const char *search_path = _eglGetSearchPath();
+ _eglPreloadForEach(search_path, callback, callback_data);
+}
+
+
+/**
* Set the probe cache at the given key.
*
* A key, instead of a _EGLDriver, is used to allow the probe cache to be share
diff --git a/src/egl/main/egldriver.h b/src/egl/main/egldriver.h
index 55686681dcb..8b34c43b924 100644
--- a/src/egl/main/egldriver.h
+++ b/src/egl/main/egldriver.h
@@ -84,11 +84,20 @@ extern void
_eglUnloadDrivers(void);
+extern _EGLDriver *
+_eglLoadDefaultDriver(EGLDisplay dpy, EGLint *major, EGLint *minor);
+
+
PUBLIC void
_eglInitDriverFallbacks(_EGLDriver *drv);
PUBLIC void
+_eglSearchPathForEach(EGLBoolean (*callback)(const char *, size_t, void *),
+ void *callback_data);
+
+
+PUBLIC void
_eglSetProbeCache(EGLint key, const void *val);
diff --git a/src/egl/main/eglglobals.c b/src/egl/main/eglglobals.c
index 5182b18e226..e63819e08a2 100644
--- a/src/egl/main/eglglobals.c
+++ b/src/egl/main/eglglobals.c
@@ -6,9 +6,6 @@
#include "eglmutex.h"
-#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
-
-
static _EGL_DECLARE_MUTEX(_eglGlobalMutex);
struct _egl_global _eglGlobal =
{
diff --git a/src/egl/main/eglmisc.c b/src/egl/main/eglmisc.c
index 984e426686e..e62a9e7de8c 100644
--- a/src/egl/main/eglmisc.c
+++ b/src/egl/main/eglmisc.c
@@ -96,6 +96,8 @@ _eglUpdateExtensionsString(_EGLDisplay *dpy)
_EGL_CHECK_EXTENSION(KHR_gl_texture_3D_image);
_EGL_CHECK_EXTENSION(KHR_gl_renderbuffer_image);
+ _EGL_CHECK_EXTENSION(NOK_swap_region);
+ _EGL_CHECK_EXTENSION(NOK_texture_from_pixmap);
#undef _EGL_CHECK_EXTENSION
}
diff --git a/src/egl/main/eglsurface.c b/src/egl/main/eglsurface.c
index 8026a6314d3..d46bdb0672e 100644
--- a/src/egl/main/eglsurface.c
+++ b/src/egl/main/eglsurface.c
@@ -36,12 +36,17 @@ _eglClampSwapInterval(_EGLSurface *surf, EGLint interval)
static EGLint
_eglParseSurfaceAttribList(_EGLSurface *surf, const EGLint *attrib_list)
{
+ _EGLDisplay *dpy = surf->Resource.Display;
EGLint type = surf->Type;
+ EGLint texture_type = EGL_PBUFFER_BIT;
EGLint i, err = EGL_SUCCESS;
if (!attrib_list)
return EGL_SUCCESS;
+ if (dpy->Extensions.NOK_texture_from_pixmap)
+ texture_type |= EGL_PIXMAP_BIT;
+
for (i = 0; attrib_list[i] != EGL_NONE; i++) {
EGLint attr = attrib_list[i++];
EGLint val = attrib_list[i];
@@ -125,7 +130,7 @@ _eglParseSurfaceAttribList(_EGLSurface *surf, const EGLint *attrib_list)
surf->LargestPbuffer = !!val;
break;
case EGL_TEXTURE_FORMAT:
- if (type != EGL_PBUFFER_BIT) {
+ if (!(type & texture_type)) {
err = EGL_BAD_ATTRIBUTE;
break;
}
@@ -143,7 +148,7 @@ _eglParseSurfaceAttribList(_EGLSurface *surf, const EGLint *attrib_list)
surf->TextureFormat = val;
break;
case EGL_TEXTURE_TARGET:
- if (type != EGL_PBUFFER_BIT) {
+ if (!(type & texture_type)) {
err = EGL_BAD_ATTRIBUTE;
break;
}
@@ -160,7 +165,7 @@ _eglParseSurfaceAttribList(_EGLSurface *surf, const EGLint *attrib_list)
surf->TextureTarget = val;
break;
case EGL_MIPMAP_TEXTURE:
- if (type != EGL_PBUFFER_BIT) {
+ if (!(type & texture_type)) {
err = EGL_BAD_ATTRIBUTE;
break;
}
@@ -452,11 +457,16 @@ EGLBoolean
_eglBindTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface,
EGLint buffer)
{
+ EGLint texture_type = EGL_PBUFFER_BIT;
+
/* Just do basic error checking and return success/fail.
* Drivers must implement the real stuff.
*/
- if (surface->Type != EGL_PBUFFER_BIT) {
+ if (dpy->Extensions.NOK_texture_from_pixmap)
+ texture_type |= EGL_PIXMAP_BIT;
+
+ if (!(surface->Type & texture_type)) {
_eglError(EGL_BAD_SURFACE, "eglBindTexImage");
return EGL_FALSE;
}
@@ -466,6 +476,11 @@ _eglBindTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface,
return EGL_FALSE;
}
+ if (surface->TextureTarget == EGL_NO_TEXTURE) {
+ _eglError(EGL_BAD_MATCH, "eglBindTexImage");
+ return EGL_FALSE;
+ }
+
if (buffer != EGL_BACK_BUFFER) {
_eglError(EGL_BAD_PARAMETER, "eglBindTexImage");
return EGL_FALSE;
diff --git a/src/egl/main/eglsurface.h b/src/egl/main/eglsurface.h
index 0a00035730f..8f520dcdf65 100644
--- a/src/egl/main/eglsurface.h
+++ b/src/egl/main/eglsurface.h
@@ -83,7 +83,7 @@ extern EGLBoolean
_eglSurfaceAttrib(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, EGLint attribute, EGLint value);
-extern EGLBoolean
+PUBLIC extern EGLBoolean
_eglBindTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, EGLint buffer);