Hello community,

here is the log from the commit of package mutter for openSUSE:Factory checked 
in at 2015-08-28 08:23:54
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/mutter (Old)
 and      /work/SRC/openSUSE:Factory/.mutter.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "mutter"

Changes:
--------
--- /work/SRC/openSUSE:Factory/mutter/mutter.changes    2015-07-16 
17:18:09.000000000 +0200
+++ /work/SRC/openSUSE:Factory/.mutter.new/mutter.changes       2015-08-28 
08:23:55.000000000 +0200
@@ -1,0 +2,12 @@
+Thu Aug 13 13:15:16 UTC 2015 - [email protected]
+
+- Fix screen flickering on nvidia devices (bgo#728464).
+  + Add the following commits from the 3.16 branch:
+    - build_fix_return_value_in_meta-sync-ring.c.patch
+    - compositor_add_support_for_GL_EXT_x11_sync_object.patch
+    - compositor_fix_GL_EXT_x11_sync_object_race_condition.patch
+    - compositor_handle_fences_in_the_frontend_X_connection.patch
+- Added autoconf and automake BuildRequires and run autoreconf for
+  the patches above.
+
+-------------------------------------------------------------------

New:
----
  build_fix_return_value_in_meta-sync-ring.c.patch
  compositor_add_support_for_GL_EXT_x11_sync_object.patch
  compositor_fix_GL_EXT_x11_sync_object_race_condition.patch
  compositor_handle_fences_in_the_frontend_X_connection.patch

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ mutter.spec ++++++
--- /var/tmp/diff_new_pack.9M1wMg/_old  2015-08-28 08:23:57.000000000 +0200
+++ /var/tmp/diff_new_pack.9M1wMg/_new  2015-08-28 08:23:57.000000000 +0200
@@ -30,6 +30,17 @@
 Group:          System/GUI/GNOME
 Url:            http://www.gnome.org
 Source:         
http://download.gnome.org/sources/mutter/3.16/%{name}-%{version}.tar.xz
+# PATCH-FIX-UPSTREAM compositor_add_support_for_GL_EXT_x11_sync_object.patch 
bgo#728464
+Patch1:         compositor_add_support_for_GL_EXT_x11_sync_object.patch
+# PATCH-FIX-UPSTREAM 
compositor_fix_GL_EXT_x11_sync_object_race_condition.patch bgo#728464
+Patch2:         compositor_fix_GL_EXT_x11_sync_object_race_condition.patch
+# PATCH-FIX-UPSTREAM build_fix_return_value_in_meta-sync-ring.c.patch 
bgo#728464
+Patch3:         build_fix_return_value_in_meta-sync-ring.c.patch
+# PATCH-FIX-UPSTREAM 
compositor_handle_fences_in_the_frontend_X_connection.patch bgo#728464
+Patch4:         compositor_handle_fences_in_the_frontend_X_connection.patch
+# autoconf and automake only needed for patches 1-4
+BuildRequires:  autoconf
+BuildRequires:  automake
 BuildRequires:  fdupes
 BuildRequires:  gobject-introspection-devel >= 0.9.5
 BuildRequires:  intltool
@@ -142,9 +153,15 @@
 %lang_package
 %prep
 %setup -q
+%patch1 -p1
+%patch2 -p1
+%patch3 -p1
+%patch4 -p1
 translation-update-upstream
 
 %build
+# Only needed for patches 1-4
+autoreconf
 %configure \
         --disable-static \
         --enable-compile-warnings=maximum

++++++ build_fix_return_value_in_meta-sync-ring.c.patch ++++++
>From a54b1261d3ec5ccf7a8262c88557b6b952bc8a2e Mon Sep 17 00:00:00 2001
From: Ting-Wei Lan <[email protected]>
Date: Sat, 8 Aug 2015 20:12:09 +0800
Subject: build: Fix return value in meta-sync-ring.c

https://bugzilla.gnome.org/show_bug.cgi?id=753380

diff --git a/src/compositor/meta-sync-ring.c b/src/compositor/meta-sync-ring.c
index 44b1c41..217ebe5 100644
--- a/src/compositor/meta-sync-ring.c
+++ b/src/compositor/meta-sync-ring.c
@@ -499,7 +499,7 @@ meta_sync_ring_after_frame (void)
   if (!ring)
     return FALSE;
 
-  g_return_if_fail (ring->xdisplay != NULL);
+  g_return_val_if_fail (ring->xdisplay != NULL, FALSE);
 
   if (ring->warmup_syncs >= NUM_SYNCS / 2)
     {
@@ -542,7 +542,7 @@ meta_sync_ring_insert_wait (void)
   if (!ring)
     return FALSE;
 
-  g_return_if_fail (ring->xdisplay != NULL);
+  g_return_val_if_fail (ring->xdisplay != NULL, FALSE);
 
   if (ring->current_sync->state != META_SYNC_STATE_READY)
     {
-- 
cgit v0.10.2

++++++ compositor_add_support_for_GL_EXT_x11_sync_object.patch ++++++
++++ 840 lines (skipped)

++++++ compositor_fix_GL_EXT_x11_sync_object_race_condition.patch ++++++
>From c77e482b60bea40a422691b16af02a429d9c2edc Mon Sep 17 00:00:00 2001
From: Aaron Plattner <[email protected]>
Date: Mon, 3 Aug 2015 21:15:15 -0700
Subject: compositor: Fix GL_EXT_x11_sync_object race condition

The compositor maintains a ring of shared fences with the X server in order to
properly synchronize rendering between the X server and the compositor's GPU
channel.  When all of the fences have been used, the compositor needs to reset
one so that it can be reused.  It does this by first waiting on the CPU for the
fence to become triggered, and then sending a request to the X server to reset
the fence.

If the compositor's GPU channel is busy processing other work (e.g. the desktop
switcher animation), then the X server may process the reset request before the
GPU has consumed the fence.  This causes the GPU channel to hang.

Fix the problem by having the compositor's GPU channel trigger its own fence
after waiting for the X server's fence.  Wait for that fence on the CPU before
sending the reset request to the X server.  This ensures that the GPU has
consumed the X11 fence before the server resets it.

Signed-off-by: Aaron Plattner <[email protected]>

https://bugzilla.gnome.org/show_bug.cgi?id=728464

diff --git a/src/compositor/meta-sync-ring.c b/src/compositor/meta-sync-ring.c
index 4ee61f8..44b1c41 100644
--- a/src/compositor/meta-sync-ring.c
+++ b/src/compositor/meta-sync-ring.c
@@ -73,7 +73,8 @@ typedef struct
   Display *xdisplay;
 
   XSyncFence xfence;
-  GLsync glsync;
+  GLsync gl_x11_sync;
+  GLsync gpu_fence;
 
   XSyncCounter xcounter;
   XSyncAlarm xalarm;
@@ -118,6 +119,8 @@ static void             (*meta_gl_wait_sync) (GLsync sync,
 static GLsync           (*meta_gl_import_sync) (GLenum external_sync_type,
                                                 GLintptr external_sync,
                                                 GLbitfield flags);
+static GLsync           (*meta_gl_fence_sync) (GLenum condition,
+                                               GLbitfield flags);
 
 static MetaSyncRing *
 meta_sync_ring_get (void)
@@ -224,6 +227,8 @@ load_required_symbols (void)
     goto out;
   if (!load_gl_symbol ("glImportSyncEXT", (void **) &meta_gl_import_sync))
     goto out;
+  if (!load_gl_symbol ("glFenceSync", (void **) &meta_gl_fence_sync))
+    goto out;
 
   success = TRUE;
  out:
@@ -238,7 +243,8 @@ meta_sync_insert (MetaSync *self)
   XSyncTriggerFence (self->xdisplay, self->xfence);
   XFlush (self->xdisplay);
 
-  meta_gl_wait_sync (self->glsync, 0, GL_TIMEOUT_IGNORED);
+  meta_gl_wait_sync (self->gl_x11_sync, 0, GL_TIMEOUT_IGNORED);
+  self->gpu_fence = meta_gl_fence_sync (GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
 
   self->state = META_SYNC_STATE_WAITING;
 }
@@ -255,9 +261,13 @@ meta_sync_check_update_finished (MetaSync *self,
       status = GL_ALREADY_SIGNALED;
       break;
     case META_SYNC_STATE_WAITING:
-      status = meta_gl_client_wait_sync (self->glsync, 0, timeout);
+      status = meta_gl_client_wait_sync (self->gpu_fence, 0, timeout);
       if (status == GL_ALREADY_SIGNALED || status == GL_CONDITION_SATISFIED)
-        self->state = META_SYNC_STATE_DONE;
+        {
+          self->state = META_SYNC_STATE_DONE;
+          meta_gl_delete_sync (self->gpu_fence);
+          self->gpu_fence = 0;
+        }
       break;
     default:
       break;
@@ -312,7 +322,8 @@ meta_sync_new (Display *xdisplay)
   self->xdisplay = xdisplay;
 
   self->xfence = XSyncCreateFence (xdisplay, DefaultRootWindow (xdisplay), 
FALSE);
-  self->glsync = meta_gl_import_sync (GL_SYNC_X11_FENCE_EXT, self->xfence, 0);
+  self->gl_x11_sync = meta_gl_import_sync (GL_SYNC_X11_FENCE_EXT, 
self->xfence, 0);
+  self->gpu_fence = 0;
 
   self->xcounter = XSyncCreateCounter (xdisplay, SYNC_VALUE_ZERO);
 
@@ -365,6 +376,8 @@ meta_sync_free (MetaSync *self)
   switch (self->state)
     {
     case META_SYNC_STATE_WAITING:
+      meta_gl_delete_sync (self->gpu_fence);
+      break;
     case META_SYNC_STATE_DONE:
       /* nothing to do */
       break;
@@ -383,7 +396,7 @@ meta_sync_free (MetaSync *self)
       break;
     }
 
-  meta_gl_delete_sync (self->glsync);
+  meta_gl_delete_sync (self->gl_x11_sync);
   XSyncDestroyFence (self->xdisplay, self->xfence);
   XSyncDestroyCounter (self->xdisplay, self->xcounter);
   XSyncDestroyAlarm (self->xdisplay, self->xalarm);
-- 
cgit v0.10.2

++++++ compositor_handle_fences_in_the_frontend_X_connection.patch ++++++
>From 916070cc7218cc80f4565ea265b0dd6e5e93cb98 Mon Sep 17 00:00:00 2001
From: Rui Matos <[email protected]>
Date: Wed, 12 Aug 2015 15:26:34 +0200
Subject: compositor: Handle fences in the frontend X connection

Since mutter has two X connections and does damage handling on the
frontend while fence triggering is done on the backend, we have a race
between XDamageSubtract() and XSyncFenceTrigger() causing missed
redraws in the GL_EXT_X11_sync_object path.

If the fence trigger gets processed first by the server, any client
drawing that happens between that and the damage subtract being
processed and is completely contained in the last damage event box
that mutter got, won't be included in the current frame nor will it
cause a new damage event.

A simple fix for this would be XSync()ing on the frontend connection
after doing all the damage subtracts but that would add a round trip
on every frame again which defeats the asynchronous design of X
fences.

Instead, if we move fence handling to the frontend we automatically
get the right ordering between damage subtracts and fence triggers.

https://bugzilla.gnome.org/show_bug.cgi?id=728464

diff --git a/src/backends/x11/meta-backend-x11.c 
b/src/backends/x11/meta-backend-x11.c
index ac38ffc..3ff8431 100644
--- a/src/backends/x11/meta-backend-x11.c
+++ b/src/backends/x11/meta-backend-x11.c
@@ -45,7 +45,6 @@
 #include <meta/util.h>
 #include "display-private.h"
 #include "compositor/compositor-private.h"
-#include "compositor/meta-sync-ring.h"
 
 struct _MetaBackendX11Private
 {
@@ -256,8 +255,6 @@ handle_host_xevent (MetaBackend *backend,
         MetaCompositor *compositor = display->compositor;
         if (meta_plugin_manager_xevent_filter (compositor->plugin_mgr, event))
           bypass_clutter = TRUE;
-        if (compositor->have_x11_sync_object)
-          meta_sync_ring_handle_event (event);
       }
   }
 
diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c
index 554faa1..2e182c2 100644
--- a/src/compositor/compositor.c
+++ b/src/compositor/compositor.c
@@ -534,8 +534,7 @@ meta_compositor_manage (MetaCompositor *compositor)
        */
       XMapWindow (xdisplay, compositor->output);
 
-      compositor->have_x11_sync_object =
-        meta_sync_ring_init (meta_backend_x11_get_xdisplay (META_BACKEND_X11 
(backend)));
+      compositor->have_x11_sync_object = meta_sync_ring_init (xdisplay);
     }
 
   redirect_windows (display->screen);
@@ -737,6 +736,9 @@ meta_compositor_process_event (MetaCompositor *compositor,
         process_damage (compositor, (XDamageNotifyEvent *) event, window);
     }
 
+  if (compositor->have_x11_sync_object)
+    meta_sync_ring_handle_event (event);
+
   /* Clutter needs to know about MapNotify events otherwise it will
      think the stage is invisible */
   if (!meta_is_wayland_compositor () && event->type == MapNotify)
diff --git a/src/compositor/meta-sync-ring.c b/src/compositor/meta-sync-ring.c
index 217ebe5..336ccd4 100644
--- a/src/compositor/meta-sync-ring.c
+++ b/src/compositor/meta-sync-ring.c
@@ -322,7 +322,7 @@ meta_sync_new (Display *xdisplay)
   self->xdisplay = xdisplay;
 
   self->xfence = XSyncCreateFence (xdisplay, DefaultRootWindow (xdisplay), 
FALSE);
-  self->gl_x11_sync = meta_gl_import_sync (GL_SYNC_X11_FENCE_EXT, 
self->xfence, 0);
+  self->gl_x11_sync = 0;
   self->gpu_fence = 0;
 
   self->xcounter = XSyncCreateCounter (xdisplay, SYNC_VALUE_ZERO);
@@ -347,6 +347,13 @@ meta_sync_new (Display *xdisplay)
   return self;
 }
 
+static void
+meta_sync_import (MetaSync *self)
+{
+  g_return_if_fail (self->gl_x11_sync == 0);
+  self->gl_x11_sync = meta_gl_import_sync (GL_SYNC_X11_FENCE_EXT, 
self->xfence, 0);
+}
+
 static Bool
 alarm_event_predicate (Display  *dpy,
                        XEvent   *event,
@@ -437,6 +444,12 @@ meta_sync_ring_init (Display *xdisplay)
       ring->syncs_array[i] = sync;
       g_hash_table_replace (ring->alarm_to_sync, (gpointer) sync->xalarm, 
sync);
     }
+  /* Since the connection we create the X fences on isn't the same as
+   * the one used for the GLX context, we need to XSync() here to
+   * ensure glImportSync() succeeds. */
+  XSync (xdisplay, False);
+  for (i = 0; i < NUM_SYNCS; ++i)
+    meta_sync_import (ring->syncs_array[i]);
 
   ring->current_sync_idx = 0;
   ring->current_sync = ring->syncs_array[0];
-- 
cgit v0.10.2


Reply via email to