Blame SOURCES/0012-xwayland-eglstream-Add-more-error-checking.patch

4c4b8b
From e8f7568016249822bb95c87447ded6abb724c13b Mon Sep 17 00:00:00 2001
4c4b8b
From: Olivier Fourdan <ofourdan@redhat.com>
4c4b8b
Date: Thu, 1 Apr 2021 08:46:52 +0200
4c4b8b
Subject: [PATCH xserver 12/27] xwayland/eglstream: Add more error checking
4c4b8b
MIME-Version: 1.0
4c4b8b
Content-Type: text/plain; charset=UTF-8
4c4b8b
Content-Transfer-Encoding: 8bit
4c4b8b
4c4b8b
eglCreateStreamKHR() can fail and return EGL_NO_STREAM_KHR, in which
4c4b8b
case there is no point in trying to create a buffer from it.
4c4b8b
4c4b8b
Similarly, eglCreateStreamProducerSurfaceKHR() also fail and return
4c4b8b
EGL_NO_SURFACE, which in turn will be used in eglMakeCurrent() as
4c4b8b
draw/read surface, and therefore would mean no draw/read buffer.
4c4b8b
4c4b8b
In those cases, log the error, and bail out early. That won't solve the
4c4b8b
issue but will help with investigating the root cause of issues with
4c4b8b
EGLStream backend.
4c4b8b
4c4b8b
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
4c4b8b
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
4c4b8b
https://gitlab.freedesktop.org/xorg/xserver/-/issues/1156
4c4b8b
(cherry picked from commit cc596bcfb273eeab82ac3d59867668af8bad2abf)
4c4b8b
---
4c4b8b
 hw/xwayland/xwayland-glamor-eglstream.c | 93 +++++++++++++++++++++++++
4c4b8b
 1 file changed, 93 insertions(+)
4c4b8b
4c4b8b
diff --git a/hw/xwayland/xwayland-glamor-eglstream.c b/hw/xwayland/xwayland-glamor-eglstream.c
4c4b8b
index 9abb7b779..77b24a4b4 100644
4c4b8b
--- a/hw/xwayland/xwayland-glamor-eglstream.c
4c4b8b
+++ b/hw/xwayland/xwayland-glamor-eglstream.c
4c4b8b
@@ -387,6 +387,84 @@ xwl_eglstream_set_window_pixmap(WindowPtr window, PixmapPtr pixmap)
4c4b8b
     xwl_screen->screen->SetWindowPixmap = xwl_eglstream_set_window_pixmap;
4c4b8b
 }
4c4b8b
 
