|
|
68333f |
From 9ceccaf38295d73b729bc3a6777fa6b948fa4007 Mon Sep 17 00:00:00 2001
|
|
|
68333f |
From: "Owen W. Taylor" <otaylor@fishsoup.net>
|
|
|
68333f |
Date: Thu, 8 May 2014 18:44:15 -0400
|
|
|
68333f |
Subject: [PATCH] Add support for quad-buffer stereo
|
|
|
68333f |
|
|
|
68333f |
Track the stereo status of windows using the new EXT_stereo_tree
|
|
|
68333f |
GLX extension.
|
|
|
68333f |
|
|
|
68333f |
When stereo is enabled or disabled, a restart is triggered via
|
|
|
68333f |
meta_restart() after a timeout, setting a _META_ENABLE_STEREO
|
|
|
68333f |
property on the root window to indicate whether we should
|
|
|
68333f |
turn on a stereo stage for clutter. The property avoids a loop,
|
|
|
68333f |
since we need to enable stereo *before* initializing Clutter and GL,
|
|
|
68333f |
but we need GL to figure out whether we have stereo windows.
|
|
|
68333f |
|
|
|
68333f |
Stereo windows are drawn to the stage using new functionality
|
|
|
68333f |
in Cogl to setup a stereo context, select which buffer to draw
|
|
|
68333f |
to, and draw either the left or right buffer of a stereo
|
|
|
68333f |
texture_from_pixmap.
|
|
|
68333f |
---
|
|
|
68333f |
src/Makefile.am | 2 +
|
|
|
68333f |
src/compositor/compositor-private.h | 10 ++
|
|
|
68333f |
src/compositor/compositor.c | 127 +++++++++++++++++++-
|
|
|
68333f |
src/compositor/meta-shaped-texture-private.h | 37 ++++++
|
|
|
68333f |
src/compositor/meta-shaped-texture.c | 166 ++++++++++++++++++++-------
|
|
|
68333f |
src/compositor/meta-window-actor-private.h | 7 ++
|
|
|
68333f |
src/compositor/meta-window-actor.c | 27 ++++-
|
|
|
68333f |
src/core/main.c | 2 +
|
|
|
68333f |
src/core/stereo.c | 144 +++++++++++++++++++++++
|
|
|
68333f |
src/core/stereo.h | 28 +++++
|
|
|
68333f |
src/meta/meta-shaped-texture.h | 3 +-
|
|
|
68333f |
11 files changed, 508 insertions(+), 45 deletions(-)
|
|
|
68333f |
create mode 100644 src/compositor/meta-shaped-texture-private.h
|
|
|
68333f |
create mode 100644 src/core/stereo.c
|
|
|
68333f |
create mode 100644 src/core/stereo.h
|
|
|
68333f |
|
|
|
68333f |
diff --git a/src/Makefile.am b/src/Makefile.am
|
|
|
68333f |
index d664b54..1d2422e 100644
|
|
|
68333f |
--- a/src/Makefile.am
|
|
|
68333f |
+++ b/src/Makefile.am
|
|
|
68333f |
@@ -122,6 +122,8 @@ libmutter_la_SOURCES = \
|
|
|
68333f |
core/restart.c \
|
|
|
68333f |
core/session.c \
|
|
|
68333f |
core/session.h \
|
|
|
68333f |
+ core/stereo.c \
|
|
|
68333f |
+ core/stereo.h \
|
|
|
68333f |
core/stack.c \
|
|
|
68333f |
core/stack.h \
|
|
|
68333f |
core/stack-tracker.c \
|
|
|
68333f |
diff --git a/src/compositor/compositor-private.h b/src/compositor/compositor-private.h
|
|
|
68333f |
index acb8d3c..b4c5c16 100644
|
|
|
68333f |
--- a/src/compositor/compositor-private.h
|
|
|
68333f |
+++ b/src/compositor/compositor-private.h
|
|
|
68333f |
@@ -28,6 +28,8 @@ struct _MetaCompositor
|
|
|
68333f |
gint64 server_time_query_time;
|
|
|
68333f |
gint64 server_time_offset;
|
|
|
68333f |
|
|
|
68333f |
+ int glx_opcode;
|
|
|
68333f |
+
|
|
|
68333f |
guint server_time_is_monotonic_time : 1;
|
|
|
68333f |
guint show_redraw : 1;
|
|
|
68333f |
guint debug : 1;
|
|
|
68333f |
@@ -56,6 +58,9 @@ struct _MetaCompScreen
|
|
|
68333f |
|
|
|
68333f |
gint switch_workspace_in_progress;
|
|
|
68333f |
|
|
|
68333f |
+ guint stereo_tree_ext : 1;
|
|
|
68333f |
+ guint have_stereo_windows : 1;
|
|
|
68333f |
+
|
|
|
68333f |
MetaPluginManager *plugin_mgr;
|
|
|
68333f |
};
|
|
|
68333f |
|
|
|
68333f |
@@ -79,4 +84,9 @@ gint64 meta_compositor_monotonic_time_to_server_time (MetaDisplay *display,
|
|
|
68333f |
|
|
|
68333f |
void meta_check_end_modal (MetaScreen *screen);
|
|
|
68333f |
|
|
|
68333f |
+gboolean meta_compositor_window_is_stereo (MetaScreen *screen,
|
|
|
68333f |
+ Window xwindow);
|
|
|
68333f |
+void meta_compositor_select_stereo_notify (MetaScreen *screen,
|
|
|
68333f |
+ Window xwindow);
|
|
|
68333f |
+
|
|
|
68333f |
#endif /* META_COMPOSITOR_PRIVATE_H */
|
|
|
68333f |
diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c
|
|
|
68333f |
index 539a7a6..fd29e48 100644
|
|
|
68333f |
--- a/src/compositor/compositor.c
|
|
|
68333f |
+++ b/src/compositor/compositor.c
|
|
|
68333f |
@@ -86,7 +86,8 @@
|
|
|
68333f |
#include "meta-window-group.h"
|
|
|
68333f |
#include "window-private.h" /* to check window->hidden */
|
|
|
68333f |
#include "display-private.h" /* for meta_display_lookup_x_window() */
|
|
|
68333f |
-#include "util-private.h"
|
|
|
68333f |
+#include "stack-tracker.h"
|
|
|
68333f |
+#include "stereo.h"
|
|
|
68333f |
#include <X11/extensions/shape.h>
|
|
|
68333f |
#include <X11/extensions/Xcomposite.h>
|
|
|
68333f |
|
|
|
68333f |
@@ -579,6 +580,101 @@ redirect_windows (MetaCompositor *compositor,
|
|
|
68333f |
}
|
|
|
68333f |
}
|
|
|
68333f |
|
|
|
68333f |
+#define GLX_STEREO_TREE_EXT 0x20F5
|
|
|
68333f |
+#define GLX_STEREO_NOTIFY_MASK_EXT 0x00000001
|
|
|
68333f |
+#define GLX_STEREO_NOTIFY_EXT 0x00000000
|
|
|
68333f |
+
|
|
|
68333f |
+typedef struct {
|
|
|
68333f |
+ int type;
|
|
|
68333f |
+ unsigned long serial;
|
|
|
68333f |
+ Bool send_event;
|
|
|
68333f |
+ Display *display;
|
|
|
68333f |
+ int extension;
|
|
|
68333f |
+ int evtype;
|
|
|
68333f |
+ Drawable window;
|
|
|
68333f |
+ Bool stereo_tree;
|
|
|
68333f |
+} StereoNotifyEvent;
|
|
|
68333f |
+
|
|
|
68333f |
+static gboolean
|
|
|
68333f |
+screen_has_stereo_tree_ext (MetaScreen *screen)
|
|
|
68333f |
+{
|
|
|
68333f |
+#if 0
|
|
|
68333f |
+ MetaDisplay *display = meta_screen_get_display (screen);
|
|
|
68333f |
+ Display *xdisplay = meta_display_get_xdisplay (display);
|
|
|
68333f |
+ const char *extensions_string;
|
|
|
68333f |
+
|
|
|
68333f |
+ static const char * (*query_extensions_string) (Display *display,
|
|
|
68333f |
+ int screen);
|
|
|
68333f |
+
|
|
|
68333f |
+ if (query_extensions_string == NULL)
|
|
|
68333f |
+ query_extensions_string =
|
|
|
68333f |
+ (const char * (*) (Display *, int))
|
|
|
68333f |
+ cogl_get_proc_address ("glXQueryExtensionsString");
|
|
|
68333f |
+
|
|
|
68333f |
+ extensions_string = query_extensions_string (xdisplay,
|
|
|
68333f |
+ meta_screen_get_screen_number (screen));
|
|
|
68333f |
+
|
|
|
68333f |
+ return strstr (extensions_string, "EXT_stereo_tree") != 0;
|
|
|
68333f |
+#else
|
|
|
68333f |
+ return TRUE;
|
|
|
68333f |
+#endif
|
|
|
68333f |
+}
|
|
|
68333f |
+
|
|
|
68333f |
+#include <GL/gl.h>
|
|
|
68333f |
+
|
|
|
68333f |
+gboolean
|
|
|
68333f |
+meta_compositor_window_is_stereo (MetaScreen *screen,
|
|
|
68333f |
+ Window xwindow)
|
|
|
68333f |
+{
|
|
|
68333f |
+ MetaCompScreen *info = meta_screen_get_compositor_data (screen);
|
|
|
68333f |
+ MetaDisplay *display = meta_screen_get_display (screen);
|
|
|
68333f |
+ Display *xdisplay = meta_display_get_xdisplay (display);
|
|
|
68333f |
+
|
|
|
68333f |
+ static int (*query_drawable) (Display *dpy,
|
|
|
68333f |
+ Drawable draw,
|
|
|
68333f |
+ int attribute,
|
|
|
68333f |
+ unsigned int *value);
|
|
|
68333f |
+
|
|
|
68333f |
+ if (info->stereo_tree_ext)
|
|
|
68333f |
+ {
|
|
|
68333f |
+ unsigned int stereo_tree = 0;
|
|
|
68333f |
+
|
|
|
68333f |
+ if (query_drawable == NULL)
|
|
|
68333f |
+ query_drawable =
|
|
|
68333f |
+ (int (*) (Display *, Drawable, int, unsigned int *))
|
|
|
68333f |
+ cogl_get_proc_address ("glXQueryDrawable");
|
|
|
68333f |
+
|
|
|
68333f |
+ query_drawable (xdisplay, xwindow, GLX_STEREO_TREE_EXT, &stereo_tree);
|
|
|
68333f |
+
|
|
|
68333f |
+ return stereo_tree != 0;
|
|
|
68333f |
+ }
|
|
|
68333f |
+ else
|
|
|
68333f |
+ return FALSE;
|
|
|
68333f |
+}
|
|
|
68333f |
+
|
|
|
68333f |
+void
|
|
|
68333f |
+meta_compositor_select_stereo_notify (MetaScreen *screen,
|
|
|
68333f |
+ Window xwindow)
|
|
|
68333f |
+{
|
|
|
68333f |
+ MetaCompScreen *info = meta_screen_get_compositor_data (screen);
|
|
|
68333f |
+ MetaDisplay *display = meta_screen_get_display (screen);
|
|
|
68333f |
+ Display *xdisplay = meta_display_get_xdisplay (display);
|
|
|
68333f |
+
|
|
|
68333f |
+ static void (*select_event) (Display *dpy,
|
|
|
68333f |
+ Drawable draw,
|
|
|
68333f |
+ unsigned long event_mask);
|
|
|
68333f |
+
|
|
|
68333f |
+ if (info->stereo_tree_ext)
|
|
|
68333f |
+ {
|
|
|
68333f |
+ if (select_event == NULL)
|
|
|
68333f |
+ select_event =
|
|
|
68333f |
+ (void (*) (Display *, Drawable, unsigned long))
|
|
|
68333f |
+ cogl_get_proc_address ("glXSelectEvent");
|
|
|
68333f |
+
|
|
|
68333f |
+ select_event (xdisplay, xwindow, GLX_STEREO_NOTIFY_MASK_EXT);
|
|
|
68333f |
+ }
|
|
|
68333f |
+}
|
|
|
68333f |
+
|
|
|
68333f |
void
|
|
|
68333f |
meta_compositor_manage_screen (MetaCompositor *compositor,
|
|
|
68333f |
MetaScreen *screen)
|
|
|
68333f |
@@ -609,6 +705,8 @@ meta_compositor_manage_screen (MetaCompositor *compositor,
|
|
|
68333f |
info->output = None;
|
|
|
68333f |
info->windows = NULL;
|
|
|
68333f |
|
|
|
68333f |
+ info->stereo_tree_ext = screen_has_stereo_tree_ext (screen);
|
|
|
68333f |
+
|
|
|
68333f |
meta_screen_set_cm_selection (screen);
|
|
|
68333f |
|
|
|
68333f |
info->stage = clutter_stage_new ();
|
|
|
68333f |
@@ -995,6 +1093,23 @@ meta_compositor_process_event (MetaCompositor *compositor,
|
|
|
68333f |
DEBUG_TRACE ("meta_compositor_process_event (process_damage)\n");
|
|
|
68333f |
process_damage (compositor, (XDamageNotifyEvent *) event, window);
|
|
|
68333f |
}
|
|
|
68333f |
+ else if (event->type == GenericEvent &&
|
|
|
68333f |
+ event->xcookie.extension == compositor->glx_opcode)
|
|
|
68333f |
+ {
|
|
|
68333f |
+ if (event->xcookie.evtype == GLX_STEREO_NOTIFY_EXT)
|
|
|
68333f |
+ {
|
|
|
68333f |
+ StereoNotifyEvent *stereo_event = (StereoNotifyEvent *)(event->xcookie.data);
|
|
|
68333f |
+ window = meta_display_lookup_x_window (compositor->display, stereo_event->window);
|
|
|
68333f |
+
|
|
|
68333f |
+ if (window != NULL)
|
|
|
68333f |
+ {
|
|
|
68333f |
+ MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window));
|
|
|
68333f |
+ meta_window_actor_stereo_notify (window_actor, stereo_event->stereo_tree);
|
|
|
68333f |
+ meta_stack_tracker_queue_sync_stack (window->screen->stack_tracker);
|
|
|
68333f |
+ }
|
|
|
68333f |
+ }
|
|
|
68333f |
+ }
|
|
|
68333f |
+
|
|
|
68333f |
break;
|
|
|
68333f |
}
|
|
|
68333f |
|
|
|
68333f |
@@ -1209,6 +1324,7 @@ meta_compositor_sync_stack (MetaCompositor *compositor,
|
|
|
68333f |
{
|
|
|
68333f |
GList *old_stack;
|
|
|
68333f |
MetaCompScreen *info = meta_screen_get_compositor_data (screen);
|
|
|
68333f |
+ int stereo_window_count = 0;
|
|
|
68333f |
|
|
|
68333f |
DEBUG_TRACE ("meta_compositor_sync_stack\n");
|
|
|
68333f |
|
|
|
68333f |
@@ -1286,12 +1402,16 @@ meta_compositor_sync_stack (MetaCompositor *compositor,
|
|
|
68333f |
* near the front of the other.)
|
|
|
68333f |
*/
|
|
|
68333f |
info->windows = g_list_prepend (info->windows, actor);
|
|
|
68333f |
+ if (meta_window_actor_is_stereo (actor))
|
|
|
68333f |
+ stereo_window_count++;
|
|
|
68333f |
|
|
|
68333f |
stack = g_list_remove (stack, window);
|
|
|
68333f |
old_stack = g_list_remove (old_stack, actor);
|
|
|
68333f |
}
|
|
|
68333f |
|
|
|
68333f |
sync_actor_stacking (info);
|
|
|
68333f |
+
|
|
|
68333f |
+ meta_stereo_set_have_stereo_windows (stereo_window_count > 0);
|
|
|
68333f |
}
|
|
|
68333f |
|
|
|
68333f |
void
|
|
|
68333f |
@@ -1505,6 +1625,7 @@ meta_compositor_new (MetaDisplay *display)
|
|
|
68333f |
Atom atoms[G_N_ELEMENTS(atom_names)];
|
|
|
68333f |
MetaCompositor *compositor;
|
|
|
68333f |
Display *xdisplay = meta_display_get_xdisplay (display);
|
|
|
68333f |
+ int glx_major_opcode, glx_first_event, glx_first_error;
|
|
|
68333f |
|
|
|
68333f |
if (!composite_at_least_version (display, 0, 3))
|
|
|
68333f |
return NULL;
|
|
|
68333f |
@@ -1531,6 +1652,10 @@ meta_compositor_new (MetaDisplay *display)
|
|
|
68333f |
compositor->repaint_func_id = clutter_threads_add_repaint_func (meta_repaint_func,
|
|
|
68333f |
compositor,
|
|
|
68333f |
NULL);
|
|
|
68333f |
+ if (XQueryExtension (xdisplay,
|
|
|
68333f |
+ "GLX",
|
|
|
68333f |
+ &glx_major_opcode, &glx_first_event, &glx_first_error))
|
|
|
68333f |
+ compositor->glx_opcode = glx_major_opcode;
|
|
|
68333f |
|
|
|
68333f |
return compositor;
|
|
|
68333f |
}
|
|
|
68333f |
diff --git a/src/compositor/meta-shaped-texture-private.h b/src/compositor/meta-shaped-texture-private.h
|
|
|
68333f |
new file mode 100644
|
|
|
68333f |
index 0000000..c70f6a8
|
|
|
68333f |
--- /dev/null
|
|
|
68333f |
+++ b/src/compositor/meta-shaped-texture-private.h
|
|
|
68333f |
@@ -0,0 +1,37 @@
|
|
|
68333f |
+/*
|
|
|
68333f |
+ * shaped texture
|
|
|
68333f |
+ *
|
|
|
68333f |
+ * An actor to draw a texture clipped to a list of rectangles
|
|
|
68333f |
+ *
|
|
|
68333f |
+ * Authored By Neil Roberts <neil@linux.intel.com>
|
|
|
68333f |
+ *
|
|
|
68333f |
+ * Copyright (C) 2008 Intel Corporation
|
|
|
68333f |
+ * 2013 Red Hat, Inc.
|
|
|
68333f |
+ *
|
|
|
68333f |
+ * This program is free software; you can redistribute it and/or
|
|
|
68333f |
+ * modify it under the terms of the GNU General Public License as
|
|
|
68333f |
+ * published by the Free Software Foundation; either version 2 of the
|
|
|
68333f |
+ * License, or (at your option) any later version.
|
|
|
68333f |
+ *
|
|
|
68333f |
+ * This program is distributed in the hope that it will be useful, but
|
|
|
68333f |
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
68333f |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
68333f |
+ * General Public License for more details.
|
|
|
68333f |
+ *
|
|
|
68333f |
+ * You should have received a copy of the GNU General Public License
|
|
|
68333f |
+ * along with this program; if not, write to the Free Software
|
|
|
68333f |
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
|
|
68333f |
+ * 02111-1307, USA.
|
|
|
68333f |
+ */
|
|
|
68333f |
+
|
|
|
68333f |
+#ifndef __META_SHAPED_TEXTURE_PRIVATE_H__
|
|
|
68333f |
+#define __META_SHAPED_TEXTURE_PRIVATE_H__
|
|
|
68333f |
+
|
|
|
68333f |
+#include <meta/meta-shaped-texture.h>
|
|
|
68333f |
+
|
|
|
68333f |
+ClutterActor *meta_shaped_texture_new (void);
|
|
|
68333f |
+gboolean meta_shaped_texture_get_unobscured_bounds (MetaShapedTexture *stex,
|
|
|
68333f |
+ cairo_rectangle_int_t *unobscured_bounds);
|
|
|
68333f |
+gboolean meta_shaped_texture_is_obscured (MetaShapedTexture *self);
|
|
|
68333f |
+
|
|
|
68333f |
+#endif
|
|
|
68333f |
diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c
|
|
|
68333f |
index c6239c9..132cb09 100644
|
|
|
68333f |
--- a/src/compositor/meta-shaped-texture.c
|
|
|
68333f |
+++ b/src/compositor/meta-shaped-texture.c
|
|
|
68333f |
@@ -65,8 +65,10 @@ G_DEFINE_TYPE (MetaShapedTexture, meta_shaped_texture,
|
|
|
68333f |
struct _MetaShapedTexturePrivate
|
|
|
68333f |
{
|
|
|
68333f |
MetaTextureTower *paint_tower;
|
|
|
68333f |
+ MetaTextureTower *paint_tower_right;
|
|
|
68333f |
Pixmap pixmap;
|
|
|
68333f |
CoglTexturePixmapX11 *texture;
|
|
|
68333f |
+ CoglTexturePixmapX11 *texture_right;
|
|
|
68333f |
CoglTexture *mask_texture;
|
|
|
68333f |
CoglPipeline *pipeline;
|
|
|
68333f |
CoglPipeline *pipeline_unshaped;
|
|
|
68333f |
@@ -75,6 +77,7 @@ struct _MetaShapedTexturePrivate
|
|
|
68333f |
|
|
|
68333f |
guint tex_width, tex_height;
|
|
|
68333f |
|
|
|
68333f |
+ guint stereo : 1;
|
|
|
68333f |
guint create_mipmaps : 1;
|
|
|
68333f |
};
|
|
|
68333f |
|
|
|
68333f |
@@ -103,7 +106,9 @@ meta_shaped_texture_init (MetaShapedTexture *self)
|
|
|
68333f |
priv = self->priv = META_SHAPED_TEXTURE_GET_PRIVATE (self);
|
|
|
68333f |
|
|
|
68333f |
priv->paint_tower = meta_texture_tower_new ();
|
|
|
68333f |
+ priv->paint_tower_right = NULL; /* demand create */
|
|
|
68333f |
priv->texture = NULL;
|
|
|
68333f |
+ priv->texture_right = NULL;
|
|
|
68333f |
priv->mask_texture = NULL;
|
|
|
68333f |
priv->create_mipmaps = TRUE;
|
|
|
68333f |
}
|
|
|
68333f |
@@ -114,13 +119,13 @@ meta_shaped_texture_dispose (GObject *object)
|
|
|
68333f |
MetaShapedTexture *self = (MetaShapedTexture *) object;
|
|
|
68333f |
MetaShapedTexturePrivate *priv = self->priv;
|
|
|
68333f |
|
|
|
68333f |
- if (priv->paint_tower)
|
|
|
68333f |
- meta_texture_tower_free (priv->paint_tower);
|
|
|
68333f |
- priv->paint_tower = NULL;
|
|
|
68333f |
+ g_clear_pointer (&priv->paint_tower, meta_texture_tower_free);
|
|
|
68333f |
+ g_clear_pointer (&priv->paint_tower_right, meta_texture_tower_free);
|
|
|
68333f |
|
|
|
68333f |
g_clear_pointer (&priv->pipeline, cogl_object_unref);
|
|
|
68333f |
g_clear_pointer (&priv->pipeline_unshaped, cogl_object_unref);
|
|
|
68333f |
g_clear_pointer (&priv->texture, cogl_object_unref);
|
|
|
68333f |
+ g_clear_pointer (&priv->texture_right, cogl_object_unref);
|
|
|
68333f |
|
|
|
68333f |
meta_shaped_texture_set_mask_texture (self, NULL);
|
|
|
68333f |
meta_shaped_texture_set_clip_region (self, NULL);
|
|
|
68333f |
@@ -129,11 +134,11 @@ meta_shaped_texture_dispose (GObject *object)
|
|
|
68333f |
}
|
|
|
68333f |
|
|
|
68333f |
static void
|
|
|
68333f |
-meta_shaped_texture_paint (ClutterActor *actor)
|
|
|
68333f |
+paint_texture (MetaShapedTexture *stex,
|
|
|
68333f |
+ CoglTexture *paint_tex)
|
|
|
68333f |
{
|
|
|
68333f |
- MetaShapedTexture *stex = (MetaShapedTexture *) actor;
|
|
|
68333f |
MetaShapedTexturePrivate *priv = stex->priv;
|
|
|
68333f |
- CoglTexture *paint_tex;
|
|
|
68333f |
+ ClutterActor *actor = CLUTTER_ACTOR (stex);
|
|
|
68333f |
guint tex_width, tex_height;
|
|
|
68333f |
ClutterActorBox alloc;
|
|
|
68333f |
|
|
|
68333f |
@@ -145,32 +150,6 @@ meta_shaped_texture_paint (ClutterActor *actor)
|
|
|
68333f |
if (priv->clip_region && cairo_region_is_empty (priv->clip_region))
|
|
|
68333f |
return;
|
|
|
68333f |
|
|
|
68333f |
- if (!CLUTTER_ACTOR_IS_REALIZED (CLUTTER_ACTOR (stex)))
|
|
|
68333f |
- clutter_actor_realize (CLUTTER_ACTOR (stex));
|
|
|
68333f |
-
|
|
|
68333f |
- /* The GL EXT_texture_from_pixmap extension does allow for it to be
|
|
|
68333f |
- * used together with SGIS_generate_mipmap, however this is very
|
|
|
68333f |
- * rarely supported. Also, even when it is supported there
|
|
|
68333f |
- * are distinct performance implications from:
|
|
|
68333f |
- *
|
|
|
68333f |
- * - Updating mipmaps that we don't need
|
|
|
68333f |
- * - Having to reallocate pixmaps on the server into larger buffers
|
|
|
68333f |
- *
|
|
|
68333f |
- * So, we just unconditionally use our mipmap emulation code. If we
|
|
|
68333f |
- * wanted to use SGIS_generate_mipmap, we'd have to query COGL to
|
|
|
68333f |
- * see if it was supported (no API currently), and then if and only
|
|
|
68333f |
- * if that was the case, set the clutter texture quality to HIGH.
|
|
|
68333f |
- * Setting the texture quality to high without SGIS_generate_mipmap
|
|
|
68333f |
- * support for TFP textures will result in fallbacks to XGetImage.
|
|
|
68333f |
- */
|
|
|
68333f |
- if (priv->create_mipmaps)
|
|
|
68333f |
- paint_tex = meta_texture_tower_get_paint_texture (priv->paint_tower);
|
|
|
68333f |
- else
|
|
|
68333f |
- paint_tex = COGL_TEXTURE (priv->texture);
|
|
|
68333f |
-
|
|
|
68333f |
- if (paint_tex == NULL)
|
|
|
68333f |
- return;
|
|
|
68333f |
-
|
|
|
68333f |
tex_width = priv->tex_width;
|
|
|
68333f |
tex_height = priv->tex_height;
|
|
|
68333f |
|
|
|
68333f |
@@ -279,6 +258,76 @@ meta_shaped_texture_paint (ClutterActor *actor)
|
|
|
68333f |
}
|
|
|
68333f |
|
|
|
68333f |
static void
|
|
|
68333f |
+meta_shaped_texture_paint (ClutterActor *actor)
|
|
|
68333f |
+{
|
|
|
68333f |
+ MetaShapedTexture *stex = (MetaShapedTexture *) actor;
|
|
|
68333f |
+ MetaShapedTexturePrivate *priv = stex->priv;
|
|
|
68333f |
+ CoglFramebuffer *fb;
|
|
|
68333f |
+ gboolean stereo;
|
|
|
68333f |
+ CoglTexture *paint_tex;
|
|
|
68333f |
+ CoglTexture *paint_tex_right;
|
|
|
68333f |
+
|
|
|
68333f |
+ if (priv->clip_region && cairo_region_is_empty (priv->clip_region))
|
|
|
68333f |
+ return;
|
|
|
68333f |
+
|
|
|
68333f |
+ if (!CLUTTER_ACTOR_IS_REALIZED (CLUTTER_ACTOR (stex)))
|
|
|
68333f |
+ clutter_actor_realize (CLUTTER_ACTOR (stex));
|
|
|
68333f |
+
|
|
|
68333f |
+ /* The GL EXT_texture_from_pixmap extension does allow for it to be
|
|
|
68333f |
+ * used together with SGIS_generate_mipmap, however this is very
|
|
|
68333f |
+ * rarely supported. Also, even when it is supported there
|
|
|
68333f |
+ * are distinct performance implications from:
|
|
|
68333f |
+ *
|
|
|
68333f |
+ * - Updating mipmaps that we don't need
|
|
|
68333f |
+ * - Having to reallocate pixmaps on the server into larger buffers
|
|
|
68333f |
+ *
|
|
|
68333f |
+ * So, we just unconditionally use our mipmap emulation code. If we
|
|
|
68333f |
+ * wanted to use SGIS_generate_mipmap, we'd have to query COGL to
|
|
|
68333f |
+ * see if it was supported (no API currently), and then if and only
|
|
|
68333f |
+ * if that was the case, set the clutter texture quality to HIGH.
|
|
|
68333f |
+ * Setting the texture quality to high without SGIS_generate_mipmap
|
|
|
68333f |
+ * support for TFP textures will result in fallbacks to XGetImage.
|
|
|
68333f |
+ */
|
|
|
68333f |
+ if (priv->create_mipmaps)
|
|
|
68333f |
+ paint_tex = meta_texture_tower_get_paint_texture (priv->paint_tower);
|
|
|
68333f |
+ else
|
|
|
68333f |
+ paint_tex = COGL_TEXTURE (priv->texture);
|
|
|
68333f |
+
|
|
|
68333f |
+ if (paint_tex == NULL)
|
|
|
68333f |
+ return;
|
|
|
68333f |
+
|
|
|
68333f |
+ fb = cogl_get_draw_framebuffer ();
|
|
|
68333f |
+
|
|
|
68333f |
+ stereo = priv->stereo && cogl_framebuffer_get_is_stereo (fb);
|
|
|
68333f |
+
|
|
|
68333f |
+ if (stereo)
|
|
|
68333f |
+ {
|
|
|
68333f |
+ if (priv->create_mipmaps)
|
|
|
68333f |
+ paint_tex_right = meta_texture_tower_get_paint_texture (priv->paint_tower_right);
|
|
|
68333f |
+ else
|
|
|
68333f |
+ paint_tex_right = COGL_TEXTURE (priv->texture_right);
|
|
|
68333f |
+ }
|
|
|
68333f |
+ else
|
|
|
68333f |
+ paint_tex_right = NULL;
|
|
|
68333f |
+
|
|
|
68333f |
+ if (paint_tex != NULL)
|
|
|
68333f |
+ {
|
|
|
68333f |
+ if (stereo)
|
|
|
68333f |
+ cogl_framebuffer_set_stereo_mode (fb, COGL_STEREO_LEFT);
|
|
|
68333f |
+ paint_texture (stex, paint_tex);
|
|
|
68333f |
+ if (stereo)
|
|
|
68333f |
+ cogl_framebuffer_set_stereo_mode (fb, COGL_STEREO_BOTH);
|
|
|
68333f |
+ }
|
|
|
68333f |
+
|
|
|
68333f |
+ if (paint_tex_right != NULL)
|
|
|
68333f |
+ {
|
|
|
68333f |
+ cogl_framebuffer_set_stereo_mode (fb, COGL_STEREO_RIGHT);
|
|
|
68333f |
+ paint_texture (stex, paint_tex_right);
|
|
|
68333f |
+ cogl_framebuffer_set_stereo_mode (fb, COGL_STEREO_BOTH);
|
|
|
68333f |
+ }
|
|
|
68333f |
+}
|
|
|
68333f |
+
|
|
|
68333f |
+static void
|
|
|
68333f |
meta_shaped_texture_pick (ClutterActor *actor,
|
|
|
68333f |
const ClutterColor *color)
|
|
|
68333f |
{
|
|
|
68333f |
@@ -392,6 +441,12 @@ meta_shaped_texture_set_create_mipmaps (MetaShapedTexture *stex,
|
|
|
68333f |
base_texture = create_mipmaps ?
|
|
|
68333f |
COGL_TEXTURE (priv->texture) : NULL;
|
|
|
68333f |
meta_texture_tower_set_base_texture (priv->paint_tower, base_texture);
|
|
|
68333f |
+
|
|
|
68333f |
+ if (priv->stereo)
|
|
|
68333f |
+ {
|
|
|
68333f |
+ base_texture = create_mipmaps ? COGL_TEXTURE (priv->texture_right) : NULL;
|
|
|
68333f |
+ meta_texture_tower_set_base_texture (priv->paint_tower_right, base_texture);
|
|
|
68333f |
+ }
|
|
|
68333f |
}
|
|
|
68333f |
}
|
|
|
68333f |
|
|
|
68333f |
@@ -435,13 +490,16 @@ meta_shaped_texture_update_area (MetaShapedTexture *stex,
|
|
|
68333f |
x, y, width, height);
|
|
|
68333f |
|
|
|
68333f |
meta_texture_tower_update_area (priv->paint_tower, x, y, width, height);
|
|
|
68333f |
+ if (priv->stereo)
|
|
|
68333f |
+ meta_texture_tower_update_area (priv->paint_tower_right, x, y, width, height);
|
|
|
68333f |
|
|
|
68333f |
clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (stex), &clip);
|
|
|
68333f |
}
|
|
|
68333f |
|
|
|
68333f |
static void
|
|
|
68333f |
set_cogl_texture (MetaShapedTexture *stex,
|
|
|
68333f |
- CoglTexturePixmapX11 *cogl_tex)
|
|
|
68333f |
+ CoglTexturePixmapX11 *cogl_tex,
|
|
|
68333f |
+ gboolean stereo)
|
|
|
68333f |
{
|
|
|
68333f |
MetaShapedTexturePrivate *priv;
|
|
|
68333f |
guint width, height;
|
|
|
68333f |
@@ -452,9 +510,17 @@ set_cogl_texture (MetaShapedTexture *stex,
|
|
|
68333f |
|
|
|
68333f |
if (priv->texture != NULL)
|
|
|
68333f |
cogl_object_unref (priv->texture);
|
|
|
68333f |
+ if (priv->texture_right != NULL)
|
|
|
68333f |
+ cogl_object_unref (priv->texture_right);
|
|
|
68333f |
|
|
|
68333f |
+ priv->stereo = stereo;
|
|
|
68333f |
priv->texture = cogl_tex;
|
|
|
68333f |
|
|
|
68333f |
+ if (priv->stereo)
|
|
|
68333f |
+ priv->texture_right = cogl_texture_pixmap_x11_new_right ((CoglTexturePixmapX11 *)cogl_tex);
|
|
|
68333f |
+ else
|
|
|
68333f |
+ priv->texture_right = NULL;
|
|
|
68333f |
+
|
|
|
68333f |
if (priv->pipeline != NULL)
|
|
|
68333f |
cogl_pipeline_set_layer_texture (priv->pipeline, 0, COGL_TEXTURE (cogl_tex));
|
|
|
68333f |
|
|
|
68333f |
@@ -493,7 +559,8 @@ set_cogl_texture (MetaShapedTexture *stex,
|
|
|
68333f |
*/
|
|
|
68333f |
void
|
|
|
68333f |
meta_shaped_texture_set_pixmap (MetaShapedTexture *stex,
|
|
|
68333f |
- Pixmap pixmap)
|
|
|
68333f |
+ Pixmap pixmap,
|
|
|
68333f |
+ gboolean stereo)
|
|
|
68333f |
{
|
|
|
68333f |
MetaShapedTexturePrivate *priv;
|
|
|
68333f |
|
|
|
68333f |
@@ -501,23 +568,44 @@ meta_shaped_texture_set_pixmap (MetaShapedTexture *stex,
|
|
|
68333f |
|
|
|
68333f |
priv = stex->priv;
|
|
|
68333f |
|
|
|
68333f |
- if (priv->pixmap == pixmap)
|
|
|
68333f |
+ if (priv->pixmap == pixmap && priv->stereo == stereo)
|
|
|
68333f |
return;
|
|
|
68333f |
|
|
|
68333f |
priv->pixmap = pixmap;
|
|
|
68333f |
+ priv->stereo = stereo;
|
|
|
68333f |
|
|
|
68333f |
if (pixmap != None)
|
|
|
68333f |
{
|
|
|
68333f |
CoglContext *ctx =
|
|
|
68333f |
clutter_backend_get_cogl_context (clutter_get_default_backend ());
|
|
|
68333f |
- set_cogl_texture (stex, cogl_texture_pixmap_x11_new (ctx, pixmap, FALSE, NULL));
|
|
|
68333f |
+ CoglTexturePixmapX11 *texture;
|
|
|
68333f |
+ if (priv->stereo)
|
|
|
68333f |
+ texture = cogl_texture_pixmap_x11_new_left (ctx, pixmap, FALSE, NULL);
|
|
|
68333f |
+ else
|
|
|
68333f |
+ texture = cogl_texture_pixmap_x11_new (ctx, pixmap, FALSE, NULL);
|
|
|
68333f |
+ set_cogl_texture (stex, texture, stereo);
|
|
|
68333f |
}
|
|
|
68333f |
else
|
|
|
68333f |
- set_cogl_texture (stex, NULL);
|
|
|
68333f |
+ set_cogl_texture (stex, NULL, stereo);
|
|
|
68333f |
+
|
|
|
68333f |
+ if (priv->stereo)
|
|
|
68333f |
+ {
|
|
|
68333f |
+ if (priv->paint_tower_right == NULL)
|
|
|
68333f |
+ priv->paint_tower_right = meta_texture_tower_new ();
|
|
|
68333f |
+ }
|
|
|
68333f |
+ else
|
|
|
68333f |
+ {
|
|
|
68333f |
+ g_clear_pointer (&priv->paint_tower_right, meta_texture_tower_free);
|
|
|
68333f |
+ }
|
|
|
68333f |
|
|
|
68333f |
if (priv->create_mipmaps)
|
|
|
68333f |
- meta_texture_tower_set_base_texture (priv->paint_tower,
|
|
|
68333f |
- COGL_TEXTURE (priv->texture));
|
|
|
68333f |
+ {
|
|
|
68333f |
+ meta_texture_tower_set_base_texture (priv->paint_tower,
|
|
|
68333f |
+ COGL_TEXTURE (priv->texture));
|
|
|
68333f |
+ if (priv->stereo)
|
|
|
68333f |
+ meta_texture_tower_set_base_texture (priv->paint_tower_right,
|
|
|
68333f |
+ COGL_TEXTURE (priv->texture_right));
|
|
|
68333f |
+ }
|
|
|
68333f |
}
|
|
|
68333f |
|
|
|
68333f |
/**
|
|
|
68333f |
diff --git a/src/compositor/meta-window-actor-private.h b/src/compositor/meta-window-actor-private.h
|
|
|
68333f |
index 90a9e35..914a8db 100644
|
|
|
68333f |
--- a/src/compositor/meta-window-actor-private.h
|
|
|
68333f |
+++ b/src/compositor/meta-window-actor-private.h
|
|
|
68333f |
@@ -66,4 +66,11 @@ void meta_window_actor_reset_visible_regions (MetaWindowActor *self);
|
|
|
68333f |
void meta_window_actor_effect_completed (MetaWindowActor *actor,
|
|
|
68333f |
gulong event);
|
|
|
68333f |
|
|
|
68333f |
+void meta_window_actor_stereo_notify (MetaWindowActor *actor,
|
|
|
68333f |
+ gboolean stereo_tree);
|
|
|
68333f |
+
|
|
|
68333f |
+gboolean meta_window_actor_is_stereo (MetaWindowActor *actor);
|
|
|
68333f |
+
|
|
|
68333f |
+void meta_window_actor_detach (MetaWindowActor *self);
|
|
|
68333f |
+
|
|
|
68333f |
#endif /* META_WINDOW_ACTOR_PRIVATE_H */
|
|
|
68333f |
diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c
|
|
|
68333f |
index 42d1257..1a11d0e 100644
|
|
|
68333f |
--- a/src/compositor/meta-window-actor.c
|
|
|
68333f |
+++ b/src/compositor/meta-window-actor.c
|
|
|
68333f |
@@ -108,6 +108,7 @@ struct _MetaWindowActorPrivate
|
|
|
68333f |
guint visible : 1;
|
|
|
68333f |
guint mapped : 1;
|
|
|
68333f |
guint argb32 : 1;
|
|
|
68333f |
+ guint stereo : 1;
|
|
|
68333f |
guint disposed : 1;
|
|
|
68333f |
guint redecorating : 1;
|
|
|
68333f |
|
|
|
68333f |
@@ -175,7 +176,6 @@ static gboolean meta_window_actor_get_paint_volume (ClutterActor *actor,
|
|
|
68333f |
ClutterPaintVolume *volume);
|
|
|
68333f |
|
|
|
68333f |
|
|
|
68333f |
-static void meta_window_actor_detach (MetaWindowActor *self);
|
|
|
68333f |
static gboolean meta_window_actor_has_shadow (MetaWindowActor *self);
|
|
|
68333f |
|
|
|
68333f |
static void meta_window_actor_handle_updates (MetaWindowActor *self);
|
|
|
68333f |
@@ -362,6 +362,9 @@ meta_window_actor_constructed (GObject *object)
|
|
|
68333f |
if (format && format->type == PictTypeDirect && format->direct.alphaMask)
|
|
|
68333f |
priv->argb32 = TRUE;
|
|
|
68333f |
|
|
|
68333f |
+ priv->stereo = meta_compositor_window_is_stereo (screen, xwindow);
|
|
|
68333f |
+ meta_compositor_select_stereo_notify (screen, xwindow);
|
|
|
68333f |
+
|
|
|
68333f |
if (!priv->actor)
|
|
|
68333f |
{
|
|
|
68333f |
priv->actor = meta_shaped_texture_new ();
|
|
|
68333f |
@@ -1218,7 +1221,7 @@ meta_window_actor_effect_completed (MetaWindowActor *self,
|
|
|
68333f |
* when the window is unmapped or when we want to update to a new
|
|
|
68333f |
* pixmap for a new size.
|
|
|
68333f |
*/
|
|
|
68333f |
-static void
|
|
|
68333f |
+void
|
|
|
68333f |
meta_window_actor_detach (MetaWindowActor *self)
|
|
|
68333f |
{
|
|
|
68333f |
MetaWindowActorPrivate *priv = self->priv;
|
|
|
68333f |
@@ -1234,7 +1237,7 @@ meta_window_actor_detach (MetaWindowActor *self)
|
|
|
68333f |
* pixmap, but it certainly doesn't work with current DRI/Mesa
|
|
|
68333f |
*/
|
|
|
68333f |
meta_shaped_texture_set_pixmap (META_SHAPED_TEXTURE (priv->actor),
|
|
|
68333f |
- None);
|
|
|
68333f |
+ None, FALSE);
|
|
|
68333f |
cogl_flush();
|
|
|
68333f |
|
|
|
68333f |
XFreePixmap (xdisplay, priv->back_pixmap);
|
|
|
68333f |
@@ -1823,7 +1826,7 @@ check_needs_pixmap (MetaWindowActor *self)
|
|
|
68333f |
FALSE);
|
|
|
68333f |
|
|
|
68333f |
meta_shaped_texture_set_pixmap (META_SHAPED_TEXTURE (priv->actor),
|
|
|
68333f |
- priv->back_pixmap);
|
|
|
68333f |
+ priv->back_pixmap, priv->stereo);
|
|
|
68333f |
|
|
|
68333f |
texture = meta_shaped_texture_get_texture (META_SHAPED_TEXTURE (priv->actor));
|
|
|
68333f |
|
|
|
68333f |
@@ -2575,3 +2578,19 @@ meta_window_actor_set_updates_frozen (MetaWindowActor *self,
|
|
|
68333f |
meta_window_actor_thaw (self);
|
|
|
68333f |
}
|
|
|
68333f |
}
|
|
|
68333f |
+
|
|
|
68333f |
+void
|
|
|
68333f |
+meta_window_actor_stereo_notify (MetaWindowActor *self,
|
|
|
68333f |
+ gboolean stereo_tree)
|
|
|
68333f |
+{
|
|
|
68333f |
+ MetaWindowActorPrivate *priv = self->priv;
|
|
|
68333f |
+
|
|
|
68333f |
+ priv->stereo = stereo_tree;
|
|
|
68333f |
+ meta_window_actor_detach (self);
|
|
|
68333f |
+}
|
|
|
68333f |
+
|
|
|
68333f |
+gboolean
|
|
|
68333f |
+meta_window_actor_is_stereo (MetaWindowActor *self)
|
|
|
68333f |
+{
|
|
|
68333f |
+ return self->priv->stereo;
|
|
|
68333f |
+}
|
|
|
68333f |
diff --git a/src/core/main.c b/src/core/main.c
|
|
|
68333f |
index d5bde44..8092afc 100644
|
|
|
68333f |
--- a/src/core/main.c
|
|
|
68333f |
+++ b/src/core/main.c
|
|
|
68333f |
@@ -444,6 +444,8 @@ meta_init (void)
|
|
|
68333f |
|
|
|
68333f |
meta_restart_init ();
|
|
|
68333f |
|
|
|
68333f |
+ meta_stereo_init ();
|
|
|
68333f |
+
|
|
|
68333f |
/*
|
|
|
68333f |
* Clutter can only be initialized after the UI.
|
|
|
68333f |
*/
|
|
|
68333f |
diff --git a/src/core/stereo.c b/src/core/stereo.c
|
|
|
68333f |
new file mode 100644
|
|
|
68333f |
index 0000000..d16a210
|
|
|
68333f |
--- /dev/null
|
|
|
68333f |
+++ b/src/core/stereo.c
|
|
|
68333f |
@@ -0,0 +1,144 @@
|
|
|
68333f |
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
|
|
68333f |
+
|
|
|
68333f |
+/*
|
|
|
68333f |
+ * Copyright (C) 2014 Red Hat, Inc.
|
|
|
68333f |
+ *
|
|
|
68333f |
+ * This program is free software; you can redistribute it and/or
|
|
|
68333f |
+ * modify it under the terms of the GNU General Public License as
|
|
|
68333f |
+ * published by the Free Software Foundation; either version 2 of the
|
|
|
68333f |
+ * License, or (at your option) any later version.
|
|
|
68333f |
+ *
|
|
|
68333f |
+ * This program is distributed in the hope that it will be useful, but
|
|
|
68333f |
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
68333f |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
68333f |
+ * General Public License for more details.
|
|
|
68333f |
+ *
|
|
|
68333f |
+ * You should have received a copy of the GNU General Public License
|
|
|
68333f |
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
|
|
|
68333f |
+ */
|
|
|
68333f |
+
|
|
|
68333f |
+/*
|
|
|
68333f |
+ * SECTION:stereo
|
|
|
68333f |
+ * @short_description: Keep track of whether we are a stereo compositor
|
|
|
68333f |
+ *
|
|
|
68333f |
+ * With GLX, we need to use a different GL context for stereo and
|
|
|
68333f |
+ * non-stereo support. Support for multiple GL contexts is unfinished
|
|
|
68333f |
+ * in Cogl and entirely lacking in Clutter, so it's by far easier
|
|
|
68333f |
+ * to just restart Mutter when we detect a stereo window.
|
|
|
68333f |
+ *
|
|
|
68333f |
+ * A property _MUTTER_ENABLE_STEREO is maintained on the root window
|
|
|
68333f |
+ * to know whether we should initialize clutter for stereo or not.
|
|
|
68333f |
+ * When the presence or absence of stereo windows mismatches the
|
|
|
68333f |
+ * stereo-enabled state for a sufficiently long period of time,
|
|
|
68333f |
+ * we restart Mutter.
|
|
|
68333f |
+ */
|
|
|
68333f |
+
|
|
|
68333f |
+#include <config.h>
|
|
|
68333f |
+
|
|
|
68333f |
+#include <clutter/x11/clutter-x11.h>
|
|
|
68333f |
+#include <gio/gunixinputstream.h>
|
|
|
68333f |
+#include <X11/Xatom.h>
|
|
|
68333f |
+
|
|
|
68333f |
+#include <meta/main.h>
|
|
|
68333f |
+#include "ui.h"
|
|
|
68333f |
+#include <meta/util.h>
|
|
|
68333f |
+#include "display-private.h"
|
|
|
68333f |
+#include "stereo.h"
|
|
|
68333f |
+
|
|
|
68333f |
+static guint stereo_switch_id = 0;
|
|
|
68333f |
+static gboolean stereo_enabled = FALSE;
|
|
|
68333f |
+/* -1 so the first time meta_stereo_set_have_stereo_windows() is called
|
|
|
68333f |
+ * we avoid the short-circuit and set up a timeout to restart
|
|
|
68333f |
+ * if necessary */
|
|
|
68333f |
+static gboolean stereo_have_windows = (gboolean)-1;
|
|
|
68333f |
+static gboolean stereo_restart = FALSE;
|
|
|
68333f |
+
|
|
|
68333f |
+#define STEREO_ENABLE_WAIT 1000
|
|
|
68333f |
+#define STEREO_DISABLE_WAIT 5000
|
|
|
68333f |
+
|
|
|
68333f |
+void
|
|
|
68333f |
+meta_stereo_init (void)
|
|
|
68333f |
+{
|
|
|
68333f |
+ Display *xdisplay = meta_ui_get_display ();
|
|
|
68333f |
+ Window root = DefaultRootWindow (xdisplay);
|
|
|
68333f |
+ Atom atom_enable_stereo = XInternAtom (xdisplay, "_MUTTER_ENABLE_STEREO", False);
|
|
|
68333f |
+ Atom type;
|
|
|
68333f |
+ int format;
|
|
|
68333f |
+ unsigned long n_items, bytes_after;
|
|
|
68333f |
+ guchar *data;
|
|
|
68333f |
+
|
|
|
68333f |
+ XGetWindowProperty (xdisplay, root, atom_enable_stereo,
|
|
|
68333f |
+ 0, 1, False, XA_INTEGER,
|
|
|
68333f |
+ &type, &format, &n_items, &bytes_after, &data);
|
|
|
68333f |
+ if (type == XA_INTEGER)
|
|
|
68333f |
+ {
|
|
|
68333f |
+ if (format == 32 && n_items == 1 && bytes_after == 0)
|
|
|
68333f |
+ {
|
|
|
68333f |
+ stereo_enabled = *(long *)data;
|
|
|
68333f |
+ }
|
|
|
68333f |
+ else
|
|
|
68333f |
+ {
|
|
|
68333f |
+ meta_warning ("Bad value for _MUTTER_ENABLE_STEREO property\n");
|
|
|
68333f |
+ }
|
|
|
68333f |
+
|
|
|
68333f |
+ XFree (data);
|
|
|
68333f |
+ }
|
|
|
68333f |
+ else if (type != None)
|
|
|
68333f |
+ {
|
|
|
68333f |
+ meta_warning ("Bad type for _MUTTER_ENABLE_STEREO property\n");
|
|
|
68333f |
+ }
|
|
|
68333f |
+
|
|
|
68333f |
+ meta_verbose ("On startup, _MUTTER_ENABLE_STEREO=%s",
|
|
|
68333f |
+ stereo_enabled ? "yes" : "no");
|
|
|
68333f |
+ clutter_x11_set_use_stereo_stage (stereo_enabled);
|
|
|
68333f |
+}
|
|
|
68333f |
+
|
|
|
68333f |
+static gboolean
|
|
|
68333f |
+meta_stereo_switch (gpointer data)
|
|
|
68333f |
+{
|
|
|
68333f |
+ stereo_switch_id = 0;
|
|
|
68333f |
+ stereo_restart = TRUE;
|
|
|
68333f |
+
|
|
|
68333f |
+ meta_restart (stereo_have_windows ?
|
|
|
68333f |
+ _("Enabling stereo...") :
|
|
|
68333f |
+ _("Disabling stereo..."));
|
|
|
68333f |
+
|
|
|
68333f |
+ return FALSE;
|
|
|
68333f |
+}
|
|
|
68333f |
+
|
|
|
68333f |
+void
|
|
|
68333f |
+meta_stereo_set_have_stereo_windows (gboolean have_windows)
|
|
|
68333f |
+{
|
|
|
68333f |
+ have_windows = have_windows != FALSE;
|
|
|
68333f |
+
|
|
|
68333f |
+ if (!stereo_restart && have_windows != stereo_have_windows)
|
|
|
68333f |
+ {
|
|
|
68333f |
+ MetaDisplay *display = meta_get_display ();
|
|
|
68333f |
+ Display *xdisplay = meta_display_get_xdisplay (display);
|
|
|
68333f |
+ Window root = DefaultRootWindow (xdisplay);
|
|
|
68333f |
+ Atom atom_enable_stereo = XInternAtom (xdisplay, "_MUTTER_ENABLE_STEREO", False);
|
|
|
68333f |
+ long value;
|
|
|
68333f |
+
|
|
|
68333f |
+ stereo_have_windows = have_windows;
|
|
|
68333f |
+
|
|
|
68333f |
+ if (stereo_have_windows)
|
|
|
68333f |
+ meta_verbose ("Detected stereo windows\n");
|
|
|
68333f |
+ else
|
|
|
68333f |
+ meta_verbose ("No stereo windows detected\n");
|
|
|
68333f |
+
|
|
|
68333f |
+ value = stereo_have_windows;
|
|
|
68333f |
+ XChangeProperty (xdisplay, root,
|
|
|
68333f |
+ atom_enable_stereo, XA_INTEGER, 32,
|
|
|
68333f |
+ PropModeReplace, (guchar *)&value, 1);
|
|
|
68333f |
+
|
|
|
68333f |
+ if (stereo_switch_id != 0)
|
|
|
68333f |
+ {
|
|
|
68333f |
+ g_source_remove (stereo_switch_id);
|
|
|
68333f |
+ stereo_switch_id = 0;
|
|
|
68333f |
+ }
|
|
|
68333f |
+
|
|
|
68333f |
+ if (stereo_have_windows != stereo_enabled)
|
|
|
68333f |
+ stereo_switch_id = g_timeout_add (stereo_have_windows ? STEREO_ENABLE_WAIT : STEREO_DISABLE_WAIT,
|
|
|
68333f |
+ meta_stereo_switch, NULL);
|
|
|
68333f |
+ }
|
|
|
68333f |
+}
|
|
|
68333f |
diff --git a/src/core/stereo.h b/src/core/stereo.h
|
|
|
68333f |
new file mode 100644
|
|
|
68333f |
index 0000000..ccd1d70
|
|
|
68333f |
--- /dev/null
|
|
|
68333f |
+++ b/src/core/stereo.h
|
|
|
68333f |
@@ -0,0 +1,28 @@
|
|
|
68333f |
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
|
|
68333f |
+
|
|
|
68333f |
+/*
|
|
|
68333f |
+ * Copyright (C) 2014 Red Hat, Inc.
|
|
|
68333f |
+ *
|
|
|
68333f |
+ * This program is free software; you can redistribute it and/or
|
|
|
68333f |
+ * modify it under the terms of the GNU General Public License as
|
|
|
68333f |
+ * published by the Free Software Foundation; either version 2 of the
|
|
|
68333f |
+ * License, or (at your option) any later version.
|
|
|
68333f |
+ *
|
|
|
68333f |
+ * This program is distributed in the hope that it will be useful, but
|
|
|
68333f |
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
68333f |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
68333f |
+ * General Public License for more details.
|
|
|
68333f |
+ *
|
|
|
68333f |
+ * You should have received a copy of the GNU General Public License
|
|
|
68333f |
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
|
|
|
68333f |
+ */
|
|
|
68333f |
+
|
|
|
68333f |
+#ifndef META_STEREO_H
|
|
|
68333f |
+#define META_STEREO_H
|
|
|
68333f |
+
|
|
|
68333f |
+void meta_stereo_init (void);
|
|
|
68333f |
+void meta_stereo_set_have_stereo_windows (gboolean have_windows);
|
|
|
68333f |
+gboolean meta_stereo_is_restart (void);
|
|
|
68333f |
+void meta_stereo_finish_restart (void);
|
|
|
68333f |
+
|
|
|
68333f |
+#endif
|
|
|
68333f |
diff --git a/src/meta/meta-shaped-texture.h b/src/meta/meta-shaped-texture.h
|
|
|
68333f |
index 28fb5f6..fcf33c3 100644
|
|
|
68333f |
--- a/src/meta/meta-shaped-texture.h
|
|
|
68333f |
+++ b/src/meta/meta-shaped-texture.h
|
|
|
68333f |
@@ -76,7 +76,8 @@ void meta_shaped_texture_update_area (MetaShapedTexture *stex,
|
|
|
68333f |
int height);
|
|
|
68333f |
|
|
|
68333f |
void meta_shaped_texture_set_pixmap (MetaShapedTexture *stex,
|
|
|
68333f |
- Pixmap pixmap);
|
|
|
68333f |
+ Pixmap pixmap,
|
|
|
68333f |
+ gboolean stereo);
|
|
|
68333f |
|
|
|
68333f |
CoglTexture * meta_shaped_texture_get_texture (MetaShapedTexture *stex);
|
|
|
68333f |
|
|
|
68333f |
--
|
|
|
68333f |
1.8.3.1
|
|
|
68333f |
|