From 8f958edcef4adfe4a2323da50e4aa53c3bd8e431 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Mon, 11 May 2015 16:53:41 -0400 Subject: [PATCH] Force cursor update after applying configuration The qxl kms driver has a bug where the cursor gets hidden implicitly after a drmModeSetCrtc call. This commit works around the bug by forcing a drmModeSetCursor2 call after the drmModeSetCrtc calls. This is pretty hacky and won't ever go upstream. https://bugzilla.gnome.org/show_bug.cgi?id=746078 --- src/backends/native/meta-launcher.c | 37 ++++++++++++++++++++++++++ src/backends/native/meta-monitor-manager-kms.c | 37 ++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) diff --git a/src/backends/native/meta-launcher.c b/src/backends/native/meta-launcher.c index ea28e5a..5aabb3a 100644 --- a/src/backends/native/meta-launcher.c +++ b/src/backends/native/meta-launcher.c @@ -107,6 +107,30 @@ get_seat_proxy (GCancellable *cancellable, } static void +frame_callback (CoglOnscreen *onscreen, + CoglFrameEvent event, + CoglFrameInfo *frame_info, + void *user_data) +{ + CoglFrameClosure **frame_closure = user_data; + + MetaBackend *backend = meta_get_backend (); + MetaCursorRenderer *renderer = meta_backend_get_cursor_renderer (backend); + CoglOnscreen *cogl_onscreen; + + if (event != COGL_FRAME_EVENT_COMPLETE) + return; + + meta_cursor_renderer_native_force_update (META_CURSOR_RENDERER_NATIVE (renderer)); + + cogl_onscreen = COGL_ONSCREEN (cogl_get_draw_framebuffer ()); + cogl_onscreen_remove_frame_callback (cogl_onscreen, + *frame_closure); + + *frame_closure = NULL; +} + +static void session_unpause (void) { MetaBackend *backend; @@ -124,6 +148,8 @@ session_unpause (void) MetaCursorRendererNative *cursor_renderer_native = META_CURSOR_RENDERER_NATIVE (meta_backend_get_cursor_renderer (backend)); ClutterActor *stage = meta_backend_get_stage (backend); + CoglOnscreen *cogl_onscreen; + static CoglFrameClosure *frame_closure = NULL; /* When we mode-switch back, we need to immediately queue a redraw * in case nothing else queued one for us, and force the cursor to @@ -131,6 +157,17 @@ session_unpause (void) clutter_actor_queue_redraw (stage); meta_cursor_renderer_native_force_update (cursor_renderer_native); + + cogl_onscreen = COGL_ONSCREEN (cogl_get_draw_framebuffer ()); + + if (frame_closure) + cogl_onscreen_remove_frame_callback (cogl_onscreen, frame_closure); + + frame_closure = cogl_onscreen_add_frame_callback (cogl_onscreen, + frame_callback, + &frame_closure, + NULL); + meta_idle_monitor_native_reset_idletime (meta_idle_monitor_get_core ()); } } diff --git a/src/backends/native/meta-monitor-manager-kms.c b/src/backends/native/meta-monitor-manager-kms.c index 04d96aa..ad23859 100644 --- a/src/backends/native/meta-monitor-manager-kms.c +++ b/src/backends/native/meta-monitor-manager-kms.c @@ -27,6 +27,7 @@ #include "meta-monitor-config.h" #include "meta-backend-private.h" #include "meta-renderer-native.h" +#include "meta-cursor-renderer-native.h" #include #include @@ -94,6 +95,9 @@ struct _MetaMonitorManagerKms drmModeConnector **connectors; unsigned int n_connectors; + /* used to find out when configuration has been applied */ + CoglFrameClosure *frame_closure; + GUdevClient *udev; GSettings *desktop_settings; @@ -1050,6 +1054,29 @@ set_underscan (MetaMonitorManagerKms *manager_kms, } static void +frame_callback (CoglOnscreen *onscreen, + CoglFrameEvent event, + CoglFrameInfo *frame_info, + void *user_data) +{ + MetaMonitorManagerKms *manager_kms = user_data; + MetaBackend *backend = meta_get_backend (); + MetaCursorRenderer *renderer = meta_backend_get_cursor_renderer (backend); + CoglOnscreen *cogl_onscreen; + + if (event != COGL_FRAME_EVENT_COMPLETE) + return; + + meta_cursor_renderer_native_force_update (META_CURSOR_RENDERER_NATIVE (renderer)); + + cogl_onscreen = COGL_ONSCREEN (cogl_get_draw_framebuffer ()); + cogl_onscreen_remove_frame_callback (cogl_onscreen, + manager_kms->frame_closure); + + manager_kms->frame_closure = NULL; +} + +static void meta_monitor_manager_kms_apply_configuration (MetaMonitorManager *manager, MetaCRTCInfo **crtcs, unsigned int n_crtcs, @@ -1057,6 +1084,7 @@ meta_monitor_manager_kms_apply_configuration (MetaMonitorManager *manager, unsigned int n_outputs) { MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (manager); + CoglOnscreen *cogl_onscreen; unsigned i; int screen_width, screen_height; @@ -1144,6 +1172,15 @@ meta_monitor_manager_kms_apply_configuration (MetaMonitorManager *manager, crtc->current_mode = NULL; } + cogl_onscreen = COGL_ONSCREEN (cogl_get_draw_framebuffer ()); + if (manager_kms->frame_closure) + cogl_onscreen_remove_frame_callback (cogl_onscreen, + manager_kms->frame_closure); + manager_kms->frame_closure = cogl_onscreen_add_frame_callback (cogl_onscreen, + frame_callback, + manager, + NULL); + for (i = 0; i < n_outputs; i++) { MetaOutputInfo *output_info = outputs[i]; -- 2.7.4