(*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().
*/
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;
(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++) {
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);
return -1;
}
- /* We always want to throttle to some event (either a frame callback or
- * a sync request) after the commit so that we can be sure the
- * compositor has had a chance to handle it and send us a release event
- * before we look for a free buffer */
- while (dri2_surf->throttle_callback != NULL)
- if (wl_display_dispatch_queue(dri2_dpy->wl_dpy,
- dri2_dpy->wl_queue) == -1)
- return -1;
+ /* There might be a buffer release already queued that wasn't processed */
+ wl_display_dispatch_queue_pending(dri2_dpy->wl_dpy, dri2_dpy->wl_queue);
if (dri2_surf->back == NULL) {
for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) {
(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 },
struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
int i;
+ while (dri2_surf->throttle_callback != NULL)
+ if (wl_display_dispatch_queue(dri2_dpy->wl_dpy,
+ dri2_dpy->wl_queue) == -1)
+ return -1;
+
for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++)
if (dri2_surf->color_buffers[i].age > 0)
dri2_surf->color_buffers[i].age++;
.get_dri_drawable = dri2_surface_get_dri_drawable,
};
+static const __DRIextension *dri2_loader_extensions[] = {
+ &dri2_loader_extension.base,
+ &image_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);
* 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;
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;
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
cleanup_registry:
wl_registry_destroy(dri2_dpy->wl_registry);
wl_event_queue_destroy(dri2_dpy->wl_queue);
+ if (disp->PlatformDisplay == NULL)
+ wl_display_disconnect(dri2_dpy->wl_dpy);
cleanup_dpy:
free(dri2_dpy);
+ disp->DriverData = NULL;
return EGL_FALSE;
}
/* find back buffer */
- /* We always want to throttle to some event (either a frame callback or
- * a sync request) after the commit so that we can be sure the
- * compositor has had a chance to handle it and send us a release event
- * before we look for a free buffer */
- while (dri2_surf->throttle_callback != NULL)
- if (wl_display_dispatch_queue(dri2_dpy->wl_dpy,
- dri2_dpy->wl_queue) == -1)
- return -1;
+ /* There might be a buffer release already queued that wasn't processed */
+ wl_display_dispatch_queue_pending(dri2_dpy->wl_dpy, dri2_dpy->wl_queue);
/* try get free buffer already created */
for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) {
{
struct dri2_egl_display *dri2_dpy = dri2_egl_display(dri2_surf->base.Resource.Display);
+ while (dri2_surf->throttle_callback != NULL)
+ if (wl_display_dispatch_queue(dri2_dpy->wl_dpy,
+ dri2_dpy->wl_queue) == -1)
+ return;
+
if (dri2_surf->base.SwapInterval > 0) {
dri2_surf->throttle_callback =
wl_surface_frame(dri2_surf->wl_win->surface);
config, dri2_surf);
if (dri2_surf->dri_drawable == NULL) {
_eglError(EGL_BAD_ALLOC, "swrast->createNewDrawable");
- goto cleanup_dri_drawable;
+ goto cleanup_surf;
}
dri2_wl_swap_interval(drv, disp, &dri2_surf->base,
return &dri2_surf->base;
- cleanup_dri_drawable:
- dri2_dpy->core->destroyDrawable(dri2_surf->dri_drawable);
cleanup_surf:
free(dri2_surf);
.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);
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
return EGL_TRUE;
+ cleanup_screen:
+ dri2_dpy->core->destroyScreen(dri2_dpy->dri_screen);
cleanup_driver:
dlclose(dri2_dpy->driver);
cleanup_shm:
cleanup_registry:
wl_registry_destroy(dri2_dpy->wl_registry);
wl_event_queue_destroy(dri2_dpy->wl_queue);
+ if (disp->PlatformDisplay == NULL)
+ wl_display_disconnect(dri2_dpy->wl_dpy);
cleanup_dpy:
free(dri2_dpy);
+ disp->DriverData = NULL;
return EGL_FALSE;
}