}
static const struct wl_callback_listener sync_listener = {
- sync_callback
+ .done = sync_callback
};
static int
dri2_surf->color_buffers[i].locked = 0;
}
-static struct wl_buffer_listener wl_buffer_listener = {
- wl_buffer_release
+static const struct wl_buffer_listener wl_buffer_listener = {
+ .release = wl_buffer_release
};
static void
struct dri2_egl_config *dri2_conf = dri2_egl_config(conf);
struct wl_egl_window *window = native_window;
struct dri2_egl_surface *dri2_surf;
+ const __DRIconfig *config;
(void) drv;
_eglError(EGL_BAD_ALLOC, "dri2_create_surface");
return NULL;
}
-
+
if (!_eglInitSurface(&dri2_surf->base, disp, EGL_WINDOW_BIT, conf, attrib_list))
goto cleanup_surf;
else
dri2_surf->format = WL_DRM_FORMAT_ARGB8888;
+ if (!window) {
+ _eglError(EGL_BAD_NATIVE_WINDOW, "dri2_create_surface");
+ goto cleanup_surf;
+ }
+
dri2_surf->wl_win = window;
dri2_surf->wl_win->private = dri2_surf;
dri2_surf->base.Width = -1;
dri2_surf->base.Height = -1;
+ config = dri2_get_dri_config(dri2_conf, EGL_WINDOW_BIT,
+ dri2_surf->base.GLColorspace);
+
dri2_surf->dri_drawable =
- (*dri2_dpy->dri2->createNewDrawable) (dri2_dpy->dri_screen,
- dri2_conf->dri_double_config,
- dri2_surf);
+ (*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_dri_drawable;
+ goto cleanup_surf;
}
return &dri2_surf->base;
- cleanup_dri_drawable:
- dri2_dpy->core->destroyDrawable(dri2_surf->dri_drawable);
cleanup_surf:
free(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,
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 =
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)
}
if (dri2_surf->back->dri_image == NULL) {
- dri2_surf->back->dri_image =
+ dri2_surf->back->dri_image =
dri2_dpy->image->createImage(dri2_dpy->dri_screen,
dri2_surf->base.Width,
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;
}
}
static const struct wl_callback_listener throttle_listener = {
- wayland_throttle_callback
+ .done = wayland_throttle_callback
};
static void
&wl_buffer_listener, dri2_surf);
}
+static EGLBoolean
+try_damage_buffer(struct dri2_egl_surface *dri2_surf,
+ const EGLint *rects,
+ EGLint n_rects)
+{
+/* The WL_SURFACE_DAMAGE_BUFFER_SINCE_VERSION macro and
+ * wl_proxy_get_version() were both introduced in wayland 1.10.
+ * Instead of bumping our wayland dependency we just make this
+ * function conditional on the required 1.10 features, falling
+ * back to old (correct but suboptimal) behaviour for older
+ * wayland.
+ */
+#ifdef WL_SURFACE_DAMAGE_BUFFER_SINCE_VERSION
+ int i;
+
+ if (wl_proxy_get_version((struct wl_proxy *) dri2_surf->wl_win->surface)
+ < WL_SURFACE_DAMAGE_BUFFER_SINCE_VERSION)
+ return EGL_FALSE;
+
+ for (i = 0; i < n_rects; i++) {
+ const int *rect = &rects[i * 4];
+
+ wl_surface_damage_buffer(dri2_surf->wl_win->surface,
+ rect[0],
+ dri2_surf->base.Height - rect[1] - rect[3],
+ rect[2], rect[3]);
+ }
+ return EGL_TRUE;
+#endif
+ return EGL_FALSE;
+}
/**
* Called via eglSwapBuffers(), drv->API.SwapBuffers().
*/
dri2_surf->dx = 0;
dri2_surf->dy = 0;
- if (n_rects == 0) {
+ /* If the compositor doesn't support damage_buffer, we deliberately
+ * ignore the damage region and post maximum damage, due to
+ * https://bugs.freedesktop.org/78190 */
+ if (!n_rects || !try_damage_buffer(dri2_surf, rects, n_rects))
wl_surface_damage(dri2_surf->wl_win->surface,
0, 0, INT32_MAX, INT32_MAX);
- } else {
- for (i = 0; i < n_rects; i++) {
- const int *rect = &rects[i * 4];
- wl_surface_damage(dri2_surf->wl_win->surface,
- rect[0],
- dri2_surf->base.Height - rect[1] - rect[3],
- rect[2], rect[3]);
- }
- }
if (dri2_dpy->is_different_gpu) {
_EGLContext *ctx = _eglGetCurrentContext();
return NULL;
}
-static char
-is_fd_render_node(int fd)
-{
- struct stat render;
-
- if (fstat(fd, &render))
- return 0;
-
- if (!S_ISCHR(render.st_mode))
- return 0;
-
- if (render.st_rdev & 0x80)
- return 1;
- return 0;
-}
-
static int
dri2_wl_authenticate(_EGLDisplay *disp, uint32_t id)
{
if (!dri2_dpy->device_name)
return;
-#ifdef O_CLOEXEC
- dri2_dpy->fd = open(dri2_dpy->device_name, O_RDWR | O_CLOEXEC);
- if (dri2_dpy->fd == -1 && errno == EINVAL)
-#endif
- {
- dri2_dpy->fd = open(dri2_dpy->device_name, O_RDWR);
- if (dri2_dpy->fd != -1)
- fcntl(dri2_dpy->fd, F_SETFD, fcntl(dri2_dpy->fd, F_GETFD) |
- FD_CLOEXEC);
- }
+ dri2_dpy->fd = loader_open_device(dri2_dpy->device_name);
if (dri2_dpy->fd == -1) {
_eglLog(_EGL_WARNING, "wayland-egl: could not open %s (%s)",
dri2_dpy->device_name, strerror(errno));
return;
}
- if (is_fd_render_node(dri2_dpy->fd)) {
+ if (drmGetNodeTypeFromFd(dri2_dpy->fd) == DRM_NODE_RENDER) {
dri2_dpy->authenticated = 1;
} else {
drmGetMagic(dri2_dpy->fd, &magic);
}
static const struct wl_drm_listener drm_listener = {
- drm_handle_device,
- drm_handle_format,
- drm_handle_authenticated,
- drm_handle_capabilities
+ .device = drm_handle_device,
+ .format = drm_handle_format,
+ .authenticated = drm_handle_authenticated,
+ .capabilities = drm_handle_capabilities
};
static void
}
static const struct wl_registry_listener registry_listener_drm = {
- registry_handle_global_drm,
- registry_handle_global_remove
+ .global = registry_handle_global_drm,
+ .global_remove = registry_handle_global_remove
};
static EGLBoolean
.query_buffer_age = dri2_wl_query_buffer_age,
.create_wayland_buffer_from_image = dri2_wl_create_wayland_buffer_from_image,
.get_sync_values = dri2_fallback_get_sync_values,
+ .get_dri_drawable = dri2_surface_get_dri_drawable,
};
static EGLBoolean
* will return a render-node when the requested gpu is different
* to the server, but also if the client asks for the same gpu than
* the server by requesting its pci-id */
- dri2_dpy->is_render_node = is_fd_render_node(dri2_dpy->fd);
+ dri2_dpy->is_render_node = drmGetNodeTypeFromFd(dri2_dpy->fd) == DRM_NODE_RENDER;
dri2_dpy->driver_name = loader_get_driver_for_fd(dri2_dpy->fd, 0);
if (dri2_dpy->driver_name == NULL) {
} else
dri2_dpy->extensions[3] = NULL;
- dri2_dpy->swap_available = EGL_TRUE;
-
if (!dri2_create_screen(disp))
goto cleanup_driver;
wl_event_queue_destroy(dri2_dpy->wl_queue);
cleanup_dpy:
free(dri2_dpy);
-
+ disp->DriverData = NULL;
+
return EGL_FALSE;
}
* Taken from weston shared/os-compatibility.c
*/
+#ifndef HAVE_MKOSTEMP
+
static int
set_cloexec_or_close(int fd)
{
return -1;
}
+#endif
+
/*
* Taken from weston shared/os-compatibility.c
*/
struct dri2_egl_config *dri2_conf = dri2_egl_config(conf);
struct wl_egl_window *window = native_window;
struct dri2_egl_surface *dri2_surf;
+ const __DRIconfig *config;
(void) drv;
dri2_surf->base.Width = -1;
dri2_surf->base.Height = -1;
+ config = dri2_get_dri_config(dri2_conf, EGL_WINDOW_BIT,
+ dri2_surf->base.GLColorspace);
+
dri2_surf->dri_drawable =
- (*dri2_dpy->swrast->createNewDrawable) (dri2_dpy->dri_screen,
- dri2_conf->dri_double_config,
- dri2_surf);
+ (*dri2_dpy->swrast->createNewDrawable)(dri2_dpy->dri_screen,
+ config, dri2_surf);
if (dri2_surf->dri_drawable == NULL) {
_eglError(EGL_BAD_ALLOC, "swrast->createNewDrawable");
goto cleanup_dri_drawable;
}
static const struct wl_shm_listener shm_listener = {
- shm_handle_format
+ .format = shm_handle_format
};
static void
}
static const struct wl_registry_listener registry_listener_swrast = {
- registry_handle_global_swrast,
- registry_handle_global_remove
+ .global = registry_handle_global_swrast,
+ .global_remove = registry_handle_global_remove
};
static struct dri2_egl_display_vtbl dri2_wl_swrast_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 EGLBoolean
if (roundtrip(dri2_dpy) < 0 || dri2_dpy->formats == 0)
goto cleanup_shm;
+ dri2_dpy->fd = -1;
dri2_dpy->driver_name = strdup("swrast");
if (!dri2_load_driver_swrast(disp))
goto cleanup_shm;
wl_event_queue_destroy(dri2_dpy->wl_queue);
cleanup_dpy:
free(dri2_dpy);
+ disp->DriverData = NULL;
return EGL_FALSE;
}