summaryrefslogtreecommitdiff
path: root/lib/mesa/src/egl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/mesa/src/egl')
-rw-r--r--lib/mesa/src/egl/Makefile.am12
-rw-r--r--lib/mesa/src/egl/drivers/dri2/egl_dri2.h74
-rw-r--r--lib/mesa/src/egl/drivers/dri2/egl_dri2_fallbacks.h3
-rw-r--r--lib/mesa/src/egl/drivers/dri2/platform_android.c989
-rw-r--r--lib/mesa/src/egl/drivers/dri2/platform_drm.c136
-rw-r--r--lib/mesa/src/egl/drivers/dri2/platform_surfaceless.c248
-rw-r--r--lib/mesa/src/egl/drivers/dri2/platform_wayland.c182
-rw-r--r--lib/mesa/src/egl/drivers/dri2/platform_x11_dri3.c80
-rw-r--r--lib/mesa/src/egl/drivers/haiku/.editorconfig2
-rwxr-xr-xlib/mesa/src/egl/egl-symbols-check2
-rw-r--r--lib/mesa/src/egl/main/eglapi.c765
-rw-r--r--lib/mesa/src/egl/main/eglapi.h290
-rw-r--r--lib/mesa/src/egl/main/eglconfig.c7
-rw-r--r--lib/mesa/src/egl/main/eglcontext.c56
-rw-r--r--lib/mesa/src/egl/main/eglcurrent.c107
-rw-r--r--lib/mesa/src/egl/main/eglcurrent.h73
-rw-r--r--lib/mesa/src/egl/main/egldefines.h5
-rw-r--r--lib/mesa/src/egl/main/egldisplay.c72
-rw-r--r--lib/mesa/src/egl/main/egldisplay.h13
-rw-r--r--lib/mesa/src/egl/main/eglfallbacks.c30
-rw-r--r--lib/mesa/src/egl/main/eglglobals.c17
-rw-r--r--lib/mesa/src/egl/main/eglglobals.h15
-rw-r--r--lib/mesa/src/egl/main/eglsurface.c27
-rw-r--r--lib/mesa/src/egl/main/eglsync.c62
-rw-r--r--lib/mesa/src/egl/main/eglsync.h2
-rw-r--r--lib/mesa/src/egl/wayland/wayland-drm/wayland-drm-protocol.c2
-rw-r--r--lib/mesa/src/egl/wayland/wayland-drm/wayland-drm.c2
-rw-r--r--lib/mesa/src/egl/wayland/wayland-egl/wayland-egl-priv.h9
-rw-r--r--lib/mesa/src/egl/wayland/wayland-egl/wayland-egl.c3
29 files changed, 2628 insertions, 657 deletions
diff --git a/lib/mesa/src/egl/Makefile.am b/lib/mesa/src/egl/Makefile.am
index 6953d44e6..304b0d313 100644
--- a/lib/mesa/src/egl/Makefile.am
+++ b/lib/mesa/src/egl/Makefile.am
@@ -49,7 +49,7 @@ libEGL_la_LDFLAGS = \
dri2_backend_FILES =
dri3_backend_FILES =
-if HAVE_EGL_PLATFORM_X11
+if HAVE_PLATFORM_X11
AM_CFLAGS += -DHAVE_X11_PLATFORM
AM_CFLAGS += $(XCB_DRI2_CFLAGS)
libEGL_la_LIBADD += $(XCB_DRI2_LIBS)
@@ -64,7 +64,7 @@ libEGL_la_LIBADD += $(top_builddir)/src/loader/libloader_dri3_helper.la
endif
endif
-if HAVE_EGL_PLATFORM_WAYLAND
+if HAVE_PLATFORM_WAYLAND
AM_CFLAGS += -DHAVE_WAYLAND_PLATFORM
AM_CFLAGS += $(WAYLAND_CFLAGS)
libEGL_la_LIBADD += $(WAYLAND_LIBS)
@@ -84,6 +84,11 @@ AM_CFLAGS += -DHAVE_SURFACELESS_PLATFORM
dri2_backend_FILES += drivers/dri2/platform_surfaceless.c
endif
+if HAVE_EGL_PLATFORM_ANDROID
+AM_CFLAGS += -DHAVE_ANDROID_PLATFORM
+dri2_backend_FILES += drivers/dri2/platform_android.c
+endif
+
if HAVE_EGL_DRIVER_DRI2
AM_CFLAGS += \
-I$(top_srcdir)/src/loader \
@@ -101,7 +106,7 @@ libEGL_la_SOURCES += \
$(dri3_backend_FILES)
libEGL_la_LIBADD += $(top_builddir)/src/loader/libloader.la
-libEGL_la_LIBADD += $(DLOPEN_LIBS) $(LIBDRM_LIBS)
+libEGL_la_LIBADD += $(DLOPEN_LIBS) $(LIBDRM_LIBS) $(CLOCK_LIB)
endif
include $(top_srcdir)/install-lib-links.mk
@@ -127,6 +132,5 @@ EXTRA_DIST = \
egl-symbols-check \
SConscript \
drivers/haiku \
- docs \
main/egl.def \
main/README.txt
diff --git a/lib/mesa/src/egl/drivers/dri2/egl_dri2.h b/lib/mesa/src/egl/drivers/dri2/egl_dri2.h
index 52ad92b18..0020a5b98 100644
--- a/lib/mesa/src/egl/drivers/dri2/egl_dri2.h
+++ b/lib/mesa/src/egl/drivers/dri2/egl_dri2.h
@@ -80,8 +80,6 @@
#include "eglimage.h"
#include "eglsync.h"
-#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
-
struct wl_buffer;
struct dri2_egl_driver
@@ -143,6 +141,10 @@ struct dri2_egl_display_vtbl {
EGLint (*query_buffer_age)(_EGLDriver *drv, _EGLDisplay *dpy,
_EGLSurface *surf);
+ EGLBoolean (*query_surface)(_EGLDriver *drv, _EGLDisplay *dpy,
+ _EGLSurface *surf, EGLint attribute,
+ EGLint *value);
+
struct wl_buffer* (*create_wayland_buffer_from_image)(
_EGLDriver *drv, _EGLDisplay *dpy, _EGLImage *img);
@@ -174,10 +176,14 @@ struct dri2_egl_display
const __DRI2configQueryExtension *config;
const __DRI2fenceExtension *fence;
const __DRI2rendererQueryExtension *rendererQuery;
+ const __DRI2interopExtension *interop;
int fd;
+ /* dri2_initialize/dri2_terminate increment/decrement this count, so does
+ * dri2_make_current (tracks if there are active contexts/surfaces). */
+ int ref_count;
+
int own_device;
- int swap_available;
int invalidate_available;
int min_swap_interval;
int max_swap_interval;
@@ -186,17 +192,15 @@ struct dri2_egl_display
struct gbm_dri_device *gbm_dri;
#endif
- char *device_name;
char *driver_name;
- __DRIdri2LoaderExtension dri2_loader_extension;
- __DRIswrastLoaderExtension swrast_loader_extension;
- const __DRIextension *extensions[5];
+ const __DRIextension **loader_extensions;
const __DRIextension **driver_extensions;
#ifdef HAVE_X11_PLATFORM
xcb_connection_t *conn;
int screen;
+ int swap_available;
#ifdef HAVE_DRI3
struct loader_dri3_extensions loader_dri3_ext;
#endif
@@ -209,13 +213,14 @@ struct dri2_egl_display
struct wl_drm *wl_drm;
struct wl_shm *wl_shm;
struct wl_event_queue *wl_queue;
- int authenticated;
- int formats;
+ int authenticated;
+ int formats;
uint32_t capabilities;
- int is_render_node;
+ char *device_name;
#endif
- int is_different_gpu;
+ int is_render_node;
+ int is_different_gpu;
};
struct dri2_egl_context
@@ -255,7 +260,7 @@ struct dri2_egl_surface
int dx;
int dy;
struct wl_callback *throttle_callback;
- int format;
+ int format;
#endif
#ifdef HAVE_DRM_PLATFORM
@@ -285,12 +290,17 @@ struct dri2_egl_surface
#ifdef HAVE_ANDROID_PLATFORM
struct ANativeWindow *window;
struct ANativeWindowBuffer *buffer;
+ __DRIimage *dri_image;
/* EGL-owned buffers */
__DRIbuffer *local_buffers[__DRI_BUFFER_COUNT];
#endif
-};
+#if defined(HAVE_SURFACELESS_PLATFORM)
+ __DRIimage *front;
+ unsigned int visual;
+#endif
+};
struct dri2_egl_config
{
@@ -307,6 +317,8 @@ struct dri2_egl_image
struct dri2_egl_sync {
_EGLSync base;
+ mtx_t mutex;
+ cnd_t cond;
int refcount;
void *fence;
};
@@ -349,13 +361,17 @@ dri2_lookup_egl_image(__DRIscreen *screen, void *image, void *data);
struct dri2_egl_config *
dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id,
- EGLint surface_type, const EGLint *attr_list,
- const unsigned int *rgba_masks);
+ EGLint surface_type, const EGLint *attr_list,
+ const unsigned int *rgba_masks);
_EGLImage *
dri2_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp,
- _EGLContext *ctx, EGLenum target,
- EGLClientBuffer buffer, const EGLint *attr_list);
+ _EGLContext *ctx, EGLenum target,
+ EGLClientBuffer buffer, const EGLint *attr_list);
+
+_EGLImage *
+dri2_create_image_dma_buf(_EGLDisplay *disp, _EGLContext *ctx,
+ EGLClientBuffer buffer, const EGLint *attr_list);
EGLBoolean
dri2_initialize_x11(_EGLDriver *drv, _EGLDisplay *disp);
@@ -379,4 +395,28 @@ const __DRIconfig *
dri2_get_dri_config(struct dri2_egl_config *conf, EGLint surface_type,
EGLenum colorspace);
+static inline void
+dri2_set_WL_bind_wayland_display(_EGLDriver *drv, _EGLDisplay *disp)
+{
+#ifdef HAVE_WAYLAND_PLATFORM
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+
+ (void) drv;
+
+ if (dri2_dpy->device_name && dri2_dpy->image) {
+ if (dri2_dpy->image->base.version >= 10 &&
+ dri2_dpy->image->getCapabilities != NULL) {
+ int capabilities;
+
+ capabilities =
+ dri2_dpy->image->getCapabilities(dri2_dpy->dri_screen);
+ disp->Extensions.WL_bind_wayland_display =
+ (capabilities & __DRI_IMAGE_CAP_GLOBAL_NAMES) != 0;
+ } else {
+ disp->Extensions.WL_bind_wayland_display = EGL_TRUE;
+ }
+ }
+#endif
+}
+
#endif /* EGL_DRI2_INCLUDED */
diff --git a/lib/mesa/src/egl/drivers/dri2/egl_dri2_fallbacks.h b/lib/mesa/src/egl/drivers/dri2/egl_dri2_fallbacks.h
index e769af36e..8dad27116 100644
--- a/lib/mesa/src/egl/drivers/dri2/egl_dri2_fallbacks.h
+++ b/lib/mesa/src/egl/drivers/dri2/egl_dri2_fallbacks.h
@@ -66,7 +66,8 @@ dri2_fallback_swap_buffers_with_damage(_EGLDriver *drv, _EGLDisplay *dpy,
_EGLSurface *surf,
const EGLint *rects, EGLint n_rects)
{
- return EGL_FALSE;
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(dpy);
+ return dri2_dpy->vtbl->swap_buffers(drv, dpy, surf);
}
static inline EGLBoolean
diff --git a/lib/mesa/src/egl/drivers/dri2/platform_android.c b/lib/mesa/src/egl/drivers/dri2/platform_android.c
new file mode 100644
index 000000000..cf60f1d6b
--- /dev/null
+++ b/lib/mesa/src/egl/drivers/dri2/platform_android.c
@@ -0,0 +1,989 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2010-2011 Chia-I Wu <olvaffe@gmail.com>
+ * Copyright (C) 2010-2011 LunarG Inc.
+ *
+ * Based on platform_x11, which has
+ *
+ * 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 <errno.h>
+#include <dlfcn.h>
+#include <fcntl.h>
+#include <xf86drm.h>
+
+#if ANDROID_VERSION >= 0x402
+#include <sync/sync.h>
+#endif
+
+#include "loader.h"
+#include "egl_dri2.h"
+#include "egl_dri2_fallbacks.h"
+#include "gralloc_drm.h"
+
+#define ALIGN(val, align) (((val) + (align) - 1) & ~((align) - 1))
+
+static int
+get_format_bpp(int native)
+{
+ int bpp;
+
+ switch (native) {
+ case HAL_PIXEL_FORMAT_RGBA_8888:
+ case HAL_PIXEL_FORMAT_RGBX_8888:
+ case HAL_PIXEL_FORMAT_BGRA_8888:
+ bpp = 4;
+ break;
+ case HAL_PIXEL_FORMAT_RGB_888:
+ bpp = 3;
+ break;
+ case HAL_PIXEL_FORMAT_RGB_565:
+ bpp = 2;
+ break;
+ case HAL_PIXEL_FORMAT_YV12:
+ bpp = 1;
+ break;
+ default:
+ bpp = 0;
+ break;
+ }
+
+ return bpp;
+}
+
+/* createImageFromFds requires fourcc format */
+static int get_fourcc(int native)
+{
+ switch (native) {
+ case HAL_PIXEL_FORMAT_RGB_565: return __DRI_IMAGE_FOURCC_RGB565;
+ case HAL_PIXEL_FORMAT_BGRA_8888: return __DRI_IMAGE_FOURCC_ARGB8888;
+ case HAL_PIXEL_FORMAT_RGBA_8888: return __DRI_IMAGE_FOURCC_ABGR8888;
+ case HAL_PIXEL_FORMAT_RGBX_8888: return __DRI_IMAGE_FOURCC_XBGR8888;
+ case HAL_PIXEL_FORMAT_YV12: return __DRI_IMAGE_FOURCC_YVU420;
+ default:
+ _eglLog(_EGL_WARNING, "unsupported native buffer format 0x%x", native);
+ }
+ return -1;
+}
+
+static int get_format(int format)
+{
+ switch (format) {
+ case HAL_PIXEL_FORMAT_BGRA_8888: return __DRI_IMAGE_FORMAT_ARGB8888;
+ case HAL_PIXEL_FORMAT_RGB_565: return __DRI_IMAGE_FORMAT_RGB565;
+ case HAL_PIXEL_FORMAT_RGBA_8888: return __DRI_IMAGE_FORMAT_ABGR8888;
+ case HAL_PIXEL_FORMAT_RGBX_8888: return __DRI_IMAGE_FORMAT_XBGR8888;
+ case HAL_PIXEL_FORMAT_RGB_888:
+ /* unsupported */
+ default:
+ _eglLog(_EGL_WARNING, "unsupported native buffer format 0x%x", format);
+ }
+ return -1;
+}
+
+static int
+get_native_buffer_fd(struct ANativeWindowBuffer *buf)
+{
+ native_handle_t *handle = (native_handle_t *)buf->handle;
+ /*
+ * Various gralloc implementations exist, but the dma-buf fd tends
+ * to be first. Access it directly to avoid a dependency on specific
+ * gralloc versions.
+ */
+ return (handle && handle->numFds) ? handle->data[0] : -1;
+}
+
+static int
+get_native_buffer_name(struct ANativeWindowBuffer *buf)
+{
+ return gralloc_drm_get_gem_handle(buf->handle);
+}
+
+static EGLBoolean
+droid_window_dequeue_buffer(struct dri2_egl_surface *dri2_surf)
+{
+#if ANDROID_VERSION >= 0x0402
+ int fence_fd;
+
+ if (dri2_surf->window->dequeueBuffer(dri2_surf->window, &dri2_surf->buffer,
+ &fence_fd))
+ return EGL_FALSE;
+
+ /* If access to the buffer is controlled by a sync fence, then block on the
+ * fence.
+ *
+ * It may be more performant to postpone blocking until there is an
+ * immediate need to write to the buffer. But doing so would require adding
+ * hooks to the DRI2 loader.
+ *
+ * From the ANativeWindow::dequeueBuffer documentation:
+ *
+ * The libsync fence file descriptor returned in the int pointed to by
+ * the fenceFd argument will refer to the fence that must signal
+ * before the dequeued buffer may be written to. A value of -1
+ * indicates that the caller may access the buffer immediately without
+ * waiting on a fence. If a valid file descriptor is returned (i.e.
+ * any value except -1) then the caller is responsible for closing the
+ * file descriptor.
+ */
+ if (fence_fd >= 0) {
+ /* From the SYNC_IOC_WAIT documentation in <linux/sync.h>:
+ *
+ * Waits indefinitely if timeout < 0.
+ */
+ int timeout = -1;
+ sync_wait(fence_fd, timeout);
+ close(fence_fd);
+ }
+
+ dri2_surf->buffer->common.incRef(&dri2_surf->buffer->common);
+#else
+ if (dri2_surf->window->dequeueBuffer(dri2_surf->window, &dri2_surf->buffer))
+ return EGL_FALSE;
+
+ dri2_surf->buffer->common.incRef(&dri2_surf->buffer->common);
+ dri2_surf->window->lockBuffer(dri2_surf->window, dri2_surf->buffer);
+#endif
+
+ return EGL_TRUE;
+}
+
+static EGLBoolean
+droid_window_enqueue_buffer(_EGLDisplay *disp, struct dri2_egl_surface *dri2_surf)
+{
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+
+ /* To avoid blocking other EGL calls, release the display mutex before
+ * we enter droid_window_enqueue_buffer() and re-acquire the mutex upon
+ * return.
+ */
+ mtx_unlock(&disp->Mutex);
+
+#if ANDROID_VERSION >= 0x0402
+ /* Queue the buffer without a sync fence. This informs the ANativeWindow
+ * that it may access the buffer immediately.
+ *
+ * From ANativeWindow::dequeueBuffer:
+ *
+ * The fenceFd argument specifies a libsync fence file descriptor for
+ * a fence that must signal before the buffer can be accessed. If
+ * the buffer can be accessed immediately then a value of -1 should
+ * be used. The caller must not use the file descriptor after it
+ * is passed to queueBuffer, and the ANativeWindow implementation
+ * is responsible for closing it.
+ */
+ int fence_fd = -1;
+ dri2_surf->window->queueBuffer(dri2_surf->window, dri2_surf->buffer,
+ fence_fd);
+#else
+ dri2_surf->window->queueBuffer(dri2_surf->window, dri2_surf->buffer);
+#endif
+
+ dri2_surf->buffer->common.decRef(&dri2_surf->buffer->common);
+ dri2_surf->buffer = NULL;
+
+ mtx_lock(&disp->Mutex);
+
+ if (dri2_surf->dri_image) {
+ dri2_dpy->image->destroyImage(dri2_surf->dri_image);
+ dri2_surf->dri_image = NULL;
+ }
+
+ return EGL_TRUE;
+}
+
+static void
+droid_window_cancel_buffer(_EGLDisplay *disp, struct dri2_egl_surface *dri2_surf)
+{
+ /* no cancel buffer? */
+ droid_window_enqueue_buffer(disp, dri2_surf);
+}
+
+static __DRIbuffer *
+droid_alloc_local_buffer(struct dri2_egl_surface *dri2_surf,
+ unsigned int att, unsigned int format)
+{
+ struct dri2_egl_display *dri2_dpy =
+ dri2_egl_display(dri2_surf->base.Resource.Display);
+
+ if (att >= ARRAY_SIZE(dri2_surf->local_buffers))
+ return NULL;
+
+ if (!dri2_surf->local_buffers[att]) {
+ dri2_surf->local_buffers[att] =
+ dri2_dpy->dri2->allocateBuffer(dri2_dpy->dri_screen, att, format,
+ dri2_surf->base.Width, dri2_surf->base.Height);
+ }
+
+ return dri2_surf->local_buffers[att];
+}
+
+static void
+droid_free_local_buffers(struct dri2_egl_surface *dri2_surf)
+{
+ struct dri2_egl_display *dri2_dpy =
+ dri2_egl_display(dri2_surf->base.Resource.Display);
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(dri2_surf->local_buffers); i++) {
+ if (dri2_surf->local_buffers[i]) {
+ dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen,
+ dri2_surf->local_buffers[i]);
+ dri2_surf->local_buffers[i] = NULL;
+ }
+ }
+}
+
+static _EGLSurface *
+droid_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type,
+ _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 dri2_egl_surface *dri2_surf;
+ struct ANativeWindow *window = native_window;
+ const __DRIconfig *config;
+
+ dri2_surf = calloc(1, sizeof *dri2_surf);
+ if (!dri2_surf) {
+ _eglError(EGL_BAD_ALLOC, "droid_create_surface");
+ return NULL;
+ }
+
+ if (!_eglInitSurface(&dri2_surf->base, disp, type, conf, attrib_list))
+ goto cleanup_surface;
+
+ if (type == EGL_WINDOW_BIT) {
+ int format;
+
+ if (!window || window->common.magic != ANDROID_NATIVE_WINDOW_MAGIC) {
+ _eglError(EGL_BAD_NATIVE_WINDOW, "droid_create_surface");
+ goto cleanup_surface;
+ }
+ if (window->query(window, NATIVE_WINDOW_FORMAT, &format)) {
+ _eglError(EGL_BAD_NATIVE_WINDOW, "droid_create_surface");
+ goto cleanup_surface;
+ }
+
+ if (format != dri2_conf->base.NativeVisualID) {
+ _eglLog(_EGL_WARNING, "Native format mismatch: 0x%x != 0x%x",
+ format, dri2_conf->base.NativeVisualID);
+ }
+
+ window->query(window, NATIVE_WINDOW_WIDTH, &dri2_surf->base.Width);
+ window->query(window, NATIVE_WINDOW_HEIGHT, &dri2_surf->base.Height);
+ }
+
+ config = dri2_get_dri_config(dri2_conf, EGL_WINDOW_BIT,
+ dri2_surf->base.GLColorspace);
+ if (!config)
+ goto cleanup_surface;
+
+ dri2_surf->dri_drawable =
+ (*dri2_dpy->dri2->createNewDrawable)(dri2_dpy->dri_screen, config,
+ dri2_surf);
+ if (dri2_surf->dri_drawable == NULL) {
+ _eglError(EGL_BAD_ALLOC, "dri2->createNewDrawable");
+ goto cleanup_surface;
+ }
+
+ if (window) {
+ window->common.incRef(&window->common);
+ dri2_surf->window = window;
+ }
+
+ return &dri2_surf->base;
+
+cleanup_surface:
+ free(dri2_surf);
+
+ return NULL;
+}
+
+static _EGLSurface *
+droid_create_window_surface(_EGLDriver *drv, _EGLDisplay *disp,
+ _EGLConfig *conf, void *native_window,
+ const EGLint *attrib_list)
+{
+ return droid_create_surface(drv, disp, EGL_WINDOW_BIT, conf,
+ native_window, attrib_list);
+}
+
+static _EGLSurface *
+droid_create_pbuffer_surface(_EGLDriver *drv, _EGLDisplay *disp,
+ _EGLConfig *conf, const EGLint *attrib_list)
+{
+ return droid_create_surface(drv, disp, EGL_PBUFFER_BIT, conf,
+ NULL, attrib_list);
+}
+
+static EGLBoolean
+droid_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf)
+{
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+ struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf);
+
+ droid_free_local_buffers(dri2_surf);
+
+ if (dri2_surf->base.Type == EGL_WINDOW_BIT) {
+ if (dri2_surf->buffer)
+ droid_window_cancel_buffer(disp, dri2_surf);
+
+ dri2_surf->window->common.decRef(&dri2_surf->window->common);
+ }
+
+ (*dri2_dpy->core->destroyDrawable)(dri2_surf->dri_drawable);
+
+ free(dri2_surf);
+
+ return EGL_TRUE;
+}
+
+static int
+update_buffers(struct dri2_egl_surface *dri2_surf)
+{
+ if (dri2_surf->base.Type != EGL_WINDOW_BIT)
+ return 0;
+
+ /* try to dequeue the next back buffer */
+ if (!dri2_surf->buffer && !droid_window_dequeue_buffer(dri2_surf)) {
+ _eglLog(_EGL_WARNING, "Could not dequeue buffer from native window");
+ return -1;
+ }
+
+ /* free outdated buffers and update the surface size */
+ if (dri2_surf->base.Width != dri2_surf->buffer->width ||
+ dri2_surf->base.Height != dri2_surf->buffer->height) {
+ droid_free_local_buffers(dri2_surf);
+ dri2_surf->base.Width = dri2_surf->buffer->width;
+ dri2_surf->base.Height = dri2_surf->buffer->height;
+ }
+
+ return 0;
+}
+
+static int
+get_back_bo(struct dri2_egl_surface *dri2_surf)
+{
+ struct dri2_egl_display *dri2_dpy =
+ dri2_egl_display(dri2_surf->base.Resource.Display);
+ int fourcc, pitch;
+ int offset = 0, fd;
+
+ if (dri2_surf->dri_image)
+ return 0;
+
+ if (!dri2_surf->buffer)
+ return -1;
+
+ fd = get_native_buffer_fd(dri2_surf->buffer);
+ if (fd < 0) {
+ _eglLog(_EGL_WARNING, "Could not get native buffer FD");
+ return -1;
+ }
+
+ fourcc = get_fourcc(dri2_surf->buffer->format);
+
+ pitch = dri2_surf->buffer->stride *
+ get_format_bpp(dri2_surf->buffer->format);
+
+ if (fourcc == -1 || pitch == 0) {
+ _eglLog(_EGL_WARNING, "Invalid buffer fourcc(%x) or pitch(%d)",
+ fourcc, pitch);
+ return -1;
+ }
+
+ dri2_surf->dri_image =
+ dri2_dpy->image->createImageFromFds(dri2_dpy->dri_screen,
+ dri2_surf->base.Width,
+ dri2_surf->base.Height,
+ fourcc,
+ &fd,
+ 1,
+ &pitch,
+ &offset,
+ dri2_surf);
+ if (!dri2_surf->dri_image)
+ return -1;
+
+ return 0;
+}
+
+static int
+droid_image_get_buffers(__DRIdrawable *driDrawable,
+ unsigned int format,
+ uint32_t *stamp,
+ void *loaderPrivate,
+ uint32_t buffer_mask,
+ struct __DRIimageList *images)
+{
+ struct dri2_egl_surface *dri2_surf = loaderPrivate;
+
+ images->image_mask = 0;
+
+ if (update_buffers(dri2_surf) < 0)
+ return 0;
+
+ if (buffer_mask & __DRI_IMAGE_BUFFER_FRONT) {
+ /*
+ * We don't support front buffers and GLES doesn't require them for
+ * window surfaces, but some DRI drivers will request them anyway.
+ * We just ignore such request as other platforms backends do.
+ */
+ }
+
+ if (buffer_mask & __DRI_IMAGE_BUFFER_BACK) {
+ if (get_back_bo(dri2_surf) < 0)
+ return 0;
+
+ images->back = dri2_surf->dri_image;
+ images->image_mask |= __DRI_IMAGE_BUFFER_BACK;
+ }
+
+ return 1;
+}
+
+static EGLBoolean
+droid_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);
+
+ if (dri2_surf->base.Type != EGL_WINDOW_BIT)
+ return EGL_TRUE;
+
+ dri2_flush_drawable_for_swapbuffers(disp, draw);
+
+ if (dri2_surf->buffer)
+ droid_window_enqueue_buffer(disp, dri2_surf);
+
+ (*dri2_dpy->flush->invalidate)(dri2_surf->dri_drawable);
+
+ return EGL_TRUE;
+}
+
+static _EGLImage *
+droid_create_image_from_prime_fd(_EGLDisplay *disp, _EGLContext *ctx,
+ struct ANativeWindowBuffer *buf, int fd)
+{
+ unsigned int offsets[3] = { 0, 0, 0 };
+ unsigned int pitches[3] = { 0, 0, 0 };
+
+ const int fourcc = get_fourcc(buf->format);
+ if (fourcc == -1) {
+ _eglError(EGL_BAD_PARAMETER, "eglCreateEGLImageKHR");
+ return NULL;
+ }
+
+ pitches[0] = buf->stride * get_format_bpp(buf->format);
+ if (pitches[0] == 0) {
+ _eglError(EGL_BAD_PARAMETER, "eglCreateEGLImageKHR");
+ return NULL;
+ }
+
+ switch (buf->format) {
+ case HAL_PIXEL_FORMAT_YV12:
+ /* Y plane is assumed to be at offset 0. */
+ /* Cr plane is located after Y plane */
+ offsets[1] = offsets[0] + pitches[0] * buf->height;
+ pitches[1] = ALIGN(pitches[0] / 2, 16);
+ /* Cb plane is located after Cr plane */
+ offsets[2] = offsets[1] + pitches[1] * buf->height / 2;
+ pitches[2] = pitches[1];
+
+ const EGLint attr_list_yv12[] = {
+ EGL_WIDTH, buf->width,
+ EGL_HEIGHT, buf->height,
+ EGL_LINUX_DRM_FOURCC_EXT, fourcc,
+ EGL_DMA_BUF_PLANE0_FD_EXT, fd,
+ EGL_DMA_BUF_PLANE0_PITCH_EXT, pitches[0],
+ EGL_DMA_BUF_PLANE0_OFFSET_EXT, offsets[0],
+ EGL_DMA_BUF_PLANE1_FD_EXT, fd,
+ EGL_DMA_BUF_PLANE1_PITCH_EXT, pitches[1],
+ EGL_DMA_BUF_PLANE1_OFFSET_EXT, offsets[1],
+ EGL_DMA_BUF_PLANE2_FD_EXT, fd,
+ EGL_DMA_BUF_PLANE2_PITCH_EXT, pitches[2],
+ EGL_DMA_BUF_PLANE2_OFFSET_EXT, offsets[2],
+ EGL_NONE, 0
+ };
+
+ return dri2_create_image_dma_buf(disp, ctx, NULL, attr_list_yv12);
+ }
+
+ const EGLint attr_list[] = {
+ EGL_WIDTH, buf->width,
+ EGL_HEIGHT, buf->height,
+ EGL_LINUX_DRM_FOURCC_EXT, fourcc,
+ EGL_DMA_BUF_PLANE0_FD_EXT, fd,
+ EGL_DMA_BUF_PLANE0_PITCH_EXT, pitches[0],
+ EGL_DMA_BUF_PLANE0_OFFSET_EXT, 0,
+ EGL_NONE, 0
+ };
+
+ return dri2_create_image_dma_buf(disp, ctx, NULL, attr_list);
+}
+
+static _EGLImage *
+droid_create_image_from_name(_EGLDisplay *disp, _EGLContext *ctx,
+ struct ANativeWindowBuffer *buf)
+{
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+ struct dri2_egl_image *dri2_img;
+ int name;
+ int format;
+
+ name = get_native_buffer_name(buf);
+ if (!name) {
+ _eglError(EGL_BAD_PARAMETER, "eglCreateEGLImageKHR");
+ return NULL;
+ }
+
+ format = get_format(buf->format);
+ if (format == -1)
+ return NULL;
+
+ dri2_img = calloc(1, sizeof(*dri2_img));
+ if (!dri2_img) {
+ _eglError(EGL_BAD_ALLOC, "droid_create_image_mesa_drm");
+ return NULL;
+ }
+
+ if (!_eglInitImage(&dri2_img->base, disp)) {
+ free(dri2_img);
+ return NULL;
+ }
+
+ dri2_img->dri_image =
+ dri2_dpy->image->createImageFromName(dri2_dpy->dri_screen,
+ buf->width,
+ buf->height,
+ format,
+ name,
+ buf->stride,
+ dri2_img);
+ if (!dri2_img->dri_image) {
+ free(dri2_img);
+ _eglError(EGL_BAD_ALLOC, "droid_create_image_mesa_drm");
+ return NULL;
+ }
+
+ return &dri2_img->base;
+}
+
+static EGLBoolean
+droid_query_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
+ EGLint attribute, EGLint *value)
+{
+ struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf);
+ switch (attribute) {
+ case EGL_WIDTH:
+ if (dri2_surf->base.Type == EGL_WINDOW_BIT && dri2_surf->window) {
+ dri2_surf->window->query(dri2_surf->window,
+ NATIVE_WINDOW_DEFAULT_WIDTH, value);
+ return EGL_TRUE;
+ }
+ break;
+ case EGL_HEIGHT:
+ if (dri2_surf->base.Type == EGL_WINDOW_BIT && dri2_surf->window) {
+ dri2_surf->window->query(dri2_surf->window,
+ NATIVE_WINDOW_DEFAULT_HEIGHT, value);
+ return EGL_TRUE;
+ }
+ break;
+ default:
+ break;
+ }
+ return _eglQuerySurface(drv, dpy, surf, attribute, value);
+}
+
+static _EGLImage *
+dri2_create_image_android_native_buffer(_EGLDisplay *disp,
+ _EGLContext *ctx,
+ struct ANativeWindowBuffer *buf)
+{
+ int fd;
+
+ if (ctx != NULL) {
+ /* From the EGL_ANDROID_image_native_buffer spec:
+ *
+ * * If <target> is EGL_NATIVE_BUFFER_ANDROID and <ctx> is not
+ * EGL_NO_CONTEXT, the error EGL_BAD_CONTEXT is generated.
+ */
+ _eglError(EGL_BAD_CONTEXT, "eglCreateEGLImageKHR: for "
+ "EGL_NATIVE_BUFFER_ANDROID, the context must be "
+ "EGL_NO_CONTEXT");
+ return NULL;
+ }
+
+ if (!buf || buf->common.magic != ANDROID_NATIVE_BUFFER_MAGIC ||
+ buf->common.version != sizeof(*buf)) {
+ _eglError(EGL_BAD_PARAMETER, "eglCreateEGLImageKHR");
+ return NULL;
+ }
+
+ fd = get_native_buffer_fd(buf);
+ if (fd >= 0)
+ return droid_create_image_from_prime_fd(disp, ctx, buf, fd);
+
+ return droid_create_image_from_name(disp, ctx, buf);
+}
+
+static _EGLImage *
+droid_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp,
+ _EGLContext *ctx, EGLenum target,
+ EGLClientBuffer buffer, const EGLint *attr_list)
+{
+ switch (target) {
+ case EGL_NATIVE_BUFFER_ANDROID:
+ return dri2_create_image_android_native_buffer(disp, ctx,
+ (struct ANativeWindowBuffer *) buffer);
+ default:
+ return dri2_create_image_khr(drv, disp, ctx, target, buffer, attr_list);
+ }
+}
+
+static void
+droid_flush_front_buffer(__DRIdrawable * driDrawable, void *loaderPrivate)
+{
+}
+
+static int
+droid_get_buffers_parse_attachments(struct dri2_egl_surface *dri2_surf,
+ unsigned int *attachments, int count)
+{
+ int num_buffers = 0, i;
+
+ /* fill dri2_surf->buffers */
+ for (i = 0; i < count * 2; i += 2) {
+ __DRIbuffer *buf, *local;
+
+ assert(num_buffers < ARRAY_SIZE(dri2_surf->buffers));
+ buf = &dri2_surf->buffers[num_buffers];
+
+ switch (attachments[i]) {
+ case __DRI_BUFFER_BACK_LEFT:
+ if (dri2_surf->base.Type == EGL_WINDOW_BIT) {
+ buf->attachment = attachments[i];
+ buf->name = get_native_buffer_name(dri2_surf->buffer);
+ buf->cpp = get_format_bpp(dri2_surf->buffer->format);
+ buf->pitch = dri2_surf->buffer->stride * buf->cpp;
+ buf->flags = 0;
+
+ if (buf->name)
+ num_buffers++;
+
+ break;
+ }
+ /* fall through for pbuffers */
+ case __DRI_BUFFER_DEPTH:
+ case __DRI_BUFFER_STENCIL:
+ case __DRI_BUFFER_ACCUM:
+ case __DRI_BUFFER_DEPTH_STENCIL:
+ case __DRI_BUFFER_HIZ:
+ local = droid_alloc_local_buffer(dri2_surf,
+ attachments[i], attachments[i + 1]);
+
+ if (local) {
+ *buf = *local;
+ num_buffers++;
+ }
+ break;
+ case __DRI_BUFFER_FRONT_LEFT:
+ case __DRI_BUFFER_FRONT_RIGHT:
+ case __DRI_BUFFER_FAKE_FRONT_LEFT:
+ case __DRI_BUFFER_FAKE_FRONT_RIGHT:
+ case __DRI_BUFFER_BACK_RIGHT:
+ default:
+ /* no front or right buffers */
+ break;
+ }
+ }
+
+ return num_buffers;
+}
+
+static __DRIbuffer *
+droid_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;
+
+ if (update_buffers(dri2_surf) < 0)
+ return NULL;
+
+ dri2_surf->buffer_count =
+ droid_get_buffers_parse_attachments(dri2_surf, attachments, count);
+
+ if (width)
+ *width = dri2_surf->base.Width;
+ if (height)
+ *height = dri2_surf->base.Height;
+
+ *out_count = dri2_surf->buffer_count;
+
+ return dri2_surf->buffers;
+}
+
+static EGLBoolean
+droid_add_configs_for_visuals(_EGLDriver *drv, _EGLDisplay *dpy)
+{
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(dpy);
+ static const struct {
+ int format;
+ unsigned int rgba_masks[4];
+ } visuals[] = {
+ { HAL_PIXEL_FORMAT_RGBA_8888, { 0xff, 0xff00, 0xff0000, 0xff000000 } },
+ { HAL_PIXEL_FORMAT_RGBX_8888, { 0xff, 0xff00, 0xff0000, 0x0 } },
+ { HAL_PIXEL_FORMAT_RGB_888, { 0xff, 0xff00, 0xff0000, 0x0 } },
+ { HAL_PIXEL_FORMAT_RGB_565, { 0xf800, 0x7e0, 0x1f, 0x0 } },
+ { HAL_PIXEL_FORMAT_BGRA_8888, { 0xff0000, 0xff00, 0xff, 0xff000000 } },
+ };
+ EGLint config_attrs[] = {
+ EGL_NATIVE_VISUAL_ID, 0,
+ EGL_NATIVE_VISUAL_TYPE, 0,
+ EGL_FRAMEBUFFER_TARGET_ANDROID, EGL_TRUE,
+ EGL_RECORDABLE_ANDROID, EGL_TRUE,
+ EGL_NONE
+ };
+ unsigned int format_count[ARRAY_SIZE(visuals)] = { 0 };
+ int count, i, j;
+
+ count = 0;
+ for (i = 0; dri2_dpy->driver_configs[i]; i++) {
+ const EGLint surface_type = EGL_WINDOW_BIT | EGL_PBUFFER_BIT;
+ struct dri2_egl_config *dri2_conf;
+ unsigned int double_buffered = 0;
+
+ dri2_dpy->core->getConfigAttrib(dri2_dpy->driver_configs[i],
+ __DRI_ATTRIB_DOUBLE_BUFFER, &double_buffered);
+
+ /* support only double buffered configs */
+ if (!double_buffered)
+ continue;
+
+ for (j = 0; j < ARRAY_SIZE(visuals); j++) {
+ config_attrs[1] = visuals[j].format;
+ config_attrs[3] = visuals[j].format;
+
+ dri2_conf = dri2_add_config(dpy, dri2_dpy->driver_configs[i],
+ count + 1, surface_type, config_attrs, visuals[j].rgba_masks);
+ if (dri2_conf) {
+ count++;
+ format_count[j]++;
+ }
+ }
+ }
+
+ for (i = 0; i < ARRAY_SIZE(format_count); i++) {
+ if (!format_count[i]) {
+ _eglLog(_EGL_DEBUG, "No DRI config supports native format 0x%x",
+ visuals[i].format);
+ }
+ }
+
+ return (count != 0);
+}
+
+static int
+droid_open_device(void)
+{
+ const hw_module_t *mod;
+ int fd = -1, err;
+
+ err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &mod);
+ if (!err) {
+ const gralloc_module_t *gr = (gralloc_module_t *) mod;
+
+ err = -EINVAL;
+ if (gr->perform)
+ err = gr->perform(gr, GRALLOC_MODULE_PERFORM_GET_DRM_FD, &fd);
+ }
+ if (err || fd < 0) {
+ _eglLog(_EGL_WARNING, "fail to get drm fd");
+ fd = -1;
+ }
+
+ return (fd >= 0) ? fcntl(fd, F_DUPFD_CLOEXEC, 3) : -1;
+}
+
+/* support versions < JellyBean */
+#ifndef ALOGW
+#define ALOGW LOGW
+#endif
+#ifndef ALOGD
+#define ALOGD LOGD
+#endif
+#ifndef ALOGI
+#define ALOGI LOGI
+#endif
+
+static void
+droid_log(EGLint level, const char *msg)
+{
+ switch (level) {
+ case _EGL_DEBUG:
+ ALOGD("%s", msg);
+ break;
+ case _EGL_INFO:
+ ALOGI("%s", msg);
+ break;
+ case _EGL_WARNING:
+ ALOGW("%s", msg);
+ break;
+ case _EGL_FATAL:
+ LOG_FATAL("%s", msg);
+ break;
+ default:
+ break;
+ }
+}
+
+static struct dri2_egl_display_vtbl droid_display_vtbl = {
+ .authenticate = NULL,
+ .create_window_surface = droid_create_window_surface,
+ .create_pixmap_surface = dri2_fallback_create_pixmap_surface,
+ .create_pbuffer_surface = droid_create_pbuffer_surface,
+ .destroy_surface = droid_destroy_surface,
+ .create_image = droid_create_image_khr,
+ .swap_interval = dri2_fallback_swap_interval,
+ .swap_buffers = droid_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,
+ .query_surface = droid_query_surface,
+ .create_wayland_buffer_from_image = dri2_fallback_create_wayland_buffer_from_image,
+ .get_sync_values = dri2_fallback_get_sync_values,
+ .get_dri_drawable = dri2_surface_get_dri_drawable,
+};
+
+static const __DRIdri2LoaderExtension droid_dri2_loader_extension = {
+ .base = { __DRI_DRI2_LOADER, 3 },
+
+ .getBuffers = NULL,
+ .flushFrontBuffer = droid_flush_front_buffer,
+ .getBuffersWithFormat = droid_get_buffers_with_format,
+};
+
+static const __DRIimageLoaderExtension droid_image_loader_extension = {
+ .base = { __DRI_IMAGE_LOADER, 1 },
+
+ .getBuffers = droid_image_get_buffers,
+ .flushFrontBuffer = droid_flush_front_buffer,
+};
+
+static const __DRIextension *droid_dri2_loader_extensions[] = {
+ &droid_dri2_loader_extension.base,
+ &image_lookup_extension.base,
+ &use_invalidate.base,
+ NULL,
+};
+
+static const __DRIextension *droid_image_loader_extensions[] = {
+ &droid_image_loader_extension.base,
+ &image_lookup_extension.base,
+ &use_invalidate.base,
+ NULL,
+};
+
+EGLBoolean
+dri2_initialize_android(_EGLDriver *drv, _EGLDisplay *dpy)
+{
+ struct dri2_egl_display *dri2_dpy;
+ const char *err;
+
+ _eglSetLogProc(droid_log);
+
+ loader_set_logger(_eglLog);
+
+ dri2_dpy = calloc(1, sizeof(*dri2_dpy));
+ if (!dri2_dpy)
+ return _eglError(EGL_BAD_ALLOC, "eglInitialize");
+
+ dpy->DriverData = (void *) dri2_dpy;
+
+ dri2_dpy->fd = droid_open_device();
+ if (dri2_dpy->fd < 0) {
+ err = "DRI2: failed to open device";
+ goto cleanup_display;
+ }
+
+ dri2_dpy->driver_name = loader_get_driver_for_fd(dri2_dpy->fd);
+ if (dri2_dpy->driver_name == NULL) {
+ err = "DRI2: failed to get driver name";
+ goto cleanup_device;
+ }
+
+ if (!dri2_load_driver(dpy)) {
+ err = "DRI2: failed to load driver";
+ goto cleanup_driver_name;
+ }
+
+ dri2_dpy->is_render_node = drmGetNodeTypeFromFd(dri2_dpy->fd) == DRM_NODE_RENDER;
+
+ /* render nodes cannot use Gem names, and thus do not support
+ * the __DRI_DRI2_LOADER extension */
+ if (!dri2_dpy->is_render_node)
+ dri2_dpy->loader_extensions = droid_dri2_loader_extensions;
+ else
+ dri2_dpy->loader_extensions = droid_image_loader_extensions;
+
+ if (!dri2_create_screen(dpy)) {
+ err = "DRI2: failed to create screen";
+ goto cleanup_driver;
+ }
+
+ if (!droid_add_configs_for_visuals(drv, dpy)) {
+ err = "DRI2: failed to add configs";
+ goto cleanup_screen;
+ }
+
+ dpy->Extensions.ANDROID_framebuffer_target = EGL_TRUE;
+ dpy->Extensions.ANDROID_image_native_buffer = EGL_TRUE;
+ dpy->Extensions.ANDROID_recordable = EGL_TRUE;
+
+ /* Fill vtbl last to prevent accidentally calling virtual function during
+ * initialization.
+ */
+ dri2_dpy->vtbl = &droid_display_vtbl;
+
+ return EGL_TRUE;
+
+cleanup_screen:
+ dri2_dpy->core->destroyScreen(dri2_dpy->dri_screen);
+cleanup_driver:
+ dlclose(dri2_dpy->driver);
+cleanup_driver_name:
+ free(dri2_dpy->driver_name);
+cleanup_device:
+ close(dri2_dpy->fd);
+cleanup_display:
+ free(dri2_dpy);
+ dpy->DriverData = NULL;
+
+ return _eglError(EGL_NOT_INITIALIZED, err);
+}
diff --git a/lib/mesa/src/egl/drivers/dri2/platform_drm.c b/lib/mesa/src/egl/drivers/dri2/platform_drm.c
index 3f4f7e781..ea1a7f126 100644
--- a/lib/mesa/src/egl/drivers/dri2/platform_drm.c
+++ b/lib/mesa/src/egl/drivers/dri2/platform_drm.c
@@ -191,9 +191,6 @@ dri2_drm_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf)
struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf);
unsigned i;
- if (!_eglPutSurface(surf))
- return EGL_TRUE;
-
(*dri2_dpy->core->destroyDrawable)(dri2_surf->dri_drawable);
for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) {
@@ -534,7 +531,7 @@ swrast_put_image2(__DRIdrawable *driDrawable,
return;
bo = gbm_dri_bo(dri2_surf->current->bo);
- if (gbm_dri_bo_map(bo) == NULL)
+ if (gbm_dri_bo_map_dumb(bo) == NULL)
return;
internal_stride = bo->base.base.stride;
@@ -544,7 +541,7 @@ swrast_put_image2(__DRIdrawable *driDrawable,
data + i * stride, stride);
}
- gbm_dri_bo_unmap(bo);
+ gbm_dri_bo_unmap_dumb(bo);
}
static void
@@ -564,7 +561,7 @@ swrast_get_image(__DRIdrawable *driDrawable,
return;
bo = gbm_dri_bo(dri2_surf->current->bo);
- if (gbm_dri_bo_map(bo) == NULL)
+ if (gbm_dri_bo_map_dumb(bo) == NULL)
return;
internal_stride = bo->base.base.stride;
@@ -575,7 +572,65 @@ swrast_get_image(__DRIdrawable *driDrawable,
bo->map + (x + i) * internal_stride + y, stride);
}
- gbm_dri_bo_unmap(bo);
+ gbm_dri_bo_unmap_dumb(bo);
+}
+
+static EGLBoolean
+drm_add_configs_for_visuals(_EGLDriver *drv, _EGLDisplay *disp)
+{
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+ static const struct {
+ int format;
+ unsigned int red_mask;
+ unsigned int alpha_mask;
+ } visuals[] = {
+ { GBM_FORMAT_XRGB2101010, 0x3ff00000, 0x00000000 },
+ { GBM_FORMAT_ARGB2101010, 0x3ff00000, 0xc0000000 },
+ { GBM_FORMAT_XRGB8888, 0x00ff0000, 0x00000000 },
+ { GBM_FORMAT_ARGB8888, 0x00ff0000, 0xff000000 },
+ { GBM_FORMAT_RGB565, 0x0000f800, 0x00000000 },
+ };
+ EGLint attr_list[] = {
+ EGL_NATIVE_VISUAL_ID, 0,
+ EGL_NONE,
+ };
+ unsigned int format_count[ARRAY_SIZE(visuals)] = { 0 };
+ unsigned int count, i, j;
+
+ count = 0;
+ for (i = 0; dri2_dpy->driver_configs[i]; i++) {
+ unsigned int red, alpha;
+
+ dri2_dpy->core->getConfigAttrib(dri2_dpy->driver_configs[i],
+ __DRI_ATTRIB_RED_MASK, &red);
+ dri2_dpy->core->getConfigAttrib(dri2_dpy->driver_configs[i],
+ __DRI_ATTRIB_ALPHA_MASK, &alpha);
+
+ for (j = 0; j < ARRAY_SIZE(visuals); j++) {
+ struct dri2_egl_config *dri2_conf;
+
+ if (visuals[j].red_mask != red || visuals[j].alpha_mask != alpha)
+ continue;
+
+ attr_list[1] = visuals[j].format;
+
+ dri2_conf = dri2_add_config(disp, dri2_dpy->driver_configs[i],
+ count + 1, EGL_WINDOW_BIT, attr_list, NULL);
+ if (dri2_conf) {
+ count++;
+ format_count[j]++;
+ }
+ }
+ }
+
+ for (i = 0; i < ARRAY_SIZE(format_count); i++) {
+ if (!format_count[i]) {
+ _eglLog(_EGL_DEBUG, "No DRI config supports native format 0x%x",
+ visuals[i].format);
+ }
+ }
+
+ return (count != 0);
}
static struct dri2_egl_display_vtbl dri2_drm_display_vtbl = {
@@ -602,8 +657,8 @@ dri2_initialize_drm(_EGLDriver *drv, _EGLDisplay *disp)
{
struct dri2_egl_display *dri2_dpy;
struct gbm_device *gbm;
+ const char *err;
int fd = -1;
- int i;
loader_set_logger(_eglLog);
@@ -623,28 +678,36 @@ dri2_initialize_drm(_EGLDriver *drv, _EGLDisplay *disp)
fd = loader_open_device("/dev/dri/card0");
dri2_dpy->own_device = 1;
gbm = gbm_create_device(fd);
- if (gbm == NULL)
+ if (gbm == NULL) {
+ err = "DRI2: failed to create gbm device";
goto cleanup;
+ }
} else {
fd = fcntl(gbm_device_get_fd(gbm), F_DUPFD_CLOEXEC, 3);
- if (fd < 0)
+ if (fd < 0) {
+ err = "DRI2: failed to fcntl() existing gbm device";
goto cleanup;
+ }
}
- if (strcmp(gbm_device_get_backend_name(gbm), "drm") != 0)
+ if (strcmp(gbm_device_get_backend_name(gbm), "drm") != 0) {
+ err = "DRI2: gbm device using incorrect/incompatible backend";
goto cleanup;
+ }
dri2_dpy->gbm_dri = gbm_dri_device(gbm);
- if (dri2_dpy->gbm_dri->base.type != GBM_DRM_DRIVER_TYPE_DRI)
+ if (dri2_dpy->gbm_dri->base.type != GBM_DRM_DRIVER_TYPE_DRI) {
+ err = "DRI2: gbm device using incorrect/incompatible type";
goto cleanup;
+ }
dri2_dpy->fd = fd;
- dri2_dpy->device_name = loader_get_device_name_for_fd(dri2_dpy->fd);
dri2_dpy->driver_name = strdup(dri2_dpy->gbm_dri->base.driver_name);
dri2_dpy->dri_screen = dri2_dpy->gbm_dri->screen;
dri2_dpy->core = dri2_dpy->gbm_dri->core;
dri2_dpy->dri2 = dri2_dpy->gbm_dri->dri2;
+ dri2_dpy->fence = dri2_dpy->gbm_dri->fence;
dri2_dpy->image = dri2_dpy->gbm_dri->image;
dri2_dpy->flush = dri2_dpy->gbm_dri->flush;
dri2_dpy->swrast = dri2_dpy->gbm_dri->swrast;
@@ -666,33 +729,9 @@ dri2_initialize_drm(_EGLDriver *drv, _EGLDisplay *disp)
dri2_setup_screen(disp);
- for (i = 0; dri2_dpy->driver_configs[i]; i++) {
- EGLint format, attr_list[3];
- unsigned int red, alpha;
-
- dri2_dpy->core->getConfigAttrib(dri2_dpy->driver_configs[i],
- __DRI_ATTRIB_RED_MASK, &red);
- dri2_dpy->core->getConfigAttrib(dri2_dpy->driver_configs[i],
- __DRI_ATTRIB_ALPHA_MASK, &alpha);
- if (red == 0x3ff00000 && alpha == 0x00000000)
- format = GBM_FORMAT_XRGB2101010;
- else if (red == 0x3ff00000 && alpha == 0xc0000000)
- format = GBM_FORMAT_ARGB2101010;
- else if (red == 0x00ff0000 && alpha == 0x00000000)
- format = GBM_FORMAT_XRGB8888;
- else if (red == 0x00ff0000 && alpha == 0xff000000)
- format = GBM_FORMAT_ARGB8888;
- else if (red == 0xf800)
- format = GBM_FORMAT_RGB565;
- else
- continue;
-
- attr_list[0] = EGL_NATIVE_VISUAL_ID;
- attr_list[1] = format;
- attr_list[2] = EGL_NONE;
-
- dri2_add_config(disp, dri2_dpy->driver_configs[i],
- i + 1, EGL_WINDOW_BIT, attr_list, NULL);
+ if (!drm_add_configs_for_visuals(drv, disp)) {
+ err = "DRI2: failed to add configs";
+ goto cleanup;
}
disp->Extensions.KHR_image_pixmap = EGL_TRUE;
@@ -700,19 +739,9 @@ dri2_initialize_drm(_EGLDriver *drv, _EGLDisplay *disp)
disp->Extensions.EXT_buffer_age = EGL_TRUE;
#ifdef HAVE_WAYLAND_PLATFORM
- if (dri2_dpy->image) {
- if (dri2_dpy->image->base.version >= 10 &&
- dri2_dpy->image->getCapabilities != NULL) {
- int capabilities;
-
- capabilities =
- dri2_dpy->image->getCapabilities(dri2_dpy->dri_screen);
- disp->Extensions.WL_bind_wayland_display =
- (capabilities & __DRI_IMAGE_CAP_GLOBAL_NAMES) != 0;
- } else
- disp->Extensions.WL_bind_wayland_display = EGL_TRUE;
- }
+ dri2_dpy->device_name = loader_get_device_name_for_fd(dri2_dpy->fd);
#endif
+ dri2_set_WL_bind_wayland_display(drv, disp);
/* Fill vtbl last to prevent accidentally calling virtual function during
* initialization.
@@ -726,5 +755,6 @@ cleanup:
close(fd);
free(dri2_dpy);
- return EGL_FALSE;
+ disp->DriverData = NULL;
+ return _eglError(EGL_NOT_INITIALIZED, err);
}
diff --git a/lib/mesa/src/egl/drivers/dri2/platform_surfaceless.c b/lib/mesa/src/egl/drivers/dri2/platform_surfaceless.c
index 48f15df75..025aaa255 100644
--- a/lib/mesa/src/egl/drivers/dri2/platform_surfaceless.c
+++ b/lib/mesa/src/egl/drivers/dri2/platform_surfaceless.c
@@ -37,10 +37,204 @@
#include "egl_dri2_fallbacks.h"
#include "loader.h"
+static __DRIimage*
+surfaceless_alloc_image(struct dri2_egl_display *dri2_dpy,
+ struct dri2_egl_surface *dri2_surf)
+{
+ return dri2_dpy->image->createImage(
+ dri2_dpy->dri_screen,
+ dri2_surf->base.Width,
+ dri2_surf->base.Height,
+ dri2_surf->visual,
+ 0,
+ NULL);
+}
+
+static void
+surfaceless_free_images(struct dri2_egl_surface *dri2_surf)
+{
+ struct dri2_egl_display *dri2_dpy =
+ dri2_egl_display(dri2_surf->base.Resource.Display);
+
+ if (dri2_surf->front) {
+ dri2_dpy->image->destroyImage(dri2_surf->front);
+ dri2_surf->front = NULL;
+ }
+}
+
+static int
+surfaceless_image_get_buffers(__DRIdrawable *driDrawable,
+ unsigned int format,
+ uint32_t *stamp,
+ void *loaderPrivate,
+ uint32_t buffer_mask,
+ struct __DRIimageList *buffers)
+{
+ struct dri2_egl_surface *dri2_surf = loaderPrivate;
+ struct dri2_egl_display *dri2_dpy =
+ dri2_egl_display(dri2_surf->base.Resource.Display);
+
+ buffers->image_mask = 0;
+ buffers->front = NULL;
+ buffers->back = NULL;
+
+ /* The EGL 1.5 spec states that pbuffers are single-buffered. Specifically,
+ * the spec states that they have a back buffer but no front buffer, in
+ * contrast to pixmaps, which have a front buffer but no back buffer.
+ *
+ * Single-buffered surfaces with no front buffer confuse Mesa; so we deviate
+ * from the spec, following the precedent of Mesa's EGL X11 platform. The
+ * X11 platform correctly assigns pbuffers to single-buffered configs, but
+ * assigns the pbuffer a front buffer instead of a back buffer.
+ *
+ * Pbuffers in the X11 platform mostly work today, so let's just copy its
+ * behavior instead of trying to fix (and hence potentially breaking) the
+ * world.
+ */
+
+ if (buffer_mask & __DRI_IMAGE_BUFFER_FRONT) {
+
+ if (!dri2_surf->front)
+ dri2_surf->front =
+ surfaceless_alloc_image(dri2_dpy, dri2_surf);
+
+ buffers->image_mask |= __DRI_IMAGE_BUFFER_FRONT;
+ buffers->front = dri2_surf->front;
+ }
+
+ return 1;
+}
+
+static _EGLSurface *
+dri2_surfaceless_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type,
+ _EGLConfig *conf, 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 dri2_egl_surface *dri2_surf;
+ const __DRIconfig *config;
+
+ /* Make sure to calloc so all pointers
+ * are originally NULL.
+ */
+ dri2_surf = calloc(1, sizeof *dri2_surf);
+
+ if (!dri2_surf) {
+ _eglError(EGL_BAD_ALLOC, "eglCreatePbufferSurface");
+ return NULL;
+ }
+
+ if (!_eglInitSurface(&dri2_surf->base, disp, type, conf, attrib_list))
+ goto cleanup_surface;
+
+ config = dri2_get_dri_config(dri2_conf, type,
+ dri2_surf->base.GLColorspace);
+
+ if (!config)
+ goto cleanup_surface;
+
+ dri2_surf->dri_drawable =
+ (*dri2_dpy->dri2->createNewDrawable)(dri2_dpy->dri_screen, config,
+ dri2_surf);
+ if (dri2_surf->dri_drawable == NULL) {
+ _eglError(EGL_BAD_ALLOC, "dri2->createNewDrawable");
+ goto cleanup_surface;
+ }
+
+ if (conf->RedSize == 5)
+ dri2_surf->visual = __DRI_IMAGE_FORMAT_RGB565;
+ else if (conf->AlphaSize == 0)
+ dri2_surf->visual = __DRI_IMAGE_FORMAT_XRGB8888;
+ else
+ dri2_surf->visual = __DRI_IMAGE_FORMAT_ARGB8888;
+
+ return &dri2_surf->base;
+
+ cleanup_surface:
+ free(dri2_surf);
+ return NULL;
+}
+
+static EGLBoolean
+surfaceless_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf)
+{
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+ struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf);
+
+ surfaceless_free_images(dri2_surf);
+
+ (*dri2_dpy->core->destroyDrawable)(dri2_surf->dri_drawable);
+
+ free(dri2_surf);
+ return EGL_TRUE;
+}
+
+static _EGLSurface *
+dri2_surfaceless_create_pbuffer_surface(_EGLDriver *drv, _EGLDisplay *disp,
+ _EGLConfig *conf, const EGLint *attrib_list)
+{
+ return dri2_surfaceless_create_surface(drv, disp, EGL_PBUFFER_BIT, conf,
+ attrib_list);
+}
+
+static EGLBoolean
+surfaceless_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf)
+{
+ assert(!surf || surf->Type == EGL_PBUFFER_BIT);
+
+ /* From the EGL 1.5 spec:
+ * If surface is a [...] pbuffer surface, eglSwapBuffers has no effect.
+ */
+ return EGL_TRUE;
+}
+
+static EGLBoolean
+surfaceless_add_configs_for_visuals(_EGLDriver *drv, _EGLDisplay *dpy)
+{
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(dpy);
+ static const struct {
+ const char *format_name;
+ unsigned int rgba_masks[4];
+ } visuals[] = {
+ { "ARGB8888", { 0xff0000, 0xff00, 0xff, 0xff000000 } },
+ { "RGB888", { 0xff0000, 0xff00, 0xff, 0x0 } },
+ { "RGB565", { 0x00f800, 0x07e0, 0x1f, 0x0 } },
+ };
+ unsigned int format_count[ARRAY_SIZE(visuals)] = { 0 };
+ unsigned int count, i, j;
+
+ count = 0;
+ for (i = 0; dri2_dpy->driver_configs[i] != NULL; i++) {
+ for (j = 0; j < ARRAY_SIZE(visuals); j++) {
+ struct dri2_egl_config *dri2_conf;
+
+ dri2_conf = dri2_add_config(dpy, dri2_dpy->driver_configs[i],
+ count + 1, EGL_PBUFFER_BIT, NULL, visuals[j].rgba_masks);
+
+ if (dri2_conf) {
+ count++;
+ format_count[j]++;
+ }
+ }
+ }
+
+ for (i = 0; i < ARRAY_SIZE(format_count); i++) {
+ if (!format_count[i]) {
+ _eglLog(_EGL_DEBUG, "No DRI config supports native format %s",
+ visuals[i].format_name);
+ }
+ }
+
+ return (count != 0);
+}
+
static struct dri2_egl_display_vtbl dri2_surfaceless_display_vtbl = {
.create_pixmap_surface = dri2_fallback_create_pixmap_surface,
+ .create_pbuffer_surface = dri2_surfaceless_create_pbuffer_surface,
+ .destroy_surface = surfaceless_destroy_surface,
.create_image = dri2_create_image_khr,
.swap_interval = dri2_fallback_swap_interval,
+ .swap_buffers = surfaceless_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,
@@ -48,6 +242,7 @@ static struct dri2_egl_display_vtbl dri2_surfaceless_display_vtbl = {
.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,
+ .get_dri_drawable = dri2_surface_get_dri_drawable,
};
static void
@@ -55,25 +250,21 @@ 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;
-}
+static const __DRIimageLoaderExtension image_loader_extension = {
+ .base = { __DRI_IMAGE_LOADER, 1 },
+ .getBuffers = surfaceless_image_get_buffers,
+ .flushFrontBuffer = surfaceless_flush_front_buffer,
+};
#define DRM_RENDER_DEV_NAME "%s/renderD%d"
+static const __DRIextension *image_loader_extensions[] = {
+ &image_loader_extension.base,
+ &image_lookup_extension.base,
+ &use_invalidate.base,
+ NULL,
+};
+
EGLBoolean
dri2_initialize_surfaceless(_EGLDriver *drv, _EGLDisplay *disp)
{
@@ -103,7 +294,7 @@ dri2_initialize_surfaceless(_EGLDriver *drv, _EGLDisplay *disp)
if (dri2_dpy->fd < 0)
continue;
- dri2_dpy->driver_name = loader_get_driver_for_fd(dri2_dpy->fd, 0);
+ dri2_dpy->driver_name = loader_get_driver_for_fd(dri2_dpy->fd);
if (dri2_dpy->driver_name) {
if (dri2_load_driver(disp)) {
driver_loaded = 1;
@@ -119,27 +310,16 @@ dri2_initialize_surfaceless(_EGLDriver *drv, _EGLDisplay *disp)
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;
+ dri2_dpy->loader_extensions = image_loader_extensions;
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);
+ if (!surfaceless_add_configs_for_visuals(drv, disp)) {
+ err = "DRI2: failed to add configs";
+ goto cleanup_screen;
}
disp->Extensions.KHR_image_base = EGL_TRUE;
@@ -151,12 +331,16 @@ dri2_initialize_surfaceless(_EGLDriver *drv, _EGLDisplay *disp)
return EGL_TRUE;
+cleanup_screen:
+ dri2_dpy->core->destroyScreen(dri2_dpy->dri_screen);
+
cleanup_driver:
dlclose(dri2_dpy->driver);
free(dri2_dpy->driver_name);
close(dri2_dpy->fd);
cleanup_display:
free(dri2_dpy);
+ disp->DriverData = NULL;
return _eglError(EGL_NOT_INITIALIZED, err);
}
diff --git a/lib/mesa/src/egl/drivers/dri2/platform_wayland.c b/lib/mesa/src/egl/drivers/dri2/platform_wayland.c
index 341acb7ed..789e03559 100644
--- a/lib/mesa/src/egl/drivers/dri2/platform_wayland.c
+++ b/lib/mesa/src/egl/drivers/dri2/platform_wayland.c
@@ -118,6 +118,13 @@ resize_callback(struct wl_egl_window *wl_win, void *data)
(*dri2_dpy->flush->invalidate)(dri2_surf->dri_drawable);
}
+static void
+destroy_window_callback(void *data)
+{
+ struct dri2_egl_surface *dri2_surf = data;
+ dri2_surf->wl_win = NULL;
+}
+
/**
* Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface().
*/
@@ -159,6 +166,7 @@ dri2_wl_create_surface(_EGLDriver *drv, _EGLDisplay *disp,
dri2_surf->wl_win->private = dri2_surf;
dri2_surf->wl_win->resize_callback = resize_callback;
+ dri2_surf->wl_win->destroy_window_callback = destroy_window_callback;
dri2_surf->base.Width = -1;
dri2_surf->base.Height = -1;
@@ -229,9 +237,6 @@ dri2_wl_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf)
(void) drv;
- if (!_eglPutSurface(surf))
- return EGL_TRUE;
-
(*dri2_dpy->core->destroyDrawable)(dri2_surf->dri_drawable);
for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) {
@@ -257,8 +262,11 @@ dri2_wl_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf)
if (dri2_surf->throttle_callback)
wl_callback_destroy(dri2_surf->throttle_callback);
- dri2_surf->wl_win->private = NULL;
- dri2_surf->wl_win->resize_callback = NULL;
+ if (dri2_surf->wl_win) {
+ dri2_surf->wl_win->private = NULL;
+ dri2_surf->wl_win->resize_callback = NULL;
+ dri2_surf->wl_win->destroy_window_callback = NULL;
+ }
free(surf);
@@ -305,7 +313,7 @@ get_back_bo(struct dri2_egl_surface *dri2_surf)
{
struct dri2_egl_display *dri2_dpy =
dri2_egl_display(dri2_surf->base.Resource.Display);
- int i;
+ int i, use_flags;
unsigned int dri_image_format;
/* currently supports three WL DRM formats,
@@ -352,6 +360,8 @@ get_back_bo(struct dri2_egl_surface *dri2_surf)
if (dri2_surf->back == NULL)
return -1;
+ use_flags = __DRI_IMAGE_USE_SHARE | __DRI_IMAGE_USE_BACKBUFFER;
+
if (dri2_dpy->is_different_gpu &&
dri2_surf->back->linear_copy == NULL) {
dri2_surf->back->linear_copy =
@@ -359,7 +369,7 @@ get_back_bo(struct dri2_egl_surface *dri2_surf)
dri2_surf->base.Width,
dri2_surf->base.Height,
dri_image_format,
- __DRI_IMAGE_USE_SHARE |
+ use_flags |
__DRI_IMAGE_USE_LINEAR,
NULL);
if (dri2_surf->back->linear_copy == NULL)
@@ -373,7 +383,7 @@ get_back_bo(struct dri2_egl_surface *dri2_surf)
dri2_surf->base.Height,
dri_image_format,
dri2_dpy->is_different_gpu ?
- 0 : __DRI_IMAGE_USE_SHARE,
+ 0 : use_flags,
NULL);
dri2_surf->back->age = 0;
}
@@ -582,6 +592,14 @@ dri2_wl_flush_front_buffer(__DRIdrawable * driDrawable, void *loaderPrivate)
(void) loaderPrivate;
}
+static const __DRIdri2LoaderExtension dri2_loader_extension = {
+ .base = { __DRI_DRI2_LOADER, 3 },
+
+ .getBuffers = dri2_wl_get_buffers,
+ .flushFrontBuffer = dri2_wl_flush_front_buffer,
+ .getBuffersWithFormat = dri2_wl_get_buffers_with_format,
+};
+
static const __DRIimageLoaderExtension image_loader_extension = {
.base = { __DRI_IMAGE_LOADER, 1 },
@@ -1061,17 +1079,67 @@ static struct dri2_egl_display_vtbl dri2_wl_display_vtbl = {
.get_dri_drawable = dri2_surface_get_dri_drawable,
};
+static const __DRIextension *dri2_loader_extensions[] = {
+ &dri2_loader_extension.base,
+ &image_lookup_extension.base,
+ &use_invalidate.base,
+ NULL,
+};
+
+static const __DRIextension *image_loader_extensions[] = {
+ &image_loader_extension.base,
+ &image_lookup_extension.base,
+ &use_invalidate.base,
+ NULL,
+};
+
+static EGLBoolean
+dri2_wl_add_configs_for_visuals(_EGLDriver *drv, _EGLDisplay *disp)
+{
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+ static const struct {
+ const char *format_name;
+ int has_format;
+ unsigned int rgba_masks[4];
+ } visuals[] = {
+ { "XRGB8888", HAS_XRGB8888, { 0xff0000, 0xff00, 0x00ff, 0xff000000 } },
+ { "ARGB8888", HAS_ARGB8888, { 0xff0000, 0xff00, 0x00ff, 0 } },
+ { "RGB565", HAS_RGB565, { 0x00f800, 0x07e0, 0x001f, 0 } },
+ };
+ unsigned int format_count[ARRAY_SIZE(visuals)] = { 0 };
+ unsigned int count, i, j;
+
+ count = 0;
+ for (i = 0; dri2_dpy->driver_configs[i]; i++) {
+ for (j = 0; j < ARRAY_SIZE(visuals); j++) {
+ struct dri2_egl_config *dri2_conf;
+
+ if (!(dri2_dpy->formats & visuals[j].has_format))
+ continue;
+
+ dri2_conf = dri2_add_config(disp, dri2_dpy->driver_configs[i],
+ count + 1, EGL_WINDOW_BIT, NULL, visuals[j].rgba_masks);
+ if (dri2_conf) {
+ count++;
+ format_count[j]++;
+ }
+ }
+ }
+
+ for (i = 0; i < ARRAY_SIZE(format_count); i++) {
+ if (!format_count[i]) {
+ _eglLog(_EGL_DEBUG, "No DRI config supports native format %s",
+ visuals[i].format_name);
+ }
+ }
+
+ return (count != 0);
+}
+
static EGLBoolean
dri2_initialize_wayland_drm(_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);
@@ -1126,7 +1194,7 @@ dri2_initialize_wayland_drm(_EGLDriver *drv, _EGLDisplay *disp)
* the server by requesting its pci-id */
dri2_dpy->is_render_node = drmGetNodeTypeFromFd(dri2_dpy->fd) == DRM_NODE_RENDER;
- dri2_dpy->driver_name = loader_get_driver_for_fd(dri2_dpy->fd, 0);
+ dri2_dpy->driver_name = loader_get_driver_for_fd(dri2_dpy->fd);
if (dri2_dpy->driver_name == NULL) {
_eglError(EGL_BAD_ALLOC, "DRI2: failed to get driver name");
goto cleanup_fd;
@@ -1135,25 +1203,12 @@ dri2_initialize_wayland_drm(_EGLDriver *drv, _EGLDisplay *disp)
if (!dri2_load_driver(disp))
goto cleanup_driver_name;
- 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;
+ if (!dri2_dpy->is_render_node)
+ dri2_dpy->loader_extensions = dri2_loader_extensions;
+ else
+ dri2_dpy->loader_extensions = image_loader_extensions;
if (!dri2_create_screen(disp))
goto cleanup_driver;
@@ -1187,18 +1242,12 @@ dri2_initialize_wayland_drm(_EGLDriver *drv, _EGLDisplay *disp)
goto cleanup_screen;
}
- 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);
+ if (!dri2_wl_add_configs_for_visuals(drv, disp)) {
+ _eglError(EGL_NOT_INITIALIZED, "DRI2: failed to add configs");
+ goto cleanup_screen;
}
- disp->Extensions.WL_bind_wayland_display = EGL_TRUE;
+ dri2_set_WL_bind_wayland_display(drv, disp);
/* 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
@@ -1236,6 +1285,7 @@ dri2_initialize_wayland_drm(_EGLDriver *drv, _EGLDisplay *disp)
wl_event_queue_destroy(dri2_dpy->wl_queue);
cleanup_dpy:
free(dri2_dpy);
+ disp->DriverData = NULL;
return EGL_FALSE;
}
@@ -1789,17 +1839,24 @@ static struct dri2_egl_display_vtbl dri2_wl_swrast_display_vtbl = {
.get_dri_drawable = dri2_surface_get_dri_drawable,
};
+static const __DRIswrastLoaderExtension swrast_loader_extension = {
+ .base = { __DRI_SWRAST_LOADER, 2 },
+
+ .getDrawableInfo = dri2_wl_swrast_get_drawable_info,
+ .putImage = dri2_wl_swrast_put_image,
+ .getImage = dri2_wl_swrast_get_image,
+ .putImage2 = dri2_wl_swrast_put_image2,
+};
+
+static const __DRIextension *swrast_loader_extensions[] = {
+ &swrast_loader_extension.base,
+ NULL,
+};
+
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);
@@ -1839,30 +1896,16 @@ dri2_initialize_wayland_swrast(_EGLDriver *drv, _EGLDisplay *disp)
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;
+ dri2_dpy->loader_extensions = swrast_loader_extensions;
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);
+ if (!dri2_wl_add_configs_for_visuals(drv, disp)) {
+ _eglError(EGL_NOT_INITIALIZED, "DRI2: failed to add configs");
+ goto cleanup_screen;
}
/* Fill vtbl last to prevent accidentally calling virtual function during
@@ -1872,6 +1915,8 @@ dri2_initialize_wayland_swrast(_EGLDriver *drv, _EGLDisplay *disp)
return EGL_TRUE;
+ cleanup_screen:
+ dri2_dpy->core->destroyScreen(dri2_dpy->dri_screen);
cleanup_driver:
dlclose(dri2_dpy->driver);
cleanup_shm:
@@ -1881,6 +1926,7 @@ dri2_initialize_wayland_swrast(_EGLDriver *drv, _EGLDisplay *disp)
wl_event_queue_destroy(dri2_dpy->wl_queue);
cleanup_dpy:
free(dri2_dpy);
+ disp->DriverData = NULL;
return EGL_FALSE;
}
diff --git a/lib/mesa/src/egl/drivers/dri2/platform_x11_dri3.c b/lib/mesa/src/egl/drivers/dri2/platform_x11_dri3.c
index 8e4a131b1..475ec05a9 100644
--- a/lib/mesa/src/egl/drivers/dri2/platform_x11_dri3.c
+++ b/lib/mesa/src/egl/drivers/dri2/platform_x11_dri3.c
@@ -96,11 +96,24 @@ static __DRIcontext *
egl_dri3_get_dri_context(struct loader_dri3_drawable *draw)
{
_EGLContext *ctx = _eglGetCurrentContext();
- struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx);
-
+ struct dri2_egl_context *dri2_ctx;
+ if (!ctx)
+ return NULL;
+ dri2_ctx = dri2_egl_context(ctx);
return dri2_ctx->dri_context;
}
+static __DRIscreen *
+egl_dri3_get_dri_screen(struct loader_dri3_drawable *draw)
+{
+ _EGLContext *ctx = _eglGetCurrentContext();
+ struct dri2_egl_context *dri2_ctx;
+ if (!ctx)
+ return NULL;
+ dri2_ctx = dri2_egl_context(ctx);
+ return dri2_egl_display(dri2_ctx->base.Resource.Display)->dri_screen;
+}
+
static void
egl_dri3_flush_drawable(struct loader_dri3_drawable *draw, unsigned flags)
{
@@ -110,13 +123,14 @@ egl_dri3_flush_drawable(struct loader_dri3_drawable *draw, unsigned flags)
dri2_flush_drawable_for_swapbuffers(disp, &dri3_surf->base);
}
-static struct loader_dri3_vtable egl_dri3_vtable = {
+static const struct loader_dri3_vtable egl_dri3_vtable = {
.get_swap_interval = egl_dri3_get_swap_interval,
.clamp_swap_interval = egl_dri3_clamp_swap_interval,
.set_swap_interval = egl_dri3_set_swap_interval,
.set_drawable_size = egl_dri3_set_drawable_size,
.in_current_context = egl_dri3_in_current_context,
.get_dri_context = egl_dri3_get_dri_context,
+ .get_dri_screen = egl_dri3_get_dri_screen,
.flush_drawable = egl_dri3_flush_drawable,
.show_fps = NULL,
};
@@ -128,9 +142,6 @@ dri3_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf)
(void) drv;
- if (!_eglPutSurface(surf))
- return EGL_TRUE;
-
loader_dri3_drawable_fini(&dri3_surf->loader_drawable);
free(surf);
@@ -224,6 +235,25 @@ dri3_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type,
return NULL;
}
+static int
+dri3_authenticate(_EGLDisplay *disp, uint32_t id)
+{
+#ifdef HAVE_WAYLAND_PLATFORM
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+
+ if (dri2_dpy->device_name) {
+ _eglLog(_EGL_WARNING,
+ "Wayland client render node authentication is unnecessary");
+ return 0;
+ }
+
+ _eglLog(_EGL_WARNING,
+ "Wayland client primary node authentication isn't supported");
+#endif
+
+ return -1;
+}
+
/**
* Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface().
*/
@@ -417,7 +447,7 @@ dri3_get_dri_drawable(_EGLSurface *surf)
}
struct dri2_egl_display_vtbl dri3_x11_display_vtbl = {
- .authenticate = NULL,
+ .authenticate = dri3_authenticate,
.create_window_surface = dri3_create_window_surface,
.create_pixmap_surface = dri3_create_pixmap_surface,
.create_pbuffer_surface = dri3_create_pbuffer_surface,
@@ -435,29 +465,6 @@ struct dri2_egl_display_vtbl dri3_x11_display_vtbl = {
.get_dri_drawable = dri3_get_dri_drawable,
};
-static char *
-dri3_get_device_name(int fd)
-{
- char *ret = NULL;
-
- ret = drmGetRenderDeviceNameFromFd(fd);
- if (ret)
- return ret;
-
- /* For dri3, render node support is required for WL_bind_wayland_display.
- * In order not to regress on older systems without kernel or libdrm
- * support, fall back to dri2. User can override it with environment
- * variable if they don't need to use that extension.
- */
- if (getenv("EGL_FORCE_DRI3") == NULL) {
- _eglLog(_EGL_WARNING, "Render node support not available, falling back to dri2");
- _eglLog(_EGL_WARNING, "If you want to force dri3, set EGL_FORCE_DRI3 environment variable");
- } else
- ret = loader_get_device_name_for_fd(fd);
-
- return ret;
-}
-
EGLBoolean
dri3_x11_connect(struct dri2_egl_display *dri2_dpy)
{
@@ -530,18 +537,19 @@ dri3_x11_connect(struct dri2_egl_display *dri2_dpy)
dri2_dpy->fd = loader_get_user_preferred_fd(dri2_dpy->fd, &dri2_dpy->is_different_gpu);
- dri2_dpy->driver_name = loader_get_driver_for_fd(dri2_dpy->fd, 0);
+ dri2_dpy->driver_name = loader_get_driver_for_fd(dri2_dpy->fd);
if (!dri2_dpy->driver_name) {
_eglLog(_EGL_WARNING, "DRI3: No driver found");
close(dri2_dpy->fd);
return EGL_FALSE;
}
- dri2_dpy->device_name = dri3_get_device_name(dri2_dpy->fd);
- if (!dri2_dpy->device_name) {
- close(dri2_dpy->fd);
- return EGL_FALSE;
- }
+#ifdef HAVE_WAYLAND_PLATFORM
+ /* Only try to get a render device name since dri3 doesn't provide a
+ * mechanism for authenticating client opened device node fds. If this
+ * fails then don't advertise the extension. */
+ dri2_dpy->device_name = drmGetRenderDeviceNameFromFd(dri2_dpy->fd);
+#endif
return EGL_TRUE;
}
diff --git a/lib/mesa/src/egl/drivers/haiku/.editorconfig b/lib/mesa/src/egl/drivers/haiku/.editorconfig
new file mode 100644
index 000000000..5ae8c6f76
--- /dev/null
+++ b/lib/mesa/src/egl/drivers/haiku/.editorconfig
@@ -0,0 +1,2 @@
+[*.cpp]
+indent_style = tab
diff --git a/lib/mesa/src/egl/egl-symbols-check b/lib/mesa/src/egl/egl-symbols-check
index 5d46fed57..409867fab 100755
--- a/lib/mesa/src/egl/egl-symbols-check
+++ b/lib/mesa/src/egl/egl-symbols-check
@@ -46,6 +46,8 @@ eglWaitClient
eglWaitGL
eglWaitNative
eglWaitSync
+MesaGLInteropEGLQueryDeviceInfo
+MesaGLInteropEGLExportObject
_fini
_init
EOF
diff --git a/lib/mesa/src/egl/main/eglapi.c b/lib/mesa/src/egl/main/eglapi.c
index 4dee9cf1b..697b6fef0 100644
--- a/lib/mesa/src/egl/main/eglapi.c
+++ b/lib/mesa/src/egl/main/eglapi.c
@@ -88,6 +88,7 @@
#include <string.h>
#include "c99_compat.h"
#include "c11/threads.h"
+#include "GL/mesa_glinterop.h"
#include "eglcompiler.h"
#include "eglglobals.h"
@@ -249,6 +250,78 @@ _eglUnlockDisplay(_EGLDisplay *dpy)
mtx_unlock(&dpy->Mutex);
}
+static EGLBoolean
+_eglSetFuncName(const char *funcName, _EGLDisplay *disp, EGLenum objectType, _EGLResource *object)
+{
+ _EGLThreadInfo *thr = _eglGetCurrentThread();
+ if (!_eglIsCurrentThreadDummy()) {
+ thr->CurrentFuncName = funcName;
+ thr->CurrentObjectLabel = NULL;
+
+ if (objectType == EGL_OBJECT_THREAD_KHR)
+ thr->CurrentObjectLabel = thr->Label;
+ else if (objectType == EGL_OBJECT_DISPLAY_KHR && disp)
+ thr->CurrentObjectLabel = disp->Label;
+ else if (object)
+ thr->CurrentObjectLabel = object->Label;
+
+ return EGL_TRUE;
+ }
+
+ _eglDebugReportFull(EGL_BAD_ALLOC, funcName, funcName,
+ EGL_DEBUG_MSG_CRITICAL_KHR, NULL, NULL);
+ return EGL_FALSE;
+}
+
+#define _EGL_FUNC_START(disp, objectType, object, ret) \
+ do { \
+ if (!_eglSetFuncName(__func__, disp, objectType, (_EGLResource *) object)) { \
+ if (disp) \
+ _eglUnlockDisplay(disp); \
+ return ret; \
+ } \
+ } while(0)
+
+/**
+ * Convert an attribute list from EGLint[] to EGLAttrib[].
+ *
+ * Return an EGL error code. The output parameter out_attrib_list is modified
+ * only on success.
+ */
+EGLint
+_eglConvertIntsToAttribs(const EGLint *int_list, EGLAttrib **out_attrib_list)
+{
+ size_t len = 0;
+ EGLAttrib *attrib_list;
+
+ if (int_list) {
+ while (int_list[2*len] != EGL_NONE)
+ ++len;
+ }
+
+ if (len == 0) {
+ *out_attrib_list = NULL;
+ return EGL_SUCCESS;
+ }
+
+ if (2*len + 1 > SIZE_MAX / sizeof(EGLAttrib))
+ return EGL_BAD_ALLOC;
+
+ attrib_list = malloc((2*len + 1) * sizeof(EGLAttrib));
+ if (!attrib_list)
+ return EGL_BAD_ALLOC;
+
+ for (size_t i = 0; i < len; ++i) {
+ attrib_list[2*i + 0] = int_list[2*i + 0];
+ attrib_list[2*i + 1] = int_list[2*i + 1];
+ }
+
+ attrib_list[2*len] = EGL_NONE;
+
+ *out_attrib_list = attrib_list;
+ return EGL_SUCCESS;
+}
+
static EGLint *
_eglConvertAttribsToInt(const EGLAttrib *attr_list)
@@ -286,6 +359,8 @@ eglGetDisplay(EGLNativeDisplayType nativeDisplay)
_EGLDisplay *dpy;
void *native_display_ptr;
+ _EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_NO_DISPLAY);
+
STATIC_ASSERT(sizeof(void*) == sizeof(nativeDisplay));
native_display_ptr = (void*) nativeDisplay;
@@ -294,9 +369,9 @@ eglGetDisplay(EGLNativeDisplayType nativeDisplay)
return _eglGetDisplayHandle(dpy);
}
-static EGLDisplay EGLAPIENTRY
-eglGetPlatformDisplayEXT(EGLenum platform, void *native_display,
- const EGLint *attrib_list)
+static EGLDisplay
+_eglGetPlatformDisplayCommon(EGLenum platform, void *native_display,
+ const EGLint *attrib_list)
{
_EGLDisplay *dpy;
@@ -318,6 +393,11 @@ eglGetPlatformDisplayEXT(EGLenum platform, void *native_display,
attrib_list);
break;
#endif
+#ifdef HAVE_SURFACELESS_PLATFORM
+ case EGL_PLATFORM_SURFACELESS_MESA:
+ dpy = _eglGetSurfacelessDisplay(native_display, attrib_list);
+ break;
+#endif
default:
RETURN_EGL_ERROR(NULL, EGL_BAD_PARAMETER, NULL);
}
@@ -325,17 +405,28 @@ eglGetPlatformDisplayEXT(EGLenum platform, void *native_display,
return _eglGetDisplayHandle(dpy);
}
+static EGLDisplay EGLAPIENTRY
+eglGetPlatformDisplayEXT(EGLenum platform, void *native_display,
+ const EGLint *attrib_list)
+{
+ _EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_NO_DISPLAY);
+ return _eglGetPlatformDisplayCommon(platform, native_display, attrib_list);
+}
+
EGLDisplay EGLAPIENTRY
eglGetPlatformDisplay(EGLenum platform, void *native_display,
const EGLAttrib *attrib_list)
{
EGLDisplay display;
- EGLint *int_attribs = _eglConvertAttribsToInt(attrib_list);
+ EGLint *int_attribs;
+ _EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_NO_DISPLAY);
+
+ 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);
+ display = _eglGetPlatformDisplayCommon(platform, native_display, int_attribs);
free(int_attribs);
return display;
}
@@ -405,13 +496,15 @@ _eglCreateExtensionsString(_EGLDisplay *dpy)
_eglAppendExtension(&exts, "EGL_KHR_image");
_EGL_CHECK_EXTENSION(KHR_image_base);
_EGL_CHECK_EXTENSION(KHR_image_pixmap);
+ _EGL_CHECK_EXTENSION(KHR_no_config_context);
_EGL_CHECK_EXTENSION(KHR_reusable_sync);
_EGL_CHECK_EXTENSION(KHR_surfaceless_context);
- _EGL_CHECK_EXTENSION(KHR_vg_parent_image);
+ if (dpy->Extensions.EXT_swap_buffers_with_damage)
+ _eglAppendExtension(&exts, "EGL_KHR_swap_buffers_with_damage");
_EGL_CHECK_EXTENSION(KHR_wait_sync);
- _EGL_CHECK_EXTENSION(MESA_configless_context);
- _EGL_CHECK_EXTENSION(MESA_drm_display);
+ if (dpy->Extensions.KHR_no_config_context)
+ _eglAppendExtension(&exts, "EGL_MESA_configless_context");
_EGL_CHECK_EXTENSION(MESA_drm_image);
_EGL_CHECK_EXTENSION(MESA_image_dma_buf_export);
@@ -432,14 +525,11 @@ _eglCreateAPIsString(_EGLDisplay *dpy)
if (dpy->ClientAPIs & EGL_OPENGL_BIT)
strcat(dpy->ClientAPIsString, "OpenGL ");
- if (dpy->ClientAPIs & EGL_OPENGL_ES_BIT)
+ if (dpy->ClientAPIs & EGL_OPENGL_ES_BIT ||
+ dpy->ClientAPIs & EGL_OPENGL_ES2_BIT ||
+ dpy->ClientAPIs & EGL_OPENGL_ES3_BIT_KHR) {
strcat(dpy->ClientAPIsString, "OpenGL_ES ");
-
- if (dpy->ClientAPIs & EGL_OPENGL_ES2_BIT)
- strcat(dpy->ClientAPIsString, "OpenGL_ES2 ");
-
- if (dpy->ClientAPIs & EGL_OPENGL_ES3_BIT_KHR)
- strcat(dpy->ClientAPIsString, "OpenGL_ES3 ");
+ }
if (dpy->ClientAPIs & EGL_OPENVG_BIT)
strcat(dpy->ClientAPIsString, "OpenVG ");
@@ -477,6 +567,8 @@ eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
{
_EGLDisplay *disp = _eglLockDisplay(dpy);
+ _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
+
if (!disp)
RETURN_EGL_ERROR(NULL, EGL_BAD_DISPLAY, EGL_FALSE);
@@ -527,6 +619,8 @@ eglTerminate(EGLDisplay dpy)
{
_EGLDisplay *disp = _eglLockDisplay(dpy);
+ _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
+
if (!disp)
RETURN_EGL_ERROR(NULL, EGL_BAD_DISPLAY, EGL_FALSE);
@@ -554,6 +648,7 @@ eglQueryString(EGLDisplay dpy, EGLint name)
}
disp = _eglLockDisplay(dpy);
+ _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, NULL);
_EGL_CHECK_DISPLAY(disp, NULL, drv);
switch (name) {
@@ -579,6 +674,8 @@ eglGetConfigs(EGLDisplay dpy, EGLConfig *configs,
_EGLDriver *drv;
EGLBoolean ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
+
_EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
ret = drv->API.GetConfigs(drv, disp, configs, config_size, num_config);
@@ -594,6 +691,8 @@ eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs,
_EGLDriver *drv;
EGLBoolean ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
+
_EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
ret = drv->API.ChooseConfig(drv, disp, attrib_list, configs,
config_size, num_config);
@@ -611,6 +710,8 @@ eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config,
_EGLDriver *drv;
EGLBoolean ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
+
_EGL_CHECK_CONFIG(disp, conf, EGL_FALSE, drv);
ret = drv->API.GetConfigAttrib(drv, disp, conf, attribute, value);
@@ -629,9 +730,13 @@ eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_list,
_EGLContext *context;
EGLContext ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_CONTEXT);
+
_EGL_CHECK_DISPLAY(disp, EGL_NO_CONTEXT, drv);
- if (!config && !disp->Extensions.MESA_configless_context)
+ if (config != EGL_NO_CONFIG_KHR)
+ _EGL_CHECK_CONFIG(disp, conf, EGL_NO_CONTEXT, drv);
+ else if (!disp->Extensions.KHR_no_config_context)
RETURN_EGL_ERROR(disp, EGL_BAD_CONFIG, EGL_NO_CONTEXT);
if (!share && share_list != EGL_NO_CONTEXT)
@@ -652,6 +757,8 @@ eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
_EGLDriver *drv;
EGLBoolean ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_CONTEXT_KHR, context, EGL_FALSE);
+
_EGL_CHECK_CONTEXT(disp, context, EGL_FALSE, drv);
_eglUnlinkContext(context);
ret = drv->API.DestroyContext(drv, disp, context);
@@ -671,6 +778,8 @@ eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read,
_EGLDriver *drv;
EGLBoolean ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_CONTEXT_KHR, context, EGL_FALSE);
+
if (!disp)
RETURN_EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_FALSE);
drv = disp->Driver;
@@ -717,6 +826,8 @@ eglQueryContext(EGLDisplay dpy, EGLContext ctx,
_EGLDriver *drv;
EGLBoolean ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_CONTEXT_KHR, context, EGL_FALSE);
+
_EGL_CHECK_CONTEXT(disp, context, EGL_FALSE, drv);
ret = drv->API.QueryContext(drv, disp, context, attribute, value);
@@ -733,11 +844,30 @@ _eglCreateWindowSurfaceCommon(_EGLDisplay *disp, EGLConfig config,
_EGLSurface *surf;
EGLSurface ret;
- _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
if (native_window == NULL)
RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
+#ifdef HAVE_SURFACELESS_PLATFORM
+ if (disp->Platform == _EGL_PLATFORM_SURFACELESS) {
+ /* From the EGL_MESA_platform_surfaceless spec (v1):
+ *
+ * eglCreatePlatformWindowSurface fails when called with a <display>
+ * that belongs to the surfaceless platform. It returns
+ * EGL_NO_SURFACE and generates EGL_BAD_NATIVE_WINDOW. The
+ * justification for this unconditional failure is that the
+ * surfaceless platform has no native windows, and therefore the
+ * <native_window> parameter is always invalid.
+ *
+ * This check must occur before checking the EGLConfig, which emits
+ * EGL_BAD_CONFIG.
+ */
+ RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
+ }
+#endif
+
+ _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
+
surf = drv->API.CreateWindowSurface(drv, disp, conf, native_window,
attrib_list);
ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
@@ -751,19 +881,16 @@ eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config,
EGLNativeWindowType window, const EGLint *attrib_list)
{
_EGLDisplay *disp = _eglLockDisplay(dpy);
+
+ _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
STATIC_ASSERT(sizeof(void*) == sizeof(window));
return _eglCreateWindowSurfaceCommon(disp, config, (void*) window,
attrib_list);
}
-
-static EGLSurface EGLAPIENTRY
-eglCreatePlatformWindowSurfaceEXT(EGLDisplay dpy, EGLConfig config,
- void *native_window,
- const EGLint *attrib_list)
+static void *
+fixupNativeWindow(_EGLDisplay *disp, void *native_window)
{
- _EGLDisplay *disp = _eglLockDisplay(dpy);
-
#ifdef HAVE_X11_PLATFORM
if (disp->Platform == _EGL_PLATFORM_X11 && native_window != NULL) {
/* The `native_window` parameter for the X11 platform differs between
@@ -773,10 +900,22 @@ eglCreatePlatformWindowSurfaceEXT(EGLDisplay dpy, EGLConfig config,
* `Window*`. Convert `Window*` to `Window` because that's what
* dri2_x11_create_window_surface() expects.
*/
- native_window = (void*) (* (Window*) native_window);
+ return (void *)(* (Window*) native_window);
}
#endif
+ return native_window;
+}
+
+static EGLSurface EGLAPIENTRY
+eglCreatePlatformWindowSurfaceEXT(EGLDisplay dpy, EGLConfig config,
+ void *native_window,
+ const EGLint *attrib_list)
+{
+ _EGLDisplay *disp = _eglLockDisplay(dpy);
+
+ native_window = fixupNativeWindow(disp, native_window);
+ _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
return _eglCreateWindowSurfaceCommon(disp, config, native_window,
attrib_list);
}
@@ -787,18 +926,39 @@ eglCreatePlatformWindowSurface(EGLDisplay dpy, EGLConfig config,
void *native_window,
const EGLAttrib *attrib_list)
{
+ _EGLDisplay *disp = _eglLockDisplay(dpy);
EGLSurface surface;
- EGLint *int_attribs = _eglConvertAttribsToInt(attrib_list);
+ EGLint *int_attribs;
+
+ _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
+ int_attribs = _eglConvertAttribsToInt(attrib_list);
if (attrib_list && !int_attribs)
- RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_NO_SURFACE);
+ RETURN_EGL_ERROR(disp, EGL_BAD_ALLOC, EGL_NO_SURFACE);
- surface = eglCreatePlatformWindowSurfaceEXT(dpy, config, native_window,
- int_attribs);
+ native_window = fixupNativeWindow(disp, native_window);
+ surface = _eglCreateWindowSurfaceCommon(disp, config, native_window,
+ int_attribs);
free(int_attribs);
return surface;
}
+static void *
+fixupNativePixmap(_EGLDisplay *disp, void *native_pixmap)
+{
+#ifdef HAVE_X11_PLATFORM
+ /* The `native_pixmap` parameter for the X11 platform differs between
+ * eglCreatePixmapSurface() and eglCreatePlatformPixmapSurfaceEXT(). In
+ * eglCreatePixmapSurface(), the type of `native_pixmap` is an Xlib
+ * `Pixmap`. In eglCreatePlatformPixmapSurfaceEXT(), the type is
+ * `Pixmap*`. Convert `Pixmap*` to `Pixmap` because that's what
+ * dri2_x11_create_pixmap_surface() expects.
+ */
+ if (disp->Platform == _EGL_PLATFORM_X11 && native_pixmap != NULL)
+ return (void *)(* (Pixmap*) native_pixmap);
+#endif
+ return native_pixmap;
+}
static EGLSurface
_eglCreatePixmapSurfaceCommon(_EGLDisplay *disp, EGLConfig config,
@@ -809,6 +969,22 @@ _eglCreatePixmapSurfaceCommon(_EGLDisplay *disp, EGLConfig config,
_EGLSurface *surf;
EGLSurface ret;
+#if HAVE_SURFACELESS_PLATFORM
+ if (disp->Platform == _EGL_PLATFORM_SURFACELESS) {
+ /* From the EGL_MESA_platform_surfaceless spec (v1):
+ *
+ * [Like eglCreatePlatformWindowSurface,] eglCreatePlatformPixmapSurface
+ * also fails when called with a <display> that belongs to the
+ * surfaceless platform. It returns EGL_NO_SURFACE and generates
+ * EGL_BAD_NATIVE_PIXMAP.
+ *
+ * This check must occur before checking the EGLConfig, which emits
+ * EGL_BAD_CONFIG.
+ */
+ RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_PIXMAP, EGL_NO_SURFACE);
+ }
+#endif
+
_EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
surf = drv->API.CreatePixmapSurface(drv, disp, conf, native_pixmap,
attrib_list);
@@ -823,6 +999,8 @@ eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config,
EGLNativePixmapType pixmap, const EGLint *attrib_list)
{
_EGLDisplay *disp = _eglLockDisplay(dpy);
+
+ _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
STATIC_ASSERT(sizeof(void*) == sizeof(pixmap));
return _eglCreatePixmapSurfaceCommon(disp, config, (void*) pixmap,
attrib_list);
@@ -835,19 +1013,8 @@ eglCreatePlatformPixmapSurfaceEXT(EGLDisplay dpy, EGLConfig config,
{
_EGLDisplay *disp = _eglLockDisplay(dpy);
-#ifdef HAVE_X11_PLATFORM
- /* The `native_pixmap` parameter for the X11 platform differs between
- * eglCreatePixmapSurface() and eglCreatePlatformPixmapSurfaceEXT(). In
- * eglCreatePixmapSurface(), the type of `native_pixmap` is an Xlib
- * `Pixmap`. In eglCreatePlatformPixmapSurfaceEXT(), the type is
- * `Pixmap*`. Convert `Pixmap*` to `Pixmap` because that's what
- * dri2_x11_create_pixmap_surface() expects.
- */
- if (disp->Platform == _EGL_PLATFORM_X11 && native_pixmap != NULL) {
- native_pixmap = (void*) (* (Pixmap*) native_pixmap);
- }
-#endif
-
+ _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
+ native_pixmap = fixupNativePixmap(disp, native_pixmap);
return _eglCreatePixmapSurfaceCommon(disp, config, native_pixmap,
attrib_list);
}
@@ -858,14 +1025,19 @@ eglCreatePlatformPixmapSurface(EGLDisplay dpy, EGLConfig config,
void *native_pixmap,
const EGLAttrib *attrib_list)
{
+ _EGLDisplay *disp = _eglLockDisplay(dpy);
EGLSurface surface;
- EGLint *int_attribs = _eglConvertAttribsToInt(attrib_list);
+ EGLint *int_attribs;
+
+ _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
+ int_attribs = _eglConvertAttribsToInt(attrib_list);
if (attrib_list && !int_attribs)
- RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_NO_SURFACE);
+ RETURN_EGL_ERROR(disp, EGL_BAD_ALLOC, EGL_NO_SURFACE);
- surface = eglCreatePlatformPixmapSurfaceEXT(dpy, config, native_pixmap,
- int_attribs);
+ native_pixmap = fixupNativePixmap(disp, native_pixmap);
+ surface = _eglCreatePixmapSurfaceCommon(disp, config, native_pixmap,
+ int_attribs);
free(int_attribs);
return surface;
}
@@ -881,6 +1053,7 @@ eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config,
_EGLSurface *surf;
EGLSurface ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
_EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
surf = drv->API.CreatePbufferSurface(drv, disp, conf, attrib_list);
@@ -898,6 +1071,7 @@ eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
_EGLDriver *drv;
EGLBoolean ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
_EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
_eglUnlinkSurface(surf);
ret = drv->API.DestroySurface(drv, disp, surf);
@@ -914,6 +1088,7 @@ eglQuerySurface(EGLDisplay dpy, EGLSurface surface,
_EGLDriver *drv;
EGLBoolean ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
_EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
ret = drv->API.QuerySurface(drv, disp, surf, attribute, value);
@@ -929,6 +1104,7 @@ eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface,
_EGLDriver *drv;
EGLBoolean ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
_EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
ret = drv->API.SurfaceAttrib(drv, disp, surf, attribute, value);
@@ -944,6 +1120,7 @@ eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
_EGLDriver *drv;
EGLBoolean ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
_EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
ret = drv->API.BindTexImage(drv, disp, surf, buffer);
@@ -959,6 +1136,7 @@ eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
_EGLDriver *drv;
EGLBoolean ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
_EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
ret = drv->API.ReleaseTexImage(drv, disp, surf, buffer);
@@ -971,17 +1149,17 @@ eglSwapInterval(EGLDisplay dpy, EGLint interval)
{
_EGLDisplay *disp = _eglLockDisplay(dpy);
_EGLContext *ctx = _eglGetCurrentContext();
- _EGLSurface *surf;
+ _EGLSurface *surf = ctx ? ctx->DrawSurface : NULL;
_EGLDriver *drv;
EGLBoolean ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
_EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
ctx->Resource.Display != disp)
RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE);
- surf = ctx->DrawSurface;
if (_eglGetSurfaceHandle(surf) == EGL_NO_SURFACE)
RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
@@ -1000,6 +1178,7 @@ eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
_EGLDriver *drv;
EGLBoolean ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
_EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
/* surface must be bound to current context in EGL 1.4 */
@@ -1015,13 +1194,11 @@ eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
}
-static EGLBoolean EGLAPIENTRY
-eglSwapBuffersWithDamageEXT(EGLDisplay dpy, EGLSurface surface,
- EGLint *rects, EGLint n_rects)
+static EGLBoolean
+eglSwapBuffersWithDamageCommon(_EGLDisplay *disp, _EGLSurface *surf,
+ EGLint *rects, EGLint n_rects)
{
_EGLContext *ctx = _eglGetCurrentContext();
- _EGLDisplay *disp = _eglLockDisplay(dpy);
- _EGLSurface *surf = _eglLookupSurface(surface, disp);
_EGLDriver *drv;
EGLBoolean ret;
@@ -1040,6 +1217,26 @@ eglSwapBuffersWithDamageEXT(EGLDisplay dpy, EGLSurface surface,
RETURN_EGL_EVAL(disp, ret);
}
+static EGLBoolean EGLAPIENTRY
+eglSwapBuffersWithDamageEXT(EGLDisplay dpy, EGLSurface surface,
+ EGLint *rects, EGLint n_rects)
+{
+ _EGLDisplay *disp = _eglLockDisplay(dpy);
+ _EGLSurface *surf = _eglLookupSurface(surface, disp);
+ _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
+ return eglSwapBuffersWithDamageCommon(disp, surf, rects, n_rects);
+}
+
+static EGLBoolean EGLAPIENTRY
+eglSwapBuffersWithDamageKHR(EGLDisplay dpy, EGLSurface surface,
+ EGLint *rects, EGLint n_rects)
+{
+ _EGLDisplay *disp = _eglLockDisplay(dpy);
+ _EGLSurface *surf = _eglLookupSurface(surface, disp);
+ _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
+ return eglSwapBuffersWithDamageCommon(disp, surf, rects, n_rects);
+}
+
EGLBoolean EGLAPIENTRY
eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
{
@@ -1049,6 +1246,7 @@ eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
EGLBoolean ret;
void *native_pixmap_ptr;
+ _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
STATIC_ASSERT(sizeof(void*) == sizeof(target));
native_pixmap_ptr = (void*) target;
@@ -1061,8 +1259,8 @@ eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
}
-EGLBoolean EGLAPIENTRY
-eglWaitClient(void)
+static EGLBoolean
+_eglWaitClientCommon(void)
{
_EGLContext *ctx = _eglGetCurrentContext();
_EGLDisplay *disp;
@@ -1088,22 +1286,19 @@ eglWaitClient(void)
RETURN_EGL_EVAL(disp, ret);
}
+EGLBoolean EGLAPIENTRY
+eglWaitClient(void)
+{
+ _EGL_FUNC_START(NULL, EGL_OBJECT_CONTEXT_KHR, _eglGetCurrentContext(), EGL_FALSE);
+ return _eglWaitClientCommon();
+}
EGLBoolean EGLAPIENTRY
eglWaitGL(void)
{
- _EGLThreadInfo *t = _eglGetCurrentThread();
- EGLint api_index = t->CurrentAPIIndex;
- EGLint es_index = _eglConvertApiToIndex(EGL_OPENGL_ES_API);
- EGLBoolean ret;
-
- if (api_index != es_index && _eglIsCurrentThreadDummy())
- RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_FALSE);
-
- t->CurrentAPIIndex = es_index;
- ret = eglWaitClient();
- t->CurrentAPIIndex = api_index;
- return ret;
+ /* Since we only support OpenGL and GLES, eglWaitGL is equivalent to eglWaitClient. */
+ _EGL_FUNC_START(NULL, EGL_OBJECT_CONTEXT_KHR, _eglGetCurrentContext(), EGL_FALSE);
+ return _eglWaitClientCommon();
}
@@ -1118,6 +1313,8 @@ eglWaitNative(EGLint engine)
if (!ctx)
RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
+ _EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_FALSE);
+
disp = ctx->Resource.Display;
mtx_lock(&disp->Mutex);
@@ -1167,6 +1364,8 @@ eglGetCurrentSurface(EGLint readdraw)
_EGLSurface *surf;
EGLSurface ret;
+ _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_NO_SURFACE);
+
if (!ctx)
RETURN_EGL_SUCCESS(NULL, EGL_NO_SURFACE);
@@ -1200,13 +1399,6 @@ eglGetError(void)
}
-static EGLDisplay EGLAPIENTRY
-eglGetDRMDisplayMESA(int fd)
-{
- _EGLDisplay *dpy = _eglFindDisplay(_EGL_PLATFORM_DRM, (void *) (intptr_t) fd);
- return _eglGetDisplayHandle(dpy);
-}
-
/**
** EGL 1.2
**/
@@ -1225,15 +1417,18 @@ eglGetDRMDisplayMESA(int fd)
EGLBoolean EGLAPIENTRY
eglBindAPI(EGLenum api)
{
- _EGLThreadInfo *t = _eglGetCurrentThread();
+ _EGLThreadInfo *t;
+
+ _EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_FALSE);
+ t = _eglGetCurrentThread();
if (_eglIsCurrentThreadDummy())
RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_FALSE);
if (!_eglIsApiValid(api))
RETURN_EGL_ERROR(NULL, EGL_BAD_PARAMETER, EGL_FALSE);
- t->CurrentAPIIndex = _eglConvertApiToIndex(api);
+ t->CurrentAPI = api;
RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
}
@@ -1249,7 +1444,7 @@ eglQueryAPI(void)
EGLenum ret;
/* returns one of EGL_OPENGL_API, EGL_OPENGL_ES_API or EGL_OPENVG_API */
- ret = _eglConvertApiFromIndex(t->CurrentAPIIndex);
+ ret = t->CurrentAPI;
RETURN_EGL_SUCCESS(NULL, ret);
}
@@ -1266,6 +1461,8 @@ eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype,
_EGLSurface *surf;
EGLSurface ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
+
_EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
surf = drv->API.CreatePbufferFromClientBuffer(drv, disp, buftype, buffer,
@@ -1282,25 +1479,19 @@ eglReleaseThread(void)
/* unbind current contexts */
if (!_eglIsCurrentThreadDummy()) {
_EGLThreadInfo *t = _eglGetCurrentThread();
- EGLint api_index = t->CurrentAPIIndex;
- EGLint i;
+ _EGLContext *ctx = t->CurrentContext;
- for (i = 0; i < _EGL_API_NUM_APIS; i++) {
- _EGLContext *ctx = t->CurrentContexts[i];
- if (ctx) {
- _EGLDisplay *disp = ctx->Resource.Display;
- _EGLDriver *drv;
+ _EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_FALSE);
- t->CurrentAPIIndex = i;
+ if (ctx) {
+ _EGLDisplay *disp = ctx->Resource.Display;
+ _EGLDriver *drv;
- mtx_lock(&disp->Mutex);
- drv = disp->Driver;
- (void) drv->API.MakeCurrent(drv, disp, NULL, NULL, NULL);
- mtx_unlock(&disp->Mutex);
- }
+ mtx_lock(&disp->Mutex);
+ drv = disp->Driver;
+ (void) drv->API.MakeCurrent(drv, disp, NULL, NULL, NULL);
+ mtx_unlock(&disp->Mutex);
}
-
- t->CurrentAPIIndex = api_index;
}
_eglDestroyCurrentThread();
@@ -1309,11 +1500,10 @@ eglReleaseThread(void)
}
-static EGLImage EGLAPIENTRY
-eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target,
+static EGLImage
+_eglCreateImageCommon(_EGLDisplay *disp, EGLContext ctx, EGLenum target,
EGLClientBuffer buffer, const EGLint *attr_list)
{
- _EGLDisplay *disp = _eglLockDisplay(dpy);
_EGLContext *context = _eglLookupContext(ctx, disp);
_EGLDriver *drv;
_EGLImage *img;
@@ -1337,18 +1527,31 @@ eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target,
RETURN_EGL_EVAL(disp, ret);
}
+static EGLImage EGLAPIENTRY
+eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target,
+ EGLClientBuffer buffer, const EGLint *attr_list)
+{
+ _EGLDisplay *disp = _eglLockDisplay(dpy);
+ _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_IMAGE_KHR);
+ return _eglCreateImageCommon(disp, ctx, target, buffer, attr_list);
+}
+
EGLImage EGLAPIENTRY
eglCreateImage(EGLDisplay dpy, EGLContext ctx, EGLenum target,
EGLClientBuffer buffer, const EGLAttrib *attr_list)
{
+ _EGLDisplay *disp = _eglLockDisplay(dpy);
EGLImage image;
- EGLint *int_attribs = _eglConvertAttribsToInt(attr_list);
+ EGLint *int_attribs;
+
+ _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_IMAGE_KHR);
+ int_attribs = _eglConvertAttribsToInt(attr_list);
if (attr_list && !int_attribs)
- RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_NO_IMAGE);
+ RETURN_EGL_ERROR(disp, EGL_BAD_ALLOC, EGL_NO_IMAGE);
- image = eglCreateImageKHR(dpy, ctx, target, buffer, int_attribs);
+ image = _eglCreateImageCommon(disp, ctx, target, buffer, int_attribs);
free(int_attribs);
return image;
}
@@ -1362,6 +1565,8 @@ eglDestroyImage(EGLDisplay dpy, EGLImage image)
_EGLDriver *drv;
EGLBoolean ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_IMAGE_KHR, img, EGL_FALSE);
+
_EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
if (!disp->Extensions.KHR_image_base)
RETURN_EGL_EVAL(disp, EGL_FALSE);
@@ -1376,11 +1581,10 @@ eglDestroyImage(EGLDisplay dpy, EGLImage image)
static EGLSync
-_eglCreateSync(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list,
- const EGLAttrib *attrib_list64, EGLBoolean is64,
+_eglCreateSync(_EGLDisplay *disp, EGLenum type, const EGLAttrib *attrib_list,
+ EGLBoolean orig_is_EGLAttrib,
EGLenum invalid_type_error)
{
- _EGLDisplay *disp = _eglLockDisplay(dpy);
_EGLContext *ctx = _eglGetCurrentContext();
_EGLDriver *drv;
_EGLSync *sync;
@@ -1388,11 +1592,21 @@ _eglCreateSync(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list,
_EGL_CHECK_DISPLAY(disp, EGL_NO_SYNC_KHR, drv);
- if (!disp->Extensions.KHR_cl_event2 && is64)
- RETURN_EGL_EVAL(disp, EGL_NO_SYNC_KHR);
+ if (!disp->Extensions.KHR_cl_event2 && orig_is_EGLAttrib) {
+ /* There exist two EGLAttrib variants of eglCreateSync*:
+ * eglCreateSync64KHR which requires EGL_KHR_cl_event2, and eglCreateSync
+ * which requires EGL 1.5. Here we use the presence of EGL_KHR_cl_event2
+ * support as a proxy for EGL 1.5 support, even though that's not
+ * entirely correct (though _eglComputeVersion does the same).
+ *
+ * The EGL spec provides no guidance on how to handle unsupported
+ * functions. EGL_BAD_MATCH seems reasonable.
+ */
+ RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SYNC_KHR);
+ }
/* return an error if the client API doesn't support GL_OES_EGL_sync */
- if (!ctx || ctx->Resource.Display != dpy ||
+ if (!ctx || ctx->Resource.Display != disp ||
ctx->ClientAPI != EGL_OPENGL_ES_API)
RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SYNC_KHR);
@@ -1413,7 +1627,7 @@ _eglCreateSync(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list,
RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR);
}
- sync = drv->API.CreateSyncKHR(drv, disp, type, attrib_list, attrib_list64);
+ sync = drv->API.CreateSyncKHR(drv, disp, type, attrib_list);
ret = (sync) ? _eglLinkSync(sync) : EGL_NO_SYNC_KHR;
RETURN_EGL_EVAL(disp, ret);
@@ -1421,17 +1635,40 @@ _eglCreateSync(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list,
static EGLSync EGLAPIENTRY
-eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list)
+eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *int_list)
{
- return _eglCreateSync(dpy, type, attrib_list, NULL, EGL_FALSE,
+ _EGLDisplay *disp = _eglLockDisplay(dpy);
+ _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
+
+ EGLSync sync;
+ EGLAttrib *attrib_list;
+ EGLint err;
+
+ if (sizeof(int_list[0]) == sizeof(attrib_list[0])) {
+ attrib_list = (EGLAttrib *) int_list;
+ } else {
+ err = _eglConvertIntsToAttribs(int_list, &attrib_list);
+ if (err != EGL_SUCCESS)
+ RETURN_EGL_ERROR(disp, err, EGL_NO_SYNC);
+ }
+
+ sync = _eglCreateSync(disp, type, attrib_list, EGL_FALSE,
EGL_BAD_ATTRIBUTE);
+
+ if (sizeof(int_list[0]) != sizeof(attrib_list[0]))
+ free(attrib_list);
+
+ /* Don't double-unlock the display. _eglCreateSync already unlocked it. */
+ return sync;
}
static EGLSync EGLAPIENTRY
eglCreateSync64KHR(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list)
{
- return _eglCreateSync(dpy, type, NULL, attrib_list, EGL_TRUE,
+ _EGLDisplay *disp = _eglLockDisplay(dpy);
+ _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
+ return _eglCreateSync(disp, type, attrib_list, EGL_TRUE,
EGL_BAD_ATTRIBUTE);
}
@@ -1439,7 +1676,9 @@ eglCreateSync64KHR(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list)
EGLSync EGLAPIENTRY
eglCreateSync(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list)
{
- return _eglCreateSync(dpy, type, NULL, attrib_list, EGL_TRUE,
+ _EGLDisplay *disp = _eglLockDisplay(dpy);
+ _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
+ return _eglCreateSync(disp, type, attrib_list, EGL_TRUE,
EGL_BAD_PARAMETER);
}
@@ -1452,6 +1691,8 @@ eglDestroySync(EGLDisplay dpy, EGLSync sync)
_EGLDriver *drv;
EGLBoolean ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
+
_EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
assert(disp->Extensions.KHR_reusable_sync ||
disp->Extensions.KHR_fence_sync);
@@ -1471,6 +1712,8 @@ eglClientWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout)
_EGLDriver *drv;
EGLint ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
+
_EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
assert(disp->Extensions.KHR_reusable_sync ||
disp->Extensions.KHR_fence_sync);
@@ -1478,17 +1721,30 @@ eglClientWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout)
if (s->SyncStatus == EGL_SIGNALED_KHR)
RETURN_EGL_EVAL(disp, EGL_CONDITION_SATISFIED_KHR);
+ /* if sync type is EGL_SYNC_REUSABLE_KHR, dpy should be
+ * unlocked here to allow other threads also to be able to
+ * go into waiting state.
+ */
+
+ if (s->Type == EGL_SYNC_REUSABLE_KHR)
+ _eglUnlockDisplay(dpy);
+
ret = drv->API.ClientWaitSyncKHR(drv, disp, s, flags, timeout);
- RETURN_EGL_EVAL(disp, ret);
+ /*
+ * 'disp' is already unlocked for reusable sync type,
+ * so passing 'NULL' to bypass unlocking display.
+ */
+ if (s->Type == EGL_SYNC_REUSABLE_KHR)
+ RETURN_EGL_EVAL(NULL, ret);
+ else
+ RETURN_EGL_EVAL(disp, ret);
}
-static EGLint EGLAPIENTRY
-eglWaitSyncKHR(EGLDisplay dpy, EGLSync sync, EGLint flags)
+static EGLint
+_eglWaitSyncCommon(_EGLDisplay *disp, _EGLSync *s, EGLint flags)
{
- _EGLDisplay *disp = _eglLockDisplay(dpy);
- _EGLSync *s = _eglLookupSync(sync, disp);
_EGLContext *ctx = _eglGetCurrentContext();
_EGLDriver *drv;
EGLint ret;
@@ -1509,6 +1765,15 @@ eglWaitSyncKHR(EGLDisplay dpy, EGLSync sync, EGLint flags)
RETURN_EGL_EVAL(disp, ret);
}
+static EGLint EGLAPIENTRY
+eglWaitSyncKHR(EGLDisplay dpy, EGLSync sync, EGLint flags)
+{
+ _EGLDisplay *disp = _eglLockDisplay(dpy);
+ _EGLSync *s = _eglLookupSync(sync, disp);
+ _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
+ return _eglWaitSyncCommon(disp, s, flags);
+}
+
EGLBoolean EGLAPIENTRY
eglWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags)
@@ -1517,7 +1782,10 @@ eglWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags)
* EGLBoolean. In both cases, the return values can only be EGL_FALSE and
* EGL_TRUE.
*/
- return eglWaitSyncKHR(dpy, sync, flags);
+ _EGLDisplay *disp = _eglLockDisplay(dpy);
+ _EGLSync *s = _eglLookupSync(sync, disp);
+ _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
+ return _eglWaitSyncCommon(disp, s, flags);
}
@@ -1529,6 +1797,8 @@ eglSignalSyncKHR(EGLDisplay dpy, EGLSync sync, EGLenum mode)
_EGLDriver *drv;
EGLBoolean ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
+
_EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
assert(disp->Extensions.KHR_reusable_sync);
ret = drv->API.SignalSyncKHR(drv, disp, s, mode);
@@ -1537,11 +1807,9 @@ eglSignalSyncKHR(EGLDisplay dpy, EGLSync sync, EGLenum mode)
}
-EGLBoolean EGLAPIENTRY
-eglGetSyncAttrib(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib *value)
+static EGLBoolean
+_eglGetSyncAttribCommon(_EGLDisplay *disp, _EGLSync *s, EGLint attribute, EGLAttrib *value)
{
- _EGLDisplay *disp = _eglLockDisplay(dpy);
- _EGLSync *s = _eglLookupSync(sync, disp);
_EGLDriver *drv;
EGLBoolean ret;
@@ -1553,18 +1821,31 @@ eglGetSyncAttrib(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib *valu
RETURN_EGL_EVAL(disp, ret);
}
+EGLBoolean EGLAPIENTRY
+eglGetSyncAttrib(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib *value)
+{
+ _EGLDisplay *disp = _eglLockDisplay(dpy);
+ _EGLSync *s = _eglLookupSync(sync, disp);
+ _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
+ return _eglGetSyncAttribCommon(disp, s, attribute, value);
+}
+
static EGLBoolean EGLAPIENTRY
eglGetSyncAttribKHR(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLint *value)
{
+ _EGLDisplay *disp = _eglLockDisplay(dpy);
+ _EGLSync *s = _eglLookupSync(sync, disp);
EGLAttrib attrib;
EGLBoolean result;
+ _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
+
if (!value)
- RETURN_EGL_ERROR(NULL, EGL_BAD_PARAMETER, EGL_FALSE);
+ RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
attrib = *value;
- result = eglGetSyncAttrib(dpy, sync, attribute, &attrib);
+ result = _eglGetSyncAttribCommon(disp, s, attribute, &attrib);
/* The EGL_KHR_fence_sync spec says this about eglGetSyncAttribKHR:
*
@@ -1588,6 +1869,8 @@ eglSwapBuffersRegionNOK(EGLDisplay dpy, EGLSurface surface,
_EGLDriver *drv;
EGLBoolean ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
+
_EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
if (!disp->Extensions.NOK_swap_region)
@@ -1612,6 +1895,8 @@ eglCreateDRMImageMESA(EGLDisplay dpy, const EGLint *attr_list)
_EGLImage *img;
EGLImage ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
+
_EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR, drv);
if (!disp->Extensions.MESA_drm_image)
RETURN_EGL_EVAL(disp, EGL_NO_IMAGE_KHR);
@@ -1631,6 +1916,8 @@ eglExportDRMImageMESA(EGLDisplay dpy, EGLImage image,
_EGLDriver *drv;
EGLBoolean ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_IMAGE_KHR, img, EGL_FALSE);
+
_EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
assert(disp->Extensions.MESA_drm_image);
@@ -1652,6 +1939,8 @@ eglBindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
_EGLDriver *drv;
EGLBoolean ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
+
_EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
assert(disp->Extensions.WL_bind_wayland_display);
@@ -1670,6 +1959,8 @@ eglUnbindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
_EGLDriver *drv;
EGLBoolean ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
+
_EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
assert(disp->Extensions.WL_bind_wayland_display);
@@ -1689,6 +1980,8 @@ eglQueryWaylandBufferWL(EGLDisplay dpy, struct wl_resource *buffer,
_EGLDriver *drv;
EGLBoolean ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
+
_EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
assert(disp->Extensions.WL_bind_wayland_display);
@@ -1709,6 +2002,8 @@ eglCreateWaylandBufferFromImageWL(EGLDisplay dpy, EGLImage image)
_EGLDriver *drv;
struct wl_buffer *ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
+
_EGL_CHECK_DISPLAY(disp, NULL, drv);
assert(disp->Extensions.WL_create_wayland_buffer_from_image);
@@ -1731,6 +2026,8 @@ eglPostSubBufferNV(EGLDisplay dpy, EGLSurface surface,
_EGLDriver *drv;
EGLBoolean ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
+
_EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
if (!disp->Extensions.NV_post_sub_buffer)
@@ -1751,6 +2048,8 @@ eglGetSyncValuesCHROMIUM(EGLDisplay display, EGLSurface surface,
_EGLDriver *drv;
EGLBoolean ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
+
_EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
if (!disp->Extensions.CHROMIUM_sync_control)
RETURN_EGL_EVAL(disp, EGL_FALSE);
@@ -1773,6 +2072,8 @@ eglExportDMABUFImageQueryMESA(EGLDisplay dpy, EGLImage image,
_EGLDriver *drv;
EGLBoolean ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_IMAGE_KHR, img, EGL_FALSE);
+
_EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
assert(disp->Extensions.MESA_image_dma_buf_export);
@@ -1794,6 +2095,8 @@ eglExportDMABUFImageMESA(EGLDisplay dpy, EGLImage image,
_EGLDriver *drv;
EGLBoolean ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_IMAGE_KHR, img, EGL_FALSE);
+
_EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
assert(disp->Extensions.MESA_image_dma_buf_export);
@@ -1805,6 +2108,148 @@ eglExportDMABUFImageMESA(EGLDisplay dpy, EGLImage image,
RETURN_EGL_EVAL(disp, ret);
}
+static EGLint EGLAPIENTRY
+eglLabelObjectKHR(EGLDisplay dpy, EGLenum objectType, EGLObjectKHR object,
+ EGLLabelKHR label)
+{
+ _EGLDisplay *disp = NULL;
+ _EGLResourceType type;
+
+ _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_BAD_ALLOC);
+
+ if (objectType == EGL_OBJECT_THREAD_KHR) {
+ _EGLThreadInfo *t = _eglGetCurrentThread();
+
+ if (!_eglIsCurrentThreadDummy()) {
+ t->Label = label;
+ return EGL_SUCCESS;
+ }
+
+ RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_BAD_ALLOC);
+ }
+
+ disp = _eglLockDisplay(dpy);
+ if (disp == NULL)
+ RETURN_EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_BAD_DISPLAY);
+
+ if (objectType == EGL_OBJECT_DISPLAY_KHR) {
+ if (dpy != (EGLDisplay) object)
+ RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_BAD_PARAMETER);
+
+ disp->Label = label;
+ RETURN_EGL_EVAL(disp, EGL_SUCCESS);
+ }
+
+ switch (objectType) {
+ case EGL_OBJECT_CONTEXT_KHR:
+ type = _EGL_RESOURCE_CONTEXT;
+ break;
+ case EGL_OBJECT_SURFACE_KHR:
+ type = _EGL_RESOURCE_SURFACE;
+ break;
+ case EGL_OBJECT_IMAGE_KHR:
+ type = _EGL_RESOURCE_IMAGE;
+ break;
+ case EGL_OBJECT_SYNC_KHR:
+ type = _EGL_RESOURCE_SYNC;
+ break;
+ case EGL_OBJECT_STREAM_KHR:
+ default:
+ RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_BAD_PARAMETER);
+ }
+
+ if (_eglCheckResource(object, type, disp)) {
+ _EGLResource *res = (_EGLResource *) object;
+
+ res->Label = label;
+ RETURN_EGL_EVAL(disp, EGL_SUCCESS);
+ }
+
+ RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_BAD_PARAMETER);
+}
+
+static EGLBoolean
+validDebugMessageLevel(EGLAttrib level)
+{
+ return (level >= EGL_DEBUG_MSG_CRITICAL_KHR &&
+ level <= EGL_DEBUG_MSG_INFO_KHR);
+}
+
+static EGLint EGLAPIENTRY
+eglDebugMessageControlKHR(EGLDEBUGPROCKHR callback,
+ const EGLAttrib *attrib_list)
+{
+ unsigned int newEnabled;
+
+ _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_BAD_ALLOC);
+
+ mtx_lock(_eglGlobal.Mutex);
+
+ newEnabled = _eglGlobal.debugTypesEnabled;
+ if (attrib_list != NULL) {
+ int i;
+
+ for (i = 0; attrib_list[i] != EGL_NONE; i += 2) {
+ if (validDebugMessageLevel(attrib_list[i])) {
+ if (attrib_list[i + 1])
+ newEnabled |= DebugBitFromType(attrib_list[i]);
+ else
+ newEnabled &= ~DebugBitFromType(attrib_list[i]);
+ continue;
+ }
+
+ // On error, set the last error code, call the current
+ // debug callback, and return the error code.
+ mtx_unlock(_eglGlobal.Mutex);
+ _eglReportError(EGL_BAD_ATTRIBUTE, NULL,
+ "Invalid attribute 0x%04lx", (unsigned long) attrib_list[i]);
+ return EGL_BAD_ATTRIBUTE;
+ }
+ }
+
+ if (callback != NULL) {
+ _eglGlobal.debugCallback = callback;
+ _eglGlobal.debugTypesEnabled = newEnabled;
+ } else {
+ _eglGlobal.debugCallback = NULL;
+ _eglGlobal.debugTypesEnabled = _EGL_DEBUG_BIT_CRITICAL | _EGL_DEBUG_BIT_ERROR;
+ }
+
+ mtx_unlock(_eglGlobal.Mutex);
+ return EGL_SUCCESS;
+}
+
+static EGLBoolean EGLAPIENTRY
+eglQueryDebugKHR(EGLint attribute, EGLAttrib *value)
+{
+ _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_BAD_ALLOC);
+
+ mtx_lock(_eglGlobal.Mutex);
+
+ do {
+ if (validDebugMessageLevel(attribute)) {
+ if (_eglGlobal.debugTypesEnabled & DebugBitFromType(attribute))
+ *value = EGL_TRUE;
+ else
+ *value = EGL_FALSE;
+ break;
+ }
+
+ if (attribute == EGL_DEBUG_CALLBACK_KHR) {
+ *value = (EGLAttrib) _eglGlobal.debugCallback;
+ break;
+ }
+
+ mtx_unlock(_eglGlobal.Mutex);
+ _eglReportError(EGL_BAD_ATTRIBUTE, NULL,
+ "Invalid attribute 0x%04lx", (unsigned long) attribute);
+ return EGL_FALSE;
+ } while (0);
+
+ mtx_unlock(_eglGlobal.Mutex);
+ return EGL_TRUE;
+}
+
__eglMustCastToProperFunctionPointerType EGLAPIENTRY
eglGetProcAddress(const char *procname)
{
@@ -1860,7 +2305,6 @@ eglGetProcAddress(const char *procname)
{ "eglGetPlatformDisplay", (_EGLProc) eglGetPlatformDisplay },
{ "eglCreatePlatformWindowSurface", (_EGLProc) eglCreatePlatformWindowSurface },
{ "eglCreatePlatformPixmapSurface", (_EGLProc) eglCreatePlatformPixmapSurface },
- { "eglGetDRMDisplayMESA", (_EGLProc) eglGetDRMDisplayMESA },
{ "eglCreateImageKHR", (_EGLProc) eglCreateImageKHR },
{ "eglDestroyImageKHR", (_EGLProc) eglDestroyImage },
{ "eglCreateSyncKHR", (_EGLProc) eglCreateSyncKHR },
@@ -1879,12 +2323,16 @@ eglGetProcAddress(const char *procname)
{ "eglCreateWaylandBufferFromImageWL", (_EGLProc) eglCreateWaylandBufferFromImageWL },
{ "eglPostSubBufferNV", (_EGLProc) eglPostSubBufferNV },
{ "eglSwapBuffersWithDamageEXT", (_EGLProc) eglSwapBuffersWithDamageEXT },
+ { "eglSwapBuffersWithDamageKHR", (_EGLProc) eglSwapBuffersWithDamageKHR },
{ "eglGetPlatformDisplayEXT", (_EGLProc) eglGetPlatformDisplayEXT },
{ "eglCreatePlatformWindowSurfaceEXT", (_EGLProc) eglCreatePlatformWindowSurfaceEXT },
{ "eglCreatePlatformPixmapSurfaceEXT", (_EGLProc) eglCreatePlatformPixmapSurfaceEXT },
{ "eglGetSyncValuesCHROMIUM", (_EGLProc) eglGetSyncValuesCHROMIUM },
{ "eglExportDMABUFImageQueryMESA", (_EGLProc) eglExportDMABUFImageQueryMESA },
{ "eglExportDMABUFImageMESA", (_EGLProc) eglExportDMABUFImageMESA },
+ { "eglLabelObjectKHR", (_EGLProc) eglLabelObjectKHR },
+ { "eglDebugMessageControlKHR", (_EGLProc) eglDebugMessageControlKHR },
+ { "eglQueryDebugKHR", (_EGLProc) eglQueryDebugKHR },
{ NULL, NULL }
};
EGLint i;
@@ -1893,6 +2341,8 @@ eglGetProcAddress(const char *procname)
if (!procname)
RETURN_EGL_SUCCESS(NULL, NULL);
+ _EGL_FUNC_START(NULL, EGL_NONE, NULL, NULL);
+
ret = NULL;
if (strncmp(procname, "egl", 3) == 0) {
for (i = 0; egl_functions[i].name; i++) {
@@ -1907,3 +2357,74 @@ eglGetProcAddress(const char *procname)
RETURN_EGL_SUCCESS(NULL, ret);
}
+
+static int
+_eglLockDisplayInterop(EGLDisplay dpy, EGLContext context,
+ _EGLDisplay **disp, _EGLDriver **drv,
+ _EGLContext **ctx)
+{
+
+ *disp = _eglLockDisplay(dpy);
+ if (!*disp || !(*disp)->Initialized || !(*disp)->Driver) {
+ if (*disp)
+ _eglUnlockDisplay(*disp);
+ return MESA_GLINTEROP_INVALID_DISPLAY;
+ }
+
+ *drv = (*disp)->Driver;
+
+ *ctx = _eglLookupContext(context, *disp);
+ if (!*ctx ||
+ ((*ctx)->ClientAPI != EGL_OPENGL_API &&
+ (*ctx)->ClientAPI != EGL_OPENGL_ES_API)) {
+ _eglUnlockDisplay(*disp);
+ return MESA_GLINTEROP_INVALID_CONTEXT;
+ }
+
+ return MESA_GLINTEROP_SUCCESS;
+}
+
+PUBLIC int
+MesaGLInteropEGLQueryDeviceInfo(EGLDisplay dpy, EGLContext context,
+ struct mesa_glinterop_device_info *out)
+{
+ _EGLDisplay *disp;
+ _EGLDriver *drv;
+ _EGLContext *ctx;
+ int ret;
+
+ ret = _eglLockDisplayInterop(dpy, context, &disp, &drv, &ctx);
+ if (ret != MESA_GLINTEROP_SUCCESS)
+ return ret;
+
+ if (drv->API.GLInteropQueryDeviceInfo)
+ ret = drv->API.GLInteropQueryDeviceInfo(disp, ctx, out);
+ else
+ ret = MESA_GLINTEROP_UNSUPPORTED;
+
+ _eglUnlockDisplay(disp);
+ return ret;
+}
+
+PUBLIC int
+MesaGLInteropEGLExportObject(EGLDisplay dpy, EGLContext context,
+ struct mesa_glinterop_export_in *in,
+ struct mesa_glinterop_export_out *out)
+{
+ _EGLDisplay *disp;
+ _EGLDriver *drv;
+ _EGLContext *ctx;
+ int ret;
+
+ ret = _eglLockDisplayInterop(dpy, context, &disp, &drv, &ctx);
+ if (ret != MESA_GLINTEROP_SUCCESS)
+ return ret;
+
+ if (drv->API.GLInteropExportObject)
+ ret = drv->API.GLInteropExportObject(disp, ctx, in, out);
+ else
+ ret = MESA_GLINTEROP_UNSUPPORTED;
+
+ _eglUnlockDisplay(disp);
+ return ret;
+}
diff --git a/lib/mesa/src/egl/main/eglapi.h b/lib/mesa/src/egl/main/eglapi.h
index 6c54c7c41..b9bcc8ec8 100644
--- a/lib/mesa/src/egl/main/eglapi.h
+++ b/lib/mesa/src/egl/main/eglapi.h
@@ -41,155 +41,165 @@ extern "C" {
*/
typedef void (*_EGLProc)(void);
-
-/**
- * Typedefs for all EGL API entrypoint functions.
- */
-
-/* driver funcs */
-typedef EGLBoolean (*Initialize_t)(_EGLDriver *, _EGLDisplay *dpy);
-typedef EGLBoolean (*Terminate_t)(_EGLDriver *, _EGLDisplay *dpy);
-
-/* config funcs */
-typedef EGLBoolean (*GetConfigs_t)(_EGLDriver *drv, _EGLDisplay *dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config);
-typedef EGLBoolean (*ChooseConfig_t)(_EGLDriver *drv, _EGLDisplay *dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config);
-typedef EGLBoolean (*GetConfigAttrib_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *config, EGLint attribute, EGLint *value);
-
-/* context funcs */
-typedef _EGLContext *(*CreateContext_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *config, _EGLContext *share_list, const EGLint *attrib_list);
-typedef EGLBoolean (*DestroyContext_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx);
-/* this is the only function (other than Initialize) that may be called with an uninitialized display */
-typedef EGLBoolean (*MakeCurrent_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw, _EGLSurface *read, _EGLContext *ctx);
-typedef EGLBoolean (*QueryContext_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx, EGLint attribute, EGLint *value);
-
-/* surface funcs */
-typedef _EGLSurface *(*CreateWindowSurface_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *config, void *native_window, const EGLint *attrib_list);
-typedef _EGLSurface *(*CreatePixmapSurface_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *config, void *native_pixmap, const EGLint *attrib_list);
-typedef _EGLSurface *(*CreatePbufferSurface_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *config, const EGLint *attrib_list);
-typedef EGLBoolean (*DestroySurface_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface);
-typedef EGLBoolean (*QuerySurface_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface, EGLint attribute, EGLint *value);
-typedef EGLBoolean (*SurfaceAttrib_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface, EGLint attribute, EGLint value);
-typedef EGLBoolean (*BindTexImage_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface, EGLint buffer);
-typedef EGLBoolean (*ReleaseTexImage_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface, EGLint buffer);
-typedef EGLBoolean (*SwapInterval_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, EGLint interval);
-typedef EGLBoolean (*SwapBuffers_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw);
-typedef EGLBoolean (*CopyBuffers_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface, void *native_pixmap_target);
-
-/* misc funcs */
-typedef EGLBoolean (*WaitClient_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx);
-typedef EGLBoolean (*WaitNative_t)(_EGLDriver *drv, _EGLDisplay *dpy, EGLint engine);
-
-/* this function may be called from multiple threads at the same time */
-typedef _EGLProc (*GetProcAddress_t)(_EGLDriver *drv, const char *procname);
-
-
-
-typedef _EGLSurface *(*CreatePbufferFromClientBuffer_t)(_EGLDriver *drv, _EGLDisplay *dpy, EGLenum buftype, EGLClientBuffer buffer, _EGLConfig *config, const EGLint *attrib_list);
-
-
-typedef _EGLImage *(*CreateImageKHR_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attr_list);
-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 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, 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 (*GetSyncAttrib_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync, EGLint attribute, EGLAttrib *value);
-
-
-typedef EGLBoolean (*SwapBuffersRegionNOK_t)(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf, EGLint numRects, const EGLint *rects);
-
-typedef _EGLImage *(*CreateDRMImageMESA_t)(_EGLDriver *drv, _EGLDisplay *disp, const EGLint *attr_list);
-typedef EGLBoolean (*ExportDRMImageMESA_t)(_EGLDriver *drv, _EGLDisplay *disp, _EGLImage *img, EGLint *name, EGLint *handle, EGLint *stride);
-
struct wl_display;
-typedef EGLBoolean (*BindWaylandDisplayWL_t)(_EGLDriver *drv, _EGLDisplay *disp, struct wl_display *display);
-typedef EGLBoolean (*UnbindWaylandDisplayWL_t)(_EGLDriver *drv, _EGLDisplay *disp, struct wl_display *display);
-typedef EGLBoolean (*QueryWaylandBufferWL_t)(_EGLDriver *drv, _EGLDisplay *displ, struct wl_resource *buffer, EGLint attribute, EGLint *value);
-
-typedef struct wl_buffer * (*CreateWaylandBufferFromImageWL_t)(_EGLDriver *drv, _EGLDisplay *disp, _EGLImage *img);
-
-typedef EGLBoolean (*PostSubBufferNV_t)(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surface, EGLint x, EGLint y, EGLint width, EGLint height);
-
-typedef EGLint (*QueryBufferAge_t)(_EGLDriver *drv,
- _EGLDisplay *dpy, _EGLSurface *surface);
-
-typedef EGLBoolean (*SwapBuffersWithDamageEXT_t) (_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface, const EGLint *rects, EGLint n_rects);
-
-typedef EGLBoolean (*GetSyncValuesCHROMIUM_t) (_EGLDisplay *dpy, _EGLSurface *surface, EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc);
-
-typedef EGLBoolean (*ExportDMABUFImageQueryMESA_t)(_EGLDriver *drv, _EGLDisplay *disp, _EGLImage *img, EGLint *fourcc, EGLint *nplanes, EGLuint64KHR *modifiers);
-typedef EGLBoolean (*ExportDMABUFImageMESA_t)(_EGLDriver *drv, _EGLDisplay *disp, _EGLImage *img, EGLint *fds, EGLint *strides, EGLint *offsets);
+struct mesa_glinterop_device_info;
+struct mesa_glinterop_export_in;
+struct mesa_glinterop_export_out;
/**
* The API dispatcher jumps through these functions
*/
struct _egl_api
{
- Initialize_t Initialize;
- Terminate_t Terminate;
-
- GetConfigs_t GetConfigs;
- ChooseConfig_t ChooseConfig;
- GetConfigAttrib_t GetConfigAttrib;
-
- CreateContext_t CreateContext;
- DestroyContext_t DestroyContext;
- MakeCurrent_t MakeCurrent;
- QueryContext_t QueryContext;
-
- CreateWindowSurface_t CreateWindowSurface;
- CreatePixmapSurface_t CreatePixmapSurface;
- CreatePbufferSurface_t CreatePbufferSurface;
- DestroySurface_t DestroySurface;
- QuerySurface_t QuerySurface;
- SurfaceAttrib_t SurfaceAttrib;
- BindTexImage_t BindTexImage;
- ReleaseTexImage_t ReleaseTexImage;
- SwapInterval_t SwapInterval;
- SwapBuffers_t SwapBuffers;
- CopyBuffers_t CopyBuffers;
-
- WaitClient_t WaitClient;
- WaitNative_t WaitNative;
- GetProcAddress_t GetProcAddress;
-
- CreatePbufferFromClientBuffer_t CreatePbufferFromClientBuffer;
-
- CreateImageKHR_t CreateImageKHR;
- DestroyImageKHR_t DestroyImageKHR;
-
- CreateSyncKHR_t CreateSyncKHR;
- DestroySyncKHR_t DestroySyncKHR;
- ClientWaitSyncKHR_t ClientWaitSyncKHR;
- WaitSyncKHR_t WaitSyncKHR;
- SignalSyncKHR_t SignalSyncKHR;
- GetSyncAttrib_t GetSyncAttrib;
-
- SwapBuffersRegionNOK_t SwapBuffersRegionNOK;
-
- CreateDRMImageMESA_t CreateDRMImageMESA;
- ExportDRMImageMESA_t ExportDRMImageMESA;
-
- BindWaylandDisplayWL_t BindWaylandDisplayWL;
- UnbindWaylandDisplayWL_t UnbindWaylandDisplayWL;
- QueryWaylandBufferWL_t QueryWaylandBufferWL;
-
- CreateWaylandBufferFromImageWL_t CreateWaylandBufferFromImageWL;
-
- SwapBuffersWithDamageEXT_t SwapBuffersWithDamageEXT;
-
- PostSubBufferNV_t PostSubBufferNV;
-
- QueryBufferAge_t QueryBufferAge;
- GetSyncValuesCHROMIUM_t GetSyncValuesCHROMIUM;
-
- ExportDMABUFImageQueryMESA_t ExportDMABUFImageQueryMESA;
- ExportDMABUFImageMESA_t ExportDMABUFImageMESA;
+ /* driver funcs */
+ EGLBoolean (*Initialize)(_EGLDriver *, _EGLDisplay *dpy);
+ EGLBoolean (*Terminate)(_EGLDriver *, _EGLDisplay *dpy);
+
+ /* config funcs */
+ EGLBoolean (*GetConfigs)(_EGLDriver *drv, _EGLDisplay *dpy,
+ EGLConfig *configs, EGLint config_size,
+ EGLint *num_config);
+ EGLBoolean (*ChooseConfig)(_EGLDriver *drv, _EGLDisplay *dpy,
+ const EGLint *attrib_list, EGLConfig *configs,
+ EGLint config_size, EGLint *num_config);
+ EGLBoolean (*GetConfigAttrib)(_EGLDriver *drv, _EGLDisplay *dpy,
+ _EGLConfig *config, EGLint attribute,
+ EGLint *value);
+
+ /* context funcs */
+ _EGLContext *(*CreateContext)(_EGLDriver *drv, _EGLDisplay *dpy,
+ _EGLConfig *config, _EGLContext *share_list,
+ const EGLint *attrib_list);
+ EGLBoolean (*DestroyContext)(_EGLDriver *drv, _EGLDisplay *dpy,
+ _EGLContext *ctx);
+ /* this is the only function (other than Initialize) that may be called
+ * with an uninitialized display
+ */
+ EGLBoolean (*MakeCurrent)(_EGLDriver *drv, _EGLDisplay *dpy,
+ _EGLSurface *draw, _EGLSurface *read,
+ _EGLContext *ctx);
+ EGLBoolean (*QueryContext)(_EGLDriver *drv, _EGLDisplay *dpy,
+ _EGLContext *ctx, EGLint attribute,
+ EGLint *value);
+
+ /* surface funcs */
+ _EGLSurface *(*CreateWindowSurface)(_EGLDriver *drv, _EGLDisplay *dpy,
+ _EGLConfig *config, void *native_window,
+ const EGLint *attrib_list);
+ _EGLSurface *(*CreatePixmapSurface)(_EGLDriver *drv, _EGLDisplay *dpy,
+ _EGLConfig *config, void *native_pixmap,
+ const EGLint *attrib_list);
+ _EGLSurface *(*CreatePbufferSurface)(_EGLDriver *drv, _EGLDisplay *dpy,
+ _EGLConfig *config,
+ const EGLint *attrib_list);
+ EGLBoolean (*DestroySurface)(_EGLDriver *drv, _EGLDisplay *dpy,
+ _EGLSurface *surface);
+ EGLBoolean (*QuerySurface)(_EGLDriver *drv, _EGLDisplay *dpy,
+ _EGLSurface *surface, EGLint attribute,
+ EGLint *value);
+ EGLBoolean (*SurfaceAttrib)(_EGLDriver *drv, _EGLDisplay *dpy,
+ _EGLSurface *surface, EGLint attribute,
+ EGLint value);
+ EGLBoolean (*BindTexImage)(_EGLDriver *drv, _EGLDisplay *dpy,
+ _EGLSurface *surface, EGLint buffer);
+ EGLBoolean (*ReleaseTexImage)(_EGLDriver *drv, _EGLDisplay *dpy,
+ _EGLSurface *surface, EGLint buffer);
+ EGLBoolean (*SwapInterval)(_EGLDriver *drv, _EGLDisplay *dpy,
+ _EGLSurface *surf, EGLint interval);
+ EGLBoolean (*SwapBuffers)(_EGLDriver *drv, _EGLDisplay *dpy,
+ _EGLSurface *draw);
+ EGLBoolean (*CopyBuffers)(_EGLDriver *drv, _EGLDisplay *dpy,
+ _EGLSurface *surface, void *native_pixmap_target);
+
+ /* misc functions */
+ EGLBoolean (*WaitClient)(_EGLDriver *drv, _EGLDisplay *dpy,
+ _EGLContext *ctx);
+ EGLBoolean (*WaitNative)(_EGLDriver *drv, _EGLDisplay *dpy,
+ EGLint engine);
+
+ /* this function may be called from multiple threads at the same time */
+ _EGLProc (*GetProcAddress)(_EGLDriver *drv, const char *procname);
+
+ _EGLSurface *(*CreatePbufferFromClientBuffer)(_EGLDriver *drv,
+ _EGLDisplay *dpy,
+ EGLenum buftype,
+ EGLClientBuffer buffer,
+ _EGLConfig *config,
+ const EGLint *attrib_list);
+
+ _EGLImage *(*CreateImageKHR)(_EGLDriver *drv, _EGLDisplay *dpy,
+ _EGLContext *ctx, EGLenum target,
+ EGLClientBuffer buffer,
+ const EGLint *attr_list);
+ EGLBoolean (*DestroyImageKHR)(_EGLDriver *drv, _EGLDisplay *dpy,
+ _EGLImage *image);
+
+ _EGLSync *(*CreateSyncKHR)(_EGLDriver *drv, _EGLDisplay *dpy, EGLenum type,
+ const EGLAttrib *attrib_list);
+ EGLBoolean (*DestroySyncKHR)(_EGLDriver *drv, _EGLDisplay *dpy,
+ _EGLSync *sync);
+ EGLint (*ClientWaitSyncKHR)(_EGLDriver *drv, _EGLDisplay *dpy,
+ _EGLSync *sync, EGLint flags, EGLTime timeout);
+ EGLint (*WaitSyncKHR)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync);
+ EGLBoolean (*SignalSyncKHR)(_EGLDriver *drv, _EGLDisplay *dpy,
+ _EGLSync *sync, EGLenum mode);
+ EGLBoolean (*GetSyncAttrib)(_EGLDriver *drv, _EGLDisplay *dpy,
+ _EGLSync *sync, EGLint attribute,
+ EGLAttrib *value);
+
+ EGLBoolean (*SwapBuffersRegionNOK)(_EGLDriver *drv, _EGLDisplay *disp,
+ _EGLSurface *surf, EGLint numRects,
+ const EGLint *rects);
+
+ _EGLImage *(*CreateDRMImageMESA)(_EGLDriver *drv, _EGLDisplay *disp,
+ const EGLint *attr_list);
+ EGLBoolean (*ExportDRMImageMESA)(_EGLDriver *drv, _EGLDisplay *disp,
+ _EGLImage *img, EGLint *name,
+ EGLint *handle, EGLint *stride);
+
+ EGLBoolean (*BindWaylandDisplayWL)(_EGLDriver *drv, _EGLDisplay *disp,
+ struct wl_display *display);
+ EGLBoolean (*UnbindWaylandDisplayWL)(_EGLDriver *drv, _EGLDisplay *disp,
+ struct wl_display *display);
+ EGLBoolean (*QueryWaylandBufferWL)(_EGLDriver *drv, _EGLDisplay *displ,
+ struct wl_resource *buffer,
+ EGLint attribute, EGLint *value);
+
+ struct wl_buffer *(*CreateWaylandBufferFromImageWL)(_EGLDriver *drv,
+ _EGLDisplay *disp,
+ _EGLImage *img);
+
+ EGLBoolean (*SwapBuffersWithDamageEXT)(_EGLDriver *drv, _EGLDisplay *dpy,
+ _EGLSurface *surface,
+ const EGLint *rects, EGLint n_rects);
+
+ EGLBoolean (*PostSubBufferNV)(_EGLDriver *drv, _EGLDisplay *disp,
+ _EGLSurface *surface, EGLint x, EGLint y,
+ EGLint width, EGLint height);
+
+ EGLint (*QueryBufferAge)(_EGLDriver *drv,
+ _EGLDisplay *dpy, _EGLSurface *surface);
+ EGLBoolean (*GetSyncValuesCHROMIUM)(_EGLDisplay *dpy, _EGLSurface *surface,
+ EGLuint64KHR *ust, EGLuint64KHR *msc,
+ EGLuint64KHR *sbc);
+
+ EGLBoolean (*ExportDMABUFImageQueryMESA)(_EGLDriver *drv, _EGLDisplay *disp,
+ _EGLImage *img, EGLint *fourcc,
+ EGLint *nplanes,
+ EGLuint64KHR *modifiers);
+ EGLBoolean (*ExportDMABUFImageMESA)(_EGLDriver *drv, _EGLDisplay *disp,
+ _EGLImage *img, EGLint *fds,
+ EGLint *strides, EGLint *offsets);
+
+ int (*GLInteropQueryDeviceInfo)(_EGLDisplay *dpy, _EGLContext *ctx,
+ struct mesa_glinterop_device_info *out);
+ int (*GLInteropExportObject)(_EGLDisplay *dpy, _EGLContext *ctx,
+ struct mesa_glinterop_export_in *in,
+ struct mesa_glinterop_export_out *out);
};
+EGLint _eglConvertIntsToAttribs(const EGLint *int_list,
+ EGLAttrib **out_attrib_list);
#ifdef __cplusplus
}
diff --git a/lib/mesa/src/egl/main/eglconfig.c b/lib/mesa/src/egl/main/eglconfig.c
index 435d92453..6161d26e4 100644
--- a/lib/mesa/src/egl/main/eglconfig.c
+++ b/lib/mesa/src/egl/main/eglconfig.c
@@ -38,6 +38,7 @@
#include <assert.h>
#include "c99_compat.h"
+#include "eglcompiler.h"
#include "eglconfig.h"
#include "egldisplay.h"
#include "eglcurrent.h"
@@ -598,14 +599,14 @@ _eglCompareConfigs(const _EGLConfig *conf1, const _EGLConfig *conf2,
return 0;
/* the enum values have the desired ordering */
- assert(EGL_NONE < EGL_SLOW_CONFIG);
- assert(EGL_SLOW_CONFIG < EGL_NON_CONFORMANT_CONFIG);
+ STATIC_ASSERT(EGL_NONE < EGL_SLOW_CONFIG);
+ STATIC_ASSERT(EGL_SLOW_CONFIG < EGL_NON_CONFORMANT_CONFIG);
val1 = conf1->ConfigCaveat - conf2->ConfigCaveat;
if (val1)
return val1;
/* the enum values have the desired ordering */
- assert(EGL_RGB_BUFFER < EGL_LUMINANCE_BUFFER);
+ STATIC_ASSERT(EGL_RGB_BUFFER < EGL_LUMINANCE_BUFFER);
val1 = conf1->ColorBufferType - conf2->ColorBufferType;
if (val1)
return val1;
diff --git a/lib/mesa/src/egl/main/eglcontext.c b/lib/mesa/src/egl/main/eglcontext.c
index ae19862bc..60625f647 100644
--- a/lib/mesa/src/egl/main/eglcontext.c
+++ b/lib/mesa/src/egl/main/eglcontext.c
@@ -457,6 +457,16 @@ _eglParseContextAttribList(_EGLContext *ctx, _EGLDisplay *dpy,
/**
* Initialize the given _EGLContext object to defaults and/or the values
* in the attrib_list.
+ *
+ * According to EGL 1.5 Section 3.7:
+ *
+ * "EGL_OPENGL_API and EGL_OPENGL_ES_API are interchangeable for all
+ * purposes except eglCreateContext."
+ *
+ * And since we only support GL and GLES, this is the only place where the
+ * bound API matters at all. We look up the current API from the current
+ * thread, and stash that in the context we're initializing. Our caller is
+ * responsible for determining whether that's an API it supports.
*/
EGLBoolean
_eglInitContext(_EGLContext *ctx, _EGLDisplay *dpy, _EGLConfig *conf,
@@ -528,9 +538,14 @@ _eglQueryContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *c,
switch (attribute) {
case EGL_CONFIG_ID:
- if (!c->Config)
- return _eglError(EGL_BAD_ATTRIBUTE, "eglQueryContext");
- *value = c->Config->ConfigID;
+ /*
+ * From EGL_KHR_no_config_context:
+ *
+ * "Querying EGL_CONFIG_ID returns the ID of the EGLConfig with
+ * respect to which the context was created, or zero if created
+ * without respect to an EGLConfig."
+ */
+ *value = c->Config ? c->Config->ConfigID : 0;
break;
case EGL_CONTEXT_CLIENT_VERSION:
*value = c->ClientMajorVersion;
@@ -557,20 +572,16 @@ _eglQueryContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *c,
static _EGLContext *
_eglBindContextToThread(_EGLContext *ctx, _EGLThreadInfo *t)
{
- EGLint apiIndex;
_EGLContext *oldCtx;
- apiIndex = (ctx) ?
- _eglConvertApiToIndex(ctx->ClientAPI) : t->CurrentAPIIndex;
-
- oldCtx = t->CurrentContexts[apiIndex];
+ oldCtx = t->CurrentContext;
if (ctx != oldCtx) {
if (oldCtx)
oldCtx->Binding = NULL;
if (ctx)
ctx->Binding = t;
- t->CurrentContexts[apiIndex] = ctx;
+ t->CurrentContext = ctx;
}
return oldCtx;
@@ -585,7 +596,6 @@ _eglCheckMakeCurrent(_EGLContext *ctx, _EGLSurface *draw, _EGLSurface *read)
{
_EGLThreadInfo *t = _eglGetCurrentThread();
_EGLDisplay *dpy;
- EGLint conflict_api;
if (_eglIsCurrentThreadDummy())
return _eglError(EGL_BAD_ALLOC, "eglMakeCurrent");
@@ -617,13 +627,11 @@ _eglCheckMakeCurrent(_EGLContext *ctx, _EGLSurface *draw, _EGLSurface *read)
if (ctx->Binding && ctx->Binding != t)
return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent");
if (draw && draw->CurrentContext && draw->CurrentContext != ctx) {
- if (draw->CurrentContext->Binding != t ||
- draw->CurrentContext->ClientAPI != ctx->ClientAPI)
+ if (draw->CurrentContext->Binding != t)
return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent");
}
if (read && read->CurrentContext && read->CurrentContext != ctx) {
- if (read->CurrentContext->Binding != t ||
- read->CurrentContext->ClientAPI != ctx->ClientAPI)
+ if (read->CurrentContext->Binding != t)
return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent");
}
@@ -634,9 +642,9 @@ _eglCheckMakeCurrent(_EGLContext *ctx, _EGLSurface *draw, _EGLSurface *read)
(read && read->Config != ctx->Config))
return _eglError(EGL_BAD_MATCH, "eglMakeCurrent");
} else {
- /* Otherwise we must be using the EGL_MESA_configless_context
+ /* Otherwise we must be using the EGL_KHR_no_config_context
* extension */
- assert(dpy->Extensions.MESA_configless_context);
+ assert(dpy->Extensions.KHR_no_config_context);
/* The extension doesn't permit binding draw and read buffers with
* differing contexts */
@@ -644,22 +652,6 @@ _eglCheckMakeCurrent(_EGLContext *ctx, _EGLSurface *draw, _EGLSurface *read)
return _eglError(EGL_BAD_MATCH, "eglMakeCurrent");
}
- switch (ctx->ClientAPI) {
- /* OpenGL and OpenGL ES are conflicting */
- case EGL_OPENGL_ES_API:
- conflict_api = EGL_OPENGL_API;
- break;
- case EGL_OPENGL_API:
- conflict_api = EGL_OPENGL_ES_API;
- break;
- default:
- conflict_api = -1;
- break;
- }
-
- if (conflict_api >= 0 && _eglGetAPIContext(conflict_api))
- return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent");
-
return EGL_TRUE;
}
diff --git a/lib/mesa/src/egl/main/eglcurrent.c b/lib/mesa/src/egl/main/eglcurrent.c
index 835631d3b..eae7bdcea 100644
--- a/lib/mesa/src/egl/main/eglcurrent.c
+++ b/lib/mesa/src/egl/main/eglcurrent.c
@@ -26,8 +26,10 @@
**************************************************************************/
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <stdarg.h>
#include "c99_compat.h"
#include "c11/threads.h"
@@ -35,10 +37,9 @@
#include "eglcurrent.h"
#include "eglglobals.h"
-
/* This should be kept in sync with _eglInitThreadInfo() */
#define _EGL_THREAD_INFO_INITIALIZER \
- { EGL_SUCCESS, { NULL }, 0 }
+ { EGL_SUCCESS, NULL, EGL_OPENGL_ES_API, NULL, NULL, NULL }
/* a fallback thread info to guarantee that every thread always has one */
static _EGLThreadInfo dummy_thread = _EGL_THREAD_INFO_INITIALIZER;
@@ -111,7 +112,7 @@ _eglInitThreadInfo(_EGLThreadInfo *t)
memset(t, 0, sizeof(*t));
t->LastError = EGL_SUCCESS;
/* default, per EGL spec */
- t->CurrentAPIIndex = _eglConvertApiToIndex(EGL_OPENGL_ES_API);
+ t->CurrentAPI = EGL_OPENGL_ES_API;
}
@@ -205,32 +206,21 @@ _eglIsCurrentThreadDummy(void)
/**
- * Return the currently bound context of the given API, or NULL.
- */
-_EGLContext *
-_eglGetAPIContext(EGLenum api)
-{
- _EGLThreadInfo *t = _eglGetCurrentThread();
- return t->CurrentContexts[_eglConvertApiToIndex(api)];
-}
-
-
-/**
* Return the currently bound context of the current API, or NULL.
*/
_EGLContext *
_eglGetCurrentContext(void)
{
_EGLThreadInfo *t = _eglGetCurrentThread();
- return t->CurrentContexts[t->CurrentAPIIndex];
+ return t->CurrentContext;
}
/**
* Record EGL error code and return EGL_FALSE.
*/
-EGLBoolean
-_eglError(EGLint errCode, const char *msg)
+static EGLBoolean
+_eglInternalError(EGLint errCode, const char *msg)
{
_EGLThreadInfo *t = _eglGetCurrentThread();
@@ -290,3 +280,86 @@ _eglError(EGLint errCode, const char *msg)
return EGL_FALSE;
}
+
+EGLBoolean
+_eglError(EGLint errCode, const char *msg)
+{
+ if (errCode != EGL_SUCCESS) {
+ EGLint type;
+ if (errCode == EGL_BAD_ALLOC) {
+ type = EGL_DEBUG_MSG_CRITICAL_KHR;
+ } else {
+ type = EGL_DEBUG_MSG_ERROR_KHR;
+ }
+
+ _eglDebugReport(errCode, msg, type, NULL);
+ } else
+ _eglInternalError(errCode, msg);
+
+ return EGL_FALSE;
+}
+
+/**
+ * Returns the label set for the current thread.
+ */
+EGLLabelKHR
+_eglGetThreadLabel(void)
+{
+ _EGLThreadInfo *t = _eglGetCurrentThread();
+ return t->Label;
+}
+
+static void
+_eglDebugReportFullv(EGLenum error, const char *command, const char *funcName,
+ EGLint type, EGLLabelKHR objectLabel, const char *message, va_list args)
+{
+ EGLDEBUGPROCKHR callback = NULL;
+
+ mtx_lock(_eglGlobal.Mutex);
+ if (_eglGlobal.debugTypesEnabled & DebugBitFromType(type)) {
+ callback = _eglGlobal.debugCallback;
+ }
+ mtx_unlock(_eglGlobal.Mutex);
+
+ if (callback != NULL) {
+ char *buf = NULL;
+
+ if (message != NULL) {
+ if (vasprintf(&buf, message, args) < 0) {
+ buf = NULL;
+ }
+ }
+ callback(error, command, type, _eglGetThreadLabel(), objectLabel, buf);
+ free(buf);
+ }
+
+ if (type == EGL_DEBUG_MSG_CRITICAL_KHR || type == EGL_DEBUG_MSG_ERROR_KHR) {
+ _eglInternalError(error, funcName);
+ }
+}
+
+void
+_eglDebugReportFull(EGLenum error, const char *command, const char *funcName,
+ EGLint type, EGLLabelKHR objectLabel, const char *message, ...)
+{
+ va_list args;
+ va_start(args, message);
+ _eglDebugReportFullv(error, command, funcName, type, objectLabel, message, args);
+ va_end(args);
+}
+
+void
+_eglDebugReport(EGLenum error, const char *funcName,
+ EGLint type, const char *message, ...)
+{
+ _EGLThreadInfo *thr = _eglGetCurrentThread();
+ va_list args;
+
+ if (funcName == NULL) {
+ funcName = thr->CurrentFuncName;
+ }
+
+ va_start(args, message);
+ _eglDebugReportFullv(error, thr->CurrentFuncName, funcName, type, thr->CurrentObjectLabel, message, args);
+ va_end(args);
+}
diff --git a/lib/mesa/src/egl/main/eglcurrent.h b/lib/mesa/src/egl/main/eglcurrent.h
index 1e386acda..9ec07bac8 100644
--- a/lib/mesa/src/egl/main/eglcurrent.h
+++ b/lib/mesa/src/egl/main/eglcurrent.h
@@ -46,20 +46,22 @@ extern "C" {
EGL_OPENGL_BIT)
-#define _EGL_API_FIRST_API EGL_OPENGL_ES_API
-#define _EGL_API_LAST_API EGL_OPENGL_API
-#define _EGL_API_NUM_APIS (_EGL_API_LAST_API - _EGL_API_FIRST_API + 1)
-
-
/**
* Per-thread info
*/
struct _egl_thread_info
{
EGLint LastError;
- _EGLContext *CurrentContexts[_EGL_API_NUM_APIS];
- /* use index for fast access to current context */
- EGLint CurrentAPIIndex;
+ _EGLContext *CurrentContext;
+ EGLenum CurrentAPI;
+ EGLLabelKHR Label;
+
+ /**
+ * The name of the EGL function that's being called at the moment. This is
+ * used to report the function name to the EGL_KHR_debug callback.
+ */
+ const char *CurrentFuncName;
+ EGLLabelKHR CurrentObjectLabel;
};
@@ -69,29 +71,12 @@ struct _egl_thread_info
static inline EGLBoolean
_eglIsApiValid(EGLenum api)
{
- return (api >= _EGL_API_FIRST_API && api <= _EGL_API_LAST_API);
-}
-
-
-/**
- * Convert a client API enum to an index, for use by thread info.
- * The client API enum is assumed to be valid.
- */
-static inline EGLint
-_eglConvertApiToIndex(EGLenum api)
-{
- return api - _EGL_API_FIRST_API;
-}
-
-
-/**
- * Convert an index, used by thread info, to a client API enum.
- * The index is assumed to be valid.
- */
-static inline EGLenum
-_eglConvertApiFromIndex(EGLint idx)
-{
- return _EGL_API_FIRST_API + idx;
+#ifdef ANDROID
+ /* OpenGL is not a valid/supported API on Android */
+ return api == EGL_OPENGL_ES_API;
+#else
+ return (api == EGL_OPENGL_ES_API || api == EGL_OPENGL_API);
+#endif
}
@@ -108,16 +93,34 @@ _eglIsCurrentThreadDummy(void);
extern _EGLContext *
-_eglGetAPIContext(EGLenum api);
-
-
-extern _EGLContext *
_eglGetCurrentContext(void);
extern EGLBoolean
_eglError(EGLint errCode, const char *msg);
+extern EGLLabelKHR
+_eglGetThreadLabel(void);
+
+extern void
+_eglDebugReportFull(EGLenum error, const char *command, const char *funcName,
+ EGLint type, EGLLabelKHR objectLabel, const char *message, ...);
+
+extern void
+_eglDebugReport(EGLenum error, const char *funcName,
+ EGLint type, const char *message, ...);
+
+#define _eglReportCritical(error, funcName, ...) \
+ _eglDebugReport(error, funcName, EGL_DEBUG_MSG_CRITICAL_KHR, __VA_ARGS__)
+
+#define _eglReportError(error, funcName, ...) \
+ _eglDebugReport(error, funcName, EGL_DEBUG_MSG_ERROR_KHR, __VA_ARGS__)
+
+#define _eglReportWarn(funcName, ...) \
+ _eglDebugReport(EGL_SUCCESS, funcName, EGL_DEBUG_MSG_WARN_KHR, __VA_ARGS__)
+
+#define _eglReportInfo(funcName, ...) \
+ _eglDebugReport(EGL_SUCCESS, funcName, EGL_DEBUG_MSG_INFO_KHR, __VA_ARGS__)
#ifdef __cplusplus
}
diff --git a/lib/mesa/src/egl/main/egldefines.h b/lib/mesa/src/egl/main/egldefines.h
index 13a7563ce..d0502f330 100644
--- a/lib/mesa/src/egl/main/egldefines.h
+++ b/lib/mesa/src/egl/main/egldefines.h
@@ -34,6 +34,8 @@
#ifndef EGLDEFINES_INCLUDED
#define EGLDEFINES_INCLUDED
+#include "util/macros.h"
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -48,9 +50,6 @@ extern "C" {
#define _EGL_VENDOR_STRING "Mesa Project"
-#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
-#define MIN2(A, B) (((A) < (B)) ? (A) : (B))
-
#ifdef __cplusplus
}
#endif
diff --git a/lib/mesa/src/egl/main/egldisplay.c b/lib/mesa/src/egl/main/egldisplay.c
index f6db03ab5..37711bd86 100644
--- a/lib/mesa/src/egl/main/egldisplay.c
+++ b/lib/mesa/src/egl/main/egldisplay.c
@@ -44,6 +44,8 @@
#include "egldriver.h"
#include "eglglobals.h"
#include "egllog.h"
+#include "eglimage.h"
+#include "eglsync.h"
/* Includes for _eglNativePlatformDetectNativeDisplay */
#ifdef HAVE_MINCORE
@@ -178,25 +180,24 @@ _eglNativePlatformDetectNativeDisplay(void *nativeDisplay)
_EGLPlatformType
_eglGetNativePlatform(void *nativeDisplay)
{
- static _EGLPlatformType native_platform = _EGL_INVALID_PLATFORM;
- char *detection_method = NULL;
+ static _EGLPlatformType native_platform;
+ char *detection_method;
+
+ native_platform = _eglGetNativePlatformFromEnv();
+ detection_method = "environment overwrite";
if (native_platform == _EGL_INVALID_PLATFORM) {
- native_platform = _eglGetNativePlatformFromEnv();
- detection_method = "environment overwrite";
- if (native_platform == _EGL_INVALID_PLATFORM) {
- native_platform = _eglNativePlatformDetectNativeDisplay(nativeDisplay);
- detection_method = "autodetected";
- if (native_platform == _EGL_INVALID_PLATFORM) {
- native_platform = _EGL_NATIVE_PLATFORM;
- detection_method = "build-time configuration";
- }
- }
+ native_platform = _eglNativePlatformDetectNativeDisplay(nativeDisplay);
+ detection_method = "autodetected";
}
- if (detection_method != NULL)
- _eglLog(_EGL_DEBUG, "Native platform type: %s (%s)",
- egl_platforms[native_platform].name, detection_method);
+ if (native_platform == _EGL_INVALID_PLATFORM) {
+ native_platform = _EGL_NATIVE_PLATFORM;
+ detection_method = "build-time configuration";
+ }
+
+ _eglLog(_EGL_DEBUG, "Native platform type: %s (%s)",
+ egl_platforms[native_platform].name, detection_method);
return native_platform;
}
@@ -301,6 +302,26 @@ _eglReleaseDisplayResources(_EGLDriver *drv, _EGLDisplay *display)
drv->API.DestroySurface(drv, display, surf);
}
assert(!display->ResourceLists[_EGL_RESOURCE_SURFACE]);
+
+ list = display->ResourceLists[_EGL_RESOURCE_IMAGE];
+ while (list) {
+ _EGLImage *image = (_EGLImage *) list;
+ list = list->Next;
+
+ _eglUnlinkImage(image);
+ drv->API.DestroyImageKHR(drv, display, image);
+ }
+ assert(!display->ResourceLists[_EGL_RESOURCE_IMAGE]);
+
+ list = display->ResourceLists[_EGL_RESOURCE_SYNC];
+ while (list) {
+ _EGLSync *sync = (_EGLSync *) list;
+ list = list->Next;
+
+ _eglUnlinkSync(sync);
+ drv->API.DestroySyncKHR(drv, display, sync);
+ }
+ assert(!display->ResourceLists[_EGL_RESOURCE_SYNC]);
}
@@ -519,3 +540,24 @@ _eglGetWaylandDisplay(struct wl_display *native_display,
return _eglFindDisplay(_EGL_PLATFORM_WAYLAND, native_display);
}
#endif /* HAVE_WAYLAND_PLATFORM */
+
+#ifdef HAVE_SURFACELESS_PLATFORM
+_EGLDisplay*
+_eglGetSurfacelessDisplay(void *native_display,
+ const EGLint *attrib_list)
+{
+ /* This platform has no native display. */
+ if (native_display != NULL) {
+ _eglError(EGL_BAD_PARAMETER, "eglGetPlatformDisplay");
+ return NULL;
+ }
+
+ /* This platform recognizes no display attributes. */
+ if (attrib_list != NULL && attrib_list[0] != EGL_NONE) {
+ _eglError(EGL_BAD_ATTRIBUTE, "eglGetPlatformDisplay");
+ return NULL;
+ }
+
+ return _eglFindDisplay(_EGL_PLATFORM_SURFACELESS, native_display);
+}
+#endif /* HAVE_SURFACELESS_PLATFORM */
diff --git a/lib/mesa/src/egl/main/egldisplay.h b/lib/mesa/src/egl/main/egldisplay.h
index 008c46721..62d9a112f 100644
--- a/lib/mesa/src/egl/main/egldisplay.h
+++ b/lib/mesa/src/egl/main/egldisplay.h
@@ -79,6 +79,8 @@ struct _egl_resource
EGLBoolean IsLinked;
EGLint RefCount;
+ EGLLabelKHR Label;
+
/* used to link resources of the same type */
_EGLResource *Next;
};
@@ -112,13 +114,11 @@ struct _egl_extensions
EGLBoolean KHR_gl_texture_cubemap_image;
EGLBoolean KHR_image_base;
EGLBoolean KHR_image_pixmap;
+ EGLBoolean KHR_no_config_context;
EGLBoolean KHR_reusable_sync;
EGLBoolean KHR_surfaceless_context;
- EGLBoolean KHR_vg_parent_image;
EGLBoolean KHR_wait_sync;
- EGLBoolean MESA_configless_context;
- EGLBoolean MESA_drm_display;
EGLBoolean MESA_drm_image;
EGLBoolean MESA_image_dma_buf_export;
@@ -167,6 +167,8 @@ struct _egl_display
/* lists of resources */
_EGLResource *ResourceLists[_EGL_NUM_RESOURCES];
+
+ EGLLabelKHR Label;
};
@@ -272,6 +274,11 @@ _eglGetWaylandDisplay(struct wl_display *native_display,
const EGLint *attrib_list);
#endif
+#ifdef HAVE_SURFACELESS_PLATFORM
+_EGLDisplay*
+_eglGetSurfacelessDisplay(void *native_display,
+ const EGLint *attrib_list);
+#endif
#ifdef __cplusplus
}
diff --git a/lib/mesa/src/egl/main/eglfallbacks.c b/lib/mesa/src/egl/main/eglfallbacks.c
index 65daf8fd0..d0fce8c20 100644
--- a/lib/mesa/src/egl/main/eglfallbacks.c
+++ b/lib/mesa/src/egl/main/eglfallbacks.c
@@ -59,29 +59,29 @@ _eglInitDriverFallbacks(_EGLDriver *drv)
drv->API.ChooseConfig = _eglChooseConfig;
drv->API.GetConfigAttrib = _eglGetConfigAttrib;
- drv->API.CreateContext = (CreateContext_t) _eglReturnFalse;
- drv->API.DestroyContext = (DestroyContext_t) _eglReturnFalse;
- drv->API.MakeCurrent = (MakeCurrent_t) _eglReturnFalse;
+ drv->API.CreateContext = (void*) _eglReturnFalse;
+ drv->API.DestroyContext = (void*) _eglReturnFalse;
+ drv->API.MakeCurrent = (void*) _eglReturnFalse;
drv->API.QueryContext = _eglQueryContext;
- drv->API.CreateWindowSurface = (CreateWindowSurface_t) _eglReturnFalse;
- drv->API.CreatePixmapSurface = (CreatePixmapSurface_t) _eglReturnFalse;
- drv->API.CreatePbufferSurface = (CreatePbufferSurface_t) _eglReturnFalse;
+ drv->API.CreateWindowSurface = (void*) _eglReturnFalse;
+ drv->API.CreatePixmapSurface = (void*) _eglReturnFalse;
+ drv->API.CreatePbufferSurface = (void*) _eglReturnFalse;
drv->API.CreatePbufferFromClientBuffer =
- (CreatePbufferFromClientBuffer_t) _eglReturnFalse;
- drv->API.DestroySurface = (DestroySurface_t) _eglReturnFalse;
+ (void*) _eglReturnFalse;
+ drv->API.DestroySurface = (void*) _eglReturnFalse;
drv->API.QuerySurface = _eglQuerySurface;
drv->API.SurfaceAttrib = _eglSurfaceAttrib;
- drv->API.BindTexImage = (BindTexImage_t) _eglReturnFalse;
- drv->API.ReleaseTexImage = (ReleaseTexImage_t) _eglReturnFalse;
- drv->API.CopyBuffers = (CopyBuffers_t) _eglReturnFalse;
- drv->API.SwapBuffers = (SwapBuffers_t) _eglReturnFalse;
+ drv->API.BindTexImage = (void*) _eglReturnFalse;
+ drv->API.ReleaseTexImage = (void*) _eglReturnFalse;
+ drv->API.CopyBuffers = (void*) _eglReturnFalse;
+ drv->API.SwapBuffers = (void*) _eglReturnFalse;
drv->API.SwapInterval = _eglSwapInterval;
- drv->API.WaitClient = (WaitClient_t) _eglReturnFalse;
- drv->API.WaitNative = (WaitNative_t) _eglReturnFalse;
- drv->API.GetProcAddress = (GetProcAddress_t) _eglReturnFalse;
+ drv->API.WaitClient = (void*) _eglReturnFalse;
+ drv->API.WaitNative = (void*) _eglReturnFalse;
+ drv->API.GetProcAddress = (void*) _eglReturnFalse;
drv->API.CreateImageKHR = NULL;
drv->API.DestroyImageKHR = NULL;
diff --git a/lib/mesa/src/egl/main/eglglobals.c b/lib/mesa/src/egl/main/eglglobals.c
index 938d95378..cb41063e3 100644
--- a/lib/mesa/src/egl/main/eglglobals.c
+++ b/lib/mesa/src/egl/main/eglglobals.c
@@ -50,13 +50,26 @@ struct _egl_global _eglGlobal =
_eglFiniDisplay
},
- /* ClientExtensionsString */
+ /* ClientExtensionString */
"EGL_EXT_client_extensions"
" EGL_EXT_platform_base"
+#ifdef HAVE_WAYLAND_PLATFORM
" EGL_EXT_platform_wayland"
+#endif
+#ifdef HAVE_X11_PLATFORM
" EGL_EXT_platform_x11"
- " EGL_KHR_client_get_all_proc_addresses"
+#endif
+#ifdef HAVE_DRM_PLATFORM
" EGL_MESA_platform_gbm"
+#endif
+#ifdef HAVE_SURFACELESS_PLATFORM
+ " EGL_MESA_platform_surfaceless"
+#endif
+ " EGL_KHR_client_get_all_proc_addresses"
+ " EGL_KHR_debug",
+
+ NULL, /* debugCallback */
+ _EGL_DEBUG_BIT_CRITICAL | _EGL_DEBUG_BIT_ERROR, /* debugTypesEnabled */
};
diff --git a/lib/mesa/src/egl/main/eglglobals.h b/lib/mesa/src/egl/main/eglglobals.h
index ae1b75b45..ec4f3d04a 100644
--- a/lib/mesa/src/egl/main/eglglobals.h
+++ b/lib/mesa/src/egl/main/eglglobals.h
@@ -36,6 +36,13 @@
#include "egltypedefs.h"
+enum
+{
+ _EGL_DEBUG_BIT_CRITICAL = 0x1,
+ _EGL_DEBUG_BIT_ERROR = 0x2,
+ _EGL_DEBUG_BIT_WARN = 0x4,
+ _EGL_DEBUG_BIT_INFO = 0x8,
+};
/**
* Global library data
@@ -51,6 +58,9 @@ struct _egl_global
void (*AtExitCalls[10])(void);
const char *ClientExtensionString;
+
+ EGLDEBUGPROCKHR debugCallback;
+ unsigned int debugTypesEnabled;
};
@@ -60,5 +70,10 @@ extern struct _egl_global _eglGlobal;
extern void
_eglAddAtExitCall(void (*func)(void));
+static inline unsigned int DebugBitFromType(EGLenum type)
+{
+ assert(type >= EGL_DEBUG_MSG_CRITICAL_KHR && type <= EGL_DEBUG_MSG_INFO_KHR);
+ return (1 << (type - EGL_DEBUG_MSG_CRITICAL_KHR));
+}
#endif /* EGLGLOBALS_INCLUDED */
diff --git a/lib/mesa/src/egl/main/eglsurface.c b/lib/mesa/src/egl/main/eglsurface.c
index 2971bb098..3af337fef 100644
--- a/lib/mesa/src/egl/main/eglsurface.c
+++ b/lib/mesa/src/egl/main/eglsurface.c
@@ -71,6 +71,8 @@ _eglParseSurfaceAttribList(_EGLSurface *surf, const EGLint *attrib_list)
EGLint type = surf->Type;
EGLint texture_type = EGL_PBUFFER_BIT;
EGLint i, err = EGL_SUCCESS;
+ EGLint attr = EGL_NONE;
+ EGLint val = EGL_NONE;
if (!attrib_list)
return EGL_SUCCESS;
@@ -79,8 +81,8 @@ _eglParseSurfaceAttribList(_EGLSurface *surf, const EGLint *attrib_list)
texture_type |= EGL_PIXMAP_BIT;
for (i = 0; attrib_list[i] != EGL_NONE; i++) {
- EGLint attr = attrib_list[i++];
- EGLint val = attrib_list[i];
+ attr = attrib_list[i++];
+ val = attrib_list[i];
switch (attr) {
/* common attributes */
@@ -186,6 +188,7 @@ _eglParseSurfaceAttribList(_EGLSurface *surf, const EGLint *attrib_list)
err = EGL_BAD_ATTRIBUTE;
break;
}
+
switch (val) {
case EGL_TEXTURE_RGB:
case EGL_TEXTURE_RGBA:
@@ -204,6 +207,7 @@ _eglParseSurfaceAttribList(_EGLSurface *surf, const EGLint *attrib_list)
err = EGL_BAD_ATTRIBUTE;
break;
}
+
switch (val) {
case EGL_TEXTURE_2D:
case EGL_NO_TEXTURE:
@@ -229,12 +233,21 @@ _eglParseSurfaceAttribList(_EGLSurface *surf, const EGLint *attrib_list)
break;
}
- if (err != EGL_SUCCESS) {
- _eglLog(_EGL_WARNING, "bad surface attribute 0x%04x", attr);
+ if (err != EGL_SUCCESS)
break;
+ }
+
+ if (err == EGL_SUCCESS && type == EGL_PBUFFER_BIT) {
+ if ((surf->TextureTarget == EGL_NO_TEXTURE && surf->TextureFormat != EGL_NO_TEXTURE) ||
+ (surf->TextureFormat == EGL_NO_TEXTURE && surf->TextureTarget != EGL_NO_TEXTURE)) {
+ attr = surf->TextureTarget == EGL_NO_TEXTURE ? EGL_TEXTURE_TARGET : EGL_TEXTURE_FORMAT;
+ err = EGL_BAD_MATCH;
}
}
+ if (err != EGL_SUCCESS)
+ _eglLog(_EGL_WARNING, "bad surface attribute 0x%04x", attr);
+
return err;
}
@@ -249,9 +262,13 @@ _eglInitSurface(_EGLSurface *surf, _EGLDisplay *dpy, EGLint type,
{
const char *func;
EGLint renderBuffer = EGL_BACK_BUFFER;
- EGLint swapBehavior = EGL_BUFFER_PRESERVED;
+ EGLint swapBehavior = EGL_BUFFER_DESTROYED;
EGLint err;
+ /* Swap behavior can be preserved only if config supports this. */
+ if (conf->SurfaceType & EGL_SWAP_BEHAVIOR_PRESERVED_BIT)
+ swapBehavior = EGL_BUFFER_PRESERVED;
+
switch (type) {
case EGL_WINDOW_BIT:
func = "eglCreateWindowSurface";
diff --git a/lib/mesa/src/egl/main/eglsync.c b/lib/mesa/src/egl/main/eglsync.c
index 999cb480c..dea324b11 100644
--- a/lib/mesa/src/egl/main/eglsync.c
+++ b/lib/mesa/src/egl/main/eglsync.c
@@ -26,6 +26,7 @@
**************************************************************************/
+#include <inttypes.h>
#include <string.h>
#include "eglsync.h"
@@ -38,45 +39,17 @@
* Parse the list of sync attributes and return the proper error code.
*/
static EGLint
-_eglParseSyncAttribList(_EGLSync *sync, const EGLint *attrib_list)
+_eglParseSyncAttribList(_EGLSync *sync, const EGLAttrib *attrib_list)
{
- EGLint i, err = EGL_SUCCESS;
+ EGLint i;
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) {
- default:
- (void) val;
- err = EGL_BAD_ATTRIBUTE;
- break;
- }
-
- if (err != EGL_SUCCESS) {
- _eglLog(_EGL_DEBUG, "bad sync attribute 0x%04x", attr);
- break;
- }
- }
-
- return err;
-}
-
-
-static EGLint
-_eglParseSyncAttribList64(_EGLSync *sync, const EGLAttrib *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];
+ EGLAttrib attr = attrib_list[i++];
+ EGLAttrib val = attrib_list[i];
+ EGLint err = EGL_SUCCESS;
switch (attr) {
case EGL_CL_EVENT_HANDLE_KHR:
@@ -92,27 +65,21 @@ _eglParseSyncAttribList64(_EGLSync *sync, const EGLAttrib *attrib_list)
}
if (err != EGL_SUCCESS) {
- _eglLog(_EGL_DEBUG, "bad sync attribute 0x%04x", attr);
- break;
+ _eglLog(_EGL_DEBUG, "bad sync attribute 0x%" PRIxPTR, attr);
+ return err;
}
}
- return err;
+ return EGL_SUCCESS;
}
EGLBoolean
_eglInitSync(_EGLSync *sync, _EGLDisplay *dpy, EGLenum type,
- const EGLint *attrib_list, const EGLAttrib *attrib_list64)
+ const EGLAttrib *attrib_list)
{
EGLint err;
- if (!(type == EGL_SYNC_REUSABLE_KHR && dpy->Extensions.KHR_reusable_sync) &&
- !(type == EGL_SYNC_FENCE_KHR && dpy->Extensions.KHR_fence_sync) &&
- !(type == EGL_SYNC_CL_EVENT_KHR && dpy->Extensions.KHR_cl_event2 &&
- attrib_list64))
- return _eglError(EGL_BAD_ATTRIBUTE, "eglCreateSyncKHR");
-
_eglInitResource(&sync->Resource, sizeof(*sync), dpy);
sync->Type = type;
sync->SyncStatus = EGL_UNSIGNALED_KHR;
@@ -125,11 +92,7 @@ _eglInitSync(_EGLSync *sync, _EGLDisplay *dpy, EGLenum type,
sync->SyncCondition = EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR;
}
- if (attrib_list64)
- err = _eglParseSyncAttribList64(sync, attrib_list64);
- else
- err = _eglParseSyncAttribList(sync, attrib_list);
-
+ err = _eglParseSyncAttribList(sync, attrib_list);
if (err != EGL_SUCCESS)
return _eglError(err, "eglCreateSyncKHR");
@@ -152,7 +115,8 @@ _eglGetSyncAttrib(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync,
/* update the sync status */
if (sync->SyncStatus != EGL_SIGNALED_KHR &&
(sync->Type == EGL_SYNC_FENCE_KHR ||
- sync->Type == EGL_SYNC_CL_EVENT_KHR))
+ sync->Type == EGL_SYNC_CL_EVENT_KHR ||
+ sync->Type == EGL_SYNC_REUSABLE_KHR))
drv->API.ClientWaitSyncKHR(drv, dpy, sync, 0, 0);
*value = sync->SyncStatus;
diff --git a/lib/mesa/src/egl/main/eglsync.h b/lib/mesa/src/egl/main/eglsync.h
index 9b2aac882..83b6f72fc 100644
--- a/lib/mesa/src/egl/main/eglsync.h
+++ b/lib/mesa/src/egl/main/eglsync.h
@@ -53,7 +53,7 @@ struct _egl_sync
extern EGLBoolean
_eglInitSync(_EGLSync *sync, _EGLDisplay *dpy, EGLenum type,
- const EGLint *attrib_list, const EGLAttrib *attrib_list64);
+ const EGLAttrib *attrib_list);
extern EGLBoolean
diff --git a/lib/mesa/src/egl/wayland/wayland-drm/wayland-drm-protocol.c b/lib/mesa/src/egl/wayland/wayland-drm/wayland-drm-protocol.c
index 27bd9f2d1..d47dcdfad 100644
--- a/lib/mesa/src/egl/wayland/wayland-drm/wayland-drm-protocol.c
+++ b/lib/mesa/src/egl/wayland/wayland-drm/wayland-drm-protocol.c
@@ -1,3 +1,5 @@
+/* Generated by wayland-scanner 1.12.0 */
+
/*
* Copyright © 2008-2011 Kristian Høgsberg
* Copyright © 2010-2011 Intel Corporation
diff --git a/lib/mesa/src/egl/wayland/wayland-drm/wayland-drm.c b/lib/mesa/src/egl/wayland/wayland-drm/wayland-drm.c
index e00d9be6a..4fc12521d 100644
--- a/lib/mesa/src/egl/wayland/wayland-drm/wayland-drm.c
+++ b/lib/mesa/src/egl/wayland/wayland-drm/wayland-drm.c
@@ -265,6 +265,8 @@ wayland_drm_init(struct wl_display *display, char *device_name,
struct wl_drm *drm;
drm = malloc(sizeof *drm);
+ if (!drm)
+ return NULL;
drm->display = display;
drm->device_name = strdup(device_name);
diff --git a/lib/mesa/src/egl/wayland/wayland-egl/wayland-egl-priv.h b/lib/mesa/src/egl/wayland/wayland-egl/wayland-egl-priv.h
index 74a155202..c91f9cdf0 100644
--- a/lib/mesa/src/egl/wayland/wayland-egl/wayland-egl-priv.h
+++ b/lib/mesa/src/egl/wayland/wayland-egl/wayland-egl-priv.h
@@ -1,10 +1,6 @@
#ifndef _WAYLAND_EGL_PRIV_H
#define _WAYLAND_EGL_PRIV_H
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/* GCC visibility */
#if defined(__GNUC__)
#define WL_EGL_EXPORT __attribute__ ((visibility("default")))
@@ -14,6 +10,10 @@ extern "C" {
#include <wayland-client.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
struct wl_egl_window {
struct wl_surface *surface;
@@ -27,6 +27,7 @@ struct wl_egl_window {
void *private;
void (*resize_callback)(struct wl_egl_window *, void *);
+ void (*destroy_window_callback)(void *);
};
#ifdef __cplusplus
diff --git a/lib/mesa/src/egl/wayland/wayland-egl/wayland-egl.c b/lib/mesa/src/egl/wayland/wayland-egl/wayland-egl.c
index 80a5be5e3..4a4701a2d 100644
--- a/lib/mesa/src/egl/wayland/wayland-egl/wayland-egl.c
+++ b/lib/mesa/src/egl/wayland/wayland-egl/wayland-egl.c
@@ -66,6 +66,7 @@ wl_egl_window_create(struct wl_surface *surface,
egl_window->surface = surface;
egl_window->private = NULL;
egl_window->resize_callback = NULL;
+ egl_window->destroy_window_callback = NULL;
wl_egl_window_resize(egl_window, width, height, 0, 0);
egl_window->attached_width = 0;
egl_window->attached_height = 0;
@@ -76,6 +77,8 @@ wl_egl_window_create(struct wl_surface *surface,
WL_EGL_EXPORT void
wl_egl_window_destroy(struct wl_egl_window *egl_window)
{
+ if (egl_window->destroy_window_callback)
+ egl_window->destroy_window_callback(egl_window->private);
free(egl_window);
}