X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fegl%2Fdrivers%2Fdri2%2Fplatform_wayland.c;h=ff0d5c802acf21824dcd3231d9e79fb0fe8bb5b8;hb=d943ac432de1f46cea47bdbf5ffe5365e2aef386;hp=160fa8ce8d7971022a39302b5d1ed3dd72ed6ed3;hpb=052b3d4e2f159038137504f01e9ff2380a67af8b;p=mesa.git diff --git a/src/egl/drivers/dri2/platform_wayland.c b/src/egl/drivers/dri2/platform_wayland.c index 160fa8ce8d7..ff0d5c802ac 100644 --- a/src/egl/drivers/dri2/platform_wayland.c +++ b/src/egl/drivers/dri2/platform_wayland.c @@ -65,7 +65,7 @@ sync_callback(void *data, struct wl_callback *callback, uint32_t serial) } static const struct wl_callback_listener sync_listener = { - sync_callback + .done = sync_callback }; static int @@ -104,8 +104,8 @@ wl_buffer_release(void *data, struct wl_buffer *buffer) 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 @@ -130,6 +130,7 @@ dri2_wl_create_surface(_EGLDriver *drv, _EGLDisplay *disp, 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; @@ -149,6 +150,11 @@ dri2_wl_create_surface(_EGLDriver *drv, _EGLDisplay *disp, 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; @@ -157,19 +163,19 @@ dri2_wl_create_surface(_EGLDriver *drv, _EGLDisplay *disp, dri2_surf->base.Width = -1; dri2_surf->base.Height = -1; - dri2_surf->dri_drawable = - (*dri2_dpy->dri2->createNewDrawable) (dri2_dpy->dri_screen, - dri2_conf->dri_double_config, - dri2_surf); + 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, 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); @@ -299,7 +305,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, @@ -346,6 +352,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 = @@ -353,7 +361,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) @@ -367,7 +375,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; } @@ -595,7 +603,7 @@ wayland_throttle_callback(void *data, } static const struct wl_callback_listener throttle_listener = { - wayland_throttle_callback + .done = wayland_throttle_callback }; static void @@ -647,6 +655,37 @@ create_wl_buffer(struct dri2_egl_surface *dri2_surf) &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(). */ @@ -697,18 +736,12 @@ dri2_wl_swap_buffers_with_damage(_EGLDriver *drv, 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(); @@ -839,22 +872,6 @@ bad_format: return NULL; } -static char -is_fd_render_node(int fd) -{ - struct stat render; - - if (fstat(fd, &render)) - return 0; - - if (!S_ISCHR(render.st_mode)) - return 0; - - if (render.st_rdev & 0x80) - return 1; - return 0; -} - static int dri2_wl_authenticate(_EGLDisplay *disp, uint32_t id) { @@ -898,7 +915,7 @@ drm_handle_device(void *data, struct wl_drm *drm, const char *device) 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); @@ -941,10 +958,10 @@ drm_handle_authenticated(void *data, struct wl_drm *drm) } 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 @@ -969,8 +986,8 @@ registry_handle_global_remove(void *data, struct wl_registry *registry, } 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 @@ -1043,6 +1060,7 @@ static struct dri2_egl_display_vtbl dri2_wl_display_vtbl = { .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 @@ -1108,7 +1126,7 @@ dri2_initialize_wayland_drm(_EGLDriver *drv, _EGLDisplay *disp) * 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) { @@ -1237,6 +1255,8 @@ dri2_wl_swrast_get_stride_for_format(int format, int w) * Taken from weston shared/os-compatibility.c */ +#ifndef HAVE_MKOSTEMP + static int set_cloexec_or_close(int fd) { @@ -1259,6 +1279,8 @@ err: return -1; } +#endif + /* * Taken from weston shared/os-compatibility.c */ @@ -1651,6 +1673,7 @@ dri2_wl_swrast_create_window_surface(_EGLDriver *drv, _EGLDisplay *disp, 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; @@ -1675,10 +1698,12 @@ dri2_wl_swrast_create_window_surface(_EGLDriver *drv, _EGLDisplay *disp, 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; @@ -1726,7 +1751,7 @@ shm_handle_format(void *data, struct wl_shm *shm, uint32_t format) } static const struct wl_shm_listener shm_listener = { - shm_handle_format + .format = shm_handle_format }; static void @@ -1743,8 +1768,8 @@ registry_handle_global_swrast(void *data, struct wl_registry *registry, uint32_t } 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 = { @@ -1763,6 +1788,7 @@ 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 @@ -1810,6 +1836,7 @@ dri2_initialize_wayland_swrast(_EGLDriver *drv, _EGLDisplay *disp) 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;