diff --git a/libweston/compositor.c b/libweston/compositor.c index c94fa315..b60f35de 100644 --- a/libweston/compositor.c +++ b/libweston/compositor.c @@ -7103,3 +7103,38 @@ weston_compositor_load_xwayland(struct weston_compositor *compositor) return -1; return 0; } + +/** Resolve an internal compositor error by disconnecting the client. + * + * This function is used in cases when the wl_buffer turns out + * unusable and there is no fallback path. + * + * It is possible the fault is caused by a compositor bug, the underlying + * graphics stack bug or normal behaviour, or perhaps a client mistake. + * In any case, the options are to either composite garbage or nothing, + * or disconnect the client. This is a helper function for the latter. + * + * The error is sent as an INVALID_OBJECT error on the client's wl_display. + * + * \param buffer The weston buffer that is unusable. + * \param msg A custom error message attached to the protocol error. + */ +WL_EXPORT void +weston_buffer_send_server_error(struct weston_buffer *buffer, + const char *msg) +{ + struct wl_client *client; + struct wl_resource *display_resource; + uint32_t id; + + assert(buffer->resource); + id = wl_resource_get_id(buffer->resource); + client = wl_resource_get_client(buffer->resource); + display_resource = wl_client_get_object(client, 1); + + assert(display_resource); + wl_resource_post_error(display_resource, + WL_DISPLAY_ERROR_INVALID_OBJECT, + "server error with " + "wl_buffer@%u: %s", id, msg); +} diff --git a/libweston/compositor.h b/libweston/compositor.h index cd718390..b4b75197 100644 --- a/libweston/compositor.h +++ b/libweston/compositor.h @@ -2345,6 +2345,10 @@ weston_debug_compositor_create(struct weston_compositor *compositor); void weston_debug_compositor_destroy(struct weston_compositor *compositor); +void +weston_buffer_send_server_error(struct weston_buffer *buffer, + const char *msg); + #ifdef __cplusplus } #endif diff --git a/libweston/gl-renderer.c b/libweston/gl-renderer.c index f2da0d34..c9e5a8fc 100644 --- a/libweston/gl-renderer.c +++ b/libweston/gl-renderer.c @@ -2377,10 +2377,16 @@ gl_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer) gl_renderer_attach_dmabuf(es, buffer, dmabuf); else { weston_log("unhandled buffer type!\n"); + if (gr->has_bind_display) { + weston_log("eglQueryWaylandBufferWL failed\n"); + gl_renderer_print_egl_error_state(); + } weston_buffer_reference(&gs->buffer_ref, NULL); gs->buffer_type = BUFFER_TYPE_NULL; gs->y_inverted = 1; es->is_opaque = false; + weston_buffer_send_server_error(buffer, + "disconnecting due to unhandled buffer type"); } } diff --git a/libweston/pixman-renderer.c b/libweston/pixman-renderer.c index a316766e..9640b616 100644 --- a/libweston/pixman-renderer.c +++ b/libweston/pixman-renderer.c @@ -661,8 +661,11 @@ pixman_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer) es->is_opaque = true; break; default: - weston_log("Unsupported SHM buffer format\n"); + weston_log("Unsupported SHM buffer format 0x%x\n", + wl_shm_buffer_get_format(shm_buffer)); weston_buffer_reference(&ps->buffer_ref, NULL); + weston_buffer_send_server_error(buffer, + "disconnecting due to unhandled buffer type"); return; break; }