diff options
author | Jason Ekstrand <[email protected]> | 2015-06-23 18:05:25 -0700 |
---|---|---|
committer | Jason Ekstrand <[email protected]> | 2015-06-23 18:05:25 -0700 |
commit | a62edcce4eb4c800d972817a20ee874bf2a2c3ef (patch) | |
tree | 46083a8762d45a6c595c7aaee2bb1cd0fc36eb62 /src/egl | |
parent | 9b9f973ca6d3cc1ec5be27857def00a83c032464 (diff) | |
parent | 6844d6b7f8398a25eff511541b187afeb1199ce0 (diff) |
Merge remote-tracking branch 'mesa-public/master' into vulkan
Diffstat (limited to 'src/egl')
45 files changed, 1699 insertions, 2191 deletions
diff --git a/src/egl/drivers/dri2/Android.mk b/src/egl/drivers/dri2/Android.mk index 5931ce8f2f0..109e4d4a0d8 100644 --- a/src/egl/drivers/dri2/Android.mk +++ b/src/egl/drivers/dri2/Android.mk @@ -36,6 +36,7 @@ LOCAL_CFLAGS := \ -DHAVE_ANDROID_PLATFORM ifeq ($(MESA_LOLLIPOP_BUILD),true) +LOCAL_CFLAGS_arm := -DDEFAULT_DRIVER_DIR=\"/system/lib/dri\" LOCAL_CFLAGS_x86 := -DDEFAULT_DRIVER_DIR=\"/system/lib/dri\" LOCAL_CFLAGS_x86_64 := -DDEFAULT_DRIVER_DIR=\"/system/lib64/dri\" else @@ -45,7 +46,6 @@ endif LOCAL_C_INCLUDES := \ $(MESA_TOP)/src/mapi \ $(MESA_TOP)/src/egl/main \ - $(MESA_TOP)/src/loader \ $(DRM_GRALLOC_TOP) LOCAL_STATIC_LIBRARIES := \ diff --git a/src/egl/drivers/dri2/Makefile.am b/src/egl/drivers/dri2/Makefile.am index f589600be0f..55be4a75ba5 100644 --- a/src/egl/drivers/dri2/Makefile.am +++ b/src/egl/drivers/dri2/Makefile.am @@ -65,4 +65,9 @@ libegl_dri2_la_SOURCES += platform_drm.c AM_CFLAGS += -DHAVE_DRM_PLATFORM endif +if HAVE_EGL_PLATFORM_SURFACELESS +libegl_dri2_la_SOURCES += platform_surfaceless.c +AM_CFLAGS += -DHAVE_SURFACELESS_PLATFORM +endif + EXTRA_DIST = SConscript diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c index f4c29da61cf..a1cbd437f53 100644 --- a/src/egl/drivers/dri2/egl_dri2.c +++ b/src/egl/drivers/dri2/egl_dri2.c @@ -397,7 +397,7 @@ dri2_open_driver(_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) { + for (p = search_paths; p < end; p = next + 1) { int len; next = strchr(p, ':'); if (next == NULL) @@ -419,6 +419,15 @@ dri2_open_driver(_EGLDisplay *disp) /* not need continue to loop all paths once the driver is found */ if (dri2_dpy->driver != NULL) break; + +#ifdef ANDROID + snprintf(path, sizeof path, "%.*s/gallium_dri.so", len, p); + 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()); + else + break; +#endif } if (dri2_dpy->driver == NULL) { @@ -576,6 +585,7 @@ dri2_create_screen(_EGLDisplay *disp) { const __DRIextension **extensions; struct dri2_egl_display *dri2_dpy; + unsigned i; dri2_dpy = disp->DriverData; @@ -616,28 +626,26 @@ dri2_create_screen(_EGLDisplay *disp) extensions = dri2_dpy->core->getExtensions(dri2_dpy->dri_screen); if (dri2_dpy->dri2) { - unsigned i; - if (!dri2_bind_extensions(dri2_dpy, dri2_core_extensions, extensions)) goto cleanup_dri_screen; - - for (i = 0; extensions[i]; i++) { - if (strcmp(extensions[i]->name, __DRI2_ROBUSTNESS) == 0) { - dri2_dpy->robustness = (__DRIrobustnessExtension *) extensions[i]; - } - if (strcmp(extensions[i]->name, __DRI2_CONFIG_QUERY) == 0) { - dri2_dpy->config = (__DRI2configQueryExtension *) extensions[i]; - } - if (strcmp(extensions[i]->name, __DRI2_FENCE) == 0) { - dri2_dpy->fence = (__DRI2fenceExtension *) extensions[i]; - } - } } else { assert(dri2_dpy->swrast); if (!dri2_bind_extensions(dri2_dpy, swrast_core_extensions, extensions)) goto cleanup_dri_screen; } + for (i = 0; extensions[i]; i++) { + if (strcmp(extensions[i]->name, __DRI2_ROBUSTNESS) == 0) { + dri2_dpy->robustness = (__DRIrobustnessExtension *) extensions[i]; + } + if (strcmp(extensions[i]->name, __DRI2_CONFIG_QUERY) == 0) { + dri2_dpy->config = (__DRI2configQueryExtension *) extensions[i]; + } + if (strcmp(extensions[i]->name, __DRI2_FENCE) == 0) { + dri2_dpy->fence = (__DRI2fenceExtension *) extensions[i]; + } + } + dri2_setup_screen(disp); return EGL_TRUE; @@ -659,6 +667,13 @@ dri2_initialize(_EGLDriver *drv, _EGLDisplay *disp) return EGL_FALSE; switch (disp->Platform) { +#ifdef HAVE_SURFACELESS_PLATFORM + case _EGL_PLATFORM_SURFACELESS: + if (disp->Options.TestOnly) + return EGL_TRUE; + return dri2_initialize_surfaceless(drv, disp); +#endif + #ifdef HAVE_X11_PLATFORM case _EGL_PLATFORM_X11: if (disp->Options.TestOnly) @@ -729,7 +744,12 @@ dri2_terminate(_EGLDriver *drv, _EGLDisplay *disp) #endif #ifdef HAVE_WAYLAND_PLATFORM case _EGL_PLATFORM_WAYLAND: - wl_drm_destroy(dri2_dpy->wl_drm); + if (dri2_dpy->wl_drm) + wl_drm_destroy(dri2_dpy->wl_drm); + if (dri2_dpy->wl_shm) + wl_shm_destroy(dri2_dpy->wl_shm); + wl_registry_destroy(dri2_dpy->wl_registry); + wl_event_queue_destroy(dri2_dpy->wl_queue); if (dri2_dpy->own_device) { wl_display_disconnect(dri2_dpy->wl_dpy); } @@ -1252,7 +1272,8 @@ dri2_bind_tex_image(_EGLDriver *drv, format = __DRI_TEXTURE_FORMAT_RGBA; break; default: - assert(0); + assert(!"Unexpected texture format in dri2_bind_tex_image()"); + format = __DRI_TEXTURE_FORMAT_RGBA; } switch (dri2_surf->base.TextureTarget) { @@ -1260,7 +1281,8 @@ dri2_bind_tex_image(_EGLDriver *drv, target = GL_TEXTURE_2D; break; default: - assert(0); + target = GL_TEXTURE_2D; + assert(!"Unexpected texture target in dri2_bind_tex_image()"); } (*dri2_dpy->tex_buffer->setTexBuffer2)(dri2_ctx->dri_context, @@ -2210,7 +2232,7 @@ dri2_egl_unref_sync(struct dri2_egl_display *dri2_dpy, static _EGLSync * dri2_create_sync(_EGLDriver *drv, _EGLDisplay *dpy, EGLenum type, const EGLint *attrib_list, - const EGLAttribKHR *attrib_list64) + const EGLAttrib *attrib_list64) { _EGLContext *ctx = _eglGetCurrentContext(); struct dri2_egl_display *dri2_dpy = dri2_egl_display(dpy); @@ -2276,7 +2298,7 @@ dri2_destroy_sync(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync) static EGLint dri2_client_wait_sync(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync, - EGLint flags, EGLTimeKHR timeout) + EGLint flags, EGLTime timeout) { _EGLContext *ctx = _eglGetCurrentContext(); struct dri2_egl_display *dri2_dpy = dri2_egl_display(dpy); diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h index 371fb4aee4a..9985c49f984 100644 --- a/src/egl/drivers/dri2/egl_dri2.h +++ b/src/egl/drivers/dri2/egl_dri2.h @@ -196,10 +196,13 @@ struct dri2_egl_display struct wl_registry *wl_registry; struct wl_drm *wl_server_drm; struct wl_drm *wl_drm; + struct wl_shm *wl_shm; struct wl_event_queue *wl_queue; int authenticated; int formats; uint32_t capabilities; + int is_render_node; + int is_different_gpu; #endif }; @@ -253,6 +256,11 @@ struct dri2_egl_surface #ifdef HAVE_WAYLAND_PLATFORM struct wl_buffer *wl_buffer; __DRIimage *dri_image; + /* for is_different_gpu case. NULL else */ + __DRIimage *linear_copy; + /* for swrast */ + void *data; + int data_size; #endif #ifdef HAVE_DRM_PLATFORM struct gbm_bo *bo; @@ -343,6 +351,9 @@ dri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp); EGLBoolean dri2_initialize_android(_EGLDriver *drv, _EGLDisplay *disp); +EGLBoolean +dri2_initialize_surfaceless(_EGLDriver *drv, _EGLDisplay *disp); + void dri2_flush_drawable_for_swapbuffers(_EGLDisplay *disp, _EGLSurface *draw); diff --git a/src/egl/drivers/dri2/egl_dri2_fallbacks.h b/src/egl/drivers/dri2/egl_dri2_fallbacks.h index 9cba0010ba7..e769af36e60 100644 --- a/src/egl/drivers/dri2/egl_dri2_fallbacks.h +++ b/src/egl/drivers/dri2/egl_dri2_fallbacks.h @@ -45,6 +45,15 @@ dri2_fallback_create_pbuffer_surface(_EGLDriver *drv, _EGLDisplay *disp, return NULL; } +static inline _EGLImage* +dri2_fallback_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp, + _EGLContext *ctx, EGLenum target, + EGLClientBuffer buffer, + const EGLint *attr_list) +{ + return NULL; +} + static inline EGLBoolean dri2_fallback_swap_interval(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, EGLint interval) diff --git a/src/egl/drivers/dri2/platform_android.c b/src/egl/drivers/dri2/platform_android.c index f4825261bad..fed3073088a 100644 --- a/src/egl/drivers/dri2/platform_android.c +++ b/src/egl/drivers/dri2/platform_android.c @@ -707,10 +707,6 @@ dri2_initialize_android(_EGLDriver *drv, _EGLDisplay *dpy) dpy->Extensions.ANDROID_image_native_buffer = EGL_TRUE; dpy->Extensions.KHR_image_base = EGL_TRUE; - /* we're supporting EGL 1.4 */ - dpy->VersionMajor = 1; - dpy->VersionMinor = 4; - /* Fill vtbl last to prevent accidentally calling virtual function during * initialization. */ diff --git a/src/egl/drivers/dri2/platform_drm.c b/src/egl/drivers/dri2/platform_drm.c index 486b0030dcd..a62da4121fe 100644 --- a/src/egl/drivers/dri2/platform_drm.c +++ b/src/egl/drivers/dri2/platform_drm.c @@ -611,9 +611,9 @@ dri2_initialize_drm(_EGLDriver *drv, _EGLDisplay *disp) char buf[64]; int n = snprintf(buf, sizeof(buf), DRM_DEV_NAME, DRM_DIR_NAME, 0); if (n != -1 && n < sizeof(buf)) - fd = open(buf, O_RDWR); + fd = loader_open_device(buf); if (fd < 0) - fd = open("/dev/dri/card0", O_RDWR); + fd = loader_open_device("/dev/dri/card0"); dri2_dpy->own_device = 1; gbm = gbm_create_device(fd); if (gbm == NULL) @@ -632,7 +632,7 @@ dri2_initialize_drm(_EGLDriver *drv, _EGLDisplay *disp) } if (fd < 0) { - fd = dup(gbm_device_get_fd(gbm)); + fd = fcntl(gbm_device_get_fd(gbm), F_DUPFD_CLOEXEC, 3); if (fd < 0) { free(dri2_dpy); return EGL_FALSE; @@ -715,10 +715,6 @@ dri2_initialize_drm(_EGLDriver *drv, _EGLDisplay *disp) } #endif - /* we're supporting EGL 1.4 */ - disp->VersionMajor = 1; - disp->VersionMinor = 4; - /* Fill vtbl last to prevent accidentally calling virtual function during * initialization. */ diff --git a/src/egl/drivers/dri2/platform_surfaceless.c b/src/egl/drivers/dri2/platform_surfaceless.c new file mode 100644 index 00000000000..48f15df75a1 --- /dev/null +++ b/src/egl/drivers/dri2/platform_surfaceless.c @@ -0,0 +1,162 @@ +/* + * Mesa 3-D graphics library + * + * Copyright (c) 2014 The Chromium OS Authors. + * Copyright © 2011 Intel Corporation + * + * 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. + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <xf86drm.h> +#include <dlfcn.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> + +#include "egl_dri2.h" +#include "egl_dri2_fallbacks.h" +#include "loader.h" + +static struct dri2_egl_display_vtbl dri2_surfaceless_display_vtbl = { + .create_pixmap_surface = dri2_fallback_create_pixmap_surface, + .create_image = dri2_create_image_khr, + .swap_interval = dri2_fallback_swap_interval, + .swap_buffers_with_damage = dri2_fallback_swap_buffers_with_damage, + .swap_buffers_region = dri2_fallback_swap_buffers_region, + .post_sub_buffer = dri2_fallback_post_sub_buffer, + .copy_buffers = dri2_fallback_copy_buffers, + .query_buffer_age = dri2_fallback_query_buffer_age, + .create_wayland_buffer_from_image = dri2_fallback_create_wayland_buffer_from_image, + .get_sync_values = dri2_fallback_get_sync_values, +}; + +static void +surfaceless_flush_front_buffer(__DRIdrawable *driDrawable, void *loaderPrivate) +{ +} + +static __DRIbuffer * +surfaceless_get_buffers_with_format(__DRIdrawable * driDrawable, + int *width, int *height, + unsigned int *attachments, int count, + int *out_count, void *loaderPrivate) +{ + struct dri2_egl_surface *dri2_surf = loaderPrivate; + + dri2_surf->buffer_count = 1; + if (width) + *width = dri2_surf->base.Width; + if (height) + *height = dri2_surf->base.Height; + *out_count = dri2_surf->buffer_count;; + return dri2_surf->buffers; +} + +#define DRM_RENDER_DEV_NAME "%s/renderD%d" + +EGLBoolean +dri2_initialize_surfaceless(_EGLDriver *drv, _EGLDisplay *disp) +{ + struct dri2_egl_display *dri2_dpy; + const char* err; + int i; + int driver_loaded = 0; + + loader_set_logger(_eglLog); + + dri2_dpy = calloc(1, sizeof *dri2_dpy); + if (!dri2_dpy) + return _eglError(EGL_BAD_ALLOC, "eglInitialize"); + + disp->DriverData = (void *) dri2_dpy; + + const int limit = 64; + const int base = 128; + for (i = 0; i < limit; ++i) { + char *card_path; + if (asprintf(&card_path, DRM_RENDER_DEV_NAME, DRM_DIR_NAME, base + i) < 0) + continue; + + dri2_dpy->fd = loader_open_device(card_path); + + free(card_path); + if (dri2_dpy->fd < 0) + continue; + + dri2_dpy->driver_name = loader_get_driver_for_fd(dri2_dpy->fd, 0); + if (dri2_dpy->driver_name) { + if (dri2_load_driver(disp)) { + driver_loaded = 1; + break; + } + free(dri2_dpy->driver_name); + } + close(dri2_dpy->fd); + } + + if (!driver_loaded) { + err = "DRI2: failed to load driver"; + goto cleanup_display; + } + + dri2_dpy->dri2_loader_extension.base.name = __DRI_DRI2_LOADER; + dri2_dpy->dri2_loader_extension.base.version = 3; + dri2_dpy->dri2_loader_extension.getBuffers = NULL; + dri2_dpy->dri2_loader_extension.flushFrontBuffer = + surfaceless_flush_front_buffer; + dri2_dpy->dri2_loader_extension.getBuffersWithFormat = + surfaceless_get_buffers_with_format; + + dri2_dpy->extensions[0] = &dri2_dpy->dri2_loader_extension.base; + dri2_dpy->extensions[1] = &image_lookup_extension.base; + dri2_dpy->extensions[2] = &use_invalidate.base; + dri2_dpy->extensions[3] = NULL; + + if (!dri2_create_screen(disp)) { + err = "DRI2: failed to create screen"; + goto cleanup_driver; + } + + for (i = 0; dri2_dpy->driver_configs[i]; i++) { + dri2_add_config(disp, dri2_dpy->driver_configs[i], + i + 1, EGL_WINDOW_BIT, NULL, NULL); + } + + disp->Extensions.KHR_image_base = EGL_TRUE; + + /* Fill vtbl last to prevent accidentally calling virtual function during + * initialization. + */ + dri2_dpy->vtbl = &dri2_surfaceless_display_vtbl; + + return EGL_TRUE; + +cleanup_driver: + dlclose(dri2_dpy->driver); + free(dri2_dpy->driver_name); + close(dri2_dpy->fd); +cleanup_display: + free(dri2_dpy); + + return _eglError(EGL_NOT_INITIALIZED, err); +} diff --git a/src/egl/drivers/dri2/platform_wayland.c b/src/egl/drivers/dri2/platform_wayland.c index e2260053917..1c985523862 100644 --- a/src/egl/drivers/dri2/platform_wayland.c +++ b/src/egl/drivers/dri2/platform_wayland.c @@ -1,5 +1,6 @@ /* * Copyright © 2011-2012 Intel Corporation + * Copyright © 2012 Collabora, Ltd. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -35,6 +36,7 @@ #include <unistd.h> #include <fcntl.h> #include <xf86drm.h> +#include <sys/mman.h> #include "egl_dri2.h" #include "egl_dri2_fallbacks.h" @@ -120,7 +122,7 @@ resize_callback(struct wl_egl_window *wl_win, void *data) * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface(). */ static _EGLSurface * -dri2_wl_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type, +dri2_wl_create_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf, void *native_window, const EGLint *attrib_list) { @@ -137,7 +139,7 @@ dri2_wl_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type, return NULL; } - if (!_eglInitSurface(&dri2_surf->base, disp, type, conf, attrib_list)) + if (!_eglInitSurface(&dri2_surf->base, disp, EGL_WINDOW_BIT, conf, attrib_list)) goto cleanup_surf; if (conf->RedSize == 5) @@ -147,25 +149,17 @@ dri2_wl_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type, else dri2_surf->format = WL_DRM_FORMAT_ARGB8888; - switch (type) { - case EGL_WINDOW_BIT: - dri2_surf->wl_win = window; + dri2_surf->wl_win = window; - dri2_surf->wl_win->private = dri2_surf; - dri2_surf->wl_win->resize_callback = resize_callback; + dri2_surf->wl_win->private = dri2_surf; + dri2_surf->wl_win->resize_callback = resize_callback; - dri2_surf->base.Width = -1; - dri2_surf->base.Height = -1; - break; - default: - goto cleanup_surf; - } + dri2_surf->base.Width = -1; + dri2_surf->base.Height = -1; dri2_surf->dri_drawable = (*dri2_dpy->dri2->createNewDrawable) (dri2_dpy->dri_screen, - type == EGL_WINDOW_BIT ? - dri2_conf->dri_double_config : - dri2_conf->dri_single_config, + dri2_conf->dri_double_config, dri2_surf); if (dri2_surf->dri_drawable == NULL) { _eglError(EGL_BAD_ALLOC, "dri2->createNewDrawable"); @@ -193,8 +187,7 @@ dri2_wl_create_window_surface(_EGLDriver *drv, _EGLDisplay *disp, struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); _EGLSurface *surf; - surf = dri2_wl_create_surface(drv, disp, EGL_WINDOW_BIT, conf, - native_window, attrib_list); + surf = dri2_wl_create_surface(drv, disp, conf, native_window, attrib_list); if (surf != NULL) dri2_wl_swap_interval(drv, disp, surf, dri2_dpy->default_swap_interval); @@ -240,21 +233,26 @@ dri2_wl_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf) wl_buffer_destroy(dri2_surf->color_buffers[i].wl_buffer); if (dri2_surf->color_buffers[i].dri_image) dri2_dpy->image->destroyImage(dri2_surf->color_buffers[i].dri_image); + if (dri2_surf->color_buffers[i].linear_copy) + dri2_dpy->image->destroyImage(dri2_surf->color_buffers[i].linear_copy); + if (dri2_surf->color_buffers[i].data) + munmap(dri2_surf->color_buffers[i].data, + dri2_surf->color_buffers[i].data_size); } - for (i = 0; i < __DRI_BUFFER_COUNT; i++) - if (dri2_surf->dri_buffers[i] && - dri2_surf->dri_buffers[i]->attachment != __DRI_BUFFER_BACK_LEFT) - dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen, - dri2_surf->dri_buffers[i]); + if (dri2_dpy->dri2) { + for (i = 0; i < __DRI_BUFFER_COUNT; i++) + if (dri2_surf->dri_buffers[i] && + dri2_surf->dri_buffers[i]->attachment != __DRI_BUFFER_BACK_LEFT) + dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen, + dri2_surf->dri_buffers[i]); + } if (dri2_surf->throttle_callback) wl_callback_destroy(dri2_surf->throttle_callback); - if (dri2_surf->base.Type == EGL_WINDOW_BIT) { - dri2_surf->wl_win->private = NULL; - dri2_surf->wl_win->resize_callback = NULL; - } + dri2_surf->wl_win->private = NULL; + dri2_surf->wl_win->resize_callback = NULL; free(surf); @@ -274,17 +272,26 @@ dri2_wl_release_buffers(struct dri2_egl_surface *dri2_surf) wl_buffer_destroy(dri2_surf->color_buffers[i].wl_buffer); if (dri2_surf->color_buffers[i].dri_image) dri2_dpy->image->destroyImage(dri2_surf->color_buffers[i].dri_image); + if (dri2_surf->color_buffers[i].linear_copy) + dri2_dpy->image->destroyImage(dri2_surf->color_buffers[i].linear_copy); + if (dri2_surf->color_buffers[i].data) + munmap(dri2_surf->color_buffers[i].data, + dri2_surf->color_buffers[i].data_size); dri2_surf->color_buffers[i].wl_buffer = NULL; dri2_surf->color_buffers[i].dri_image = NULL; + dri2_surf->color_buffers[i].linear_copy = NULL; + dri2_surf->color_buffers[i].data = NULL; dri2_surf->color_buffers[i].locked = 0; } - for (i = 0; i < __DRI_BUFFER_COUNT; i++) - if (dri2_surf->dri_buffers[i] && - dri2_surf->dri_buffers[i]->attachment != __DRI_BUFFER_BACK_LEFT) - dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen, - dri2_surf->dri_buffers[i]); + if (dri2_dpy->dri2) { + for (i = 0; i < __DRI_BUFFER_COUNT; i++) + if (dri2_surf->dri_buffers[i] && + dri2_surf->dri_buffers[i]->attachment != __DRI_BUFFER_BACK_LEFT) + dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen, + dri2_surf->dri_buffers[i]); + } } static int @@ -338,13 +345,29 @@ get_back_bo(struct dri2_egl_surface *dri2_surf) if (dri2_surf->back == NULL) return -1; + + if (dri2_dpy->is_different_gpu && + dri2_surf->back->linear_copy == NULL) { + dri2_surf->back->linear_copy = + dri2_dpy->image->createImage(dri2_dpy->dri_screen, + dri2_surf->base.Width, + dri2_surf->base.Height, + dri_image_format, + __DRI_IMAGE_USE_SHARE | + __DRI_IMAGE_USE_LINEAR, + NULL); + if (dri2_surf->back->linear_copy == NULL) + return -1; + } + if (dri2_surf->back->dri_image == NULL) { dri2_surf->back->dri_image = dri2_dpy->image->createImage(dri2_dpy->dri_screen, dri2_surf->base.Width, dri2_surf->base.Height, dri_image_format, - __DRI_IMAGE_USE_SHARE, + dri2_dpy->is_different_gpu ? + 0 : __DRI_IMAGE_USE_SHARE, NULL); dri2_surf->back->age = 0; } @@ -407,9 +430,8 @@ update_buffers(struct dri2_egl_surface *dri2_surf) dri2_egl_display(dri2_surf->base.Resource.Display); int i; - if (dri2_surf->base.Type == EGL_WINDOW_BIT && - (dri2_surf->base.Width != dri2_surf->wl_win->width || - dri2_surf->base.Height != dri2_surf->wl_win->height)) { + if (dri2_surf->base.Width != dri2_surf->wl_win->width || + dri2_surf->base.Height != dri2_surf->wl_win->height) { dri2_wl_release_buffers(dri2_surf); @@ -432,8 +454,11 @@ update_buffers(struct dri2_egl_surface *dri2_surf) dri2_surf->color_buffers[i].wl_buffer) { wl_buffer_destroy(dri2_surf->color_buffers[i].wl_buffer); dri2_dpy->image->destroyImage(dri2_surf->color_buffers[i].dri_image); + if (dri2_dpy->is_different_gpu) + dri2_dpy->image->destroyImage(dri2_surf->color_buffers[i].linear_copy); dri2_surf->color_buffers[i].wl_buffer = NULL; dri2_surf->color_buffers[i].dri_image = NULL; + dri2_surf->color_buffers[i].linear_copy = NULL; } } @@ -578,16 +603,20 @@ create_wl_buffer(struct dri2_egl_surface *dri2_surf) { struct dri2_egl_display *dri2_dpy = dri2_egl_display(dri2_surf->base.Resource.Display); + __DRIimage *image; int fd, stride, name; if (dri2_surf->current->wl_buffer != NULL) return; + if (dri2_dpy->is_different_gpu) { + image = dri2_surf->current->linear_copy; + } else { + image = dri2_surf->current->dri_image; + } if (dri2_dpy->capabilities & WL_DRM_CAPABILITY_PRIME) { - dri2_dpy->image->queryImage(dri2_surf->current->dri_image, - __DRI_IMAGE_ATTRIB_FD, &fd); - dri2_dpy->image->queryImage(dri2_surf->current->dri_image, - __DRI_IMAGE_ATTRIB_STRIDE, &stride); + dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_FD, &fd); + dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_STRIDE, &stride); dri2_surf->current->wl_buffer = wl_drm_create_prime_buffer(dri2_dpy->wl_drm, @@ -600,10 +629,8 @@ create_wl_buffer(struct dri2_egl_surface *dri2_surf) 0, 0); close(fd); } else { - dri2_dpy->image->queryImage(dri2_surf->current->dri_image, - __DRI_IMAGE_ATTRIB_NAME, &name); - dri2_dpy->image->queryImage(dri2_surf->current->dri_image, - __DRI_IMAGE_ATTRIB_STRIDE, &stride); + dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_NAME, &name); + dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_STRIDE, &stride); dri2_surf->current->wl_buffer = wl_drm_create_buffer(dri2_dpy->wl_drm, @@ -683,6 +710,18 @@ dri2_wl_swap_buffers_with_damage(_EGLDriver *drv, } } + if (dri2_dpy->is_different_gpu) { + _EGLContext *ctx = _eglGetCurrentContext(); + struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx); + dri2_dpy->image->blitImage(dri2_ctx->dri_context, + dri2_surf->current->linear_copy, + dri2_surf->current->dri_image, + 0, 0, dri2_surf->base.Width, + dri2_surf->base.Height, + 0, 0, dri2_surf->base.Width, + dri2_surf->base.Height, 0); + } + dri2_flush_drawable_for_swapbuffers(disp, draw); (*dri2_dpy->flush->invalidate)(dri2_surf->dri_drawable); @@ -800,12 +839,33 @@ bad_format: return NULL; } +static char +is_fd_render_node(int fd) +{ + struct stat render; + + if (fstat(fd, &render)) + return 0; + + if (!S_ISCHR(render.st_mode)) + return 0; + + if (render.st_rdev & 0x80) + return 1; + return 0; +} + static int dri2_wl_authenticate(_EGLDisplay *disp, uint32_t id) { struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); int ret = 0; + if (dri2_dpy->is_render_node) { + _eglLog(_EGL_WARNING, "wayland-egl: client asks server to " + "authenticate for render-nodes"); + return 0; + } dri2_dpy->authenticated = 0; wl_drm_authenticate(dri2_dpy->wl_drm, id); @@ -831,24 +891,19 @@ drm_handle_device(void *data, struct wl_drm *drm, const char *device) if (!dri2_dpy->device_name) return; -#ifdef O_CLOEXEC - dri2_dpy->fd = open(dri2_dpy->device_name, O_RDWR | O_CLOEXEC); - if (dri2_dpy->fd == -1 && errno == EINVAL) -#endif - { - dri2_dpy->fd = open(dri2_dpy->device_name, O_RDWR); - if (dri2_dpy->fd != -1) - fcntl(dri2_dpy->fd, F_SETFD, fcntl(dri2_dpy->fd, F_GETFD) | - FD_CLOEXEC); - } + dri2_dpy->fd = loader_open_device(dri2_dpy->device_name); if (dri2_dpy->fd == -1) { _eglLog(_EGL_WARNING, "wayland-egl: could not open %s (%s)", dri2_dpy->device_name, strerror(errno)); return; } - drmGetMagic(dri2_dpy->fd, &magic); - wl_drm_authenticate(dri2_dpy->wl_drm, magic); + if (is_fd_render_node(dri2_dpy->fd)) { + dri2_dpy->authenticated = 1; + } else { + drmGetMagic(dri2_dpy->fd, &magic); + wl_drm_authenticate(dri2_dpy->wl_drm, magic); + } } static void @@ -893,7 +948,7 @@ static const struct wl_drm_listener drm_listener = { }; static void -registry_handle_global(void *data, struct wl_registry *registry, uint32_t name, +registry_handle_global_drm(void *data, struct wl_registry *registry, uint32_t name, const char *interface, uint32_t version) { struct dri2_egl_display *dri2_dpy = data; @@ -913,8 +968,8 @@ registry_handle_global_remove(void *data, struct wl_registry *registry, { } -static const struct wl_registry_listener registry_listener = { - registry_handle_global, +static const struct wl_registry_listener registry_listener_drm = { + registry_handle_global_drm, registry_handle_global_remove }; @@ -990,8 +1045,8 @@ static struct dri2_egl_display_vtbl dri2_wl_display_vtbl = { .get_sync_values = dri2_fallback_get_sync_values, }; -EGLBoolean -dri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp) +static EGLBoolean +dri2_initialize_wayland_drm(_EGLDriver *drv, _EGLDisplay *disp) { struct dri2_egl_display *dri2_dpy; const __DRIconfig *config; @@ -1027,9 +1082,9 @@ dri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp) wl_proxy_set_queue((struct wl_proxy *) dri2_dpy->wl_registry, dri2_dpy->wl_queue); wl_registry_add_listener(dri2_dpy->wl_registry, - ®istry_listener, dri2_dpy); + ®istry_listener_drm, dri2_dpy); if (roundtrip(dri2_dpy) < 0 || dri2_dpy->wl_drm == NULL) - goto cleanup_dpy; + goto cleanup_registry; if (roundtrip(dri2_dpy) < 0 || dri2_dpy->fd == -1) goto cleanup_drm; @@ -1037,6 +1092,24 @@ dri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp) if (roundtrip(dri2_dpy) < 0 || !dri2_dpy->authenticated) goto cleanup_fd; + dri2_dpy->fd = loader_get_user_preferred_fd(dri2_dpy->fd, + &dri2_dpy->is_different_gpu); + if (dri2_dpy->is_different_gpu) { + free(dri2_dpy->device_name); + dri2_dpy->device_name = loader_get_device_name_for_fd(dri2_dpy->fd); + if (!dri2_dpy->device_name) { + _eglError(EGL_BAD_ALLOC, "wayland-egl: failed to get device name " + "for requested GPU"); + goto cleanup_fd; + } + } + + /* we have to do the check now, because loader_get_user_preferred_fd + * will return a render-node when the requested gpu is different + * to the server, but also if the client asks for the same gpu than + * the server by requesting its pci-id */ + dri2_dpy->is_render_node = is_fd_render_node(dri2_dpy->fd); + dri2_dpy->driver_name = loader_get_driver_for_fd(dri2_dpy->fd, 0); if (dri2_dpy->driver_name == NULL) { _eglError(EGL_BAD_ALLOC, "DRI2: failed to get driver name"); @@ -1046,18 +1119,23 @@ dri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp) if (!dri2_load_driver(disp)) goto cleanup_driver_name; - dri2_dpy->dri2_loader_extension.base.name = __DRI_DRI2_LOADER; - dri2_dpy->dri2_loader_extension.base.version = 3; - dri2_dpy->dri2_loader_extension.getBuffers = dri2_wl_get_buffers; - dri2_dpy->dri2_loader_extension.flushFrontBuffer = dri2_wl_flush_front_buffer; - dri2_dpy->dri2_loader_extension.getBuffersWithFormat = - dri2_wl_get_buffers_with_format; - - dri2_dpy->extensions[0] = &dri2_dpy->dri2_loader_extension.base; - dri2_dpy->extensions[1] = &image_loader_extension.base; - dri2_dpy->extensions[2] = &image_lookup_extension.base; - dri2_dpy->extensions[3] = &use_invalidate.base; - dri2_dpy->extensions[4] = NULL; + dri2_dpy->extensions[0] = &image_loader_extension.base; + dri2_dpy->extensions[1] = &image_lookup_extension.base; + dri2_dpy->extensions[2] = &use_invalidate.base; + + /* render nodes cannot use Gem names, and thus do not support + * the __DRI_DRI2_LOADER extension */ + if (!dri2_dpy->is_render_node) { + dri2_dpy->dri2_loader_extension.base.name = __DRI_DRI2_LOADER; + dri2_dpy->dri2_loader_extension.base.version = 3; + dri2_dpy->dri2_loader_extension.getBuffers = dri2_wl_get_buffers; + dri2_dpy->dri2_loader_extension.flushFrontBuffer = dri2_wl_flush_front_buffer; + dri2_dpy->dri2_loader_extension.getBuffersWithFormat = + dri2_wl_get_buffers_with_format; + dri2_dpy->extensions[3] = &dri2_dpy->dri2_loader_extension.base; + dri2_dpy->extensions[4] = NULL; + } else + dri2_dpy->extensions[3] = NULL; dri2_dpy->swap_available = EGL_TRUE; @@ -1066,15 +1144,33 @@ dri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp) dri2_wl_setup_swap_interval(dri2_dpy); - /* The server shouldn't advertise WL_DRM_CAPABILITY_PRIME if the driver - * doesn't have createImageFromFds, since we're using the same driver on - * both sides. We don't want crash if that happens anyway, so fall back to - * gem names if we don't have prime support. */ + /* To use Prime, we must have _DRI_IMAGE v7 at least. + * createImageFromFds support indicates that Prime export/import + * is supported by the driver. Fall back to + * gem names if we don't have Prime support. */ if (dri2_dpy->image->base.version < 7 || dri2_dpy->image->createImageFromFds == NULL) dri2_dpy->capabilities &= ~WL_DRM_CAPABILITY_PRIME; + /* We cannot use Gem names with render-nodes, only prime fds (dma-buf). + * The server needs to accept them */ + if (dri2_dpy->is_render_node && + !(dri2_dpy->capabilities & WL_DRM_CAPABILITY_PRIME)) { + _eglLog(_EGL_WARNING, "wayland-egl: display is not render-node capable"); + goto cleanup_screen; + } + + if (dri2_dpy->is_different_gpu && + (dri2_dpy->image->base.version < 9 || + dri2_dpy->image->blitImage == NULL)) { + _eglLog(_EGL_WARNING, "wayland-egl: Different GPU selected, but the " + "Image extension in the driver is not " + "compatible. Version 9 or later and blitImage() " + "are required"); + goto cleanup_screen; + } + types = EGL_WINDOW_BIT; for (i = 0; dri2_dpy->driver_configs[i]; i++) { config = dri2_dpy->driver_configs[i]; @@ -1087,15 +1183,20 @@ dri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp) } disp->Extensions.WL_bind_wayland_display = EGL_TRUE; - disp->Extensions.WL_create_wayland_buffer_from_image = EGL_TRUE; + /* When cannot convert EGLImage to wl_buffer when on a different gpu, + * because the buffer of the EGLImage has likely a tiling mode the server + * gpu won't support. These is no way to check for now. Thus do not support the + * extension */ + if (!dri2_dpy->is_different_gpu) { + disp->Extensions.WL_create_wayland_buffer_from_image = EGL_TRUE; + } else { + dri2_wl_display_vtbl.create_wayland_buffer_from_image = + dri2_fallback_create_wayland_buffer_from_image; + } disp->Extensions.EXT_buffer_age = EGL_TRUE; disp->Extensions.EXT_swap_buffers_with_damage = EGL_TRUE; - /* we're supporting EGL 1.4 */ - disp->VersionMajor = 1; - disp->VersionMinor = 4; - /* Fill vtbl last to prevent accidentally calling virtual function during * initialization. */ @@ -1103,6 +1204,8 @@ dri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp) return EGL_TRUE; + cleanup_screen: + dri2_dpy->core->destroyScreen(dri2_dpy->dri_screen); cleanup_driver: dlclose(dri2_dpy->driver); cleanup_driver_name: @@ -1112,8 +1215,666 @@ dri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp) cleanup_drm: free(dri2_dpy->device_name); wl_drm_destroy(dri2_dpy->wl_drm); + cleanup_registry: + wl_registry_destroy(dri2_dpy->wl_registry); + wl_event_queue_destroy(dri2_dpy->wl_queue); cleanup_dpy: free(dri2_dpy); return EGL_FALSE; } + +static int +dri2_wl_swrast_get_stride_for_format(int format, int w) +{ + if (format == WL_SHM_FORMAT_RGB565) + return 2 * w; + else /* ARGB8888 || XRGB8888 */ + return 4 * w; +} + +/* + * Taken from weston shared/os-compatibility.c + */ + +static int +set_cloexec_or_close(int fd) +{ + long flags; + + if (fd == -1) + return -1; + + flags = fcntl(fd, F_GETFD); + if (flags == -1) + goto err; + + if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1) + goto err; + + return fd; + +err: + close(fd); + return -1; +} + +/* + * Taken from weston shared/os-compatibility.c + */ + +static int +create_tmpfile_cloexec(char *tmpname) +{ + int fd; + +#ifdef HAVE_MKOSTEMP + fd = mkostemp(tmpname, O_CLOEXEC); + if (fd >= 0) + unlink(tmpname); +#else + fd = mkstemp(tmpname); + if (fd >= 0) { + fd = set_cloexec_or_close(fd); + unlink(tmpname); + } +#endif + + return fd; +} + +/* + * Taken from weston shared/os-compatibility.c + * + * Create a new, unique, anonymous file of the given size, and + * return the file descriptor for it. The file descriptor is set + * CLOEXEC. The file is immediately suitable for mmap()'ing + * the given size at offset zero. + * + * The file should not have a permanent backing store like a disk, + * but may have if XDG_RUNTIME_DIR is not properly implemented in OS. + * + * The file name is deleted from the file system. + * + * The file is suitable for buffer sharing between processes by + * transmitting the file descriptor over Unix sockets using the + * SCM_RIGHTS methods. + * + * If the C library implements posix_fallocate(), it is used to + * guarantee that disk space is available for the file at the + * given size. If disk space is insufficent, errno is set to ENOSPC. + * If posix_fallocate() is not supported, program may receive + * SIGBUS on accessing mmap()'ed file contents instead. + */ +static int +os_create_anonymous_file(off_t size) +{ + static const char template[] = "/mesa-shared-XXXXXX"; + const char *path; + char *name; + int fd; + int ret; + + path = getenv("XDG_RUNTIME_DIR"); + if (!path) { + errno = ENOENT; + return -1; + } + + name = malloc(strlen(path) + sizeof(template)); + if (!name) + return -1; + + strcpy(name, path); + strcat(name, template); + + fd = create_tmpfile_cloexec(name); + + free(name); + + if (fd < 0) + return -1; + + ret = ftruncate(fd, size); + if (ret < 0) { + close(fd); + return -1; + } + + return fd; +} + + +static EGLBoolean +dri2_wl_swrast_allocate_buffer(struct dri2_egl_display *dri2_dpy, + int format, int w, int h, + void **data, int *size, + struct wl_buffer **buffer) +{ + struct wl_shm_pool *pool; + int fd, stride, size_map; + void *data_map; + + stride = dri2_wl_swrast_get_stride_for_format(format, w); + size_map = h * stride; + + /* Create a sharable buffer */ + fd = os_create_anonymous_file(size_map); + if (fd < 0) + return EGL_FALSE; + + data_map = mmap(NULL, size_map, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + if (data_map == MAP_FAILED) { + close(fd); + return EGL_FALSE; + } + + /* Share it in a wl_buffer */ + pool = wl_shm_create_pool(dri2_dpy->wl_shm, fd, size_map); + *buffer = wl_shm_pool_create_buffer(pool, 0, w, h, stride, format); + wl_shm_pool_destroy(pool); + close(fd); + + *data = data_map; + *size = size_map; + return EGL_TRUE; +} + +static int +swrast_update_buffers(struct dri2_egl_surface *dri2_surf) +{ + struct dri2_egl_display *dri2_dpy = + dri2_egl_display(dri2_surf->base.Resource.Display); + int i; + + /* we need to do the following operations only once per frame */ + if (dri2_surf->back) + return 0; + + if (dri2_surf->base.Width != dri2_surf->wl_win->width || + dri2_surf->base.Height != dri2_surf->wl_win->height) { + + dri2_wl_release_buffers(dri2_surf); + + dri2_surf->base.Width = dri2_surf->wl_win->width; + dri2_surf->base.Height = dri2_surf->wl_win->height; + dri2_surf->dx = dri2_surf->wl_win->dx; + dri2_surf->dy = dri2_surf->wl_win->dy; + dri2_surf->current = NULL; + } + + /* find back buffer */ + + /* We always want to throttle to some event (either a frame callback or + * a sync request) after the commit so that we can be sure the + * compositor has had a chance to handle it and send us a release event + * before we look for a free buffer */ + while (dri2_surf->throttle_callback != NULL) + if (wl_display_dispatch_queue(dri2_dpy->wl_dpy, + dri2_dpy->wl_queue) == -1) + return -1; + + /* try get free buffer already created */ + for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) { + if (!dri2_surf->color_buffers[i].locked && + dri2_surf->color_buffers[i].wl_buffer) { + dri2_surf->back = &dri2_surf->color_buffers[i]; + break; + } + } + + /* else choose any another free location */ + if (!dri2_surf->back) { + for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) { + if (!dri2_surf->color_buffers[i].locked) { + dri2_surf->back = &dri2_surf->color_buffers[i]; + if (!dri2_wl_swrast_allocate_buffer(dri2_dpy, + dri2_surf->format, + dri2_surf->base.Width, + dri2_surf->base.Height, + &dri2_surf->back->data, + &dri2_surf->back->data_size, + &dri2_surf->back->wl_buffer)) { + _eglError(EGL_BAD_ALLOC, "failed to allocate color buffer"); + return -1; + } + wl_proxy_set_queue((struct wl_proxy *) dri2_surf->back->wl_buffer, + dri2_dpy->wl_queue); + wl_buffer_add_listener(dri2_surf->back->wl_buffer, + &wl_buffer_listener, dri2_surf); + break; + } + } + } + + if (!dri2_surf->back) { + _eglError(EGL_BAD_ALLOC, "failed to find free buffer"); + return -1; + } + + dri2_surf->back->locked = 1; + + /* If we have an extra unlocked buffer at this point, we had to do triple + * buffering for a while, but now can go back to just double buffering. + * That means we can free any unlocked buffer now. */ + for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) { + if (!dri2_surf->color_buffers[i].locked && + dri2_surf->color_buffers[i].wl_buffer) { + wl_buffer_destroy(dri2_surf->color_buffers[i].wl_buffer); + munmap(dri2_surf->color_buffers[i].data, + dri2_surf->color_buffers[i].data_size); + dri2_surf->color_buffers[i].wl_buffer = NULL; + dri2_surf->color_buffers[i].data = NULL; + } + } + + return 0; +} + +static void* +dri2_wl_swrast_get_frontbuffer_data(struct dri2_egl_surface *dri2_surf) +{ + /* if there has been a resize: */ + if (!dri2_surf->current) + return NULL; + + return dri2_surf->current->data; +} + +static void* +dri2_wl_swrast_get_backbuffer_data(struct dri2_egl_surface *dri2_surf) +{ + assert(dri2_surf->back); + return dri2_surf->back->data; +} + +static void +dri2_wl_swrast_commit_backbuffer(struct dri2_egl_surface *dri2_surf) +{ + struct dri2_egl_display *dri2_dpy = dri2_egl_display(dri2_surf->base.Resource.Display); + + if (dri2_surf->base.SwapInterval > 0) { + dri2_surf->throttle_callback = + wl_surface_frame(dri2_surf->wl_win->surface); + wl_callback_add_listener(dri2_surf->throttle_callback, + &throttle_listener, dri2_surf); + wl_proxy_set_queue((struct wl_proxy *) dri2_surf->throttle_callback, + dri2_dpy->wl_queue); + } + + dri2_surf->current = dri2_surf->back; + dri2_surf->back = NULL; + + wl_surface_attach(dri2_surf->wl_win->surface, + dri2_surf->current->wl_buffer, + dri2_surf->dx, dri2_surf->dy); + + dri2_surf->wl_win->attached_width = dri2_surf->base.Width; + dri2_surf->wl_win->attached_height = dri2_surf->base.Height; + /* reset resize growing parameters */ + dri2_surf->dx = 0; + dri2_surf->dy = 0; + + wl_surface_damage(dri2_surf->wl_win->surface, + 0, 0, INT32_MAX, INT32_MAX); + wl_surface_commit(dri2_surf->wl_win->surface); + + /* If we're not waiting for a frame callback then we'll at least throttle + * to a sync callback so that we always give a chance for the compositor to + * handle the commit and send a release event before checking for a free + * buffer */ + if (dri2_surf->throttle_callback == NULL) { + dri2_surf->throttle_callback = wl_display_sync(dri2_dpy->wl_dpy); + wl_callback_add_listener(dri2_surf->throttle_callback, + &throttle_listener, dri2_surf); + wl_proxy_set_queue((struct wl_proxy *) dri2_surf->throttle_callback, + dri2_dpy->wl_queue); + } + + wl_display_flush(dri2_dpy->wl_dpy); +} + +static void +dri2_wl_swrast_get_drawable_info(__DRIdrawable * draw, + int *x, int *y, int *w, int *h, + void *loaderPrivate) +{ + struct dri2_egl_surface *dri2_surf = loaderPrivate; + + (void) swrast_update_buffers(dri2_surf); + *x = 0; + *y = 0; + *w = dri2_surf->base.Width; + *h = dri2_surf->base.Height; +} + +static void +dri2_wl_swrast_get_image(__DRIdrawable * read, + int x, int y, int w, int h, + char *data, void *loaderPrivate) +{ + struct dri2_egl_surface *dri2_surf = loaderPrivate; + int copy_width = dri2_wl_swrast_get_stride_for_format(dri2_surf->format, w); + int x_offset = dri2_wl_swrast_get_stride_for_format(dri2_surf->format, x); + int src_stride = dri2_wl_swrast_get_stride_for_format(dri2_surf->format, dri2_surf->base.Width); + int dst_stride = copy_width; + char *src, *dst; + + src = dri2_wl_swrast_get_frontbuffer_data(dri2_surf); + if (!src) { + memset(data, 0, copy_width * h); + return; + } + + assert(data != src); + assert(copy_width <= src_stride); + + src += x_offset; + src += y * src_stride; + dst = data; + + if (copy_width > src_stride-x_offset) + copy_width = src_stride-x_offset; + if (h > dri2_surf->base.Height-y) + h = dri2_surf->base.Height-y; + + for (; h>0; h--) { + memcpy(dst, src, copy_width); + src += src_stride; + dst += dst_stride; + } +} + +static void +dri2_wl_swrast_put_image2(__DRIdrawable * draw, int op, + int x, int y, int w, int h, int stride, + char *data, void *loaderPrivate) +{ + struct dri2_egl_surface *dri2_surf = loaderPrivate; + int copy_width = dri2_wl_swrast_get_stride_for_format(dri2_surf->format, w); + int dst_stride = dri2_wl_swrast_get_stride_for_format(dri2_surf->format, dri2_surf->base.Width); + int x_offset = dri2_wl_swrast_get_stride_for_format(dri2_surf->format, x); + char *src, *dst; + + assert(copy_width <= stride); + + (void) swrast_update_buffers(dri2_surf); + dst = dri2_wl_swrast_get_backbuffer_data(dri2_surf); + + /* partial copy, copy old content */ + if (copy_width < dst_stride) + dri2_wl_swrast_get_image(draw, 0, 0, + dri2_surf->base.Width, dri2_surf->base.Height, + dst, loaderPrivate); + + dst += x_offset; + dst += y * dst_stride; + + src = data; + + /* drivers expect we do these checks (and some rely on it) */ + if (copy_width > dst_stride-x_offset) + copy_width = dst_stride-x_offset; + if (h > dri2_surf->base.Height-y) + h = dri2_surf->base.Height-y; + + for (; h>0; h--) { + memcpy(dst, src, copy_width); + src += stride; + dst += dst_stride; + } + dri2_wl_swrast_commit_backbuffer(dri2_surf); +} + +static void +dri2_wl_swrast_put_image(__DRIdrawable * draw, int op, + int x, int y, int w, int h, + char *data, void *loaderPrivate) +{ + struct dri2_egl_surface *dri2_surf = loaderPrivate; + int stride; + + stride = dri2_wl_swrast_get_stride_for_format(dri2_surf->format, w); + dri2_wl_swrast_put_image2(draw, op, x, y, w, h, + stride, data, loaderPrivate); +} + +/** + * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface(). + */ +static _EGLSurface * +dri2_wl_swrast_create_window_surface(_EGLDriver *drv, _EGLDisplay *disp, + _EGLConfig *conf, void *native_window, + const EGLint *attrib_list) +{ + struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); + struct dri2_egl_config *dri2_conf = dri2_egl_config(conf); + struct wl_egl_window *window = native_window; + struct dri2_egl_surface *dri2_surf; + + (void) drv; + + dri2_surf = calloc(1, sizeof *dri2_surf); + if (!dri2_surf) { + _eglError(EGL_BAD_ALLOC, "dri2_create_surface"); + return NULL; + } + + if (!_eglInitSurface(&dri2_surf->base, disp, EGL_WINDOW_BIT, conf, attrib_list)) + goto cleanup_surf; + + if (conf->RedSize == 5) + dri2_surf->format = WL_SHM_FORMAT_RGB565; + else if (conf->AlphaSize == 0) + dri2_surf->format = WL_SHM_FORMAT_XRGB8888; + else + dri2_surf->format = WL_SHM_FORMAT_ARGB8888; + + dri2_surf->wl_win = window; + + dri2_surf->base.Width = -1; + dri2_surf->base.Height = -1; + + dri2_surf->dri_drawable = + (*dri2_dpy->swrast->createNewDrawable) (dri2_dpy->dri_screen, + dri2_conf->dri_double_config, + dri2_surf); + if (dri2_surf->dri_drawable == NULL) { + _eglError(EGL_BAD_ALLOC, "swrast->createNewDrawable"); + goto cleanup_dri_drawable; + } + + dri2_wl_swap_interval(drv, disp, &dri2_surf->base, + dri2_dpy->default_swap_interval); + + return &dri2_surf->base; + + cleanup_dri_drawable: + dri2_dpy->core->destroyDrawable(dri2_surf->dri_drawable); + cleanup_surf: + free(dri2_surf); + + return NULL; +} + +static EGLBoolean +dri2_wl_swrast_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw) +{ + struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); + struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw); + + dri2_dpy->core->swapBuffers(dri2_surf->dri_drawable); + return EGL_TRUE; +} + +static void +shm_handle_format(void *data, struct wl_shm *shm, uint32_t format) +{ + struct dri2_egl_display *dri2_dpy = data; + + switch (format) { + case WL_SHM_FORMAT_ARGB8888: + dri2_dpy->formats |= HAS_ARGB8888; + break; + case WL_SHM_FORMAT_XRGB8888: + dri2_dpy->formats |= HAS_XRGB8888; + break; + case WL_SHM_FORMAT_RGB565: + dri2_dpy->formats |= HAS_RGB565; + break; + } +} + +static const struct wl_shm_listener shm_listener = { + shm_handle_format +}; + +static void +registry_handle_global_swrast(void *data, struct wl_registry *registry, uint32_t name, + const char *interface, uint32_t version) +{ + struct dri2_egl_display *dri2_dpy = data; + + if (strcmp(interface, "wl_shm") == 0) { + dri2_dpy->wl_shm = + wl_registry_bind(registry, name, &wl_shm_interface, 1); + wl_shm_add_listener(dri2_dpy->wl_shm, &shm_listener, dri2_dpy); + } +} + +static const struct wl_registry_listener registry_listener_swrast = { + registry_handle_global_swrast, + registry_handle_global_remove +}; + +static struct dri2_egl_display_vtbl dri2_wl_swrast_display_vtbl = { + .authenticate = NULL, + .create_window_surface = dri2_wl_swrast_create_window_surface, + .create_pixmap_surface = dri2_wl_create_pixmap_surface, + .create_pbuffer_surface = dri2_fallback_create_pbuffer_surface, + .destroy_surface = dri2_wl_destroy_surface, + .create_image = dri2_fallback_create_image_khr, + .swap_interval = dri2_wl_swap_interval, + .swap_buffers = dri2_wl_swrast_swap_buffers, + .swap_buffers_with_damage = dri2_fallback_swap_buffers_with_damage, + .swap_buffers_region = dri2_fallback_swap_buffers_region, + .post_sub_buffer = dri2_fallback_post_sub_buffer, + .copy_buffers = dri2_fallback_copy_buffers, + .query_buffer_age = dri2_fallback_query_buffer_age, + .create_wayland_buffer_from_image = dri2_fallback_create_wayland_buffer_from_image, + .get_sync_values = dri2_fallback_get_sync_values, +}; + +static EGLBoolean +dri2_initialize_wayland_swrast(_EGLDriver *drv, _EGLDisplay *disp) +{ + struct dri2_egl_display *dri2_dpy; + const __DRIconfig *config; + uint32_t types; + int i; + static const unsigned int argb_masks[4] = + { 0xff0000, 0xff00, 0xff, 0xff000000 }; + static const unsigned int rgb_masks[4] = { 0xff0000, 0xff00, 0xff, 0 }; + static const unsigned int rgb565_masks[4] = { 0xf800, 0x07e0, 0x001f, 0 }; + + loader_set_logger(_eglLog); + + dri2_dpy = calloc(1, sizeof *dri2_dpy); + if (!dri2_dpy) + return _eglError(EGL_BAD_ALLOC, "eglInitialize"); + + disp->DriverData = (void *) dri2_dpy; + if (disp->PlatformDisplay == NULL) { + dri2_dpy->wl_dpy = wl_display_connect(NULL); + if (dri2_dpy->wl_dpy == NULL) + goto cleanup_dpy; + dri2_dpy->own_device = 1; + } else { + dri2_dpy->wl_dpy = disp->PlatformDisplay; + } + + dri2_dpy->wl_queue = wl_display_create_queue(dri2_dpy->wl_dpy); + + if (dri2_dpy->own_device) + wl_display_dispatch_pending(dri2_dpy->wl_dpy); + + dri2_dpy->wl_registry = wl_display_get_registry(dri2_dpy->wl_dpy); + wl_proxy_set_queue((struct wl_proxy *) dri2_dpy->wl_registry, + dri2_dpy->wl_queue); + wl_registry_add_listener(dri2_dpy->wl_registry, + ®istry_listener_swrast, dri2_dpy); + + if (roundtrip(dri2_dpy) < 0 || dri2_dpy->wl_shm == NULL) + goto cleanup_registry; + + if (roundtrip(dri2_dpy) < 0 || dri2_dpy->formats == 0) + goto cleanup_shm; + + dri2_dpy->driver_name = strdup("swrast"); + if (!dri2_load_driver_swrast(disp)) + goto cleanup_shm; + + dri2_dpy->swrast_loader_extension.base.name = __DRI_SWRAST_LOADER; + dri2_dpy->swrast_loader_extension.base.version = 2; + dri2_dpy->swrast_loader_extension.getDrawableInfo = dri2_wl_swrast_get_drawable_info; + dri2_dpy->swrast_loader_extension.putImage = dri2_wl_swrast_put_image; + dri2_dpy->swrast_loader_extension.getImage = dri2_wl_swrast_get_image; + dri2_dpy->swrast_loader_extension.putImage2 = dri2_wl_swrast_put_image2; + + dri2_dpy->extensions[0] = &dri2_dpy->swrast_loader_extension.base; + dri2_dpy->extensions[1] = NULL; + + if (!dri2_create_screen(disp)) + goto cleanup_driver; + + dri2_wl_setup_swap_interval(dri2_dpy); + + types = EGL_WINDOW_BIT; + for (i = 0; dri2_dpy->driver_configs[i]; i++) { + config = dri2_dpy->driver_configs[i]; + if (dri2_dpy->formats & HAS_XRGB8888) + dri2_add_config(disp, config, i + 1, types, NULL, rgb_masks); + if (dri2_dpy->formats & HAS_ARGB8888) + dri2_add_config(disp, config, i + 1, types, NULL, argb_masks); + if (dri2_dpy->formats & HAS_RGB565) + dri2_add_config(disp, config, i + 1, types, NULL, rgb565_masks); + } + + /* Fill vtbl last to prevent accidentally calling virtual function during + * initialization. + */ + dri2_dpy->vtbl = &dri2_wl_swrast_display_vtbl; + + return EGL_TRUE; + + cleanup_driver: + dlclose(dri2_dpy->driver); + cleanup_shm: + wl_shm_destroy(dri2_dpy->wl_shm); + cleanup_registry: + wl_registry_destroy(dri2_dpy->wl_registry); + wl_event_queue_destroy(dri2_dpy->wl_queue); + cleanup_dpy: + free(dri2_dpy); + + return EGL_FALSE; +} + +EGLBoolean +dri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp) +{ + EGLBoolean initialized = EGL_TRUE; + + int hw_accel = (getenv("LIBGL_ALWAYS_SOFTWARE") == NULL); + + if (hw_accel) { + if (!dri2_initialize_wayland_drm(drv, disp)) { + initialized = dri2_initialize_wayland_swrast(drv, disp); + } + } else { + initialized = dri2_initialize_wayland_swrast(drv, disp); + } + + return initialized; + +} diff --git a/src/egl/drivers/dri2/platform_x11.c b/src/egl/drivers/dri2/platform_x11.c index ddb3b54e843..56c14288204 100644 --- a/src/egl/drivers/dri2/platform_x11.c +++ b/src/egl/drivers/dri2/platform_x11.c @@ -43,6 +43,7 @@ #include "egl_dri2.h" #include "egl_dri2_fallbacks.h" +#include "loader.h" static EGLBoolean dri2_x11_swap_interval(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf, @@ -1017,15 +1018,6 @@ dri2_x11_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp, } } -static _EGLImage* -dri2_x11_swrast_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp, - _EGLContext *ctx, EGLenum target, - EGLClientBuffer buffer, - const EGLint *attr_list) -{ - return NULL; -} - static EGLBoolean dri2_x11_get_sync_values(_EGLDisplay *display, _EGLSurface *surface, EGLuint64KHR *ust, EGLuint64KHR *msc, @@ -1058,7 +1050,7 @@ static struct dri2_egl_display_vtbl dri2_x11_swrast_display_vtbl = { .create_pixmap_surface = dri2_x11_create_pixmap_surface, .create_pbuffer_surface = dri2_x11_create_pbuffer_surface, .destroy_surface = dri2_x11_destroy_surface, - .create_image = dri2_x11_swrast_create_image_khr, + .create_image = dri2_fallback_create_image_khr, .swap_interval = dri2_fallback_swap_interval, .swap_buffers = dri2_x11_swap_buffers, .swap_buffers_region = dri2_fallback_swap_buffers_region, @@ -1121,7 +1113,7 @@ dri2_initialize_x11_swrast(_EGLDriver *drv, _EGLDisplay *disp) goto cleanup_conn; dri2_dpy->swrast_loader_extension.base.name = __DRI_SWRAST_LOADER; - dri2_dpy->swrast_loader_extension.base.version = __DRI_SWRAST_LOADER_VERSION; + dri2_dpy->swrast_loader_extension.base.version = 2; dri2_dpy->swrast_loader_extension.getDrawableInfo = swrastGetDrawableInfo; dri2_dpy->swrast_loader_extension.putImage = swrastPutImage; dri2_dpy->swrast_loader_extension.getImage = swrastGetImage; @@ -1138,10 +1130,6 @@ dri2_initialize_x11_swrast(_EGLDriver *drv, _EGLDisplay *disp) goto cleanup_configs; } - /* we're supporting EGL 1.4 */ - disp->VersionMajor = 1; - disp->VersionMinor = 4; - /* Fill vtbl last to prevent accidentally calling virtual function during * initialization. */ @@ -1243,16 +1231,7 @@ dri2_initialize_x11_dri2(_EGLDriver *drv, _EGLDisplay *disp) if (!dri2_load_driver(disp)) goto cleanup_conn; -#ifdef O_CLOEXEC - dri2_dpy->fd = open(dri2_dpy->device_name, O_RDWR | O_CLOEXEC); - if (dri2_dpy->fd == -1 && errno == EINVAL) -#endif - { - dri2_dpy->fd = open(dri2_dpy->device_name, O_RDWR); - if (dri2_dpy->fd != -1) - fcntl(dri2_dpy->fd, F_SETFD, fcntl(dri2_dpy->fd, F_GETFD) | - FD_CLOEXEC); - } + dri2_dpy->fd = loader_open_device(dri2_dpy->device_name); if (dri2_dpy->fd == -1) { _eglLog(_EGL_WARNING, "DRI2: could not open %s (%s)", dri2_dpy->device_name, @@ -1292,11 +1271,6 @@ dri2_initialize_x11_dri2(_EGLDriver *drv, _EGLDisplay *disp) dri2_x11_setup_swap_interval(dri2_dpy); - if (dri2_dpy->conn) { - if (!dri2_x11_add_configs_for_visuals(dri2_dpy, disp)) - goto cleanup_configs; - } - disp->Extensions.KHR_image_pixmap = EGL_TRUE; disp->Extensions.NOK_swap_region = EGL_TRUE; disp->Extensions.NOK_texture_from_pixmap = EGL_TRUE; @@ -1312,10 +1286,6 @@ dri2_initialize_x11_dri2(_EGLDriver *drv, _EGLDisplay *disp) goto cleanup_configs; } - /* we're supporting EGL 1.4 */ - disp->VersionMajor = 1; - disp->VersionMinor = 4; - /* Fill vtbl last to prevent accidentally calling virtual function during * initialization. */ diff --git a/src/egl/drivers/haiku/SConscript b/src/egl/drivers/haiku/SConscript index 9dd2f70f4ac..ec6020ece77 100644 --- a/src/egl/drivers/haiku/SConscript +++ b/src/egl/drivers/haiku/SConscript @@ -9,7 +9,6 @@ env.Append(CPPDEFINES = [ env.Append(CPPPATH = [ '#/include', '#/src/egl/main', - '#/src/loader', ]) sources = [ @@ -22,10 +21,6 @@ if env['platform'] == 'haiku': '_EGL_NATIVE_PLATFORM=haiku', ]) -env.Prepend(LIBS = [ - libloader, -]) - egl_haiku = env.ConvenienceLibrary( target = 'egl_haiku', source = sources, diff --git a/src/egl/drivers/haiku/egl_haiku.cpp b/src/egl/drivers/haiku/egl_haiku.cpp index 4cf2ccb9db8..3d00e47c8e6 100644 --- a/src/egl/drivers/haiku/egl_haiku.cpp +++ b/src/egl/drivers/haiku/egl_haiku.cpp @@ -27,8 +27,6 @@ #include <stdint.h> #include <stdio.h> -extern "C" { -#include "loader.h" #include "eglconfig.h" #include "eglcontext.h" #include "egldisplay.h" @@ -38,13 +36,19 @@ extern "C" { #include "eglsurface.h" #include "eglimage.h" #include "egltypedefs.h" -} #include <InterfaceKit.h> #include <OpenGLKit.h> -#define CALLOC_STRUCT(T) (struct T *) calloc(1, sizeof(struct T)) +#ifdef DEBUG +# define TRACE(x...) printf("egl_haiku: " x) +# define CALLED() TRACE("CALLED: %s\n", __PRETTY_FUNCTION__) +#else +# define TRACE(x...) +# define CALLED() +#endif +#define ERROR(x...) printf("egl_haiku: " x) _EGL_DRIVER_STANDARD_TYPECASTS(haiku_egl) @@ -53,10 +57,6 @@ _EGL_DRIVER_STANDARD_TYPECASTS(haiku_egl) struct haiku_egl_driver { _EGLDriver base; - - void *handle; - _EGLProc (*get_proc_address)(const char *procname); - void (*glFlush)(void); }; struct haiku_egl_config @@ -76,81 +76,6 @@ struct haiku_egl_surface }; -/* -static void -swrastCreateDrawable(struct dri2_egl_display * dri2_dpy, - struct dri2_egl_surface * dri2_surf, int depth) -{ - -} - - -static void -swrastDestroyDrawable(struct dri2_egl_display * dri2_dpy, - struct dri2_egl_surface * dri2_surf) -{ - -} - - -static void -swrastGetDrawableInfo(__DRIdrawable * draw, int *x, int *y, - int *w, int *h, void *loaderPrivate) -{ - -} - - -static void -swrastPutImage(__DRIdrawable * draw, int op, int x, int y, - int w, int h, char *data, void *loaderPrivate) -{ - -} - - -static void -swrastGetImage(__DRIdrawable * read, int x, int y, - int w, int h, char *data, void *loaderPrivate) -{ - -} -*/ - - -static void -haiku_log(EGLint level, const char *msg) -{ - switch (level) { - case _EGL_DEBUG: - fprintf(stderr,"%s", msg); - break; - case _EGL_INFO: - fprintf(stderr,"%s", msg); - break; - case _EGL_WARNING: - fprintf(stderr,"%s", msg); - break; - case _EGL_FATAL: - fprintf(stderr,"%s", msg); - break; - default: - break; - } -} - - -/** - * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface(). - */ -static _EGLSurface * -haiku_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type, - _EGLConfig *conf, void *native_surface, const EGLint *attrib_list) -{ - return NULL; -} - - /** * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface(). */ @@ -158,25 +83,37 @@ static _EGLSurface * haiku_create_window_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf, void *native_window, const EGLint *attrib_list) { + CALLED(); + struct haiku_egl_surface* surface; - surface = (struct haiku_egl_surface*)calloc(1,sizeof (*surface)); + surface = (struct haiku_egl_surface*) calloc(1, sizeof (*surface)); + if (!surface) { + _eglError(EGL_BAD_ALLOC, "haiku_create_window_surface"); + return NULL; + } + + if (!_eglInitSurface(&surface->surf, disp, EGL_WINDOW_BIT, conf, attrib_list)) + goto cleanup_surface; - _eglInitSurface(&surface->surf, disp, EGL_WINDOW_BIT, conf, attrib_list); (&surface->surf)->SwapInterval = 1; - _eglLog(_EGL_DEBUG, "Creating window"); + TRACE("Creating window\n"); BWindow* win = (BWindow*)native_window; - _eglLog(_EGL_DEBUG, "Creating GL view"); + TRACE("Creating GL view\n"); surface->gl = new BGLView(win->Bounds(), "OpenGL", B_FOLLOW_ALL_SIDES, 0, BGL_RGB | BGL_DOUBLE | BGL_ALPHA); - _eglLog(_EGL_DEBUG, "Adding GL"); + TRACE("Adding GL\n"); win->AddChild(surface->gl); - _eglLog(_EGL_DEBUG, "Showing window"); + TRACE("Showing window\n"); win->Show(); return &surface->surf; + +cleanup_surface: + free(surface); + return NULL; } @@ -199,6 +136,10 @@ haiku_create_pbuffer_surface(_EGLDriver *drv, _EGLDisplay *disp, static EGLBoolean haiku_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf) { + if (_eglPutSurface(surf)) { + // XXX: detach haiku_egl_surface::gl from the native window and destroy it + free(surf); + } return EGL_TRUE; } @@ -206,13 +147,18 @@ haiku_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf) static EGLBoolean haiku_add_configs_for_visuals(_EGLDisplay *dpy) { - printf("Adding configs\n"); + CALLED(); struct haiku_egl_config* conf; - conf = CALLOC_STRUCT(haiku_egl_config); + conf = (struct haiku_egl_config*) calloc(1, sizeof (*conf)); + if (!conf) { + _eglError(EGL_BAD_ALLOC, "haiku_add_configs_for_visuals"); + return NULL; + } _eglInitConfig(&conf->base, dpy, 1); - _eglLog(_EGL_DEBUG,"Config inited\n"); + TRACE("Config inited\n"); + _eglSetConfigKey(&conf->base, EGL_RED_SIZE, 8); _eglSetConfigKey(&conf->base, EGL_BLUE_SIZE, 8); _eglSetConfigKey(&conf->base, EGL_GREEN_SIZE, 8); @@ -243,76 +189,40 @@ haiku_add_configs_for_visuals(_EGLDisplay *dpy) _eglSetConfigKey(&conf->base, EGL_MAX_PBUFFER_PIXELS, 0); // TODO: How to get the right value ? _eglSetConfigKey(&conf->base, EGL_SURFACE_TYPE, EGL_WINDOW_BIT /*| EGL_PIXMAP_BIT | EGL_PBUFFER_BIT*/); - printf("Config configuated\n"); + TRACE("Config configuated\n"); if (!_eglValidateConfig(&conf->base, EGL_FALSE)) { - _eglLog(_EGL_DEBUG, "Haiku failed to validate config"); - return EGL_FALSE; + _eglLog(_EGL_DEBUG, "Haiku: failed to validate config"); + goto cleanup; } - printf("Validated config\n"); + TRACE("Validated config\n"); _eglLinkConfig(&conf->base); if (!_eglGetArraySize(dpy->Configs)) { _eglLog(_EGL_WARNING, "Haiku: failed to create any config"); - return EGL_FALSE; + goto cleanup; } - printf("Config successful!\n"); - + TRACE("Config successfull\n"); + return EGL_TRUE; + +cleanup: + free(conf); + return EGL_FALSE; } extern "C" EGLBoolean init_haiku(_EGLDriver *drv, _EGLDisplay *dpy) { - _eglLog(_EGL_DEBUG,"\nInitializing Haiku EGL\n"); - //_EGLDisplay* egl_dpy; - - printf("Initializing Haiku EGL\n"); - _eglSetLogProc(haiku_log); - - loader_set_logger(_eglLog); - - /*egl_dpy = (_EGLDisplay*) calloc(1, sizeof(_EGLDisplay)); - if (!egl_dpy) - return _eglError(EGL_BAD_ALLOC, "eglInitialize"); - - dpy->DriverData=(void*) egl_dpy; - if (!dpy->PlatformDisplay) { - // OPEN DEVICE - //dri2_dpy->bwindow = (void*)haiku_create_window(); - //dri2_dpy->own_device = true; - } else { - //dri2_dpy->bwindow = (BWindow*)dpy->PlatformDisplay; - }*/ - - //dri2_dpy->driver_name = strdup("swrast"); - //if (!dri2_load_driver_swrast(dpy)) - // goto cleanup_conn; - - /*dri2_dpy->swrast_loader_extension.base.name = __DRI_SWRAST_LOADER; - dri2_dpy->swrast_loader_extension.base.version = __DRI_SWRAST_LOADER_VERSION; - dri2_dpy->swrast_loader_extension.getDrawableInfo = swrastGetDrawableInfo; - dri2_dpy->swrast_loader_extension.putImage = swrastPutImage; - dri2_dpy->swrast_loader_extension.getImage = swrastGetImage; - - dri2_dpy->extensions[0] = &dri2_dpy->swrast_loader_extension.base; - dri2_dpy->extensions[1] = NULL; - dri2_dpy->extensions[2] = NULL;*/ - - /*if (dri2_dpy->bwindow) { - if (!dri2_haiku_add_configs_for_visuals(dri2_dpy, dpy)) - goto cleanup_configs; - }*/ - _eglLog(_EGL_DEBUG,"Add configs"); - haiku_add_configs_for_visuals(dpy); - - dpy->VersionMajor=1; - dpy->VersionMinor=4; - - //dpy->Extensions.KHR_create_context = true; + CALLED(); + + TRACE("Add configs\n"); + if (!haiku_add_configs_for_visuals(dpy)) + return EGL_FALSE; - //dri2_dpy->vtbl = &dri2_haiku_display_vtbl; - _eglLog(_EGL_DEBUG, "Initialization finished"); + dpy->Version = 14; + + TRACE("Initialization finished\n"); return EGL_TRUE; } @@ -331,13 +241,24 @@ _EGLContext* haiku_create_context(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf, _EGLContext *share_list, const EGLint *attrib_list) { - _eglLog(_EGL_DEBUG,"Creating context"); + CALLED(); + struct haiku_egl_context* context; - context=(struct haiku_egl_context*)calloc(1,sizeof (*context)); - if(!_eglInitContext(&context->ctx, disp, conf, attrib_list)) - printf("ERROR creating context"); - _eglLog(_EGL_DEBUG, "Context created"); + context = (struct haiku_egl_context*) calloc(1, sizeof (*context)); + if (!context) { + _eglError(EGL_BAD_ALLOC, "haiku_create_context"); + return NULL; + } + + if (!_eglInitContext(&context->ctx, disp, conf, attrib_list)) + goto cleanup; + + TRACE("Context created\n"); return &context->ctx; + +cleanup: + free(context); + return NULL; } @@ -345,7 +266,13 @@ extern "C" EGLBoolean haiku_destroy_context(_EGLDriver* drv, _EGLDisplay *disp, _EGLContext* ctx) { - ctx=NULL; + struct haiku_egl_context* context = haiku_egl_context(ctx); + + if (_eglPutContext(ctx)) { + // XXX: teardown the context ? + free(context); + ctx = NULL + } return EGL_TRUE; } @@ -355,11 +282,16 @@ EGLBoolean haiku_make_current(_EGLDriver* drv, _EGLDisplay* dpy, _EGLSurface *dsurf, _EGLSurface *rsurf, _EGLContext *ctx) { - struct haiku_egl_context* cont=haiku_egl_context(ctx); - struct haiku_egl_surface* surf=haiku_egl_surface(dsurf); + CALLED(); + + struct haiku_egl_context* cont = haiku_egl_context(ctx); + struct haiku_egl_surface* surf = haiku_egl_surface(dsurf); _EGLContext *old_ctx; - _EGLSurface *old_dsurf, *old_rsurf; - _eglBindContext(ctx, dsurf, rsurf, &old_ctx, &old_dsurf, &old_rsurf); + _EGLSurface *old_dsurf, *old_rsurf; + + if (!_eglBindContext(ctx, dsurf, rsurf, &old_ctx, &old_dsurf, &old_rsurf)) + return EGL_FALSE; + //cont->ctx.DrawSurface=&surf->surf; surf->gl->LockGL(); return EGL_TRUE; @@ -370,7 +302,8 @@ extern "C" EGLBoolean haiku_swap_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf) { - struct haiku_egl_surface* surface=haiku_egl_surface(surf); + struct haiku_egl_surface* surface = haiku_egl_surface(surf); + surface->gl->SwapBuffers(); //gl->Render(); return EGL_TRUE; @@ -393,9 +326,15 @@ extern "C" _EGLDriver* _eglBuiltInDriverHaiku(const char *args) { - _eglLog(_EGL_DEBUG,"Driver loaded"); + CALLED(); + struct haiku_egl_driver* driver; - driver=(struct haiku_egl_driver*)calloc(1,sizeof(*driver)); + driver = (struct haiku_egl_driver*) calloc(1, sizeof(*driver)); + if (!driver) { + _eglError(EGL_BAD_ALLOC, "_eglBuiltInDriverHaiku"); + return NULL; + } + _eglInitDriverFallbacks(&driver->base); driver->base.API.Initialize = init_haiku; driver->base.API.Terminate = haiku_terminate; @@ -406,32 +345,13 @@ _eglBuiltInDriverHaiku(const char *args) driver->base.API.CreatePixmapSurface = haiku_create_pixmap_surface; driver->base.API.CreatePbufferSurface = haiku_create_pbuffer_surface; driver->base.API.DestroySurface = haiku_destroy_surface; - /* - driver->API.GetProcAddress = dri2_get_proc_address; - driver->API.WaitClient = dri2_wait_client; - driver->API.WaitNative = dri2_wait_native; - driver->API.BindTexImage = dri2_bind_tex_image; - driver->API.ReleaseTexImage = dri2_release_tex_image; - driver->API.SwapInterval = dri2_swap_interval; - */ driver->base.API.SwapBuffers = haiku_swap_buffers; - /* - driver->API.SwapBuffersWithDamageEXT = dri2_swap_buffers_with_damage; - driver->API.SwapBuffersRegionNOK = dri2_swap_buffers_region; - driver->API.PostSubBufferNV = dri2_post_sub_buffer; - driver->API.CopyBuffers = dri2_copy_buffers, - driver->API.QueryBufferAge = dri2_query_buffer_age; - driver->API.CreateImageKHR = dri2_create_image; - driver->API.DestroyImageKHR = dri2_destroy_image_khr; - driver->API.CreateWaylandBufferFromImageWL = dri2_create_wayland_buffer_from_image; - driver->API.GetSyncValuesCHROMIUM = dri2_get_sync_values_chromium; - */ driver->base.Name = "Haiku"; driver->base.Unload = haiku_unload; - _eglLog(_EGL_DEBUG, "API Calls defined"); - + TRACE("API Calls defined\n"); + return &driver->base; } diff --git a/src/egl/main/Android.mk b/src/egl/main/Android.mk index 12b66d053fc..0ba72953960 100644 --- a/src/egl/main/Android.mk +++ b/src/egl/main/Android.mk @@ -43,10 +43,7 @@ LOCAL_CFLAGS := \ -D_EGL_DRIVER_SEARCH_DIR=\"/system/lib/egl\" \ -D_EGL_OS_UNIX=1 -LOCAL_STATIC_LIBRARIES := - LOCAL_SHARED_LIBRARIES := \ - libglapi \ libdl \ libhardware \ liblog \ @@ -62,95 +59,20 @@ ifneq ($(MESA_GPU_DRIVERS),swrast) LOCAL_SHARED_LIBRARIES += libdrm endif -ifeq ($(strip $(MESA_BUILD_CLASSIC)),true) LOCAL_CFLAGS += -D_EGL_BUILT_IN_DRIVER_DRI2 -LOCAL_STATIC_LIBRARIES += libmesa_egl_dri2 +ifeq ($(strip $(MESA_BUILD_CLASSIC)),true) # require i915_dri and/or i965_dri LOCAL_REQUIRED_MODULES += \ $(addsuffix _dri, $(filter i915 i965, $(MESA_GPU_DRIVERS))) endif # MESA_BUILD_CLASSIC ifeq ($(strip $(MESA_BUILD_GALLIUM)),true) - -gallium_DRIVERS := - -# swrast -gallium_DRIVERS += libmesa_pipe_softpipe libmesa_winsys_sw_android - -# freedreno -ifneq ($(filter freedreno, $(MESA_GPU_DRIVERS)),) -gallium_DRIVERS += libmesa_winsys_freedreno libmesa_pipe_freedreno -LOCAL_SHARED_LIBRARIES += libdrm_freedreno -endif - -# i915g -ifneq ($(filter i915g, $(MESA_GPU_DRIVERS)),) -gallium_DRIVERS += libmesa_winsys_i915 libmesa_pipe_i915 -LOCAL_SHARED_LIBRARIES += libdrm_intel -endif - -# ilo -ifneq ($(filter ilo, $(MESA_GPU_DRIVERS)),) -gallium_DRIVERS += libmesa_winsys_intel libmesa_pipe_ilo -LOCAL_SHARED_LIBRARIES += libdrm_intel -endif - -# nouveau -ifneq ($(filter nouveau, $(MESA_GPU_DRIVERS)),) -gallium_DRIVERS += libmesa_winsys_nouveau libmesa_pipe_nouveau -LOCAL_SHARED_LIBRARIES += libdrm_nouveau -LOCAL_SHARED_LIBRARIES += libstlport -endif - -# r300g/r600g/radeonsi -ifneq ($(filter r300g r600g radeonsi, $(MESA_GPU_DRIVERS)),) -gallium_DRIVERS += libmesa_winsys_radeon -LOCAL_SHARED_LIBRARIES += libdrm_radeon -ifneq ($(filter r300g, $(MESA_GPU_DRIVERS)),) -gallium_DRIVERS += libmesa_pipe_r300 -endif # r300g -ifneq ($(filter r600g radeonsi, $(MESA_GPU_DRIVERS)),) -ifneq ($(filter r600g, $(MESA_GPU_DRIVERS)),) -gallium_DRIVERS += libmesa_pipe_r600 -LOCAL_SHARED_LIBRARIES += libstlport -endif # r600g -ifneq ($(filter radeonsi, $(MESA_GPU_DRIVERS)),) -gallium_DRIVERS += libmesa_pipe_radeonsi -endif # radeonsi -gallium_DRIVERS += libmesa_pipe_radeon -endif # r600g || radeonsi -endif # r300g || r600g || radeonsi - -# vmwgfx -ifneq ($(filter vmwgfx, $(MESA_GPU_DRIVERS)),) -gallium_DRIVERS += libmesa_winsys_svga libmesa_pipe_svga -endif - -# -# Notes about the order here: -# -# * libmesa_st_egl depends on libmesa_winsys_sw_android in $(gallium_DRIVERS) -# * libmesa_pipe_r300 in $(gallium_DRIVERS) depends on libmesa_st_mesa and -# libmesa_glsl -# * libmesa_st_mesa depends on libmesa_glsl -# * libmesa_glsl depends on libmesa_glsl_utils -# -LOCAL_STATIC_LIBRARIES := \ - libmesa_egl_gallium \ - libmesa_st_egl \ - $(gallium_DRIVERS) \ - libmesa_st_mesa \ - libmesa_util \ - libmesa_glsl \ - libmesa_glsl_utils \ - libmesa_gallium \ - $(LOCAL_STATIC_LIBRARIES) - +LOCAL_REQUIRED_MODULES += gallium_dri endif # MESA_BUILD_GALLIUM LOCAL_STATIC_LIBRARIES := \ - $(LOCAL_STATIC_LIBRARIES) \ + libmesa_egl_dri2 \ libmesa_loader LOCAL_MODULE := libGLES_mesa diff --git a/src/egl/main/Makefile.am b/src/egl/main/Makefile.am index b6617366c7e..9030d272b53 100644 --- a/src/egl/main/Makefile.am +++ b/src/egl/main/Makefile.am @@ -68,6 +68,10 @@ if HAVE_EGL_PLATFORM_NULL AM_CFLAGS += -DHAVE_NULL_PLATFORM endif +if HAVE_EGL_PLATFORM_SURFACELESS +AM_CFLAGS += -DHAVE_SURFACELESS_PLATFORM +endif + if HAVE_EGL_DRIVER_DRI2 AM_CFLAGS += -D_EGL_BUILT_IN_DRIVER_DRI2 AM_CFLAGS += -DHAVE_XCB_DRI2 diff --git a/src/egl/main/Makefile.sources b/src/egl/main/Makefile.sources index 304c7731c8c..e39a80f14a6 100644 --- a/src/egl/main/Makefile.sources +++ b/src/egl/main/Makefile.sources @@ -22,10 +22,6 @@ LIBEGL_C_FILES := \ eglimage.h \ egllog.c \ egllog.h \ - eglmode.c \ - eglmode.h \ - eglscreen.c \ - eglscreen.h \ eglstring.c \ eglstring.h \ eglsurface.c \ diff --git a/src/egl/main/README.txt b/src/egl/main/README.txt index b3d253dd133..1af99599729 100644 --- a/src/egl/main/README.txt +++ b/src/egl/main/README.txt @@ -16,10 +16,10 @@ The EGL code here basically consists of two things: Bootstrapping: -When the apps calls eglOpenDisplay() a device driver is selected and loaded -(look for dlsym() or LoadLibrary() in egldriver.c). +When the apps calls eglInitialize() a device driver is selected and loaded +(look for _eglAddDrivers() and _eglLoadModule() in egldriver.c). -The driver's _eglMain() function is then called. This driver function +The built-in driver's entry point function is then called. This driver function allocates, initializes and returns a new _EGLDriver object (usually a subclass of that type). @@ -30,10 +30,9 @@ driver->API.Initialize and driver->API.Terminate _must_ be implemented with driver-specific code (no default/fallback function is possible). -A bit later, the app will call eglInitialize(). This will get routed -to the driver->API.Initialize() function. Any additional driver -initialization that wasn't done in _eglMain() should be done at this -point. Typically, this will involve setting up visual configs, etc. +Shortly after, the driver->API.Initialize() function is executed. Any additional +driver initialization that wasn't done in the driver entry point should be +done at this point. Typically, this will involve setting up visual configs, etc. diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c index ba1d0ddc975..105e919683a 100644 --- a/src/egl/main/eglapi.c +++ b/src/egl/main/eglapi.c @@ -98,8 +98,6 @@ #include "egldriver.h" #include "eglsurface.h" #include "eglconfig.h" -#include "eglscreen.h" -#include "eglmode.h" #include "eglimage.h" #include "eglsync.h" #include "eglstring.h" @@ -155,12 +153,6 @@ #define _EGL_CHECK_CONFIG(disp, conf, ret, drv) \ _EGL_CHECK_OBJECT(disp, Config, conf, ret, drv) -#define _EGL_CHECK_SCREEN(disp, scrn, ret, drv) \ - _EGL_CHECK_OBJECT(disp, Screen, scrn, ret, drv) - -#define _EGL_CHECK_MODE(disp, m, ret, drv) \ - _EGL_CHECK_OBJECT(disp, Mode, m, ret, drv) - #define _EGL_CHECK_SYNC(disp, s, ret, drv) \ _EGL_CHECK_OBJECT(disp, Sync, s, ret, drv) @@ -236,40 +228,6 @@ _eglCheckSync(_EGLDisplay *disp, _EGLSync *s, const char *msg) } -#ifdef EGL_MESA_screen_surface - - -static inline _EGLDriver * -_eglCheckScreen(_EGLDisplay *disp, _EGLScreen *scrn, const char *msg) -{ - _EGLDriver *drv = _eglCheckDisplay(disp, msg); - if (!drv) - return NULL; - if (!scrn) { - _eglError(EGL_BAD_SCREEN_MESA, msg); - return NULL; - } - return drv; -} - - -static inline _EGLDriver * -_eglCheckMode(_EGLDisplay *disp, _EGLMode *m, const char *msg) -{ - _EGLDriver *drv = _eglCheckDisplay(disp, msg); - if (!drv) - return NULL; - if (!m) { - _eglError(EGL_BAD_MODE_MESA, msg); - return NULL; - } - return drv; -} - - -#endif /* EGL_MESA_screen_surface */ - - /** * Lookup and lock a display. */ @@ -293,6 +251,31 @@ _eglUnlockDisplay(_EGLDisplay *dpy) } +static EGLint * +_eglConvertAttribsToInt(const EGLAttrib *attr_list) +{ + EGLint *int_attribs = NULL; + + /* Convert attributes from EGLAttrib[] to EGLint[] */ + if (attr_list) { + int i, size = 0; + + while (attr_list[size] != EGL_NONE) + size += 2; + + size += 1; /* add space for EGL_NONE */ + + int_attribs = calloc(size, sizeof(int_attribs[0])); + if (!int_attribs) + return NULL; + + for (i = 0; i < size; i++) + int_attribs[i] = attr_list[i]; + } + return int_attribs; +} + + /** * This is typically the first EGL function that an application calls. * It associates a private _EGLDisplay object to the native display. @@ -312,7 +295,7 @@ eglGetDisplay(EGLNativeDisplayType nativeDisplay) return _eglGetDisplayHandle(dpy); } -EGLDisplay EGLAPIENTRY +static EGLDisplay EGLAPIENTRY eglGetPlatformDisplayEXT(EGLenum platform, void *native_display, const EGLint *attrib_list) { @@ -343,6 +326,21 @@ eglGetPlatformDisplayEXT(EGLenum platform, void *native_display, return _eglGetDisplayHandle(dpy); } +EGLDisplay EGLAPIENTRY +eglGetPlatformDisplay(EGLenum platform, void *native_display, + const EGLAttrib *attrib_list) +{ + EGLDisplay display; + EGLint *int_attribs = _eglConvertAttribsToInt(attrib_list); + + if (attrib_list && !int_attribs) + RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, NULL); + + display = eglGetPlatformDisplayEXT(platform, native_display, int_attribs); + free(int_attribs); + return display; +} + /** * Copy the extension into the string and update the string pointer. */ @@ -383,8 +381,6 @@ _eglCreateExtensionsString(_EGLDisplay *dpy) char *exts = dpy->ExtensionsString; - _EGL_CHECK_EXTENSION(MESA_screen_surface); - _EGL_CHECK_EXTENSION(MESA_copy_context); _EGL_CHECK_EXTENSION(MESA_drm_display); _EGL_CHECK_EXTENSION(MESA_drm_image); _EGL_CHECK_EXTENSION(MESA_configless_context); @@ -451,6 +447,26 @@ _eglCreateAPIsString(_EGLDisplay *dpy) assert(strlen(dpy->ClientAPIsString) < sizeof(dpy->ClientAPIsString)); } +static void +_eglComputeVersion(_EGLDisplay *disp) +{ + disp->Version = 14; + + if (disp->Extensions.KHR_fence_sync && + disp->Extensions.KHR_cl_event2 && + disp->Extensions.KHR_wait_sync && + disp->Extensions.KHR_image_base && + disp->Extensions.KHR_gl_texture_2D_image && + disp->Extensions.KHR_gl_texture_3D_image && + disp->Extensions.KHR_gl_texture_cubemap_image && + disp->Extensions.KHR_gl_renderbuffer_image && + disp->Extensions.KHR_create_context && + disp->Extensions.EXT_create_context_robustness && + disp->Extensions.KHR_get_all_proc_addresses && + disp->Extensions.KHR_gl_colorspace && + disp->Extensions.KHR_surfaceless_context) + disp->Version = 15; +} /** * This is typically the second EGL function that an application calls. @@ -488,17 +504,18 @@ eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor) */ disp->Extensions.KHR_get_all_proc_addresses = EGL_TRUE; + _eglComputeVersion(disp); _eglCreateExtensionsString(disp); _eglCreateAPIsString(disp); _eglsnprintf(disp->VersionString, sizeof(disp->VersionString), - "%d.%d (%s)", disp->VersionMajor, disp->VersionMinor, + "%d.%d (%s)", disp->Version / 10, disp->Version % 10, disp->Driver->Name); } /* Update applications version of major and minor if not NULL */ if ((major != NULL) && (minor != NULL)) { - *major = disp->VersionMajor; - *minor = disp->VersionMinor; + *major = disp->Version / 10; + *minor = disp->Version % 10; } RETURN_EGL_SUCCESS(disp, EGL_TRUE); @@ -740,7 +757,7 @@ eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, } -EGLSurface EGLAPIENTRY +static EGLSurface EGLAPIENTRY eglCreatePlatformWindowSurfaceEXT(EGLDisplay dpy, EGLConfig config, void *native_window, const EGLint *attrib_list) @@ -765,6 +782,24 @@ eglCreatePlatformWindowSurfaceEXT(EGLDisplay dpy, EGLConfig config, } +EGLSurface EGLAPIENTRY +eglCreatePlatformWindowSurface(EGLDisplay dpy, EGLConfig config, + void *native_window, + const EGLAttrib *attrib_list) +{ + EGLSurface surface; + EGLint *int_attribs = _eglConvertAttribsToInt(attrib_list); + + if (attrib_list && !int_attribs) + RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_NO_SURFACE); + + surface = eglCreatePlatformWindowSurfaceEXT(dpy, config, native_window, + int_attribs); + free(int_attribs); + return surface; +} + + static EGLSurface _eglCreatePixmapSurfaceCommon(_EGLDisplay *disp, EGLConfig config, void *native_pixmap, const EGLint *attrib_list) @@ -793,7 +828,7 @@ eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, attrib_list); } -EGLSurface EGLAPIENTRY +static EGLSurface EGLAPIENTRY eglCreatePlatformPixmapSurfaceEXT(EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLint *attrib_list) @@ -819,6 +854,24 @@ eglCreatePlatformPixmapSurfaceEXT(EGLDisplay dpy, EGLConfig config, EGLSurface EGLAPIENTRY +eglCreatePlatformPixmapSurface(EGLDisplay dpy, EGLConfig config, + void *native_pixmap, + const EGLAttrib *attrib_list) +{ + EGLSurface surface; + EGLint *int_attribs = _eglConvertAttribsToInt(attrib_list); + + if (attrib_list && !int_attribs) + RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_NO_SURFACE); + + surface = eglCreatePlatformPixmapSurfaceEXT(dpy, config, native_pixmap, + int_attribs); + free(int_attribs); + return surface; +} + + +EGLSurface EGLAPIENTRY eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list) { @@ -964,7 +1017,7 @@ eglSwapBuffers(EGLDisplay dpy, EGLSurface surface) #ifdef EGL_EXT_swap_buffers_with_damage -EGLBoolean EGLAPIENTRY +static EGLBoolean EGLAPIENTRY eglSwapBuffersWithDamageEXT(EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects) { @@ -1151,352 +1204,9 @@ eglGetError(void) } -__eglMustCastToProperFunctionPointerType EGLAPIENTRY -eglGetProcAddress(const char *procname) -{ - static const struct { - const char *name; - _EGLProc function; - } egl_functions[] = { - /* core functions should not be queryable, but, well... */ -#ifdef _EGL_GET_CORE_ADDRESSES - /* alphabetical order */ - { "eglBindAPI", (_EGLProc) eglBindAPI }, - { "eglBindTexImage", (_EGLProc) eglBindTexImage }, - { "eglChooseConfig", (_EGLProc) eglChooseConfig }, - { "eglCopyBuffers", (_EGLProc) eglCopyBuffers }, - { "eglCreateContext", (_EGLProc) eglCreateContext }, - { "eglCreatePbufferFromClientBuffer", (_EGLProc) eglCreatePbufferFromClientBuffer }, - { "eglCreatePbufferSurface", (_EGLProc) eglCreatePbufferSurface }, - { "eglCreatePixmapSurface", (_EGLProc) eglCreatePixmapSurface }, - { "eglCreateWindowSurface", (_EGLProc) eglCreateWindowSurface }, - { "eglDestroyContext", (_EGLProc) eglDestroyContext }, - { "eglDestroySurface", (_EGLProc) eglDestroySurface }, - { "eglGetConfigAttrib", (_EGLProc) eglGetConfigAttrib }, - { "eglGetConfigs", (_EGLProc) eglGetConfigs }, - { "eglGetCurrentContext", (_EGLProc) eglGetCurrentContext }, - { "eglGetCurrentDisplay", (_EGLProc) eglGetCurrentDisplay }, - { "eglGetCurrentSurface", (_EGLProc) eglGetCurrentSurface }, - { "eglGetDisplay", (_EGLProc) eglGetDisplay }, - { "eglGetError", (_EGLProc) eglGetError }, - { "eglGetProcAddress", (_EGLProc) eglGetProcAddress }, - { "eglInitialize", (_EGLProc) eglInitialize }, - { "eglMakeCurrent", (_EGLProc) eglMakeCurrent }, - { "eglQueryAPI", (_EGLProc) eglQueryAPI }, - { "eglQueryContext", (_EGLProc) eglQueryContext }, - { "eglQueryString", (_EGLProc) eglQueryString }, - { "eglQuerySurface", (_EGLProc) eglQuerySurface }, - { "eglReleaseTexImage", (_EGLProc) eglReleaseTexImage }, - { "eglReleaseThread", (_EGLProc) eglReleaseThread }, - { "eglSurfaceAttrib", (_EGLProc) eglSurfaceAttrib }, - { "eglSwapBuffers", (_EGLProc) eglSwapBuffers }, - { "eglSwapInterval", (_EGLProc) eglSwapInterval }, - { "eglTerminate", (_EGLProc) eglTerminate }, - { "eglWaitClient", (_EGLProc) eglWaitClient }, - { "eglWaitGL", (_EGLProc) eglWaitGL }, - { "eglWaitNative", (_EGLProc) eglWaitNative }, -#endif /* _EGL_GET_CORE_ADDRESSES */ -#ifdef EGL_MESA_screen_surface - { "eglChooseModeMESA", (_EGLProc) eglChooseModeMESA }, - { "eglGetModesMESA", (_EGLProc) eglGetModesMESA }, - { "eglGetModeAttribMESA", (_EGLProc) eglGetModeAttribMESA }, - { "eglCopyContextMESA", (_EGLProc) eglCopyContextMESA }, - { "eglGetScreensMESA", (_EGLProc) eglGetScreensMESA }, - { "eglCreateScreenSurfaceMESA", (_EGLProc) eglCreateScreenSurfaceMESA }, - { "eglShowScreenSurfaceMESA", (_EGLProc) eglShowScreenSurfaceMESA }, - { "eglScreenPositionMESA", (_EGLProc) eglScreenPositionMESA }, - { "eglQueryScreenMESA", (_EGLProc) eglQueryScreenMESA }, - { "eglQueryScreenSurfaceMESA", (_EGLProc) eglQueryScreenSurfaceMESA }, - { "eglQueryScreenModeMESA", (_EGLProc) eglQueryScreenModeMESA }, - { "eglQueryModeStringMESA", (_EGLProc) eglQueryModeStringMESA }, -#endif /* EGL_MESA_screen_surface */ #ifdef EGL_MESA_drm_display - { "eglGetDRMDisplayMESA", (_EGLProc) eglGetDRMDisplayMESA }, -#endif - { "eglCreateImageKHR", (_EGLProc) eglCreateImageKHR }, - { "eglDestroyImageKHR", (_EGLProc) eglDestroyImageKHR }, - { "eglCreateSyncKHR", (_EGLProc) eglCreateSyncKHR }, - { "eglCreateSync64KHR", (_EGLProc) eglCreateSync64KHR }, - { "eglDestroySyncKHR", (_EGLProc) eglDestroySyncKHR }, - { "eglClientWaitSyncKHR", (_EGLProc) eglClientWaitSyncKHR }, - { "eglWaitSyncKHR", (_EGLProc) eglWaitSyncKHR }, - { "eglSignalSyncKHR", (_EGLProc) eglSignalSyncKHR }, - { "eglGetSyncAttribKHR", (_EGLProc) eglGetSyncAttribKHR }, -#ifdef EGL_NOK_swap_region - { "eglSwapBuffersRegionNOK", (_EGLProc) eglSwapBuffersRegionNOK }, -#endif -#ifdef EGL_MESA_drm_image - { "eglCreateDRMImageMESA", (_EGLProc) eglCreateDRMImageMESA }, - { "eglExportDRMImageMESA", (_EGLProc) eglExportDRMImageMESA }, -#endif -#ifdef EGL_WL_bind_wayland_display - { "eglBindWaylandDisplayWL", (_EGLProc) eglBindWaylandDisplayWL }, - { "eglUnbindWaylandDisplayWL", (_EGLProc) eglUnbindWaylandDisplayWL }, - { "eglQueryWaylandBufferWL", (_EGLProc) eglQueryWaylandBufferWL }, -#endif -#ifdef EGL_WL_create_wayland_buffer_from_image - { "eglCreateWaylandBufferFromImageWL", (_EGLProc) eglCreateWaylandBufferFromImageWL }, -#endif - { "eglPostSubBufferNV", (_EGLProc) eglPostSubBufferNV }, -#ifdef EGL_EXT_swap_buffers_with_damage - { "eglSwapBuffersWithDamageEXT", (_EGLProc) eglSwapBuffersWithDamageEXT }, -#endif - { "eglGetPlatformDisplayEXT", (_EGLProc) eglGetPlatformDisplayEXT }, - { "eglCreatePlatformWindowSurfaceEXT", (_EGLProc) eglCreatePlatformWindowSurfaceEXT }, - { "eglCreatePlatformPixmapSurfaceEXT", (_EGLProc) eglCreatePlatformPixmapSurfaceEXT }, - { "eglGetSyncValuesCHROMIUM", (_EGLProc) eglGetSyncValuesCHROMIUM }, -#ifdef EGL_MESA_dma_buf_image_export - { "eglExportDMABUFImageQueryMESA", (_EGLProc) eglExportDMABUFImageQueryMESA }, - { "eglExportDMABUFImageMESA", (_EGLProc) eglExportDMABUFImageMESA }, -#endif - { NULL, NULL } - }; - EGLint i; - _EGLProc ret; - - if (!procname) - RETURN_EGL_SUCCESS(NULL, NULL); - - ret = NULL; - if (strncmp(procname, "egl", 3) == 0) { - for (i = 0; egl_functions[i].name; i++) { - if (strcmp(egl_functions[i].name, procname) == 0) { - ret = egl_functions[i].function; - break; - } - } - } - if (!ret) - ret = _eglGetDriverProc(procname); - - RETURN_EGL_SUCCESS(NULL, ret); -} - - -#ifdef EGL_MESA_screen_surface - - -/* - * EGL_MESA_screen extension - */ - -EGLBoolean EGLAPIENTRY -eglChooseModeMESA(EGLDisplay dpy, EGLScreenMESA screen, - const EGLint *attrib_list, EGLModeMESA *modes, - EGLint modes_size, EGLint *num_modes) -{ - _EGLDisplay *disp = _eglLockDisplay(dpy); - _EGLScreen *scrn = _eglLookupScreen(screen, disp); - _EGLDriver *drv; - EGLBoolean ret; - - _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv); - ret = drv->API.ChooseModeMESA(drv, disp, scrn, attrib_list, - modes, modes_size, num_modes); - - RETURN_EGL_EVAL(disp, ret); -} - - -EGLBoolean EGLAPIENTRY -eglGetModesMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *modes, - EGLint mode_size, EGLint *num_mode) -{ - _EGLDisplay *disp = _eglLockDisplay(dpy); - _EGLScreen *scrn = _eglLookupScreen(screen, disp); - _EGLDriver *drv; - EGLBoolean ret; - - _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv); - ret = drv->API.GetModesMESA(drv, disp, scrn, modes, mode_size, num_mode); - - RETURN_EGL_EVAL(disp, ret); -} - - -EGLBoolean EGLAPIENTRY -eglGetModeAttribMESA(EGLDisplay dpy, EGLModeMESA mode, - EGLint attribute, EGLint *value) -{ - _EGLDisplay *disp = _eglLockDisplay(dpy); - _EGLMode *m = _eglLookupMode(mode, disp); - _EGLDriver *drv; - EGLBoolean ret; - - _EGL_CHECK_MODE(disp, m, EGL_FALSE, drv); - ret = drv->API.GetModeAttribMESA(drv, disp, m, attribute, value); - - RETURN_EGL_EVAL(disp, ret); -} - - -EGLBoolean EGLAPIENTRY -eglCopyContextMESA(EGLDisplay dpy, EGLContext source, EGLContext dest, - EGLint mask) -{ - _EGLDisplay *disp = _eglLockDisplay(dpy); - _EGLContext *source_context = _eglLookupContext(source, disp); - _EGLContext *dest_context = _eglLookupContext(dest, disp); - _EGLDriver *drv; - EGLBoolean ret; - - _EGL_CHECK_CONTEXT(disp, source_context, EGL_FALSE, drv); - if (!dest_context) - RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE); - - ret = drv->API.CopyContextMESA(drv, disp, - source_context, dest_context, mask); - - RETURN_EGL_EVAL(disp, ret); -} - - -EGLBoolean EGLAPIENTRY -eglGetScreensMESA(EGLDisplay dpy, EGLScreenMESA *screens, - EGLint max_screens, EGLint *num_screens) -{ - _EGLDisplay *disp = _eglLockDisplay(dpy); - _EGLDriver *drv; - EGLBoolean ret; - - _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv); - ret = drv->API.GetScreensMESA(drv, disp, screens, max_screens, num_screens); - - RETURN_EGL_EVAL(disp, ret); -} - -EGLSurface EGLAPIENTRY -eglCreateScreenSurfaceMESA(EGLDisplay dpy, EGLConfig config, - const EGLint *attrib_list) -{ - _EGLDisplay *disp = _eglLockDisplay(dpy); - _EGLConfig *conf = _eglLookupConfig(config, disp); - _EGLDriver *drv; - _EGLSurface *surf; - EGLSurface ret; - - _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv); - - surf = drv->API.CreateScreenSurfaceMESA(drv, disp, conf, attrib_list); - ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE; - - RETURN_EGL_EVAL(disp, ret); -} - - -EGLBoolean EGLAPIENTRY -eglShowScreenSurfaceMESA(EGLDisplay dpy, EGLint screen, - EGLSurface surface, EGLModeMESA mode) -{ - _EGLDisplay *disp = _eglLockDisplay(dpy); - _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp); - _EGLSurface *surf = _eglLookupSurface(surface, disp); - _EGLMode *m = _eglLookupMode(mode, disp); - _EGLDriver *drv; - EGLBoolean ret; - - _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv); - if (!surf && surface != EGL_NO_SURFACE) - RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE); - if (!m && mode != EGL_NO_MODE_MESA) - RETURN_EGL_ERROR(disp, EGL_BAD_MODE_MESA, EGL_FALSE); - - ret = drv->API.ShowScreenSurfaceMESA(drv, disp, scrn, surf, m); - - RETURN_EGL_EVAL(disp, ret); -} - - -EGLBoolean EGLAPIENTRY -eglScreenPositionMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLint x, EGLint y) -{ - _EGLDisplay *disp = _eglLockDisplay(dpy); - _EGLScreen *scrn = _eglLookupScreen(screen, disp); - _EGLDriver *drv; - EGLBoolean ret; - - _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv); - ret = drv->API.ScreenPositionMESA(drv, disp, scrn, x, y); - - RETURN_EGL_EVAL(disp, ret); -} - - -EGLBoolean EGLAPIENTRY -eglQueryScreenMESA(EGLDisplay dpy, EGLScreenMESA screen, - EGLint attribute, EGLint *value) -{ - _EGLDisplay *disp = _eglLockDisplay(dpy); - _EGLScreen *scrn = _eglLookupScreen(screen, disp); - _EGLDriver *drv; - EGLBoolean ret; - - _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv); - ret = drv->API.QueryScreenMESA(drv, disp, scrn, attribute, value); - - RETURN_EGL_EVAL(disp, ret); -} - - -EGLBoolean EGLAPIENTRY -eglQueryScreenSurfaceMESA(EGLDisplay dpy, EGLScreenMESA screen, - EGLSurface *surface) -{ - _EGLDisplay *disp = _eglLockDisplay(dpy); - _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp); - _EGLDriver *drv; - _EGLSurface *surf; - EGLBoolean ret; - - _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv); - ret = drv->API.QueryScreenSurfaceMESA(drv, disp, scrn, &surf); - if (ret && surface) - *surface = _eglGetSurfaceHandle(surf); - - RETURN_EGL_EVAL(disp, ret); -} - - -EGLBoolean EGLAPIENTRY -eglQueryScreenModeMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *mode) -{ - _EGLDisplay *disp = _eglLockDisplay(dpy); - _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp); - _EGLDriver *drv; - _EGLMode *m; - EGLBoolean ret; - - _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv); - ret = drv->API.QueryScreenModeMESA(drv, disp, scrn, &m); - if (ret && mode) - *mode = m->Handle; - - RETURN_EGL_EVAL(disp, ret); -} - - -const char * EGLAPIENTRY -eglQueryModeStringMESA(EGLDisplay dpy, EGLModeMESA mode) -{ - _EGLDisplay *disp = _eglLockDisplay(dpy); - _EGLMode *m = _eglLookupMode(mode, disp); - _EGLDriver *drv; - const char *ret; - - _EGL_CHECK_MODE(disp, m, NULL, drv); - ret = drv->API.QueryModeStringMESA(drv, disp, m); - - RETURN_EGL_EVAL(disp, ret); -} - - -#endif /* EGL_MESA_screen_surface */ - - -#ifdef EGL_MESA_drm_display - -EGLDisplay EGLAPIENTRY +static EGLDisplay EGLAPIENTRY eglGetDRMDisplayMESA(int fd) { _EGLDisplay *dpy = _eglFindDisplay(_EGL_PLATFORM_DRM, (void *) (intptr_t) fd); @@ -1607,7 +1317,7 @@ eglReleaseThread(void) } -EGLImageKHR EGLAPIENTRY +static EGLImage EGLAPIENTRY eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attr_list) { @@ -1615,7 +1325,7 @@ eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, _EGLContext *context = _eglLookupContext(ctx, disp); _EGLDriver *drv; _EGLImage *img; - EGLImageKHR ret; + EGLImage ret; _EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR, drv); if (!disp->Extensions.KHR_image_base) @@ -1636,8 +1346,24 @@ eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, } +EGLImage EGLAPIENTRY +eglCreateImage(EGLDisplay dpy, EGLContext ctx, EGLenum target, + EGLClientBuffer buffer, const EGLAttrib *attr_list) +{ + EGLImage image; + EGLint *int_attribs = _eglConvertAttribsToInt(attr_list); + + if (attr_list && !int_attribs) + RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_NO_IMAGE); + + image = eglCreateImageKHR(dpy, ctx, target, buffer, int_attribs); + free(int_attribs); + return image; +} + + EGLBoolean EGLAPIENTRY -eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image) +eglDestroyImage(EGLDisplay dpy, EGLImage image) { _EGLDisplay *disp = _eglLockDisplay(dpy); _EGLImage *img = _eglLookupImage(image, disp); @@ -1657,15 +1383,16 @@ eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image) } -static EGLSyncKHR +static EGLSync _eglCreateSync(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list, - const EGLAttribKHR *attrib_list64, EGLBoolean is64) + const EGLAttrib *attrib_list64, EGLBoolean is64, + EGLenum invalid_type_error) { _EGLDisplay *disp = _eglLockDisplay(dpy); _EGLContext *ctx = _eglGetCurrentContext(); _EGLDriver *drv; _EGLSync *sync; - EGLSyncKHR ret; + EGLSync ret; _EGL_CHECK_DISPLAY(disp, EGL_NO_SYNC_KHR, drv); @@ -1680,18 +1407,18 @@ _eglCreateSync(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list, switch (type) { case EGL_SYNC_FENCE_KHR: if (!disp->Extensions.KHR_fence_sync) - RETURN_EGL_ERROR(disp, EGL_BAD_ATTRIBUTE, EGL_NO_SYNC_KHR); + RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR); break; case EGL_SYNC_REUSABLE_KHR: if (!disp->Extensions.KHR_reusable_sync) - RETURN_EGL_ERROR(disp, EGL_BAD_ATTRIBUTE, EGL_NO_SYNC_KHR); + RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR); break; case EGL_SYNC_CL_EVENT_KHR: if (!disp->Extensions.KHR_cl_event2) - RETURN_EGL_ERROR(disp, EGL_BAD_ATTRIBUTE, EGL_NO_SYNC_KHR); + RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR); break; default: - RETURN_EGL_ERROR(disp, EGL_BAD_ATTRIBUTE, EGL_NO_SYNC_KHR); + RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR); } sync = drv->API.CreateSyncKHR(drv, disp, type, attrib_list, attrib_list64); @@ -1701,22 +1428,32 @@ _eglCreateSync(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list, } -EGLSyncKHR EGLAPIENTRY +static EGLSync EGLAPIENTRY eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list) { - return _eglCreateSync(dpy, type, attrib_list, NULL, EGL_FALSE); + return _eglCreateSync(dpy, type, attrib_list, NULL, EGL_FALSE, + EGL_BAD_ATTRIBUTE); +} + + +static EGLSync EGLAPIENTRY +eglCreateSync64KHR(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list) +{ + return _eglCreateSync(dpy, type, NULL, attrib_list, EGL_TRUE, + EGL_BAD_ATTRIBUTE); } -EGLSyncKHR EGLAPIENTRY -eglCreateSync64KHR(EGLDisplay dpy, EGLenum type, const EGLAttribKHR *attrib_list) +EGLSync EGLAPIENTRY +eglCreateSync(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list) { - return _eglCreateSync(dpy, type, NULL, attrib_list, EGL_TRUE); + return _eglCreateSync(dpy, type, NULL, attrib_list, EGL_TRUE, + EGL_BAD_PARAMETER); } EGLBoolean EGLAPIENTRY -eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync) +eglDestroySync(EGLDisplay dpy, EGLSync sync) { _EGLDisplay *disp = _eglLockDisplay(dpy); _EGLSync *s = _eglLookupSync(sync, disp); @@ -1735,7 +1472,7 @@ eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync) EGLint EGLAPIENTRY -eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout) +eglClientWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout) { _EGLDisplay *disp = _eglLockDisplay(dpy); _EGLSync *s = _eglLookupSync(sync, disp); @@ -1755,8 +1492,8 @@ eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR t } -EGLint EGLAPIENTRY -eglWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags) +static EGLint EGLAPIENTRY +eglWaitSyncKHR(EGLDisplay dpy, EGLSync sync, EGLint flags) { _EGLDisplay *disp = _eglLockDisplay(dpy); _EGLSync *s = _eglLookupSync(sync, disp); @@ -1782,7 +1519,18 @@ eglWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags) EGLBoolean EGLAPIENTRY -eglSignalSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode) +eglWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags) +{ + /* The KHR version returns EGLint, while the core version returns + * EGLBoolean. In both cases, the return values can only be EGL_FALSE and + * EGL_TRUE. + */ + return eglWaitSyncKHR(dpy, sync, flags); +} + + +static EGLBoolean EGLAPIENTRY +eglSignalSyncKHR(EGLDisplay dpy, EGLSync sync, EGLenum mode) { _EGLDisplay *disp = _eglLockDisplay(dpy); _EGLSync *s = _eglLookupSync(sync, disp); @@ -1798,7 +1546,7 @@ eglSignalSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode) EGLBoolean EGLAPIENTRY -eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value) +eglGetSyncAttrib(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib *value) { _EGLDisplay *disp = _eglLockDisplay(dpy); _EGLSync *s = _eglLookupSync(sync, disp); @@ -1808,15 +1556,33 @@ eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *v _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv); assert(disp->Extensions.KHR_reusable_sync || disp->Extensions.KHR_fence_sync); - ret = drv->API.GetSyncAttribKHR(drv, disp, s, attribute, value); + ret = drv->API.GetSyncAttrib(drv, disp, s, attribute, value); RETURN_EGL_EVAL(disp, ret); } +static EGLBoolean EGLAPIENTRY +eglGetSyncAttribKHR(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLint *value) +{ + EGLAttrib attrib = *value; + EGLBoolean result = eglGetSyncAttrib(dpy, sync, attribute, &attrib); + + /* The EGL_KHR_fence_sync spec says this about eglGetSyncAttribKHR: + * + * If any error occurs, <*value> is not modified. + */ + if (result == EGL_FALSE) + return result; + + *value = attrib; + return result; +} + + #ifdef EGL_NOK_swap_region -EGLBoolean EGLAPIENTRY +static EGLBoolean EGLAPIENTRY eglSwapBuffersRegionNOK(EGLDisplay dpy, EGLSurface surface, EGLint numRects, const EGLint *rects) { @@ -1846,13 +1612,13 @@ eglSwapBuffersRegionNOK(EGLDisplay dpy, EGLSurface surface, #ifdef EGL_MESA_drm_image -EGLImageKHR EGLAPIENTRY +static EGLImage EGLAPIENTRY eglCreateDRMImageMESA(EGLDisplay dpy, const EGLint *attr_list) { _EGLDisplay *disp = _eglLockDisplay(dpy); _EGLDriver *drv; _EGLImage *img; - EGLImageKHR ret; + EGLImage ret; _EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR, drv); if (!disp->Extensions.MESA_drm_image) @@ -1864,8 +1630,8 @@ eglCreateDRMImageMESA(EGLDisplay dpy, const EGLint *attr_list) RETURN_EGL_EVAL(disp, ret); } -EGLBoolean EGLAPIENTRY -eglExportDRMImageMESA(EGLDisplay dpy, EGLImageKHR image, +static EGLBoolean EGLAPIENTRY +eglExportDRMImageMESA(EGLDisplay dpy, EGLImage image, EGLint *name, EGLint *handle, EGLint *stride) { _EGLDisplay *disp = _eglLockDisplay(dpy); @@ -1889,7 +1655,7 @@ eglExportDRMImageMESA(EGLDisplay dpy, EGLImageKHR image, #ifdef EGL_WL_bind_wayland_display struct wl_display; -EGLBoolean EGLAPIENTRY +static EGLBoolean EGLAPIENTRY eglBindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display) { _EGLDisplay *disp = _eglLockDisplay(dpy); @@ -1907,7 +1673,7 @@ eglBindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display) RETURN_EGL_EVAL(disp, ret); } -EGLBoolean EGLAPIENTRY +static EGLBoolean EGLAPIENTRY eglUnbindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display) { _EGLDisplay *disp = _eglLockDisplay(dpy); @@ -1925,7 +1691,7 @@ eglUnbindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display) RETURN_EGL_EVAL(disp, ret); } -EGLBoolean EGLAPIENTRY +static EGLBoolean EGLAPIENTRY eglQueryWaylandBufferWL(EGLDisplay dpy, struct wl_resource *buffer, EGLint attribute, EGLint *value) { @@ -1946,8 +1712,8 @@ eglQueryWaylandBufferWL(EGLDisplay dpy, struct wl_resource *buffer, #endif #ifdef EGL_WL_create_wayland_buffer_from_image -struct wl_buffer * EGLAPIENTRY -eglCreateWaylandBufferFromImageWL(EGLDisplay dpy, EGLImageKHR image) +static struct wl_buffer * EGLAPIENTRY +eglCreateWaylandBufferFromImageWL(EGLDisplay dpy, EGLImage image) { _EGLDisplay *disp = _eglLockDisplay(dpy); _EGLImage *img; @@ -1968,7 +1734,7 @@ eglCreateWaylandBufferFromImageWL(EGLDisplay dpy, EGLImageKHR image) } #endif -EGLBoolean EGLAPIENTRY +static EGLBoolean EGLAPIENTRY eglPostSubBufferNV(EGLDisplay dpy, EGLSurface surface, EGLint x, EGLint y, EGLint width, EGLint height) { @@ -1987,7 +1753,7 @@ eglPostSubBufferNV(EGLDisplay dpy, EGLSurface surface, RETURN_EGL_EVAL(disp, ret); } -EGLBoolean EGLAPIENTRY +static EGLBoolean EGLAPIENTRY eglGetSyncValuesCHROMIUM(EGLDisplay display, EGLSurface surface, EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc) @@ -2010,8 +1776,8 @@ eglGetSyncValuesCHROMIUM(EGLDisplay display, EGLSurface surface, } #ifdef EGL_MESA_image_dma_buf_export -EGLBoolean EGLAPIENTRY -eglExportDMABUFImageQueryMESA(EGLDisplay dpy, EGLImageKHR image, +static EGLBoolean EGLAPIENTRY +eglExportDMABUFImageQueryMESA(EGLDisplay dpy, EGLImage image, EGLint *fourcc, EGLint *nplanes, EGLuint64KHR *modifiers) { @@ -2032,8 +1798,8 @@ eglExportDMABUFImageQueryMESA(EGLDisplay dpy, EGLImageKHR image, RETURN_EGL_EVAL(disp, ret); } -EGLBoolean EGLAPIENTRY -eglExportDMABUFImageMESA(EGLDisplay dpy, EGLImageKHR image, +static EGLBoolean EGLAPIENTRY +eglExportDMABUFImageMESA(EGLDisplay dpy, EGLImage image, int *fds, EGLint *strides, EGLint *offsets) { _EGLDisplay *disp = _eglLockDisplay(dpy); @@ -2052,3 +1818,120 @@ eglExportDMABUFImageMESA(EGLDisplay dpy, EGLImageKHR image, RETURN_EGL_EVAL(disp, ret); } #endif + +__eglMustCastToProperFunctionPointerType EGLAPIENTRY +eglGetProcAddress(const char *procname) +{ + static const struct { + const char *name; + _EGLProc function; + } egl_functions[] = { + /* core functions queryable in the presence of + * EGL_KHR_get_all_proc_addresses or EGL 1.5 + */ + /* alphabetical order */ + { "eglBindAPI", (_EGLProc) eglBindAPI }, + { "eglBindTexImage", (_EGLProc) eglBindTexImage }, + { "eglChooseConfig", (_EGLProc) eglChooseConfig }, + { "eglCopyBuffers", (_EGLProc) eglCopyBuffers }, + { "eglCreateContext", (_EGLProc) eglCreateContext }, + { "eglCreatePbufferFromClientBuffer", (_EGLProc) eglCreatePbufferFromClientBuffer }, + { "eglCreatePbufferSurface", (_EGLProc) eglCreatePbufferSurface }, + { "eglCreatePixmapSurface", (_EGLProc) eglCreatePixmapSurface }, + { "eglCreateWindowSurface", (_EGLProc) eglCreateWindowSurface }, + { "eglDestroyContext", (_EGLProc) eglDestroyContext }, + { "eglDestroySurface", (_EGLProc) eglDestroySurface }, + { "eglGetConfigAttrib", (_EGLProc) eglGetConfigAttrib }, + { "eglGetConfigs", (_EGLProc) eglGetConfigs }, + { "eglGetCurrentContext", (_EGLProc) eglGetCurrentContext }, + { "eglGetCurrentDisplay", (_EGLProc) eglGetCurrentDisplay }, + { "eglGetCurrentSurface", (_EGLProc) eglGetCurrentSurface }, + { "eglGetDisplay", (_EGLProc) eglGetDisplay }, + { "eglGetError", (_EGLProc) eglGetError }, + { "eglGetProcAddress", (_EGLProc) eglGetProcAddress }, + { "eglInitialize", (_EGLProc) eglInitialize }, + { "eglMakeCurrent", (_EGLProc) eglMakeCurrent }, + { "eglQueryAPI", (_EGLProc) eglQueryAPI }, + { "eglQueryContext", (_EGLProc) eglQueryContext }, + { "eglQueryString", (_EGLProc) eglQueryString }, + { "eglQuerySurface", (_EGLProc) eglQuerySurface }, + { "eglReleaseTexImage", (_EGLProc) eglReleaseTexImage }, + { "eglReleaseThread", (_EGLProc) eglReleaseThread }, + { "eglSurfaceAttrib", (_EGLProc) eglSurfaceAttrib }, + { "eglSwapBuffers", (_EGLProc) eglSwapBuffers }, + { "eglSwapInterval", (_EGLProc) eglSwapInterval }, + { "eglTerminate", (_EGLProc) eglTerminate }, + { "eglWaitClient", (_EGLProc) eglWaitClient }, + { "eglWaitGL", (_EGLProc) eglWaitGL }, + { "eglWaitNative", (_EGLProc) eglWaitNative }, + { "eglCreateSync", (_EGLProc) eglCreateSync }, + { "eglDestroySync", (_EGLProc) eglDestroySync }, + { "eglClientWaitSync", (_EGLProc) eglClientWaitSync }, + { "eglGetSyncAttrib", (_EGLProc) eglGetSyncAttrib }, + { "eglWaitSync", (_EGLProc) eglWaitSync }, + { "eglCreateImage", (_EGLProc) eglCreateImage }, + { "eglDestroyImage", (_EGLProc) eglDestroyImage }, + { "eglGetPlatformDisplay", (_EGLProc) eglGetPlatformDisplay }, + { "eglCreatePlatformWindowSurface", (_EGLProc) eglCreatePlatformWindowSurface }, + { "eglCreatePlatformPixmapSurface", (_EGLProc) eglCreatePlatformPixmapSurface }, +#ifdef EGL_MESA_drm_display + { "eglGetDRMDisplayMESA", (_EGLProc) eglGetDRMDisplayMESA }, +#endif + { "eglCreateImageKHR", (_EGLProc) eglCreateImageKHR }, + { "eglDestroyImageKHR", (_EGLProc) eglDestroyImage }, + { "eglCreateSyncKHR", (_EGLProc) eglCreateSyncKHR }, + { "eglCreateSync64KHR", (_EGLProc) eglCreateSync64KHR }, + { "eglDestroySyncKHR", (_EGLProc) eglDestroySync }, + { "eglClientWaitSyncKHR", (_EGLProc) eglClientWaitSync }, + { "eglWaitSyncKHR", (_EGLProc) eglWaitSyncKHR }, + { "eglSignalSyncKHR", (_EGLProc) eglSignalSyncKHR }, + { "eglGetSyncAttribKHR", (_EGLProc) eglGetSyncAttribKHR }, +#ifdef EGL_NOK_swap_region + { "eglSwapBuffersRegionNOK", (_EGLProc) eglSwapBuffersRegionNOK }, +#endif +#ifdef EGL_MESA_drm_image + { "eglCreateDRMImageMESA", (_EGLProc) eglCreateDRMImageMESA }, + { "eglExportDRMImageMESA", (_EGLProc) eglExportDRMImageMESA }, +#endif +#ifdef EGL_WL_bind_wayland_display + { "eglBindWaylandDisplayWL", (_EGLProc) eglBindWaylandDisplayWL }, + { "eglUnbindWaylandDisplayWL", (_EGLProc) eglUnbindWaylandDisplayWL }, + { "eglQueryWaylandBufferWL", (_EGLProc) eglQueryWaylandBufferWL }, +#endif +#ifdef EGL_WL_create_wayland_buffer_from_image + { "eglCreateWaylandBufferFromImageWL", (_EGLProc) eglCreateWaylandBufferFromImageWL }, +#endif + { "eglPostSubBufferNV", (_EGLProc) eglPostSubBufferNV }, +#ifdef EGL_EXT_swap_buffers_with_damage + { "eglSwapBuffersWithDamageEXT", (_EGLProc) eglSwapBuffersWithDamageEXT }, +#endif + { "eglGetPlatformDisplayEXT", (_EGLProc) eglGetPlatformDisplayEXT }, + { "eglCreatePlatformWindowSurfaceEXT", (_EGLProc) eglCreatePlatformWindowSurfaceEXT }, + { "eglCreatePlatformPixmapSurfaceEXT", (_EGLProc) eglCreatePlatformPixmapSurfaceEXT }, + { "eglGetSyncValuesCHROMIUM", (_EGLProc) eglGetSyncValuesCHROMIUM }, +#ifdef EGL_MESA_image_dma_buf_export + { "eglExportDMABUFImageQueryMESA", (_EGLProc) eglExportDMABUFImageQueryMESA }, + { "eglExportDMABUFImageMESA", (_EGLProc) eglExportDMABUFImageMESA }, +#endif + { NULL, NULL } + }; + EGLint i; + _EGLProc ret; + + if (!procname) + RETURN_EGL_SUCCESS(NULL, NULL); + + ret = NULL; + if (strncmp(procname, "egl", 3) == 0) { + for (i = 0; egl_functions[i].name; i++) { + if (strcmp(egl_functions[i].name, procname) == 0) { + ret = egl_functions[i].function; + break; + } + } + } + if (!ret) + ret = _eglGetDriverProc(procname); + + RETURN_EGL_SUCCESS(NULL, ret); +} diff --git a/src/egl/main/eglapi.h b/src/egl/main/eglapi.h index 068d4ef5c1e..4e0378d0d5f 100644 --- a/src/egl/main/eglapi.h +++ b/src/egl/main/eglapi.h @@ -31,6 +31,11 @@ #ifndef EGLAPI_INCLUDED #define EGLAPI_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + /** * A generic function ptr type */ @@ -79,22 +84,6 @@ typedef _EGLProc (*GetProcAddress_t)(_EGLDriver *drv, const char *procname); -#ifdef EGL_MESA_screen_surface -typedef EGLBoolean (*ChooseModeMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *screen, const EGLint *attrib_list, EGLModeMESA *modes, EGLint modes_size, EGLint *num_modes); -typedef EGLBoolean (*GetModesMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *screen, EGLModeMESA *modes, EGLint mode_size, EGLint *num_mode); -typedef EGLBoolean (*GetModeAttribMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLMode *mode, EGLint attribute, EGLint *value); -typedef EGLBoolean (*CopyContextMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *source, _EGLContext *dest, EGLint mask); -typedef EGLBoolean (*GetScreensMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, EGLScreenMESA *screens, EGLint max_screens, EGLint *num_screens); -typedef _EGLSurface *(*CreateScreenSurfaceMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *config, const EGLint *attrib_list); -typedef EGLBoolean (*ShowScreenSurfaceMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *screen, _EGLSurface *surface, _EGLMode *mode); -typedef EGLBoolean (*ScreenPositionMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *screen, EGLint x, EGLint y); -typedef EGLBoolean (*QueryScreenMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *screen, EGLint attribute, EGLint *value); -typedef EGLBoolean (*QueryScreenSurfaceMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *screen, _EGLSurface **surface); -typedef EGLBoolean (*QueryScreenModeMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *screen, _EGLMode **mode); -typedef const char * (*QueryModeStringMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLMode *mode); -#endif /* EGL_MESA_screen_surface */ - - typedef _EGLSurface *(*CreatePbufferFromClientBuffer_t)(_EGLDriver *drv, _EGLDisplay *dpy, EGLenum buftype, EGLClientBuffer buffer, _EGLConfig *config, const EGLint *attrib_list); @@ -102,12 +91,12 @@ typedef _EGLImage *(*CreateImageKHR_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLCo typedef EGLBoolean (*DestroyImageKHR_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLImage *image); -typedef _EGLSync *(*CreateSyncKHR_t)(_EGLDriver *drv, _EGLDisplay *dpy, EGLenum type, const EGLint *attrib_list, const EGLAttribKHR *attrib_list64); +typedef _EGLSync *(*CreateSyncKHR_t)(_EGLDriver *drv, _EGLDisplay *dpy, EGLenum type, const EGLint *attrib_list, const EGLAttrib *attrib_list64); typedef EGLBoolean (*DestroySyncKHR_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync); -typedef EGLint (*ClientWaitSyncKHR_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync, EGLint flags, EGLTimeKHR timeout); +typedef EGLint (*ClientWaitSyncKHR_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync, EGLint flags, EGLTime timeout); typedef EGLint (*WaitSyncKHR_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync); typedef EGLBoolean (*SignalSyncKHR_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync, EGLenum mode); -typedef EGLBoolean (*GetSyncAttribKHR_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync, EGLint attribute, EGLint *value); +typedef EGLBoolean (*GetSyncAttrib_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync, EGLint attribute, EGLAttrib *value); #ifdef EGL_NOK_swap_region @@ -179,21 +168,6 @@ struct _egl_api WaitNative_t WaitNative; GetProcAddress_t GetProcAddress; -#ifdef EGL_MESA_screen_surface - ChooseModeMESA_t ChooseModeMESA; - GetModesMESA_t GetModesMESA; - GetModeAttribMESA_t GetModeAttribMESA; - CopyContextMESA_t CopyContextMESA; - GetScreensMESA_t GetScreensMESA; - CreateScreenSurfaceMESA_t CreateScreenSurfaceMESA; - ShowScreenSurfaceMESA_t ShowScreenSurfaceMESA; - ScreenPositionMESA_t ScreenPositionMESA; - QueryScreenMESA_t QueryScreenMESA; - QueryScreenSurfaceMESA_t QueryScreenSurfaceMESA; - QueryScreenModeMESA_t QueryScreenModeMESA; - QueryModeStringMESA_t QueryModeStringMESA; -#endif /* EGL_MESA_screen_surface */ - CreatePbufferFromClientBuffer_t CreatePbufferFromClientBuffer; CreateImageKHR_t CreateImageKHR; @@ -204,7 +178,7 @@ struct _egl_api ClientWaitSyncKHR_t ClientWaitSyncKHR; WaitSyncKHR_t WaitSyncKHR; SignalSyncKHR_t SignalSyncKHR; - GetSyncAttribKHR_t GetSyncAttribKHR; + GetSyncAttrib_t GetSyncAttrib; #ifdef EGL_NOK_swap_region SwapBuffersRegionNOK_t SwapBuffersRegionNOK; @@ -240,4 +214,9 @@ struct _egl_api #endif }; + +#ifdef __cplusplus +} +#endif + #endif /* EGLAPI_INCLUDED */ diff --git a/src/egl/main/eglarray.h b/src/egl/main/eglarray.h index 228f6c3d2ca..29b7128b68d 100644 --- a/src/egl/main/eglarray.h +++ b/src/egl/main/eglarray.h @@ -34,6 +34,10 @@ #include "egltypedefs.h" +#ifdef __cplusplus +extern "C" { +#endif + typedef EGLBoolean (*_EGLArrayForEach)(void *elem, void *foreach_data); @@ -83,4 +87,8 @@ _eglGetArraySize(_EGLArray *array) } +#ifdef __cplusplus +} +#endif + #endif /* EGLARRAY_INCLUDED */ diff --git a/src/egl/main/eglcompiler.h b/src/egl/main/eglcompiler.h index b457a40a32a..9804ca4f281 100644 --- a/src/egl/main/eglcompiler.h +++ b/src/egl/main/eglcompiler.h @@ -30,9 +30,17 @@ #ifndef EGLCOMPILER_INCLUDED #define EGLCOMPILER_INCLUDED +#ifdef __cplusplus +extern "C" { +#endif + #define STATIC_ASSERT(COND) \ do { \ (void) sizeof(char [1 - 2*!(COND)]); \ } while (0) +#ifdef __cplusplus +} +#endif + #endif /* EGLCOMPILER_INCLUDED */ diff --git a/src/egl/main/eglconfig.c b/src/egl/main/eglconfig.c index db42e95f88d..cf65c69b7b4 100644 --- a/src/egl/main/eglconfig.c +++ b/src/egl/main/eglconfig.c @@ -323,10 +323,6 @@ _eglValidateConfig(const _EGLConfig *conf, EGLBoolean for_matching) EGL_VG_ALPHA_FORMAT_PRE_BIT | EGL_MULTISAMPLE_RESOLVE_BOX_BIT | EGL_SWAP_BEHAVIOR_PRESERVED_BIT; -#ifdef EGL_MESA_screen_surface - if (conf->Display->Extensions.MESA_screen_surface) - mask |= EGL_SCREEN_BIT_MESA; -#endif break; case EGL_RENDERABLE_TYPE: case EGL_CONFORMANT: diff --git a/src/egl/main/eglconfig.h b/src/egl/main/eglconfig.h index dc59ea3f72f..84cb2276b70 100644 --- a/src/egl/main/eglconfig.h +++ b/src/egl/main/eglconfig.h @@ -39,6 +39,10 @@ #include "egltypedefs.h" +#ifdef __cplusplus +extern "C" { +#endif + /* update _eglValidationTable and _eglOffsetOfConfig before updating this * struct */ struct _egl_config @@ -225,4 +229,8 @@ extern EGLBoolean _eglGetConfigs(_EGLDriver *drv, _EGLDisplay *dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config); +#ifdef __cplusplus +} +#endif + #endif /* EGLCONFIG_INCLUDED */ diff --git a/src/egl/main/eglcontext.c b/src/egl/main/eglcontext.c index 514b91aeef2..e767f4b1abe 100644 --- a/src/egl/main/eglcontext.c +++ b/src/egl/main/eglcontext.c @@ -131,7 +131,7 @@ _eglParseContextAttribList(_EGLContext *ctx, _EGLDisplay *dpy, break; } - ctx->Flags = val; + ctx->Flags |= val; break; case EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR: @@ -194,7 +194,38 @@ _eglParseContextAttribList(_EGLContext *ctx, _EGLDisplay *dpy, break; } - ctx->Flags = EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR; + if (val == EGL_TRUE) + ctx->Flags |= EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR; + break; + + case EGL_CONTEXT_OPENGL_ROBUST_ACCESS: + if (dpy->Version < 15) { + err = EGL_BAD_ATTRIBUTE; + break; + } + + if (val == EGL_TRUE) + ctx->Flags |= EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR; + break; + + case EGL_CONTEXT_OPENGL_DEBUG: + if (dpy->Version < 15) { + err = EGL_BAD_ATTRIBUTE; + break; + } + + if (val == EGL_TRUE) + ctx->Flags |= EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR; + break; + + case EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE: + if (dpy->Version < 15) { + err = EGL_BAD_ATTRIBUTE; + break; + } + + if (val == EGL_TRUE) + ctx->Flags |= EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR; break; default: diff --git a/src/egl/main/eglcontext.h b/src/egl/main/eglcontext.h index 241917f3bea..69bf77d8aff 100644 --- a/src/egl/main/eglcontext.h +++ b/src/egl/main/eglcontext.h @@ -37,6 +37,10 @@ #include "egldisplay.h" +#ifdef __cplusplus +extern "C" { +#endif + /** * "Base" class for device driver contexts. */ @@ -150,4 +154,8 @@ _eglGetContextHandle(_EGLContext *ctx) } +#ifdef __cplusplus +} +#endif + #endif /* EGLCONTEXT_INCLUDED */ diff --git a/src/egl/main/eglcurrent.c b/src/egl/main/eglcurrent.c index 6ffc799d3de..835631d3ba3 100644 --- a/src/egl/main/eglcurrent.c +++ b/src/egl/main/eglcurrent.c @@ -282,14 +282,6 @@ _eglError(EGLint errCode, const char *msg) case EGL_NOT_INITIALIZED: s = "EGL_NOT_INITIALIZED"; break; -#ifdef EGL_MESA_screen_surface - case EGL_BAD_SCREEN_MESA: - s = "EGL_BAD_SCREEN_MESA"; - break; - case EGL_BAD_MODE_MESA: - s = "EGL_BAD_MODE_MESA"; - break; -#endif default: s = "other EGL error"; } diff --git a/src/egl/main/eglcurrent.h b/src/egl/main/eglcurrent.h index 3343755c985..1e386acdafb 100644 --- a/src/egl/main/eglcurrent.h +++ b/src/egl/main/eglcurrent.h @@ -34,6 +34,10 @@ #include "egltypedefs.h" +#ifdef __cplusplus +extern "C" { +#endif + #define _EGL_API_ALL_BITS \ (EGL_OPENGL_ES_BIT | \ EGL_OPENVG_BIT | \ @@ -115,4 +119,8 @@ extern EGLBoolean _eglError(EGLint errCode, const char *msg); +#ifdef __cplusplus +} +#endif + #endif /* EGLCURRENT_INCLUDED */ diff --git a/src/egl/main/egldefines.h b/src/egl/main/egldefines.h index 4c9e014fcea..a32cab26408 100644 --- a/src/egl/main/egldefines.h +++ b/src/egl/main/egldefines.h @@ -34,6 +34,9 @@ #ifndef EGLDEFINES_INCLUDED #define EGLDEFINES_INCLUDED +#ifdef __cplusplus +extern "C" { +#endif #define _EGL_MAX_EXTENSIONS_LEN 1000 @@ -41,5 +44,8 @@ #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) +#ifdef __cplusplus +} +#endif #endif /* EGLDEFINES_INCLUDED */ diff --git a/src/egl/main/egldisplay.c b/src/egl/main/egldisplay.c index a3ecba8c41e..24a0c7e61a7 100644 --- a/src/egl/main/egldisplay.c +++ b/src/egl/main/egldisplay.c @@ -71,7 +71,8 @@ static const struct { { _EGL_PLATFORM_DRM, "drm" }, { _EGL_PLATFORM_NULL, "null" }, { _EGL_PLATFORM_ANDROID, "android" }, - { _EGL_PLATFORM_HAIKU, "haiku" } + { _EGL_PLATFORM_HAIKU, "haiku" }, + { _EGL_PLATFORM_SURFACELESS, "surfaceless" }, }; diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h index b6b9ed8e278..0b50a36a098 100644 --- a/src/egl/main/egldisplay.h +++ b/src/egl/main/egldisplay.h @@ -39,6 +39,10 @@ #include "eglarray.h" +#ifdef __cplusplus +extern "C" { +#endif + enum _egl_platform_type { _EGL_PLATFORM_WINDOWS, _EGL_PLATFORM_X11, @@ -47,6 +51,7 @@ enum _egl_platform_type { _EGL_PLATFORM_NULL, _EGL_PLATFORM_ANDROID, _EGL_PLATFORM_HAIKU, + _EGL_PLATFORM_SURFACELESS, _EGL_NUM_PLATFORMS, _EGL_INVALID_PLATFORM = -1 @@ -86,8 +91,6 @@ struct _egl_resource */ struct _egl_extensions { - EGLBoolean MESA_screen_surface; - EGLBoolean MESA_copy_context; EGLBoolean MESA_drm_display; EGLBoolean MESA_drm_image; EGLBoolean MESA_configless_context; @@ -99,6 +102,7 @@ struct _egl_extensions EGLBoolean KHR_image_pixmap; EGLBoolean KHR_vg_parent_image; EGLBoolean KHR_get_all_proc_addresses; + EGLBoolean KHR_gl_colorspace; EGLBoolean KHR_gl_texture_2D_image; EGLBoolean KHR_gl_texture_cubemap_image; EGLBoolean KHR_gl_texture_3D_image; @@ -151,8 +155,7 @@ struct _egl_display /* these fields are set by the driver during init */ void *DriverData; /**< Driver private data */ - EGLint VersionMajor; /**< EGL major version */ - EGLint VersionMinor; /**< EGL minor version */ + EGLint Version; /**< EGL version major*10+minor */ EGLint ClientAPIs; /**< Bitmask of APIs supported (EGL_xxx_BIT) */ _EGLExtensions Extensions; /**< Extensions supported */ @@ -271,4 +274,9 @@ _eglGetWaylandDisplay(struct wl_display *native_display, const EGLint *attrib_list); #endif + +#ifdef __cplusplus +} +#endif + #endif /* EGLDISPLAY_INCLUDED */ diff --git a/src/egl/main/egldriver.c b/src/egl/main/egldriver.c index 6983af966b6..6ef79d96502 100644 --- a/src/egl/main/egldriver.c +++ b/src/egl/main/egldriver.c @@ -45,21 +45,9 @@ #include "egldriver.h" #include "egllog.h" -#if defined(_EGL_OS_UNIX) -#include <dlfcn.h> -#include <sys/types.h> -#include <dirent.h> -#include <unistd.h> -#endif - -#ifdef _EGL_BUILT_IN_DRIVER_HAIKU -_EGLDriver* _eglBuiltInDriverHaiku(const char* args); -#endif - typedef struct _egl_module { - char *Path; + char *Name; _EGLMain_t BuiltIn; - void *Handle; _EGLDriver *Driver; } _EGLModule; @@ -80,152 +68,23 @@ const struct { }; /** - * Wrappers for dlopen/dlclose() - */ -#if defined(_EGL_OS_WINDOWS) - - -typedef HMODULE lib_handle; - -static HMODULE -open_library(const char *filename) -{ - return LoadLibrary(filename); -} - -static void -close_library(HMODULE lib) -{ - FreeLibrary(lib); -} - - -static const char * -library_suffix(void) -{ - return ".dll"; -} - - -#elif defined(_EGL_OS_UNIX) - - -typedef void * lib_handle; - -static void * -open_library(const char *filename) -{ - return dlopen(filename, RTLD_LAZY); -} - -static void -close_library(void *lib) -{ - dlclose(lib); -} - - -static const char * -library_suffix(void) -{ - return ".so"; -} - - -#endif - - -/** - * Open the named driver and find its bootstrap function: _eglMain(). - */ -static _EGLMain_t -_eglOpenLibrary(const char *driverPath, lib_handle *handle) -{ - lib_handle lib; - _EGLMain_t mainFunc = NULL; - const char *error = "unknown error"; - - assert(driverPath); - - _eglLog(_EGL_DEBUG, "dlopen(%s)", driverPath); - lib = open_library(driverPath); - -#if defined(_EGL_OS_WINDOWS) - /* XXX untested */ - if (lib) - mainFunc = (_EGLMain_t) GetProcAddress(lib, "_eglMain"); -#elif defined(_EGL_OS_UNIX) - if (lib) { - union { - _EGLMain_t func; - void *ptr; - } tmp = { NULL }; - /* direct cast gives a warning when compiled with -pedantic */ - tmp.ptr = dlsym(lib, "_eglMain"); - mainFunc = tmp.func; - if (!mainFunc) - error = dlerror(); - } - else { - error = dlerror(); - } -#endif - - if (!lib) { - _eglLog(_EGL_WARNING, "Could not open driver %s (%s)", - driverPath, error); - return NULL; - } - - if (!mainFunc) { - _eglLog(_EGL_WARNING, "_eglMain not found in %s (%s)", - driverPath, error); - if (lib) - close_library(lib); - return NULL; - } - - *handle = lib; - return mainFunc; -} - - -/** * Load a module and create the driver object. */ static EGLBoolean _eglLoadModule(_EGLModule *mod) { - _EGLMain_t mainFunc; - lib_handle lib; _EGLDriver *drv; if (mod->Driver) return EGL_TRUE; - if (mod->BuiltIn) { - lib = (lib_handle) NULL; - mainFunc = mod->BuiltIn; - } - else { - mainFunc = _eglOpenLibrary(mod->Path, &lib); - if (!mainFunc) + if (!mod->BuiltIn) return EGL_FALSE; - } - drv = mainFunc(NULL); - if (!drv) { - if (lib) - close_library(lib); + drv = mod->BuiltIn(NULL); + if (!drv || !drv->Name) return EGL_FALSE; - } - if (!drv->Name) { - _eglLog(_EGL_WARNING, "Driver loaded from %s has no name", mod->Path); - drv->Name = "UNNAMED"; - } - - mod->Handle = (void *) lib; mod->Driver = drv; return EGL_TRUE; @@ -243,20 +102,11 @@ _eglUnloadModule(_EGLModule *mod) if (mod->Driver && mod->Driver->Unload) mod->Driver->Unload(mod->Driver); - /* - * XXX At this point (atexit), the module might be the last reference to - * libEGL. Closing the module might unmap libEGL and give problems. - */ -#if 0 - if (mod->Handle) - close_library(mod->Handle); -#endif #elif defined(_EGL_OS_WINDOWS) /* XXX Windows unloads DLLs before atexit */ #endif mod->Driver = NULL; - mod->Handle = NULL; } @@ -264,7 +114,7 @@ _eglUnloadModule(_EGLModule *mod) * Add a module to the module array. */ static _EGLModule * -_eglAddModule(const char *path) +_eglAddModule(const char *name) { _EGLModule *mod; EGLint i; @@ -278,22 +128,22 @@ _eglAddModule(const char *path) /* find duplicates */ for (i = 0; i < _eglModules->Size; i++) { mod = _eglModules->Elements[i]; - if (strcmp(mod->Path, path) == 0) + if (strcmp(mod->Name, name) == 0) return mod; } /* allocate a new one */ mod = calloc(1, sizeof(*mod)); if (mod) { - mod->Path = _eglstrdup(path); - if (!mod->Path) { + mod->Name = _eglstrdup(name); + if (!mod->Name) { free(mod); mod = NULL; } } if (mod) { _eglAppendArray(_eglModules, (void *) mod); - _eglLog(_EGL_DEBUG, "added %s to module array", mod->Path); + _eglLog(_EGL_DEBUG, "added %s to module array", mod->Name); } return mod; @@ -309,155 +159,12 @@ _eglFreeModule(void *module) _EGLModule *mod = (_EGLModule *) module; _eglUnloadModule(mod); - free(mod->Path); + free(mod->Name); free(mod); } /** - * A loader function for use with _eglPreloadForEach. The loader data is the - * filename of the driver. This function stops on the first valid driver. - */ -static EGLBoolean -_eglLoaderFile(const char *dir, size_t len, void *loader_data) -{ - char path[1024]; - const char *filename = (const char *) loader_data; - size_t flen = strlen(filename); - - /* make a full path */ - if (len + flen + 2 > sizeof(path)) - return EGL_TRUE; - if (len) { - memcpy(path, dir, len); - path[len++] = '/'; - } - memcpy(path + len, filename, flen); - len += flen; - path[len] = '\0'; - - if (library_suffix()) { - const char *suffix = library_suffix(); - size_t slen = strlen(suffix); - const char *p; - EGLBoolean need_suffix; - - p = filename + flen - slen; - need_suffix = (p < filename || strcmp(p, suffix) != 0); - if (need_suffix) { - /* overflow */ - if (len + slen + 1 > sizeof(path)) - return EGL_TRUE; - strcpy(path + len, suffix); - } - } - -#if defined(_EGL_OS_UNIX) - /* check if the file exists */ - if (access(path, F_OK)) - return EGL_TRUE; -#endif - - _eglAddModule(path); - - return EGL_TRUE; -} - - -/** - * Run the callback function on each driver directory. - * - * The process may end prematurely if the callback function returns false. - */ -static void -_eglPreloadForEach(const char *search_path, - EGLBoolean (*loader)(const char *, size_t, void *), - void *loader_data) -{ - const char *cur, *next; - size_t len; - - cur = search_path; - while (cur) { - next = strchr(cur, ':'); - len = (next) ? next - cur : strlen(cur); - - if (!loader(cur, len, loader_data)) - break; - - cur = (next) ? next + 1 : NULL; - } -} - - -/** - * Return a list of colon-separated driver directories. - */ -static const char * -_eglGetSearchPath(void) -{ - static char search_path[1024]; - -#if defined(_EGL_OS_UNIX) || defined(_EGL_OS_WINDOWS) - if (search_path[0] == '\0') { - char *buf = search_path; - size_t len = sizeof(search_path); - EGLBoolean use_env; - char dir_sep; - int ret; - -#if defined(_EGL_OS_UNIX) - use_env = (geteuid() == getuid() && getegid() == getgid()); - dir_sep = '/'; -#else - use_env = EGL_TRUE; - dir_sep = '\\'; -#endif - - if (use_env) { - char *p; - - /* extract the dirname from EGL_DRIVER */ - p = getenv("EGL_DRIVER"); - if (p && strchr(p, dir_sep)) { - ret = _eglsnprintf(buf, len, "%s", p); - if (ret > 0 && ret < len) { - p = strrchr(buf, dir_sep); - *p++ = ':'; - - len -= p - buf; - buf = p; - } - } - - /* append EGL_DRIVERS_PATH */ - p = getenv("EGL_DRIVERS_PATH"); - if (p) { - ret = _eglsnprintf(buf, len, "%s:", p); - if (ret > 0 && ret < len) { - buf += ret; - len -= ret; - } - } - } - else { - _eglLog(_EGL_DEBUG, - "ignore EGL_DRIVERS_PATH for setuid/setgid binaries"); - } - - ret = _eglsnprintf(buf, len, "%s", _EGL_DRIVER_SEARCH_DIR); - if (ret < 0 || ret >= len) - search_path[0] = '\0'; - - _eglLog(_EGL_DEBUG, "EGL search path is %s", search_path); - } -#endif /* defined(_EGL_OS_UNIX) || defined(_EGL_OS_WINDOWS) */ - - return search_path; -} - - -/** * Add the user driver to the module array. * * The user driver is specified by EGL_DRIVER. @@ -465,42 +172,15 @@ _eglGetSearchPath(void) static EGLBoolean _eglAddUserDriver(void) { - const char *search_path = _eglGetSearchPath(); char *env; - size_t name_len = 0; env = getenv("EGL_DRIVER"); -#if defined(_EGL_OS_UNIX) - if (env && strchr(env, '/')) { - search_path = ""; - if ((geteuid() != getuid() || getegid() != getgid())) { - _eglLog(_EGL_DEBUG, - "ignore EGL_DRIVER for setuid/setgid binaries"); - env = NULL; - } - } - else if (env) { - char *suffix = strchr(env, '.'); - name_len = (suffix) ? suffix - env : strlen(env); - } -#else - if (env) - name_len = strlen(env); -#endif /* _EGL_OS_UNIX */ - - /* - * Try built-in drivers first if we know the driver name. This makes sure - * we do not load the outdated external driver that is still on the - * filesystem. - */ - if (name_len) { - _EGLModule *mod; + if (env) { EGLint i; for (i = 0; _eglBuiltInDrivers[i].name; i++) { - if (strlen(_eglBuiltInDrivers[i].name) == name_len && - !strncmp(_eglBuiltInDrivers[i].name, env, name_len)) { - mod = _eglAddModule(env); + if (!strcmp(_eglBuiltInDrivers[i].name, env)) { + _EGLModule *mod = _eglAddModule(env); if (mod) mod->BuiltIn = _eglBuiltInDrivers[i].main; @@ -509,13 +189,6 @@ _eglAddUserDriver(void) } } - /* otherwise, treat env as a path */ - if (env) { - _eglPreloadForEach(search_path, _eglLoaderFile, (void *) env); - - return EGL_TRUE; - } - return EGL_FALSE; } @@ -683,18 +356,3 @@ _eglUnloadDrivers(void) _eglModules = NULL; } } - - -/** - * 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); -} diff --git a/src/egl/main/egldriver.h b/src/egl/main/egldriver.h index 11300ce1ee2..1cf6628446b 100644 --- a/src/egl/main/egldriver.h +++ b/src/egl/main/egldriver.h @@ -38,6 +38,11 @@ #include "eglapi.h" #include <stddef.h> + +#ifdef __cplusplus +extern "C" { +#endif + /** * Define an inline driver typecast function. * @@ -87,19 +92,11 @@ struct _egl_driver extern _EGLDriver * -_eglBuiltInDriverGALLIUM(const char *args); - - -extern _EGLDriver * _eglBuiltInDriverDRI2(const char *args); -extern _EGLDriver * -_eglBuiltInDriverGLX(const char *args); - - -extern _EGLDriver * -_eglMain(const char *args); +extern _EGLDriver* +_eglBuiltInDriverHaiku(const char* args); extern _EGLDriver * @@ -124,4 +121,9 @@ _eglSearchPathForEach(EGLBoolean (*callback)(const char *, size_t, void *), void *callback_data); +#ifdef __cplusplus +} +#endif + + #endif /* EGLDRIVER_INCLUDED */ diff --git a/src/egl/main/eglfallbacks.c b/src/egl/main/eglfallbacks.c index 83d775610c5..3c3701f4ae9 100644 --- a/src/egl/main/eglfallbacks.c +++ b/src/egl/main/eglfallbacks.c @@ -32,8 +32,6 @@ #include "eglconfig.h" #include "eglcontext.h" #include "eglsurface.h" -#include "eglscreen.h" -#include "eglmode.h" #include "eglsync.h" @@ -85,22 +83,6 @@ _eglInitDriverFallbacks(_EGLDriver *drv) drv->API.WaitNative = (WaitNative_t) _eglReturnFalse; drv->API.GetProcAddress = (GetProcAddress_t) _eglReturnFalse; -#ifdef EGL_MESA_screen_surface - drv->API.CopyContextMESA = (CopyContextMESA_t) _eglReturnFalse; - drv->API.CreateScreenSurfaceMESA = - (CreateScreenSurfaceMESA_t) _eglReturnFalse; - drv->API.ShowScreenSurfaceMESA = (ShowScreenSurfaceMESA_t) _eglReturnFalse; - drv->API.ChooseModeMESA = _eglChooseModeMESA; - drv->API.GetModesMESA = _eglGetModesMESA; - drv->API.GetModeAttribMESA = _eglGetModeAttribMESA; - drv->API.GetScreensMESA = _eglGetScreensMESA; - drv->API.ScreenPositionMESA = _eglScreenPositionMESA; - drv->API.QueryScreenMESA = _eglQueryScreenMESA; - drv->API.QueryScreenSurfaceMESA = _eglQueryScreenSurfaceMESA; - drv->API.QueryScreenModeMESA = _eglQueryScreenModeMESA; - drv->API.QueryModeStringMESA = _eglQueryModeStringMESA; -#endif /* EGL_MESA_screen_surface */ - drv->API.CreateImageKHR = NULL; drv->API.DestroyImageKHR = NULL; @@ -109,7 +91,7 @@ _eglInitDriverFallbacks(_EGLDriver *drv) drv->API.ClientWaitSyncKHR = NULL; drv->API.WaitSyncKHR = NULL; drv->API.SignalSyncKHR = NULL; - drv->API.GetSyncAttribKHR = _eglGetSyncAttribKHR; + drv->API.GetSyncAttrib = _eglGetSyncAttrib; #ifdef EGL_MESA_drm_image drv->API.CreateDRMImageMESA = NULL; @@ -120,7 +102,7 @@ _eglInitDriverFallbacks(_EGLDriver *drv) drv->API.SwapBuffersRegionNOK = NULL; #endif -#ifdef EGL_MESA_dma_buf_image_export +#ifdef EGL_MESA_image_dma_buf_export drv->API.ExportDMABUFImageQueryMESA = NULL; drv->API.ExportDMABUFImageMESA = NULL; #endif diff --git a/src/egl/main/eglglobals.c b/src/egl/main/eglglobals.c index 129bf29f1e9..884cff0c36b 100644 --- a/src/egl/main/eglglobals.c +++ b/src/egl/main/eglglobals.c @@ -50,16 +50,6 @@ struct _egl_global _eglGlobal = _eglFiniDisplay }, - /* ClientExtensions */ - { - true, /* EGL_EXT_client_extensions */ - true, /* EGL_EXT_platform_base */ - true, /* EGL_EXT_platform_x11 */ - true, /* EGL_EXT_platform_wayland */ - true, /* EGL_MESA_platform_gbm */ - true, /* EGL_KHR_client_get_all_proc_addresses */ - }, - /* ClientExtensionsString */ "EGL_EXT_client_extensions" " EGL_EXT_platform_base" diff --git a/src/egl/main/eglglobals.h b/src/egl/main/eglglobals.h index 04b96099a3b..ae1b75b4545 100644 --- a/src/egl/main/eglglobals.h +++ b/src/egl/main/eglglobals.h @@ -50,15 +50,6 @@ struct _egl_global EGLint NumAtExitCalls; void (*AtExitCalls[10])(void); - struct _egl_client_extensions { - bool EXT_client_extensions; - bool EXT_platform_base; - bool EXT_platform_x11; - bool EXT_platform_wayland; - bool MESA_platform_gbm; - bool KHR_get_all_proc_addresses; - } ClientExtensions; - const char *ClientExtensionString; }; diff --git a/src/egl/main/eglimage.h b/src/egl/main/eglimage.h index 50a87a18890..0dd5e120ad7 100644 --- a/src/egl/main/eglimage.h +++ b/src/egl/main/eglimage.h @@ -35,6 +35,11 @@ #include "egltypedefs.h" #include "egldisplay.h" + +#ifdef __cplusplus +extern "C" { +#endif + struct _egl_image_attrib_int { EGLint Value; @@ -116,11 +121,11 @@ _eglPutImage(_EGLImage *img) * Link an image to its display and return the handle of the link. * The handle can be passed to client directly. */ -static inline EGLImageKHR +static inline EGLImage _eglLinkImage(_EGLImage *img) { _eglLinkResource(&img->Resource, _EGL_RESOURCE_IMAGE); - return (EGLImageKHR) img; + return (EGLImage) img; } @@ -140,7 +145,7 @@ _eglUnlinkImage(_EGLImage *img) * Return NULL if the handle has no corresponding linked image. */ static inline _EGLImage * -_eglLookupImage(EGLImageKHR image, _EGLDisplay *dpy) +_eglLookupImage(EGLImage image, _EGLDisplay *dpy) { _EGLImage *img = (_EGLImage *) image; if (!dpy || !_eglCheckResource((void *) img, _EGL_RESOURCE_IMAGE, dpy)) @@ -152,13 +157,17 @@ _eglLookupImage(EGLImageKHR image, _EGLDisplay *dpy) /** * Return the handle of a linked image, or EGL_NO_IMAGE_KHR. */ -static inline EGLImageKHR +static inline EGLImage _eglGetImageHandle(_EGLImage *img) { _EGLResource *res = (_EGLResource *) img; return (res && _eglIsResourceLinked(res)) ? - (EGLImageKHR) img : EGL_NO_IMAGE_KHR; + (EGLImage) img : EGL_NO_IMAGE_KHR; } +#ifdef __cplusplus +} +#endif + #endif /* EGLIMAGE_INCLUDED */ diff --git a/src/egl/main/egllog.h b/src/egl/main/egllog.h index 12a477ee054..cf58525005e 100644 --- a/src/egl/main/egllog.h +++ b/src/egl/main/egllog.h @@ -34,6 +34,10 @@ #include "egltypedefs.h" +#ifdef __cplusplus +extern "C" { +#endif + #define _EGL_FATAL 0 /* unrecoverable error */ #define _EGL_WARNING 1 /* recoverable error/problem */ #define _EGL_INFO 2 /* just useful info */ @@ -55,4 +59,8 @@ extern void _eglLog(EGLint level, const char *fmtStr, ...); +#ifdef __cplusplus +} +#endif + #endif /* EGLLOG_INCLUDED */ diff --git a/src/egl/main/eglmode.c b/src/egl/main/eglmode.c deleted file mode 100644 index d248ea45886..00000000000 --- a/src/egl/main/eglmode.c +++ /dev/null @@ -1,357 +0,0 @@ -/************************************************************************** - * - * Copyright 2008 VMware, Inc. - * Copyright 2009-2010 Chia-I Wu <[email protected]> - * Copyright 2010 LunarG, Inc. - * 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, sub license, 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 (including the - * next paragraph) 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. - * - **************************************************************************/ - - -#include <assert.h> -#include <stdlib.h> -#include <string.h> - -#include "egldisplay.h" -#include "eglmode.h" -#include "eglcurrent.h" -#include "eglscreen.h" - - -#ifdef EGL_MESA_screen_surface - - -#define MIN2(A, B) (((A) < (B)) ? (A) : (B)) - - -/** - * Given an EGLModeMESA handle, return the corresponding _EGLMode object - * or null if non-existant. - */ -_EGLMode * -_eglLookupMode(EGLModeMESA mode, _EGLDisplay *disp) -{ - EGLint scrnum; - - if (!disp || !disp->Screens) - return NULL; - - /* loop over all screens on the display */ - for (scrnum = 0; scrnum < disp->Screens->Size; scrnum++) { - const _EGLScreen *scrn = disp->Screens->Elements[scrnum]; - EGLint idx; - - /* - * the mode ids of a screen ranges from scrn->Handle to scrn->Handle + - * scrn->NumModes - */ - if (mode >= scrn->Handle && - mode < scrn->Handle + _EGL_SCREEN_MAX_MODES) { - idx = mode - scrn->Handle; - - assert(idx < scrn->NumModes && scrn->Modes[idx].Handle == mode); - - return &scrn->Modes[idx]; - } - } - - return NULL; -} - - -/** - * Parse the attrib_list to fill in the fields of the given _eglMode - * Return EGL_FALSE if any errors, EGL_TRUE otherwise. - */ -static EGLBoolean -_eglParseModeAttribs(_EGLMode *mode, const EGLint *attrib_list) -{ - EGLint i; - - /* init all attribs to EGL_DONT_CARE */ - mode->Handle = EGL_DONT_CARE; - mode->Width = EGL_DONT_CARE; - mode->Height = EGL_DONT_CARE; - mode->RefreshRate = EGL_DONT_CARE; - mode->Optimal = EGL_DONT_CARE; - mode->Interlaced = EGL_DONT_CARE; - mode->Name = NULL; - - for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) { - switch (attrib_list[i]) { - case EGL_MODE_ID_MESA: - mode->Handle = attrib_list[++i]; - if (mode->Handle <= 0) { - _eglError(EGL_BAD_PARAMETER, "eglChooseModeMESA(handle)"); - return EGL_FALSE; - } - break; - case EGL_WIDTH: - mode->Width = attrib_list[++i]; - if (mode->Width <= 0) { - _eglError(EGL_BAD_PARAMETER, "eglChooseModeMESA(width)"); - return EGL_FALSE; - } - break; - case EGL_HEIGHT: - mode->Height = attrib_list[++i]; - if (mode->Height <= 0) { - _eglError(EGL_BAD_PARAMETER, "eglChooseModeMESA(height)"); - return EGL_FALSE; - } - break; - case EGL_REFRESH_RATE_MESA: - mode->RefreshRate = attrib_list[++i]; - if (mode->RefreshRate <= 0) { - _eglError(EGL_BAD_PARAMETER, "eglChooseModeMESA(refresh rate)"); - return EGL_FALSE; - } - break; - case EGL_INTERLACED_MESA: - mode->Interlaced = attrib_list[++i]; - if (mode->Interlaced != EGL_TRUE && mode->Interlaced != EGL_FALSE) { - _eglError(EGL_BAD_PARAMETER, "eglChooseModeMESA(interlaced)"); - return EGL_FALSE; - } - break; - case EGL_OPTIMAL_MESA: - mode->Optimal = attrib_list[++i]; - if (mode->Optimal != EGL_TRUE && mode->Optimal != EGL_FALSE) { - _eglError(EGL_BAD_PARAMETER, "eglChooseModeMESA(optimal)"); - return EGL_FALSE; - } - break; - default: - _eglError(EGL_BAD_ATTRIBUTE, "eglChooseModeMESA"); - return EGL_FALSE; - } - } - return EGL_TRUE; -} - - -/** - * Determine if the candidate mode's attributes are at least as good - * as the minimal mode's. - * \return EGL_TRUE if qualifies, EGL_FALSE otherwise - */ -static EGLBoolean -_eglModeQualifies(const _EGLMode *c, const _EGLMode *min) -{ - if (min->Handle != EGL_DONT_CARE && c->Handle != min->Handle) - return EGL_FALSE; - if (min->Width != EGL_DONT_CARE && c->Width < min->Width) - return EGL_FALSE; - if (min->Height != EGL_DONT_CARE && c->Height < min->Height) - return EGL_FALSE; - if (min->RefreshRate != EGL_DONT_CARE && c->RefreshRate < min->RefreshRate) - return EGL_FALSE; - if (min->Optimal != EGL_DONT_CARE && c->Optimal != min->Optimal) - return EGL_FALSE; - if (min->Interlaced != EGL_DONT_CARE && c->Interlaced != min->Interlaced) - return EGL_FALSE; - - return EGL_TRUE; -} - - -/** - * Return value of given mode attribute, or -1 if bad attrib. - */ -static EGLint -getModeAttrib(const _EGLMode *m, EGLint attrib) -{ - switch (attrib) { - case EGL_MODE_ID_MESA: - return m->Handle; - case EGL_WIDTH: - return m->Width; - case EGL_HEIGHT: - return m->Height; - case EGL_REFRESH_RATE_MESA: - return m->RefreshRate; - case EGL_OPTIMAL_MESA: - return m->Optimal; - case EGL_INTERLACED_MESA: - return m->Interlaced; - default: - return -1; - } -} - - -#define SMALLER 1 -#define LARGER 2 - -struct sort_info { - EGLint Attrib; - EGLint Order; /* SMALLER or LARGER */ -}; - -/* the order of these entries is the priority */ -static struct sort_info SortInfo[] = { - { EGL_OPTIMAL_MESA, LARGER }, - { EGL_INTERLACED_MESA, SMALLER }, - { EGL_WIDTH, LARGER }, - { EGL_HEIGHT, LARGER }, - { EGL_REFRESH_RATE_MESA, LARGER }, - { EGL_MODE_ID_MESA, SMALLER }, - { 0, 0 } -}; - - -/** - * Compare modes 'a' and 'b' and return -1 if a belongs before b, or 1 if a - * belongs after b, or 0 if they're equal. - * Used by qsort(). - */ -static int -_eglCompareModes(const void *a, const void *b) -{ - const _EGLMode *aMode = *((const _EGLMode **) a); - const _EGLMode *bMode = *((const _EGLMode **) b); - EGLint i; - - for (i = 0; SortInfo[i].Attrib; i++) { - const EGLint aVal = getModeAttrib(aMode, SortInfo[i].Attrib); - const EGLint bVal = getModeAttrib(bMode, SortInfo[i].Attrib); - if (aVal == bVal) { - /* a tie */ - continue; - } - else if (SortInfo[i].Order == SMALLER) { - return (aVal < bVal) ? -1 : 1; - } - else if (SortInfo[i].Order == LARGER) { - return (aVal > bVal) ? -1 : 1; - } - } - - /* all attributes identical */ - return 0; -} - - -/** - * Search for EGLModes which match the given attribute list. - * Called via eglChooseModeMESA API function. - */ -EGLBoolean -_eglChooseModeMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn, - const EGLint *attrib_list, EGLModeMESA *modes, - EGLint modes_size, EGLint *num_modes) -{ - _EGLMode **modeList, min; - EGLint i, count; - - if (!_eglParseModeAttribs(&min, attrib_list)) { - /* error code will have been recorded */ - return EGL_FALSE; - } - - /* allocate array of mode pointers */ - modeList = malloc(modes_size * sizeof(_EGLMode *)); - if (!modeList) { - _eglError(EGL_BAD_MODE_MESA, "eglChooseModeMESA(out of memory)"); - return EGL_FALSE; - } - - /* make array of pointers to qualifying modes */ - for (i = count = 0; i < scrn->NumModes && count < modes_size; i++) { - if (_eglModeQualifies(scrn->Modes + i, &min)) { - modeList[count++] = scrn->Modes + i; - } - } - - /* sort array of pointers */ - qsort(modeList, count, sizeof(_EGLMode *), _eglCompareModes); - - /* copy mode handles to output array */ - for (i = 0; i < count; i++) { - modes[i] = modeList[i]->Handle; - } - - free(modeList); - - *num_modes = count; - - return EGL_TRUE; -} - - - -/** - * Return all possible modes for the given screen. No sorting of results. - * Called via eglGetModesMESA() API function. - */ -EGLBoolean -_eglGetModesMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn, - EGLModeMESA *modes, EGLint modes_size, EGLint *num_modes) -{ - if (modes) { - EGLint i; - *num_modes = MIN2(scrn->NumModes, modes_size); - for (i = 0; i < *num_modes; i++) { - modes[i] = scrn->Modes[i].Handle; - } - } - else { - /* just return total number of supported modes */ - *num_modes = scrn->NumModes; - } - - return EGL_TRUE; -} - - -/** - * Query an attribute of a mode. - */ -EGLBoolean -_eglGetModeAttribMESA(_EGLDriver *drv, _EGLDisplay *dpy, - _EGLMode *m, EGLint attribute, EGLint *value) -{ - EGLint v; - - v = getModeAttrib(m, attribute); - if (v < 0) { - _eglError(EGL_BAD_ATTRIBUTE, "eglGetModeAttribMESA"); - return EGL_FALSE; - } - *value = v; - return EGL_TRUE; -} - - -/** - * Return human-readable string for given mode. - * This is the default function called by eglQueryModeStringMESA(). - */ -const char * -_eglQueryModeStringMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLMode *m) -{ - return m->Name; -} - - -#endif /* EGL_MESA_screen_surface */ diff --git a/src/egl/main/eglmode.h b/src/egl/main/eglmode.h deleted file mode 100644 index 664074fedee..00000000000 --- a/src/egl/main/eglmode.h +++ /dev/null @@ -1,88 +0,0 @@ -/************************************************************************** - * - * Copyright 2008 VMware, Inc. - * Copyright 2009-2010 Chia-I Wu <[email protected]> - * Copyright 2010 LunarG, Inc. - * 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, sub license, 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 (including the - * next paragraph) 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. - * - **************************************************************************/ - - -#ifndef EGLMODE_INCLUDED -#define EGLMODE_INCLUDED - -#include "egltypedefs.h" - - -#ifdef EGL_MESA_screen_surface - - -#define EGL_NO_MODE_MESA 0 - - -/** - * Data structure which corresponds to an EGLModeMESA. - */ -struct _egl_mode -{ - EGLModeMESA Handle; /* the public/opaque handle which names this mode */ - EGLint Width, Height; /* size in pixels */ - EGLint RefreshRate; /* rate * 1000.0 */ - EGLint Optimal; - EGLint Interlaced; - const char *Name; - - /* Other possible attributes */ - /* interlaced */ - /* external sync */ -}; - - -extern _EGLMode * -_eglLookupMode(EGLModeMESA mode, _EGLDisplay *dpy); - - -extern EGLBoolean -_eglChooseModeMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn, - const EGLint *attrib_list, EGLModeMESA *modes, - EGLint modes_size, EGLint *num_modes); - - -extern EGLBoolean -_eglGetModesMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn, - EGLModeMESA *modes, EGLint modes_size, EGLint *num_modes); - - -extern EGLBoolean -_eglGetModeAttribMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLMode *m, - EGLint attribute, EGLint *value); - - -extern const char * -_eglQueryModeStringMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLMode *m); - - -#endif /* EGL_MESA_screen_surface */ - - -#endif /* EGLMODE_INCLUDED */ diff --git a/src/egl/main/eglscreen.c b/src/egl/main/eglscreen.c deleted file mode 100644 index 42ac621fcd9..00000000000 --- a/src/egl/main/eglscreen.c +++ /dev/null @@ -1,235 +0,0 @@ -/************************************************************************** - * - * Copyright 2008 VMware, Inc. - * Copyright 2009-2010 Chia-I Wu <[email protected]> - * Copyright 2010 LunarG, Inc. - * 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, sub license, 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 (including the - * next paragraph) 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. - * - **************************************************************************/ - - -/* - * Ideas for screen management extension to EGL. - * - * Each EGLDisplay has one or more screens (CRTs, Flat Panels, etc). - * The screens' handles can be obtained with eglGetScreensMESA(). - * - * A new kind of EGLSurface is possible- one which can be directly scanned - * out on a screen. Such a surface is created with eglCreateScreenSurface(). - * - * To actually display a screen surface on a screen, the eglShowSurface() - * function is called. - */ - -#include <assert.h> -#include <stdlib.h> -#include <string.h> -#include "c11/threads.h" - -#include "egldisplay.h" -#include "eglcurrent.h" -#include "eglmode.h" -#include "eglsurface.h" -#include "eglscreen.h" - - -#ifdef EGL_MESA_screen_surface - - -/* ugh, no atomic op? */ -static mtx_t _eglNextScreenHandleMutex = _MTX_INITIALIZER_NP; -static EGLScreenMESA _eglNextScreenHandle = 1; - - -/** - * Return a new screen handle/ID. - * NOTE: we never reuse these! - */ -static EGLScreenMESA -_eglAllocScreenHandle(void) -{ - EGLScreenMESA s; - - mtx_lock(&_eglNextScreenHandleMutex); - s = _eglNextScreenHandle; - _eglNextScreenHandle += _EGL_SCREEN_MAX_MODES; - mtx_unlock(&_eglNextScreenHandleMutex); - - return s; -} - - -/** - * Initialize an _EGLScreen object to default values. - */ -void -_eglInitScreen(_EGLScreen *screen, _EGLDisplay *dpy, EGLint num_modes) -{ - memset(screen, 0, sizeof(_EGLScreen)); - - screen->Display = dpy; - screen->NumModes = num_modes; - screen->StepX = 1; - screen->StepY = 1; - - if (num_modes > _EGL_SCREEN_MAX_MODES) - num_modes = _EGL_SCREEN_MAX_MODES; - screen->Modes = calloc(num_modes, sizeof(*screen->Modes)); - screen->NumModes = (screen->Modes) ? num_modes : 0; -} - - -/** - * Link a screen to its display and return the handle of the link. - * The handle can be passed to client directly. - */ -EGLScreenMESA -_eglLinkScreen(_EGLScreen *screen) -{ - _EGLDisplay *display; - EGLint i; - - assert(screen && screen->Display); - display = screen->Display; - - if (!display->Screens) { - display->Screens = _eglCreateArray("Screen", 4); - if (!display->Screens) - return (EGLScreenMESA) 0; - } - - screen->Handle = _eglAllocScreenHandle(); - for (i = 0; i < screen->NumModes; i++) - screen->Modes[i].Handle = screen->Handle + i; - - _eglAppendArray(display->Screens, (void *) screen); - - return screen->Handle; -} - - -/** - * Lookup a handle to find the linked config. - * Return NULL if the handle has no corresponding linked config. - */ -_EGLScreen * -_eglLookupScreen(EGLScreenMESA screen, _EGLDisplay *display) -{ - EGLint i; - - if (!display || !display->Screens) - return NULL; - - for (i = 0; i < display->Screens->Size; i++) { - _EGLScreen *scr = (_EGLScreen *) display->Screens->Elements[i]; - if (scr->Handle == screen) { - assert(scr->Display == display); - return scr; - } - } - return NULL; -} - - -static EGLBoolean -_eglFlattenScreen(void *elem, void *buffer) -{ - _EGLScreen *scr = (_EGLScreen *) elem; - EGLScreenMESA *handle = (EGLScreenMESA *) buffer; - *handle = _eglGetScreenHandle(scr); - return EGL_TRUE; -} - - -EGLBoolean -_eglGetScreensMESA(_EGLDriver *drv, _EGLDisplay *display, EGLScreenMESA *screens, - EGLint max_screens, EGLint *num_screens) -{ - *num_screens = _eglFlattenArray(display->Screens, (void *) screens, - sizeof(screens[0]), max_screens, _eglFlattenScreen); - - return EGL_TRUE; -} - - -/** - * Set a screen's surface origin. - */ -EGLBoolean -_eglScreenPositionMESA(_EGLDriver *drv, _EGLDisplay *dpy, - _EGLScreen *scrn, EGLint x, EGLint y) -{ - scrn->OriginX = x; - scrn->OriginY = y; - - return EGL_TRUE; -} - - -/** - * Query a screen's current surface. - */ -EGLBoolean -_eglQueryScreenSurfaceMESA(_EGLDriver *drv, _EGLDisplay *dpy, - _EGLScreen *scrn, _EGLSurface **surf) -{ - *surf = scrn->CurrentSurface; - return EGL_TRUE; -} - - -/** - * Query a screen's current mode. - */ -EGLBoolean -_eglQueryScreenModeMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn, - _EGLMode **m) -{ - *m = scrn->CurrentMode; - return EGL_TRUE; -} - - -EGLBoolean -_eglQueryScreenMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn, - EGLint attribute, EGLint *value) -{ - switch (attribute) { - case EGL_SCREEN_POSITION_MESA: - value[0] = scrn->OriginX; - value[1] = scrn->OriginY; - break; - case EGL_SCREEN_POSITION_GRANULARITY_MESA: - value[0] = scrn->StepX; - value[1] = scrn->StepY; - break; - default: - _eglError(EGL_BAD_ATTRIBUTE, "eglQueryScreenMESA"); - return EGL_FALSE; - } - - return EGL_TRUE; -} - - -#endif /* EGL_MESA_screen_surface */ diff --git a/src/egl/main/eglscreen.h b/src/egl/main/eglscreen.h deleted file mode 100644 index c554e1d5812..00000000000 --- a/src/egl/main/eglscreen.h +++ /dev/null @@ -1,117 +0,0 @@ -/************************************************************************** - * - * Copyright 2008 VMware, Inc. - * Copyright 2009-2010 Chia-I Wu <[email protected]> - * Copyright 2010 LunarG, Inc. - * 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, sub license, 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 (including the - * next paragraph) 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. - * - **************************************************************************/ - - -#ifndef EGLSCREEN_INCLUDED -#define EGLSCREEN_INCLUDED - -#include "c99_compat.h" - -#include "egltypedefs.h" - - -#ifdef EGL_MESA_screen_surface - - -#define _EGL_SCREEN_MAX_MODES 16 - - -/** - * Per-screen information. - * Note that an EGL screen doesn't have a size. A screen may be set to - * one of several display modes (width/height/scanrate). The screen - * then displays a drawing surface. The drawing surface must be at least - * as large as the display mode's resolution. If it's larger, the - * OriginX and OriginY fields control what part of the surface is visible - * on the screen. - */ -struct _egl_screen -{ - _EGLDisplay *Display; - - EGLScreenMESA Handle; /* The public/opaque handle which names this object */ - - _EGLMode *CurrentMode; - _EGLSurface *CurrentSurface; - - EGLint OriginX, OriginY; /**< Origin of scan-out region w.r.t. surface */ - EGLint StepX, StepY; /**< Screen position/origin granularity */ - - EGLint NumModes; - _EGLMode *Modes; /**< array [NumModes] */ -}; - - -extern void -_eglInitScreen(_EGLScreen *screen, _EGLDisplay *dpy, EGLint num_modes); - - -extern EGLScreenMESA -_eglLinkScreen(_EGLScreen *screen); - - -extern _EGLScreen * -_eglLookupScreen(EGLScreenMESA screen, _EGLDisplay *dpy); - - -/** - * Return the handle of a linked screen. - */ -static inline EGLScreenMESA -_eglGetScreenHandle(_EGLScreen *screen) -{ - return (screen) ? screen->Handle : (EGLScreenMESA) 0; -} - - -extern EGLBoolean -_eglGetScreensMESA(_EGLDriver *drv, _EGLDisplay *dpy, EGLScreenMESA *screens, EGLint max_screens, EGLint *num_screens); - - -extern EGLBoolean -_eglScreenPositionMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn, EGLint x, EGLint y); - - -extern EGLBoolean -_eglQueryScreenSurfaceMESA(_EGLDriver *drv, _EGLDisplay *dpy, - _EGLScreen *scrn, _EGLSurface **surface); - - -extern EGLBoolean -_eglQueryScreenModeMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn, _EGLMode **m); - - -extern EGLBoolean -_eglQueryScreenMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn, EGLint attribute, EGLint *value); - - -#endif /* EGL_MESA_screen_surface */ - - -#endif /* EGLSCREEN_INCLUDED */ diff --git a/src/egl/main/eglsurface.c b/src/egl/main/eglsurface.c index e2cb73b7e91..76c60e940dc 100644 --- a/src/egl/main/eglsurface.c +++ b/src/egl/main/eglsurface.c @@ -61,50 +61,6 @@ _eglClampSwapInterval(_EGLSurface *surf, EGLint interval) } -#ifdef EGL_MESA_screen_surface -static EGLint -_eglParseScreenSurfaceAttribList(_EGLSurface *surf, const EGLint *attrib_list) -{ - EGLint i, err = EGL_SUCCESS; - - if (!attrib_list) - return EGL_SUCCESS; - - for (i = 0; attrib_list[i] != EGL_NONE; i++) { - EGLint attr = attrib_list[i++]; - EGLint val = attrib_list[i]; - - switch (attr) { - case EGL_WIDTH: - if (val < 0) { - err = EGL_BAD_PARAMETER; - break; - } - surf->Width = val; - break; - case EGL_HEIGHT: - if (val < 0) { - err = EGL_BAD_PARAMETER; - break; - } - surf->Height = val; - break; - default: - err = EGL_BAD_ATTRIBUTE; - break; - } - - if (err != EGL_SUCCESS) { - _eglLog(_EGL_WARNING, "bad surface attribute 0x%04x", attr); - break; - } - } - - return err; -} -#endif /* EGL_MESA_screen_surface */ - - /** * Parse the list of surface attributes and return the proper error code. */ @@ -119,11 +75,6 @@ _eglParseSurfaceAttribList(_EGLSurface *surf, const EGLint *attrib_list) if (!attrib_list) return EGL_SUCCESS; -#ifdef EGL_MESA_screen_surface - if (type == EGL_SCREEN_BIT_MESA) - return _eglParseScreenSurfaceAttribList(surf, attrib_list); -#endif - if (dpy->Extensions.NOK_texture_from_pixmap) texture_type |= EGL_PIXMAP_BIT; @@ -297,12 +248,6 @@ _eglInitSurface(_EGLSurface *surf, _EGLDisplay *dpy, EGLint type, case EGL_PBUFFER_BIT: func = "eglCreatePBufferSurface"; break; -#ifdef EGL_MESA_screen_surface - case EGL_SCREEN_BIT_MESA: - func = "eglCreateScreenSurface"; - renderBuffer = EGL_SINGLE_BUFFER; /* XXX correct? */ - break; -#endif default: _eglLog(_EGL_WARNING, "Bad type in _eglInitSurface"); return EGL_FALSE; diff --git a/src/egl/main/eglsurface.h b/src/egl/main/eglsurface.h index 438e27cebc8..74c429a9628 100644 --- a/src/egl/main/eglsurface.h +++ b/src/egl/main/eglsurface.h @@ -37,6 +37,10 @@ #include "egldisplay.h" +#ifdef __cplusplus +extern "C" { +#endif + /** * "Base" class for device driver surfaces. */ @@ -174,4 +178,8 @@ _eglGetSurfaceHandle(_EGLSurface *surf) } +#ifdef __cplusplus +} +#endif + #endif /* EGLSURFACE_INCLUDED */ diff --git a/src/egl/main/eglsync.c b/src/egl/main/eglsync.c index 8b8ab16b0d2..3019e6e9333 100644 --- a/src/egl/main/eglsync.c +++ b/src/egl/main/eglsync.c @@ -67,7 +67,7 @@ _eglParseSyncAttribList(_EGLSync *sync, const EGLint *attrib_list) static EGLint -_eglParseSyncAttribList64(_EGLSync *sync, const EGLAttribKHR *attrib_list) +_eglParseSyncAttribList64(_EGLSync *sync, const EGLAttrib *attrib_list) { EGLint i, err = EGL_SUCCESS; @@ -103,7 +103,7 @@ _eglParseSyncAttribList64(_EGLSync *sync, const EGLAttribKHR *attrib_list) EGLBoolean _eglInitSync(_EGLSync *sync, _EGLDisplay *dpy, EGLenum type, - const EGLint *attrib_list, const EGLAttribKHR *attrib_list64) + const EGLint *attrib_list, const EGLAttrib *attrib_list64) { EGLint err; @@ -141,8 +141,8 @@ _eglInitSync(_EGLSync *sync, _EGLDisplay *dpy, EGLenum type, EGLBoolean -_eglGetSyncAttribKHR(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync, - EGLint attribute, EGLint *value) +_eglGetSyncAttrib(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync, + EGLint attribute, EGLAttrib *value) { if (!value) return _eglError(EGL_BAD_PARAMETER, "eglGetSyncAttribKHR"); diff --git a/src/egl/main/eglsync.h b/src/egl/main/eglsync.h index 1d2eb11a7a0..9b2aac8828b 100644 --- a/src/egl/main/eglsync.h +++ b/src/egl/main/eglsync.h @@ -47,18 +47,18 @@ struct _egl_sync EGLenum Type; EGLenum SyncStatus; EGLenum SyncCondition; - EGLAttribKHR CLEvent; + EGLAttrib CLEvent; }; extern EGLBoolean _eglInitSync(_EGLSync *sync, _EGLDisplay *dpy, EGLenum type, - const EGLint *attrib_list, const EGLAttribKHR *attrib_list64); + const EGLint *attrib_list, const EGLAttrib *attrib_list64); extern EGLBoolean -_eglGetSyncAttribKHR(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync, - EGLint attribute, EGLint *value); +_eglGetSyncAttrib(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync, + EGLint attribute, EGLAttrib *value); /** @@ -87,11 +87,11 @@ _eglPutSync(_EGLSync *sync) * Link a sync to its display and return the handle of the link. * The handle can be passed to client directly. */ -static inline EGLSyncKHR +static inline EGLSync _eglLinkSync(_EGLSync *sync) { _eglLinkResource(&sync->Resource, _EGL_RESOURCE_SYNC); - return (EGLSyncKHR) sync; + return (EGLSync) sync; } @@ -110,7 +110,7 @@ _eglUnlinkSync(_EGLSync *sync) * Return NULL if the handle has no corresponding linked sync. */ static inline _EGLSync * -_eglLookupSync(EGLSyncKHR handle, _EGLDisplay *dpy) +_eglLookupSync(EGLSync handle, _EGLDisplay *dpy) { _EGLSync *sync = (_EGLSync *) handle; if (!dpy || !_eglCheckResource((void *) sync, _EGL_RESOURCE_SYNC, dpy)) @@ -122,12 +122,12 @@ _eglLookupSync(EGLSyncKHR handle, _EGLDisplay *dpy) /** * Return the handle of a linked sync, or EGL_NO_SYNC_KHR. */ -static inline EGLSyncKHR +static inline EGLSync _eglGetSyncHandle(_EGLSync *sync) { _EGLResource *res = (_EGLResource *) sync; return (res && _eglIsResourceLinked(res)) ? - (EGLSyncKHR) sync : EGL_NO_SYNC_KHR; + (EGLSync) sync : EGL_NO_SYNC_KHR; } diff --git a/src/egl/main/egltypedefs.h b/src/egl/main/egltypedefs.h index e90959affae..7facdb47f86 100644 --- a/src/egl/main/egltypedefs.h +++ b/src/egl/main/egltypedefs.h @@ -31,13 +31,16 @@ #ifndef EGLTYPEDEFS_INCLUDED #define EGLTYPEDEFS_INCLUDED -#define EGL_EGLEXT_PROTOTYPES - #include <EGL/egl.h> #include <EGL/eglext.h> #include "eglcompiler.h" + +#ifdef __cplusplus +extern "C" { +#endif + typedef struct _egl_api _EGLAPI; typedef struct _egl_array _EGLArray; @@ -68,4 +71,9 @@ typedef struct _egl_sync _EGLSync; typedef struct _egl_thread_info _EGLThreadInfo; + +#ifdef __cplusplus +} +#endif + #endif /* EGLTYPEDEFS_INCLUDED */ |