diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c index d3c678d6bf738631a2aafe5dd2e0bac68366828f..9a619a133a64314685a719760efd4a491ad394b0 100644 --- a/glamor/glamor_egl.c +++ b/glamor/glamor_egl.c @@ -355,8 +355,8 @@ glamor_make_pixmap_exportable(PixmapPtr pixmap, Bool modifiers_ok) return TRUE; } -struct gbm_bo * -glamor_gbm_bo_from_pixmap(ScreenPtr screen, PixmapPtr pixmap) +static struct gbm_bo * +glamor_gbm_bo_from_pixmap_internal(ScreenPtr screen, PixmapPtr pixmap) { struct glamor_egl_screen_private *glamor_egl = glamor_egl_get_screen_private(xf86ScreenToScrn(screen)); @@ -370,6 +370,15 @@ glamor_gbm_bo_from_pixmap(ScreenPtr screen, PixmapPtr pixmap) pixmap_priv->image, 0); } +struct gbm_bo * +glamor_gbm_bo_from_pixmap(ScreenPtr screen, PixmapPtr pixmap) +{ + if (!glamor_make_pixmap_exportable(pixmap, TRUE)) + return NULL; + + return glamor_gbm_bo_from_pixmap_internal(screen, pixmap); +} + int glamor_egl_fds_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, int *fds, uint32_t *strides, uint32_t *offsets, @@ -385,7 +394,7 @@ glamor_egl_fds_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, int *fds, if (!glamor_make_pixmap_exportable(pixmap, TRUE)) return 0; - bo = glamor_gbm_bo_from_pixmap(screen, pixmap); + bo = glamor_gbm_bo_from_pixmap_internal(screen, pixmap); if (!bo) return 0; @@ -423,7 +432,7 @@ glamor_egl_fd_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, if (!glamor_make_pixmap_exportable(pixmap, FALSE)) return -1; - bo = glamor_gbm_bo_from_pixmap(screen, pixmap); + bo = glamor_gbm_bo_from_pixmap_internal(screen, pixmap); if (!bo) return -1; @@ -452,7 +461,7 @@ glamor_egl_fd_name_from_pixmap(ScreenPtr screen, if (!glamor_make_pixmap_exportable(pixmap, FALSE)) goto failure; - bo = glamor_gbm_bo_from_pixmap(screen, pixmap); + bo = glamor_gbm_bo_from_pixmap_internal(screen, pixmap); if (!bo) goto failure; diff --git a/hw/xwayland/xwayland-cursor.c b/hw/xwayland/xwayland-cursor.c index cf8395f1dd0303c46b39b26fe69eb09189291dda..66720bcc0601d20143f7c32fcfa6597b48e0fb36 100644 --- a/hw/xwayland/xwayland-cursor.c +++ b/hw/xwayland/xwayland-cursor.c @@ -188,6 +188,8 @@ xwl_tablet_tool_set_cursor(struct xwl_tablet_tool *xwl_tablet_tool) zwp_tablet_tool_v2_set_cursor(xwl_tablet_tool->tool, xwl_tablet_tool->proximity_in_serial, NULL, 0, 0); + clear_cursor_frame_callback(xwl_cursor); + xwl_cursor->needs_update = FALSE; return; } diff --git a/hw/xwayland/xwayland-glamor-gbm.c b/hw/xwayland/xwayland-glamor-gbm.c index a211e091573dd2f96e547f1b8ef6451c6dc31210..80146ab6e51398a9bdc96a0abe733f7338095bff 100644 --- a/hw/xwayland/xwayland-glamor-gbm.c +++ b/hw/xwayland/xwayland-glamor-gbm.c @@ -169,6 +169,8 @@ xwl_glamor_gbm_create_pixmap_for_bo(ScreenPtr screen, struct gbm_bo *bo, xwl_screen->egl_context, EGL_NATIVE_PIXMAP_KHR, xwl_pixmap->bo, NULL); + if (xwl_pixmap->image == EGL_NO_IMAGE_KHR) + goto error; glGenTextures(1, &xwl_pixmap->texture); glBindTexture(GL_TEXTURE_2D, xwl_pixmap->texture); @@ -176,14 +178,31 @@ xwl_glamor_gbm_create_pixmap_for_bo(ScreenPtr screen, struct gbm_bo *bo, glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, xwl_pixmap->image); - glBindTexture(GL_TEXTURE_2D, 0); + if (eglGetError() != EGL_SUCCESS) + goto error; - xwl_pixmap_set_private(pixmap, xwl_pixmap); + glBindTexture(GL_TEXTURE_2D, 0); glamor_set_pixmap_texture(pixmap, xwl_pixmap->texture); + /* `set_pixmap_texture()` may fail silently if the FBO creation failed, + * so we check again the texture to be sure it worked. + */ + if (!glamor_get_pixmap_texture(pixmap)) + goto error; + glamor_set_pixmap_type(pixmap, GLAMOR_TEXTURE_DRM); + xwl_pixmap_set_private(pixmap, xwl_pixmap); return pixmap; + +error: + if (xwl_pixmap->image != EGL_NO_IMAGE_KHR) + eglDestroyImageKHR(xwl_screen->egl_display, xwl_pixmap->image); + if (pixmap) + glamor_destroy_pixmap(pixmap); + free(xwl_pixmap); + + return NULL; } static PixmapPtr @@ -194,6 +213,7 @@ xwl_glamor_gbm_create_pixmap(ScreenPtr screen, struct xwl_screen *xwl_screen = xwl_screen_get(screen); struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen); struct gbm_bo *bo; + PixmapPtr pixmap = NULL; if (width > 0 && height > 0 && depth >= 15 && (hint == 0 || @@ -219,10 +239,16 @@ xwl_glamor_gbm_create_pixmap(ScreenPtr screen, } if (bo) - return xwl_glamor_gbm_create_pixmap_for_bo(screen, bo, depth); + pixmap = xwl_glamor_gbm_create_pixmap_for_bo(screen, bo, depth); + + if (!pixmap) + gbm_bo_destroy(bo); } - return glamor_create_pixmap(screen, width, height, depth, hint); + if (!pixmap) + pixmap = glamor_create_pixmap(screen, width, height, depth, hint); + + return pixmap; } static Bool diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c index fbbcb39cc268d0b1761fdfd1dca36a8ea05787cc..fa46ac3e7845a627b8330d74eefe09aadb229eae 100644 --- a/hw/xwayland/xwayland-input.c +++ b/hw/xwayland/xwayland-input.c @@ -2667,6 +2667,7 @@ xwl_pointer_warp_emulator_maybe_lock(struct xwl_pointer_warp_emulator *warp_emul */ if (pointer_grab && !pointer_grab->ownerEvents && + sprite && XYToWindow(sprite, x, y) != xwl_seat->focus_window->window) return;