|
|
3e8236 |
From 55f30d3240ad636519e1fcc5a579b7d5cba0ed5f Mon Sep 17 00:00:00 2001
|
|
|
3e8236 |
From: "Owen W. Taylor" <otaylor@fishsoup.net>
|
|
|
3e8236 |
Date: Thu, 8 May 2014 18:52:09 -0400
|
|
|
3e8236 |
Subject: [PATCH] Allow setting up quad-buffer stereo output
|
|
|
3e8236 |
|
|
|
3e8236 |
Add clutter_x11_set_use_stereo_stage() that can be called
|
|
|
3e8236 |
before clutter_init() so that the CoglDisplay we create and all
|
|
|
3e8236 |
stages created from that CoglDisplay will be created with a
|
|
|
3e8236 |
stereo fbconfig.
|
|
|
3e8236 |
|
|
|
3e8236 |
This is done in clutter-x11 because of the similarity to the
|
|
|
3e8236 |
existing clutter_x11_set_use_argb_visual(), and because it's
|
|
|
3e8236 |
not clear without other examples whether the need to have
|
|
|
3e8236 |
stereo enabled from before clutter_init() is universal or
|
|
|
3e8236 |
somethign specific to GLX.
|
|
|
3e8236 |
|
|
|
3e8236 |
https://bugzilla.gnome.org/show_bug.cgi?id=732706
|
|
|
3e8236 |
---
|
|
|
3e8236 |
clutter/x11/clutter-backend-x11.c | 170 +++++++++++++++++++++++++++++---------
|
|
|
3e8236 |
clutter/x11/clutter-x11.h | 3 +
|
|
|
3e8236 |
2 files changed, 133 insertions(+), 40 deletions(-)
|
|
|
3e8236 |
|
|
|
3e8236 |
diff --git a/clutter/x11/clutter-backend-x11.c b/clutter/x11/clutter-backend-x11.c
|
|
|
3e8236 |
index b7cfcc4..bba21e7 100644
|
|
|
3e8236 |
--- a/clutter/x11/clutter-backend-x11.c
|
|
|
3e8236 |
+++ b/clutter/x11/clutter-backend-x11.c
|
|
|
3e8236 |
@@ -96,6 +96,7 @@ static const gchar *atom_names[] = {
|
|
|
3e8236 |
static gboolean _no_xevent_retrieval = FALSE;
|
|
|
3e8236 |
static gboolean clutter_enable_xinput = TRUE;
|
|
|
3e8236 |
static gboolean clutter_enable_argb = FALSE;
|
|
|
3e8236 |
+static gboolean clutter_enable_stereo = FALSE;
|
|
|
3e8236 |
static Display *_foreign_dpy = NULL;
|
|
|
3e8236 |
|
|
|
3e8236 |
/* options */
|
|
|
3e8236 |
@@ -706,6 +707,59 @@ clutter_backend_x11_get_renderer (ClutterBackend *backend,
|
|
|
3e8236 |
return renderer;
|
|
|
3e8236 |
}
|
|
|
3e8236 |
|
|
|
3e8236 |
+static gboolean
|
|
|
3e8236 |
+check_onscreen_template (CoglRenderer *renderer,
|
|
|
3e8236 |
+ CoglSwapChain *swap_chain,
|
|
|
3e8236 |
+ CoglOnscreenTemplate *onscreen_template,
|
|
|
3e8236 |
+ CoglBool enable_argb,
|
|
|
3e8236 |
+ CoglBool enable_stereo,
|
|
|
3e8236 |
+ GError **error)
|
|
|
3e8236 |
+{
|
|
|
3e8236 |
+ GError *internal_error = NULL;
|
|
|
3e8236 |
+
|
|
|
3e8236 |
+ cogl_swap_chain_set_has_alpha (swap_chain, enable_argb);
|
|
|
3e8236 |
+ cogl_onscreen_template_set_stereo_enabled (onscreen_template,
|
|
|
3e8236 |
+ clutter_enable_stereo);
|
|
|
3e8236 |
+
|
|
|
3e8236 |
+ /* cogl_renderer_check_onscreen_template() is actually just a
|
|
|
3e8236 |
+ * shorthand for creating a CoglDisplay, and calling
|
|
|
3e8236 |
+ * cogl_display_setup() on it, then throwing the display away. If we
|
|
|
3e8236 |
+ * could just return that display, then it would be more efficient
|
|
|
3e8236 |
+ * not to use cogl_renderer_check_onscreen_template(). However, the
|
|
|
3e8236 |
+ * backend API requires that we return an CoglDisplay that has not
|
|
|
3e8236 |
+ * yet been setup, so one way or the other we'll have to discard the
|
|
|
3e8236 |
+ * first display and make a new fresh one.
|
|
|
3e8236 |
+ */
|
|
|
3e8236 |
+ if (cogl_renderer_check_onscreen_template (renderer, onscreen_template, &internal_error))
|
|
|
3e8236 |
+ {
|
|
|
3e8236 |
+ clutter_enable_argb = enable_argb;
|
|
|
3e8236 |
+ clutter_enable_stereo = enable_stereo;
|
|
|
3e8236 |
+
|
|
|
3e8236 |
+ return TRUE;
|
|
|
3e8236 |
+ }
|
|
|
3e8236 |
+ else
|
|
|
3e8236 |
+ {
|
|
|
3e8236 |
+ if (enable_argb || enable_stereo) /* More possibilities to try */
|
|
|
3e8236 |
+ CLUTTER_NOTE (BACKEND,
|
|
|
3e8236 |
+ "Creation of a CoglDisplay with alpha=%s, stereo=%s failed: %s",
|
|
|
3e8236 |
+ enable_argb ? "enabled" : "disabled",
|
|
|
3e8236 |
+ enable_stereo ? "enabled" : "disabled",
|
|
|
3e8236 |
+ internal_error != NULL
|
|
|
3e8236 |
+ ? internal_error->message
|
|
|
3e8236 |
+ : "Unknown reason");
|
|
|
3e8236 |
+ else
|
|
|
3e8236 |
+ g_set_error_literal (error, CLUTTER_INIT_ERROR,
|
|
|
3e8236 |
+ CLUTTER_INIT_ERROR_BACKEND,
|
|
|
3e8236 |
+ internal_error != NULL
|
|
|
3e8236 |
+ ? internal_error->message
|
|
|
3e8236 |
+ : "Creation of a CoglDisplay failed");
|
|
|
3e8236 |
+
|
|
|
3e8236 |
+ g_clear_error (&internal_error);
|
|
|
3e8236 |
+
|
|
|
3e8236 |
+ return FALSE;
|
|
|
3e8236 |
+ }
|
|
|
3e8236 |
+}
|
|
|
3e8236 |
+
|
|
|
3e8236 |
static CoglDisplay *
|
|
|
3e8236 |
clutter_backend_x11_get_display (ClutterBackend *backend,
|
|
|
3e8236 |
CoglRenderer *renderer,
|
|
|
3e8236 |
@@ -713,56 +767,38 @@ clutter_backend_x11_get_display (ClutterBackend *backend,
|
|
|
3e8236 |
GError **error)
|
|
|
3e8236 |
{
|
|
|
3e8236 |
CoglOnscreenTemplate *onscreen_template;
|
|
|
3e8236 |
- GError *internal_error = NULL;
|
|
|
3e8236 |
- CoglDisplay *display;
|
|
|
3e8236 |
- gboolean res;
|
|
|
3e8236 |
-
|
|
|
3e8236 |
- CLUTTER_NOTE (BACKEND, "Alpha on Cogl swap chain: %s",
|
|
|
3e8236 |
- clutter_enable_argb ? "enabled" : "disabled");
|
|
|
3e8236 |
+ CoglDisplay *display = NULL;
|
|
|
3e8236 |
+ gboolean res = FALSE;
|
|
|
3e8236 |
|
|
|
3e8236 |
- cogl_swap_chain_set_has_alpha (swap_chain, clutter_enable_argb);
|
|
|
3e8236 |
+ CLUTTER_NOTE (BACKEND, "Creating CoglDisplay, alpha=%s, stereo=%s",
|
|
|
3e8236 |
+ clutter_enable_argb ? "enabled" : "disabled",
|
|
|
3e8236 |
+ clutter_enable_stereo ? "enabled" : "disabled");
|
|
|
3e8236 |
|
|
|
3e8236 |
onscreen_template = cogl_onscreen_template_new (swap_chain);
|
|
|
3e8236 |
|
|
|
3e8236 |
- res = cogl_renderer_check_onscreen_template (renderer,
|
|
|
3e8236 |
- onscreen_template,
|
|
|
3e8236 |
- &internal_error);
|
|
|
3e8236 |
- if (!res && clutter_enable_argb)
|
|
|
3e8236 |
- {
|
|
|
3e8236 |
- CLUTTER_NOTE (BACKEND,
|
|
|
3e8236 |
- "Creation of a context with a ARGB visual failed: %s",
|
|
|
3e8236 |
- internal_error != NULL ? internal_error->message
|
|
|
3e8236 |
- : "Unknown reason");
|
|
|
3e8236 |
+ /* It's possible that the current renderer doesn't support transparency
|
|
|
3e8236 |
+ * or doesn't support stereo, so we try the different combinations.
|
|
|
3e8236 |
+ */
|
|
|
3e8236 |
+ if (clutter_enable_argb && clutter_enable_stereo)
|
|
|
3e8236 |
+ res = check_onscreen_template (renderer, swap_chain, onscreen_template,
|
|
|
3e8236 |
+ TRUE, TRUE, error);
|
|
|
3e8236 |
|
|
|
3e8236 |
- g_clear_error (&internal_error);
|
|
|
3e8236 |
+ /* Prioritize stereo over alpha */
|
|
|
3e8236 |
+ if (!res && clutter_enable_stereo)
|
|
|
3e8236 |
+ res = check_onscreen_template (renderer, swap_chain, onscreen_template,
|
|
|
3e8236 |
+ FALSE, TRUE, error);
|
|
|
3e8236 |
|
|
|
3e8236 |
- /* It's possible that the current renderer doesn't support transparency
|
|
|
3e8236 |
- * in a swap_chain so lets see if we can fallback to not having any
|
|
|
3e8236 |
- * transparency...
|
|
|
3e8236 |
- *
|
|
|
3e8236 |
- * XXX: It might be nice to have a CoglRenderer feature we could
|
|
|
3e8236 |
- * explicitly check for ahead of time.
|
|
|
3e8236 |
- */
|
|
|
3e8236 |
- clutter_enable_argb = FALSE;
|
|
|
3e8236 |
- cogl_swap_chain_set_has_alpha (swap_chain, FALSE);
|
|
|
3e8236 |
- res = cogl_renderer_check_onscreen_template (renderer,
|
|
|
3e8236 |
- onscreen_template,
|
|
|
3e8236 |
- &internal_error);
|
|
|
3e8236 |
- }
|
|
|
3e8236 |
+ if (!res && clutter_enable_argb)
|
|
|
3e8236 |
+ res = check_onscreen_template (renderer, swap_chain, onscreen_template,
|
|
|
3e8236 |
+ TRUE, FALSE, error);
|
|
|
3e8236 |
|
|
|
3e8236 |
if (!res)
|
|
|
3e8236 |
- {
|
|
|
3e8236 |
- g_set_error_literal (error, CLUTTER_INIT_ERROR,
|
|
|
3e8236 |
- CLUTTER_INIT_ERROR_BACKEND,
|
|
|
3e8236 |
- internal_error->message);
|
|
|
3e8236 |
+ res = check_onscreen_template (renderer, swap_chain, onscreen_template,
|
|
|
3e8236 |
+ FALSE, FALSE, error);
|
|
|
3e8236 |
|
|
|
3e8236 |
- g_error_free (internal_error);
|
|
|
3e8236 |
- cogl_object_unref (onscreen_template);
|
|
|
3e8236 |
+ if (res)
|
|
|
3e8236 |
+ display = cogl_display_new (renderer, onscreen_template);
|
|
|
3e8236 |
|
|
|
3e8236 |
- return NULL;
|
|
|
3e8236 |
- }
|
|
|
3e8236 |
-
|
|
|
3e8236 |
- display = cogl_display_new (renderer, onscreen_template);
|
|
|
3e8236 |
cogl_object_unref (onscreen_template);
|
|
|
3e8236 |
|
|
|
3e8236 |
return display;
|
|
|
3e8236 |
@@ -1309,6 +1345,60 @@ clutter_x11_get_use_argb_visual (void)
|
|
|
3e8236 |
return clutter_enable_argb;
|
|
|
3e8236 |
}
|
|
|
3e8236 |
|
|
|
3e8236 |
+/**
|
|
|
3e8236 |
+ * clutter_x11_set_use_stereo_stage:
|
|
|
3e8236 |
+ * @use_stereo: %TRUE if the stereo stages should be used if possible.
|
|
|
3e8236 |
+ *
|
|
|
3e8236 |
+ * Sets whether the backend object for Clutter stages, will,
|
|
|
3e8236 |
+ * if possible, be created with the ability to support stereo drawing
|
|
|
3e8236 |
+ * (drawing separate images for the left and right eyes).
|
|
|
3e8236 |
+ *
|
|
|
3e8236 |
+ * This function must be called before clutter_init() is called.
|
|
|
3e8236 |
+ * During paint callbacks, cogl_framebuffer_is_stereo() can be called
|
|
|
3e8236 |
+ * on the framebuffer retrieved by cogl_get_draw_framebuffer() to
|
|
|
3e8236 |
+ * determine if stereo support was successfully enabled, and
|
|
|
3e8236 |
+ * cogl_framebuffer_set_stereo_mode() to determine which buffers
|
|
|
3e8236 |
+ * will be drawn to.
|
|
|
3e8236 |
+ *
|
|
|
3e8236 |
+ * Note that this function *does not* cause the stage to be drawn
|
|
|
3e8236 |
+ * multiple times with different perspective transformations and thus
|
|
|
3e8236 |
+ * appear in 3D, it simply enables individual ClutterActors to paint
|
|
|
3e8236 |
+ * different images for the left and and right eye.
|
|
|
3e8236 |
+ *
|
|
|
3e8236 |
+ * Since: 1.20
|
|
|
3e8236 |
+ */
|
|
|
3e8236 |
+void
|
|
|
3e8236 |
+clutter_x11_set_use_stereo_stage (gboolean use_stereo)
|
|
|
3e8236 |
+{
|
|
|
3e8236 |
+ if (_clutter_context_is_initialized ())
|
|
|
3e8236 |
+ {
|
|
|
3e8236 |
+ g_warning ("%s() can only be used before calling clutter_init()",
|
|
|
3e8236 |
+ G_STRFUNC);
|
|
|
3e8236 |
+ return;
|
|
|
3e8236 |
+ }
|
|
|
3e8236 |
+
|
|
|
3e8236 |
+ CLUTTER_NOTE (BACKEND, "STEREO stages are %s",
|
|
|
3e8236 |
+ use_stereo ? "enabled" : "disabled");
|
|
|
3e8236 |
+
|
|
|
3e8236 |
+ clutter_enable_stereo = use_stereo;
|
|
|
3e8236 |
+}
|
|
|
3e8236 |
+
|
|
|
3e8236 |
+/**
|
|
|
3e8236 |
+ * clutter_x11_get_use_stereo_stage:
|
|
|
3e8236 |
+ *
|
|
|
3e8236 |
+ * Retrieves whether the Clutter X11 backend will create stereo
|
|
|
3e8236 |
+ * stages if possible.
|
|
|
3e8236 |
+ *
|
|
|
3e8236 |
+ * Return value: %TRUE if stereo stages are used if possible
|
|
|
3e8236 |
+ *
|
|
|
3e8236 |
+ * Since: 1.20
|
|
|
3e8236 |
+ */
|
|
|
3e8236 |
+gboolean
|
|
|
3e8236 |
+clutter_x11_get_use_stereo_stage (void)
|
|
|
3e8236 |
+{
|
|
|
3e8236 |
+ return clutter_enable_stereo;
|
|
|
3e8236 |
+}
|
|
|
3e8236 |
+
|
|
|
3e8236 |
XVisualInfo *
|
|
|
3e8236 |
_clutter_backend_x11_get_visual_info (ClutterBackendX11 *backend_x11)
|
|
|
3e8236 |
{
|
|
|
3e8236 |
diff --git a/clutter/x11/clutter-x11.h b/clutter/x11/clutter-x11.h
|
|
|
3e8236 |
index 6913280..efcd37e 100644
|
|
|
3e8236 |
--- a/clutter/x11/clutter-x11.h
|
|
|
3e8236 |
+++ b/clutter/x11/clutter-x11.h
|
|
|
3e8236 |
@@ -137,6 +137,9 @@ gboolean clutter_x11_has_composite_extension (void);
|
|
|
3e8236 |
void clutter_x11_set_use_argb_visual (gboolean use_argb);
|
|
|
3e8236 |
gboolean clutter_x11_get_use_argb_visual (void);
|
|
|
3e8236 |
|
|
|
3e8236 |
+void clutter_x11_set_use_stereo_stage (gboolean use_stereo);
|
|
|
3e8236 |
+gboolean clutter_x11_get_use_stereo_stage (void);
|
|
|
3e8236 |
+
|
|
|
3e8236 |
Time clutter_x11_get_current_event_time (void);
|
|
|
3e8236 |
|
|
|
3e8236 |
gint clutter_x11_event_get_key_group (const ClutterEvent *event);
|
|
|
3e8236 |
--
|
|
|
3e8236 |
1.9.3
|
|
|
3e8236 |
|