diff options
Diffstat (limited to 'src/egl')
-rw-r--r-- | src/egl/drivers/Makefile.template | 7 | ||||
-rw-r--r-- | src/egl/drivers/dri/Makefile | 2 | ||||
-rw-r--r-- | src/egl/drivers/dri2/Makefile | 2 | ||||
-rw-r--r-- | src/egl/drivers/dri2/egl_dri2.c | 101 | ||||
-rw-r--r-- | src/egl/drivers/glx/egl_glx.c | 2 | ||||
-rw-r--r-- | src/egl/main/Makefile | 19 | ||||
-rw-r--r-- | src/egl/main/egl.pc.in | 12 | ||||
-rw-r--r-- | src/egl/main/eglapi.c | 48 | ||||
-rw-r--r-- | src/egl/main/eglapi.h | 7 | ||||
-rw-r--r-- | src/egl/main/eglconfig.c | 62 | ||||
-rw-r--r-- | src/egl/main/eglconfig.h | 23 | ||||
-rw-r--r-- | src/egl/main/egldefines.h | 1 | ||||
-rw-r--r-- | src/egl/main/egldisplay.h | 2 | ||||
-rw-r--r-- | src/egl/main/egldriver.c | 103 | ||||
-rw-r--r-- | src/egl/main/egldriver.h | 9 | ||||
-rw-r--r-- | src/egl/main/eglglobals.c | 3 | ||||
-rw-r--r-- | src/egl/main/eglmisc.c | 2 | ||||
-rw-r--r-- | src/egl/main/eglsurface.c | 23 | ||||
-rw-r--r-- | src/egl/main/eglsurface.h | 2 |
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); |