Module: Mesa
Branch: main
Commit: 8c98814874df588fa205d15ea08f93746e959952
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=8c98814874df588fa205d15ea08f93746e959952

Author: Konstantin Seurer <[email protected]>
Date:   Wed Aug 16 17:16:07 2023 +0200

vulkan/wsi/x11: Implement capture hotkey using the keymap

This way, we can avoid opening another connection. The capture key is
changes to F1 because F12 has issues on Wayland. (After pressing F12,
all keys become unresponsive, refocussing the window fixes it)

Fixes: 291fa05  ("vulkan/wsi/x11: Capture traces using a hotkey")
Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/9578
Reviewed-by: Konstantin Seurer <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24710>

---

 docs/envvars.rst                    |  2 +-
 src/vulkan/wsi/wsi_common_private.h |  2 ++
 src/vulkan/wsi/wsi_common_x11.c     | 55 ++++++++++++++++---------------------
 3 files changed, 26 insertions(+), 33 deletions(-)

diff --git a/docs/envvars.rst b/docs/envvars.rst
index 2aac7959152..4ec1fd76b8e 100644
--- a/docs/envvars.rst
+++ b/docs/envvars.rst
@@ -346,7 +346,7 @@ Core Mesa environment variables
 
    A comma-separated list of trace types used for offline analysis. The
    option names are equal to the file extension. Traces are dumped into 
``/tmp``.
-   Captures can be triggered by pressing ``F12`` with the application window
+   Captures can be triggered by pressing ``F1`` with the application window
    focused (Currently X11 only) or via :envvar:`MESA_VK_TRACE_FRAME` and
    :envvar:`MESA_VK_TRACE_TRIGGER`.
 
diff --git a/src/vulkan/wsi/wsi_common_private.h 
b/src/vulkan/wsi/wsi_common_private.h
index fd4d8482288..8ee9c025e96 100644
--- a/src/vulkan/wsi/wsi_common_private.h
+++ b/src/vulkan/wsi/wsi_common_private.h
@@ -171,6 +171,8 @@ struct wsi_swapchain {
       VkQueue queue;
    } blit;
 
+   bool capture_key_pressed;
+
    /* Command pools, one per queue family */
    VkCommandPool *cmd_pools;
 
diff --git a/src/vulkan/wsi/wsi_common_x11.c b/src/vulkan/wsi/wsi_common_x11.c
index 9be9a351f6b..0f9dad6a0e4 100644
--- a/src/vulkan/wsi/wsi_common_x11.c
+++ b/src/vulkan/wsi/wsi_common_x11.c
@@ -1045,7 +1045,6 @@ struct x11_swapchain {
    bool                                         has_mit_shm;
 
    xcb_connection_t *                           conn;
-   xcb_connection_t *                           capture_conn;
    xcb_window_t                                 window;
    xcb_gc_t                                     gc;
    uint32_t                                     depth;
@@ -1687,24 +1686,36 @@ x11_present_to_x11_sw(struct x11_swapchain *chain, 
uint32_t image_index,
 static void
 x11_capture_trace(struct x11_swapchain *chain)
 {
-   if (!chain->capture_conn)
+#ifdef XCB_KEYSYMS_AVAILABLE
+   VK_FROM_HANDLE(vk_device, device, chain->base.device);
+   if (!device->physical->instance->trace_mode)
       return;
 
-   xcb_generic_event_t *event;
-   while ((event = xcb_poll_for_event(chain->capture_conn))) {
-      if ((event->response_type & ~0x80) != XCB_KEY_PRESS) {
-         free(event);
-         continue;
-      }
+   xcb_query_keymap_cookie_t keys_cookie = xcb_query_keymap(chain->conn);
+
+   xcb_generic_error_t *error = NULL;
+   xcb_query_keymap_reply_t *keys = xcb_query_keymap_reply(chain->conn, 
keys_cookie, &error);
+   if (error) {
+      free(error);
+      return;
+   }
 
-      VK_FROM_HANDLE(vk_device, device, chain->base.device);
+   xcb_key_symbols_t *key_symbols = xcb_key_symbols_alloc(chain->conn);
+   xcb_keycode_t *keycodes = xcb_key_symbols_get_keycode(key_symbols, XK_F1);
+   if (keycodes) {
+      xcb_keycode_t keycode = keycodes[0];
+      free(keycodes);
 
       simple_mtx_lock(&device->trace_mtx);
-      device->trace_hotkey_trigger = true;
+      bool capture_key_pressed = keys->keys[keycode / 8] & (1u << (keycode % 
8));
+      device->trace_hotkey_trigger = capture_key_pressed && 
(capture_key_pressed != chain->base.capture_key_pressed);
+      chain->base.capture_key_pressed = capture_key_pressed;
       simple_mtx_unlock(&device->trace_mtx);
-
-      free(event);
    }
+
+   xcb_key_symbols_free(key_symbols);
+   free(keys);
+#endif
 }
 
 /**
@@ -2353,8 +2364,6 @@ x11_swapchain_destroy(struct wsi_swapchain *anv_chain,
                                              XCB_PRESENT_EVENT_MASK_NO_EVENT);
    xcb_discard_reply(chain->conn, cookie.sequence);
 
-   xcb_disconnect(chain->capture_conn);
-
    pthread_mutex_destroy(&chain->present_poll_mutex);
    pthread_mutex_destroy(&chain->present_progress_mutex);
    pthread_cond_destroy(&chain->present_progress_cond);
@@ -2638,24 +2647,6 @@ x11_surface_create_swapchain(VkIcdSurfaceBase 
*icd_surface,
    if (chain == NULL)
       return VK_ERROR_OUT_OF_HOST_MEMORY;
 
-#ifdef XCB_KEYSYMS_AVAILABLE
-   VK_FROM_HANDLE(vk_device, vk_device, device);
-   if (vk_device->capture_trace) {
-      chain->capture_conn = xcb_connect(NULL, NULL);
-      assert(!xcb_connection_has_error(chain->capture_conn));
-
-      xcb_key_symbols_t *key_symbols = xcb_key_symbols_alloc(conn);
-      xcb_keycode_t *keycodes = xcb_key_symbols_get_keycode(key_symbols, 
XK_F12);
-      if (keycodes) {
-         xcb_grab_key(chain->capture_conn, 1, window, XCB_MOD_MASK_ANY, 
keycodes[0],
-                      XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC);
-      }
-      xcb_key_symbols_free(key_symbols);
-
-      xcb_flush(chain->capture_conn);
-   }
-#endif
-
    int ret = pthread_mutex_init(&chain->present_progress_mutex, NULL);
    if (ret != 0) {
       vk_free(pAllocator, chain);

Reply via email to