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
This commit is contained in:
Ray Strode 2015-05-11 16:53:41 -04:00
parent af2a13ded4
commit 33150569cd
2 changed files with 75 additions and 0 deletions

View File

@ -109,6 +109,30 @@ get_seat_proxy (GCancellable *cancellable)
return seat; return seat;
} }
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 static void
session_unpause (void) session_unpause (void)
{ {
@ -128,6 +152,8 @@ session_unpause (void)
MetaBackend *backend = meta_get_backend (); MetaBackend *backend = meta_get_backend ();
MetaCursorRenderer *renderer = meta_backend_get_cursor_renderer (backend); MetaCursorRenderer *renderer = meta_backend_get_cursor_renderer (backend);
ClutterActor *stage = meta_backend_get_stage (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 /* 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 * in case nothing else queued one for us, and force the cursor to
@ -135,6 +161,17 @@ session_unpause (void)
clutter_actor_queue_redraw (stage); clutter_actor_queue_redraw (stage);
meta_cursor_renderer_native_force_update (META_CURSOR_RENDERER_NATIVE (renderer)); 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 ()); meta_idle_monitor_native_reset_idletime (meta_idle_monitor_get_core ());
} }
} }

View File

@ -25,6 +25,8 @@
#include "meta-monitor-manager-kms.h" #include "meta-monitor-manager-kms.h"
#include "meta-monitor-config.h" #include "meta-monitor-config.h"
#include "backends/meta-backend-private.h"
#include "meta-cursor-renderer-native.h"
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
@ -77,6 +79,9 @@ struct _MetaMonitorManagerKms
drmModeConnector **connectors; drmModeConnector **connectors;
unsigned int n_connectors; unsigned int n_connectors;
/* used to find out when configuration has been applied */
CoglFrameClosure *frame_closure;
GUdevClient *udev; GUdevClient *udev;
GSettings *desktop_settings; GSettings *desktop_settings;
@ -905,6 +910,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 static void
meta_monitor_manager_kms_apply_configuration (MetaMonitorManager *manager, meta_monitor_manager_kms_apply_configuration (MetaMonitorManager *manager,
MetaCRTCInfo **crtcs, MetaCRTCInfo **crtcs,
@ -916,6 +944,7 @@ meta_monitor_manager_kms_apply_configuration (MetaMonitorManager *manager,
ClutterBackend *backend; ClutterBackend *backend;
CoglContext *cogl_context; CoglContext *cogl_context;
CoglDisplay *cogl_display; CoglDisplay *cogl_display;
CoglOnscreen *cogl_onscreen;
unsigned i; unsigned i;
GPtrArray *cogl_crtcs; GPtrArray *cogl_crtcs;
int screen_width, screen_height; int screen_width, screen_height;
@ -1051,6 +1080,15 @@ meta_monitor_manager_kms_apply_configuration (MetaMonitorManager *manager,
return; 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++) for (i = 0; i < n_outputs; i++)
{ {
MetaOutputInfo *output_info = outputs[i]; MetaOutputInfo *output_info = outputs[i];