From 341cacdee2c6ad3cefccee85891c2a90215c9a1d Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Mon, 11 May 2015 17:10:45 -0400 Subject: [PATCH] workaround qxl cursor visibility wonkiness Related: #1200901 --- ...-update-after-applying-configuration.patch | 303 ++++++++++++++++++ mutter.spec | 9 + 2 files changed, 312 insertions(+) create mode 100644 0001-Force-cursor-update-after-applying-configuration.patch diff --git a/0001-Force-cursor-update-after-applying-configuration.patch b/0001-Force-cursor-update-after-applying-configuration.patch new file mode 100644 index 0000000..5aa75ba --- /dev/null +++ b/0001-Force-cursor-update-after-applying-configuration.patch @@ -0,0 +1,303 @@ +From 5c74b46e46f5e26e1915a1f85ba212770e5dc777 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 call. + +https://bugzilla.gnome.org/show_bug.cgi?id=746078 +--- + src/backends/native/meta-monitor-manager-kms.c | 38 ++++++++++++++++++++++++++ + 1 file changed, 38 insertions(+) + +diff --git a/src/backends/native/meta-monitor-manager-kms.c b/src/backends/native/meta-monitor-manager-kms.c +index cc2b18e..b56d6d3 100644 +--- a/src/backends/native/meta-monitor-manager-kms.c ++++ b/src/backends/native/meta-monitor-manager-kms.c +@@ -1,109 +1,114 @@ + /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + + /* + * Copyright (C) 2013 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Author: Giovanni Campagna + */ + + #include "config.h" + + #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 + #include + + #include + #include + #include + #include + #include + #include + + #include + #include + + #include + + typedef struct { + drmModeConnector *connector; + + unsigned n_encoders; + drmModeEncoderPtr *encoders; + drmModeEncoderPtr current_encoder; + + /* bitmasks of encoder position in the resources array */ + uint32_t encoder_mask; + uint32_t enc_clone_mask; + + uint32_t dpms_prop_id; + uint32_t edid_blob_id; + uint32_t tile_blob_id; + + int suggested_x; + int suggested_y; + uint32_t hotplug_mode_update; + } MetaOutputKms; + + typedef struct { + uint32_t underscan_prop_id; + uint32_t underscan_hborder_prop_id; + uint32_t underscan_vborder_prop_id; + } MetaCRTCKms; + + struct _MetaMonitorManagerKms + { + MetaMonitorManager parent_instance; + + int fd; + + drmModeConnector **connectors; + unsigned int n_connectors; + ++ /* used to find out when configuration has been applied */ ++ CoglFrameClosure *frame_closure; ++ + GUdevClient *udev; + + GSettings *desktop_settings; + }; + + struct _MetaMonitorManagerKmsClass + { + MetaMonitorManagerClass parent_class; + }; + + G_DEFINE_TYPE (MetaMonitorManagerKms, meta_monitor_manager_kms, META_TYPE_MONITOR_MANAGER); + + static void + free_resources (MetaMonitorManagerKms *manager_kms) + { + unsigned i; + + for (i = 0; i < manager_kms->n_connectors; i++) + drmModeFreeConnector (manager_kms->connectors[i]); + + g_free (manager_kms->connectors); + } + + static int + compare_outputs (const void *one, + const void *two) + { + const MetaOutput *o_one = one, *o_two = two; + + return strcmp (o_one->name, o_two->name); +@@ -879,70 +884,94 @@ set_underscan (MetaMonitorManagerKms *manager_kms, + { + drmModeObjectSetProperty (manager_kms->fd, crtc->crtc_id, + DRM_MODE_OBJECT_CRTC, + crtc_kms->underscan_prop_id, (uint64_t) 1); + + if (crtc_kms->underscan_hborder_prop_id) + { + uint64_t value = crtc->current_mode->width * 0.05; + drmModeObjectSetProperty (manager_kms->fd, crtc->crtc_id, + DRM_MODE_OBJECT_CRTC, + crtc_kms->underscan_hborder_prop_id, value); + } + if (crtc_kms->underscan_vborder_prop_id) + { + uint64_t value = crtc->current_mode->height * 0.05; + drmModeObjectSetProperty (manager_kms->fd, crtc->crtc_id, + DRM_MODE_OBJECT_CRTC, + crtc_kms->underscan_vborder_prop_id, value); + } + + } + else + { + drmModeObjectSetProperty (manager_kms->fd, crtc->crtc_id, + DRM_MODE_OBJECT_CRTC, + crtc_kms->underscan_prop_id, (uint64_t) 0); + } + } + + 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, + MetaOutputInfo **outputs, + unsigned int n_outputs) + { + MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (manager); + ClutterBackend *backend; + CoglContext *cogl_context; + CoglDisplay *cogl_display; ++ CoglOnscreen *cogl_onscreen; + unsigned i; + GPtrArray *cogl_crtcs; + int screen_width, screen_height; + gboolean ok; + GError *error; + + cogl_crtcs = g_ptr_array_new_full (manager->n_crtcs, (GDestroyNotify)crtc_free); + screen_width = 0; screen_height = 0; + for (i = 0; i < n_crtcs; i++) + { + MetaCRTCInfo *crtc_info = crtcs[i]; + MetaCRTC *crtc = crtc_info->crtc; + CoglKmsCrtc *cogl_crtc; + + crtc->is_dirty = TRUE; + + cogl_crtc = g_slice_new0 (CoglKmsCrtc); + g_ptr_array_add (cogl_crtcs, cogl_crtc); + + if (crtc_info->mode == NULL) + { + cogl_crtc->id = crtc->crtc_id; + cogl_crtc->x = 0; + cogl_crtc->y = 0; + cogl_crtc->count = 0; + memset (&cogl_crtc->mode, 0, sizeof (drmModeModeInfo)); + cogl_crtc->connectors = NULL; + cogl_crtc->count = 0; + + crtc->rect.x = 0; +@@ -1024,60 +1053,69 @@ meta_monitor_manager_kms_apply_configuration (MetaMonitorManager *manager, + cogl_crtc->x = 0; + cogl_crtc->y = 0; + cogl_crtc->count = 0; + memset (&cogl_crtc->mode, 0, sizeof (drmModeModeInfo)); + cogl_crtc->connectors = NULL; + cogl_crtc->count = 0; + + crtc->rect.x = 0; + crtc->rect.y = 0; + crtc->rect.width = 0; + crtc->rect.height = 0; + crtc->current_mode = NULL; + } + + backend = clutter_get_default_backend (); + cogl_context = clutter_backend_get_cogl_context (backend); + cogl_display = cogl_context_get_display (cogl_context); + + error = NULL; + ok = cogl_kms_display_set_layout (cogl_display, screen_width, screen_height, + (CoglKmsCrtc**)cogl_crtcs->pdata, cogl_crtcs->len, &error); + g_ptr_array_unref (cogl_crtcs); + + if (!ok) + { + meta_warning ("Applying display configuration failed: %s\n", error->message); + g_error_free (error); + 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]; + MetaOutput *output = output_info->output; + + output->is_primary = output_info->is_primary; + output->is_presentation = output_info->is_presentation; + output->is_underscanning = output_info->is_underscanning; + + set_underscan (manager_kms, output); + } + + /* Disable outputs not mentioned in the list */ + for (i = 0; i < manager->n_outputs; i++) + { + MetaOutput *output = &manager->outputs[i]; + + if (output->is_dirty) + { + output->is_dirty = FALSE; + continue; + } + + output->crtc = NULL; + output->is_primary = FALSE; + } + + manager->screen_width = screen_width; + manager->screen_height = screen_height; + +-- +2.5.0 + diff --git a/mutter.spec b/mutter.spec index 0c8d92a..5efad05 100644 --- a/mutter.spec +++ b/mutter.spec @@ -12,6 +12,9 @@ License: GPLv2+ URL: http://www.gnome.org Source0: http://download.gnome.org/sources/%{name}/3.18/%{name}-%{version}.tar.xz +# https://bugzilla.redhat.com/show_bug.cgi?id=1200901 +Patch0: 0001-Force-cursor-update-after-applying-configuration.patch + BuildRequires: clutter-devel >= %{clutter_version} BuildRequires: pango-devel BuildRequires: startup-notification-devel @@ -94,6 +97,7 @@ the functionality of the installed %{name} package. %prep %setup -q +%patch0 -p1 -b .fix-cursor %build autoreconf -f -i @@ -179,6 +183,11 @@ glib-compile-schemas %{_datadir}/glib-2.0/schemas &> /dev/null || : * Thu Sep 03 2015 Florian Müllner - 3.17.91-1 - Update to 3.17.91 +* Thu Sep 03 2015 Ray Strode 3.17.90-2 +- Add workaround for qxl cursor visibility wonkiness that we + did for f22 + Related: #1200901 + * Thu Aug 20 2015 Florian Müllner - 3.17.90-1 - Update to 3.17.90