From c642a96d33d5cf2fe7f2950bf48b9bbb5e5c8c5f 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 | 38 ++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) diff --git a/src/backends/native/meta-launcher.c b/src/backends/native/meta-launcher.c index 7cd338b..8a6db23 100644 --- a/src/backends/native/meta-launcher.c +++ b/src/backends/native/meta-launcher.c @@ -102,6 +102,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) { ClutterBackend *clutter_backend; @@ -120,6 +144,8 @@ session_unpause (void) MetaBackend *backend = meta_get_backend (); MetaCursorRenderer *renderer = 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 @@ -127,6 +153,17 @@ session_unpause (void) clutter_actor_queue_redraw (stage); meta_cursor_renderer_native_force_update (META_CURSOR_RENDERER_NATIVE (renderer)); + + 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 e1a6f5f..af92cd1 100644 --- a/src/backends/native/meta-monitor-manager-kms.c +++ b/src/backends/native/meta-monitor-manager-kms.c @@ -25,6 +25,8 @@ #include "meta-monitor-manager-kms.h" #include "meta-monitor-config.h" +#include "backends/meta-backend-private.h" +#include "meta-cursor-renderer-native.h" #include #include @@ -82,6 +84,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; @@ -1053,6 +1058,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, @@ -1063,6 +1091,7 @@ meta_monitor_manager_kms_apply_configuration (MetaMonitorManager *manager, ClutterBackend *backend; CoglContext *cogl_context; CoglDisplay *cogl_display; + CoglOnscreen *cogl_onscreen; unsigned i; GPtrArray *cogl_crtcs; int screen_width, screen_height; @@ -1206,6 +1235,15 @@ meta_monitor_manager_kms_apply_configuration (MetaMonitorManager *manager, return; } + 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.0