4c4b8b
+static const char *
4c4b8b
+xwl_eglstream_get_error_str(EGLint error)
4c4b8b
+{
4c4b8b
+    switch (error) {
4c4b8b
+    case EGL_BAD_PARAMETER:
4c4b8b
+        return "EGL_BAD_PARAMETER";
4c4b8b
+    case EGL_BAD_ATTRIBUTE:
4c4b8b
+        return "EGL_BAD_ATTRIBUTE";
4c4b8b
+    case EGL_BAD_MATCH:
4c4b8b
+        return "EGL_BAD_MATCH";
4c4b8b
+    case EGL_BAD_ACCESS:
4c4b8b
+        return "EGL_BAD_ACCESS";
4c4b8b
+    case EGL_BAD_STATE_KHR:
4c4b8b
+        return "EGL_BAD_STATE_KHR";
4c4b8b
+    case EGL_BAD_STREAM_KHR:
4c4b8b
+        return "EGL_BAD_STREAM_KHR";
4c4b8b
+    case EGL_BAD_DISPLAY:
4c4b8b
+        return "EGL_BAD_DISPLAY";
4c4b8b
+    case EGL_NOT_INITIALIZED:
4c4b8b
+        return "EGL_NOT_INITIALIZED";
4c4b8b
+    default:
4c4b8b
+        return "Unknown error";
4c4b8b
+    }
4c4b8b
+}
4c4b8b
+
4c4b8b
+static const char *
4c4b8b
+xwl_eglstream_get_stream_state_str(EGLint state)
4c4b8b
+{
4c4b8b
+    switch (state) {
4c4b8b
+    case EGL_STREAM_STATE_CREATED_KHR:
4c4b8b
+        return "EGL_STREAM_STATE_CREATED_KHR";
4c4b8b
+    case EGL_STREAM_STATE_CONNECTING_KHR:
4c4b8b
+        return "EGL_STREAM_STATE_CONNECTING_KHR";
4c4b8b
+    case EGL_STREAM_STATE_EMPTY_KHR:
4c4b8b
+        return "EGL_STREAM_STATE_EMPTY_KHR";
4c4b8b
+    case EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR:
4c4b8b
+        return "EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR";
4c4b8b
+    case EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR:
4c4b8b
+        return "EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR";
4c4b8b
+    case EGL_STREAM_STATE_DISCONNECTED_KHR:
4c4b8b
+        return "EGL_STREAM_STATE_DISCONNECTED_KHR";
4c4b8b
+    default:
4c4b8b
+        return "Unknown state";
4c4b8b
+    }
4c4b8b
+}
4c4b8b
+
4c4b8b
+static EGLint
4c4b8b
+xwl_eglstream_get_state(EGLDisplay egl_display, EGLStreamKHR egl_stream)
4c4b8b
+{
4c4b8b
+    EGLint state;
4c4b8b
+
4c4b8b
+    eglQueryStreamKHR(egl_display, egl_stream, EGL_STREAM_STATE_KHR, &state);
4c4b8b
+    if (!eglQueryStreamKHR(egl_display, egl_stream,
4c4b8b
+                           EGL_STREAM_STATE_KHR, &state)) {
4c4b8b
+        EGLint state_error = eglGetError();
4c4b8b
+        ErrorF("eglstream: Failed to query state - error 0x%X: %s\n",
4c4b8b
+               state_error, xwl_eglstream_get_error_str(state_error));
4c4b8b
+        return EGL_FALSE;
4c4b8b
+    }
4c4b8b
+
4c4b8b
+    return state;
4c4b8b
+}
4c4b8b
+
4c4b8b
+
4c4b8b
+static void
4c4b8b
+xwl_eglstream_print_error(EGLDisplay egl_display,
4c4b8b
+                          EGLStreamKHR egl_stream, EGLint error)
4c4b8b
+{
4c4b8b
+    ErrorF("eglstream: error 0x%X: %s\n", error,
4c4b8b
+           xwl_eglstream_get_error_str(error));
4c4b8b
+
4c4b8b
+    if (error == EGL_BAD_STATE_KHR) {
4c4b8b
+        EGLint state = xwl_eglstream_get_state(egl_display, egl_stream);
4c4b8b
+        ErrorF("eglstream: stream state 0x%X: %s\n", state,
4c4b8b
+               xwl_eglstream_get_stream_state_str(state));
4c4b8b
+    }
4c4b8b
+}
4c4b8b
+
4c4b8b
 /* Because we run asynchronously with our wayland compositor, it's possible
4c4b8b
  * that an X client event could cause us to begin creating a stream for a
4c4b8b
  * pixmap/window combo before the stream for the pixmap this window
4c4b8b
@@ -466,6 +544,13 @@ xwl_eglstream_consumer_ready_callback(void *data,
4c4b8b
             EGL_NONE
4c4b8b
         });
4c4b8b
 
4c4b8b
+    if (xwl_pixmap->surface == EGL_NO_SURFACE) {
4c4b8b
+        ErrorF("eglstream: Failed to create EGLSurface for pixmap\n");
4c4b8b
+        xwl_eglstream_print_error(xwl_screen->egl_display,
4c4b8b
+                                  xwl_pixmap->stream, eglGetError());
4c4b8b
+        goto out;
4c4b8b
+    }
4c4b8b
+
4c4b8b
     DebugF("eglstream: win %d completes eglstream for pixmap %p, congrats!\n",
4c4b8b
            pending->window->drawable.id, pending->pixmap);
4c4b8b
 
4c4b8b
@@ -543,8 +628,16 @@ xwl_eglstream_create_pixmap_and_stream(struct xwl_screen *xwl_screen,
4c4b8b
     xwl_pixmap->xwl_screen = xwl_screen;
4c4b8b
     xwl_pixmap->surface = EGL_NO_SURFACE;
4c4b8b
     xwl_pixmap->stream = eglCreateStreamKHR(xwl_screen->egl_display, NULL);
4c4b8b
+    if (xwl_pixmap->stream == EGL_NO_STREAM_KHR) {
4c4b8b
+        ErrorF("eglstream: Couldn't create EGL stream.\n");
4c4b8b
+        goto fail;
4c4b8b
+    }
4c4b8b
     stream_fd = eglGetStreamFileDescriptorKHR(xwl_screen->egl_display,
4c4b8b
                                               xwl_pixmap->stream);
4c4b8b
+    if (stream_fd == EGL_NO_FILE_DESCRIPTOR_KHR) {
4c4b8b
+        ErrorF("eglstream: Couldn't get EGL stream file descriptor.\n");
4c4b8b
+        goto fail;
4c4b8b
+    }
4c4b8b
 
4c4b8b
     wl_array_init(&stream_attribs);
4c4b8b
     xwl_pixmap->buffer =
4c4b8b
-- 
4c4b8b
2.31.1
4c4b8b