Blame SOURCES/Add-support-for-setting-up-stereo-CoglOnscreens.patch

b987e2
From 0c547943ce2e7daae80bfbe72aa3e8ea88e1ba0b Mon Sep 17 00:00:00 2001
b987e2
From: "Owen W. Taylor" <otaylor@fishsoup.net>
b987e2
Date: Mon, 28 Apr 2014 12:37:32 -0400
b987e2
Subject: [PATCH 4/8] Add support for setting up stereo CoglOnscreens
b987e2
b987e2
If we want to show quad-buffer stereo with Cogl, we need to pick an
b987e2
appropriate fbconfig for creating the CoglOnscreen objects. Add
b987e2
cogl_onscreen_template_set_stereo_enabled() to indicate whether
b987e2
stereo support is needed.
b987e2
b987e2
Add cogl_framebuffer_get_stereo_mode() to see if a framebuffer was
b987e2
created with stereo support.
b987e2
b987e2
Add cogl_framebuffer_get_stereo_mode() to pick whether to draw to
b987e2
the left, right, or both buffers.
b987e2
---
b987e2
 cogl/cogl-context-private.h                     |  1 +
b987e2
 cogl/cogl-framebuffer-private.h                 |  8 +++-
b987e2
 cogl/cogl-framebuffer.c                         | 41 +++++++++++++++++++
b987e2
 cogl/cogl-framebuffer.h                         | 52 +++++++++++++++++++++++++
b987e2
 cogl/cogl-onscreen-template.c                   |  8 ++++
b987e2
 cogl/cogl-onscreen-template.h                   | 18 +++++++++
b987e2
 cogl/cogl-types.h                               | 15 +++++++
b987e2
 cogl/driver/gl/cogl-framebuffer-gl.c            | 32 +++++++++++++++
b987e2
 cogl/winsys/cogl-winsys-glx-feature-functions.h |  1 +
b987e2
 cogl/winsys/cogl-winsys-glx.c                   |  8 +++-
b987e2
 10 files changed, 181 insertions(+), 3 deletions(-)
b987e2
b987e2
diff --git a/cogl/cogl-context-private.h b/cogl/cogl-context-private.h
b987e2
index 31033d0..f725993 100644
b987e2
--- a/cogl/cogl-context-private.h
b987e2
+++ b/cogl/cogl-context-private.h
b987e2
@@ -242,6 +242,7 @@ struct _CoglContext
b987e2
 
b987e2
   CoglBool current_gl_dither_enabled;
b987e2
   CoglColorMask current_gl_color_mask;
b987e2
+  GLenum current_gl_draw_buffer;
b987e2
 
b987e2
   /* Clipping */
b987e2
   /* TRUE if we have a valid clipping stack flushed. In that case
b987e2
diff --git a/cogl/cogl-framebuffer-private.h b/cogl/cogl-framebuffer-private.h
b987e2
index 267dbf6..747a699 100644
b987e2
--- a/cogl/cogl-framebuffer-private.h
b987e2
+++ b/cogl/cogl-framebuffer-private.h
b987e2
@@ -54,6 +54,7 @@ typedef struct
b987e2
   int samples_per_pixel;
b987e2
   CoglBool swap_throttled;
b987e2
   CoglBool depth_texture_enabled;
b987e2
+  CoglBool stereo_enabled;
b987e2
 } CoglFramebufferConfig;
b987e2
 
b987e2
 /* Flags to pass to _cogl_offscreen_new_to_texture_full */
b987e2
@@ -78,7 +79,8 @@ typedef enum _CoglFramebufferStateIndex
b987e2
   COGL_FRAMEBUFFER_STATE_INDEX_PROJECTION         = 5,
b987e2
   COGL_FRAMEBUFFER_STATE_INDEX_COLOR_MASK         = 6,
b987e2
   COGL_FRAMEBUFFER_STATE_INDEX_FRONT_FACE_WINDING = 7,
b987e2
-  COGL_FRAMEBUFFER_STATE_INDEX_MAX                = 8
b987e2
+  COGL_FRAMEBUFFER_STATE_INDEX_STEREO_MODE        = 8,
b987e2
+  COGL_FRAMEBUFFER_STATE_INDEX_MAX                = 9
b987e2
 } CoglFramebufferStateIndex;
b987e2
 
b987e2
 typedef enum _CoglFramebufferState
b987e2
@@ -90,7 +92,8 @@ typedef enum _CoglFramebufferState
b987e2
   COGL_FRAMEBUFFER_STATE_MODELVIEW          = 1<<4,
b987e2
   COGL_FRAMEBUFFER_STATE_PROJECTION         = 1<<5,
b987e2
   COGL_FRAMEBUFFER_STATE_COLOR_MASK         = 1<<6,
b987e2
-  COGL_FRAMEBUFFER_STATE_FRONT_FACE_WINDING = 1<<7
b987e2
+  COGL_FRAMEBUFFER_STATE_FRONT_FACE_WINDING = 1<<7,
b987e2
+  COGL_FRAMEBUFFER_STATE_STEREO_MODE        = 1<<8
b987e2
 } CoglFramebufferState;
b987e2
 
b987e2
 #define COGL_FRAMEBUFFER_STATE_ALL ((1<
b987e2
@@ -144,6 +147,7 @@ struct _CoglFramebuffer
b987e2
 
b987e2
   CoglBool            dither_enabled;
b987e2
   CoglColorMask       color_mask;
b987e2
+  CoglStereoMode      stereo_mode;
b987e2
 
b987e2
   /* We journal the textured rectangles we want to submit to OpenGL so
b987e2
    * we have an oppertunity to batch them together into less draw
b987e2
diff --git a/cogl/cogl-framebuffer.c b/cogl/cogl-framebuffer.c
b987e2
index 136ae86..05981b5 100644
b987e2
--- a/cogl/cogl-framebuffer.c
b987e2
+++ b/cogl/cogl-framebuffer.c
b987e2
@@ -1077,6 +1077,14 @@ _cogl_framebuffer_compare_front_face_winding_state (CoglFramebuffer *a,
b987e2
     return 0;
b987e2
 }
b987e2
 
b987e2
+static unsigned long
b987e2
+_cogl_framebuffer_compare_stereo_mode (CoglFramebuffer *a,
b987e2
+				       CoglFramebuffer *b)
b987e2
+{
b987e2
+  return a->stereo_mode != b->stereo_mode ?
b987e2
+    COGL_FRAMEBUFFER_STATE_STEREO_MODE : 0;
b987e2
+}
b987e2
+
b987e2
 unsigned long
b987e2
 _cogl_framebuffer_compare (CoglFramebuffer *a,
b987e2
                            CoglFramebuffer *b,
b987e2
@@ -1125,6 +1133,10 @@ _cogl_framebuffer_compare (CoglFramebuffer *a,
b987e2
           differences |=
b987e2
             _cogl_framebuffer_compare_front_face_winding_state (a, b);
b987e2
           break;
b987e2
+        case COGL_FRAMEBUFFER_STATE_INDEX_STEREO_MODE:
b987e2
+          differences |=
b987e2
+            _cogl_framebuffer_compare_stereo_mode (a, b);
b987e2
+          break;
b987e2
         default:
b987e2
           g_warn_if_reached ();
b987e2
         }
b987e2
@@ -1212,6 +1224,12 @@ _cogl_framebuffer_get_stencil_bits (CoglFramebuffer *framebuffer)
b987e2
   return bits.stencil;
b987e2
 }
b987e2
 
b987e2
+gboolean
b987e2
+cogl_framebuffer_get_is_stereo (CoglFramebuffer *framebuffer)
b987e2
+{
b987e2
+  return framebuffer->config.stereo_enabled;
b987e2
+}
b987e2
+
b987e2
 CoglColorMask
b987e2
 cogl_framebuffer_get_color_mask (CoglFramebuffer *framebuffer)
b987e2
 {
b987e2
@@ -1232,6 +1250,29 @@ cogl_framebuffer_set_color_mask (CoglFramebuffer *framebuffer,
b987e2
       COGL_FRAMEBUFFER_STATE_COLOR_MASK;
b987e2
 }
b987e2
 
b987e2
+CoglStereoMode
b987e2
+cogl_framebuffer_get_stereo_mode (CoglFramebuffer *framebuffer)
b987e2
+{
b987e2
+  return framebuffer->stereo_mode;
b987e2
+}
b987e2
+
b987e2
+void
b987e2
+cogl_framebuffer_set_stereo_mode (CoglFramebuffer *framebuffer,
b987e2
+				  CoglStereoMode   stereo_mode)
b987e2
+{
b987e2
+  if (framebuffer->stereo_mode == stereo_mode)
b987e2
+    return;
b987e2
+
b987e2
+  /* Stereo mode changes don't go through the journal */
b987e2
+  _cogl_framebuffer_flush_journal (framebuffer);
b987e2
+
b987e2
+  framebuffer->stereo_mode = stereo_mode;
b987e2
+
b987e2
+  if (framebuffer->context->current_draw_buffer == framebuffer)
b987e2
+    framebuffer->context->current_draw_buffer_changes |=
b987e2
+      COGL_FRAMEBUFFER_STATE_STEREO_MODE;
b987e2
+}
b987e2
+
b987e2
 CoglBool
b987e2
 cogl_framebuffer_get_dither_enabled (CoglFramebuffer *framebuffer)
b987e2
 {
b987e2
diff --git a/cogl/cogl-framebuffer.h b/cogl/cogl-framebuffer.h
b987e2
index e3fdb12..595a374 100644
b987e2
--- a/cogl/cogl-framebuffer.h
b987e2
+++ b/cogl/cogl-framebuffer.h
b987e2
@@ -733,6 +733,23 @@ cogl_framebuffer_get_alpha_bits (CoglFramebuffer *framebuffer);
b987e2
 int
b987e2
 cogl_framebuffer_get_depth_bits (CoglFramebuffer *framebuffer);
b987e2
 
b987e2
+/*
b987e2
+ * cogl_framebuffer_get_is_stereo:
b987e2
+ * @framebuffer: a pointer to a #CoglFramebuffer
b987e2
+ *
b987e2
+ * Retrieves whether @framebuffer has separate left and right
b987e2
+ * buffers for use with stereo drawing. See
b987e2
+ * cogl_framebuffer_set_stereo_mode().
b987e2
+ *
b987e2
+ * Return value: %TRUE if @framebuffer has separate left and
b987e2
+ * right buffers.
b987e2
+ *
b987e2
+ * Since: 1.20
b987e2
+ * Stability: unstable
b987e2
+ */
b987e2
+CoglBool
b987e2
+cogl_framebuffer_get_is_stereo (CoglFramebuffer *framebuffer);
b987e2
+
b987e2
 /**
b987e2
  * cogl_framebuffer_get_dither_enabled:
b987e2
  * @framebuffer: a pointer to a #CoglFramebuffer
b987e2
@@ -825,6 +842,41 @@ CoglPixelFormat
b987e2
 cogl_framebuffer_get_color_format (CoglFramebuffer *framebuffer);
b987e2
 
b987e2
 /**
b987e2
+ * cogl_framebuffer_get_stereo_mode:
b987e2
+ * @framebuffer: a pointer to a #CoglFramebuffer
b987e2
+ *
b987e2
+ * Gets the current #CoglStereoMode, which defines which stereo buffers
b987e2
+ * should be drawn to. See cogl_framebuffer_set_stereo_mode().
b987e2
+ *
b987e2
+ * Returns: A #CoglStereoMode
b987e2
+ * Since: 1.20
b987e2
+ * Stability: unstable
b987e2
+ */
b987e2
+CoglStereoMode
b987e2
+cogl_framebuffer_get_stereo_mode (CoglFramebuffer *framebuffer);
b987e2
+
b987e2
+/**
b987e2
+ * cogl_framebuffer_set_stereo_mode:
b987e2
+ * @framebuffer: a pointer to a #CoglFramebuffer
b987e2
+ * @stereo_mode: A #CoglStereoMode specifying which stereo buffers
b987e2
+ *               should be drawn tow.
b987e2
+ *
b987e2
+ * Sets which stereo buffers should be drawn to. The default
b987e2
+ * is %COGL_STEREO_BOTH, which means that both the left and
b987e2
+ * right buffers will be affected by drawing. For this to have
b987e2
+ * an effect, the display system must support stereo drawables,
b987e2
+ * and the framebuffer must have been created with stereo
b987e2
+ * enabled. (See cogl_onscreen_template_set_stereo_enabled(),
b987e2
+ * cogl_framebuffer_get_is_stereo().)
b987e2
+ *
b987e2
+ * Since: 1.20
b987e2
+ * Stability: unstable
b987e2
+ */
b987e2
+void
b987e2
+cogl_framebuffer_set_stereo_mode (CoglFramebuffer *framebuffer,
b987e2
+				  CoglStereoMode stereo_mode);
b987e2
+
b987e2
+/**
b987e2
  * cogl_framebuffer_set_depth_texture_enabled:
b987e2
  * @framebuffer: A #CoglFramebuffer
b987e2
  * @enabled: TRUE or FALSE
b987e2
diff --git a/cogl/cogl-onscreen-template.c b/cogl/cogl-onscreen-template.c
b987e2
index 5fa5b99..8854069 100644
b987e2
--- a/cogl/cogl-onscreen-template.c
b987e2
+++ b/cogl/cogl-onscreen-template.c
b987e2
@@ -88,3 +88,11 @@ cogl_onscreen_template_set_swap_throttled (
b987e2
 {
b987e2
   onscreen_template->config.swap_throttled = throttled;
b987e2
 }
b987e2
+
b987e2
+void
b987e2
+cogl_onscreen_template_set_stereo_enabled (
b987e2
+					   CoglOnscreenTemplate *onscreen_template,
b987e2
+					   CoglBool enabled)
b987e2
+{
b987e2
+  onscreen_template->config.stereo_enabled = enabled;
b987e2
+}
b987e2
diff --git a/cogl/cogl-onscreen-template.h b/cogl/cogl-onscreen-template.h
b987e2
index 58d88d4..f4645bb 100644
b987e2
--- a/cogl/cogl-onscreen-template.h
b987e2
+++ b/cogl/cogl-onscreen-template.h
b987e2
@@ -88,6 +88,24 @@ cogl_onscreen_template_set_swap_throttled (
b987e2
                                           CoglBool throttled);
b987e2
 
b987e2
 /**
b987e2
+ * cogl_onscreen_template_set_stereo_enabled:
b987e2
+ * @onscreen_template: A #CoglOnscreenTemplate template framebuffer
b987e2
+ * @enabled: Whether framebuffers are created with stereo buffers
b987e2
+ *
b987e2
+ * Sets whether future #CoglOnscreen framebuffers derived from this
b987e2
+ * template are attempted to be created with both left and right
b987e2
+ * buffers, for use with stereo display. If the display system
b987e2
+ * does not support stereo, then creation of the framebuffer will
b987e2
+ * fail.
b987e2
+ *
b987e2
+ * Since: 1.20
b987e2
+ * Stability: unstable
b987e2
+ */
b987e2
+void
b987e2
+cogl_onscreen_template_set_stereo_enabled (
b987e2
+					   CoglOnscreenTemplate *onscreen_template,
b987e2
+					   CoglBool enabled);
b987e2
+/**
b987e2
  * cogl_is_onscreen_template:
b987e2
  * @object: A #CoglObject pointer
b987e2
  *
b987e2
diff --git a/cogl/cogl-types.h b/cogl/cogl-types.h
b987e2
index 227b7ec..0a9b20c 100644
b987e2
--- a/cogl/cogl-types.h
b987e2
+++ b/cogl/cogl-types.h
b987e2
@@ -907,6 +907,21 @@ typedef enum { /*< prefix=COGL_READ_PIXELS >*/
b987e2
   COGL_READ_PIXELS_COLOR_BUFFER = 1L << 0
b987e2
 } CoglReadPixelsFlags;
b987e2
 
b987e2
+/**
b987e2
+ * CoglStereoMode:
b987e2
+ * @COGL_STEREO_BOTH: draw to both stereo buffers
b987e2
+ * @COGL_STEREO_LEFT: draw only to the left stereo buffer
b987e2
+ * @COGL_STEREO_RIGHT: draw only to the left stereo buffer
b987e2
+ *
b987e2
+ * Represents how draw should affect the two buffers
b987e2
+ * of a stereo framebuffer. See cogl_framebuffer_set_stereo_mode().
b987e2
+ */
b987e2
+typedef enum {
b987e2
+  COGL_STEREO_BOTH,
b987e2
+  COGL_STEREO_LEFT,
b987e2
+  COGL_STEREO_RIGHT
b987e2
+} CoglStereoMode;
b987e2
+
b987e2
 COGL_END_DECLS
b987e2
 
b987e2
 #endif /* __COGL_TYPES_H__ */
b987e2
diff --git a/cogl/driver/gl/cogl-framebuffer-gl.c b/cogl/driver/gl/cogl-framebuffer-gl.c
b987e2
index 660098e..86b693b 100644
b987e2
--- a/cogl/driver/gl/cogl-framebuffer-gl.c
b987e2
+++ b/cogl/driver/gl/cogl-framebuffer-gl.c
b987e2
@@ -228,6 +228,35 @@ _cogl_framebuffer_gl_flush_front_face_winding_state (CoglFramebuffer *framebuffe
b987e2
   context->current_pipeline_age--;
b987e2
 }
b987e2
 
b987e2
+static void
b987e2
+_cogl_framebuffer_gl_flush_stereo_mode_state (CoglFramebuffer *framebuffer)
b987e2
+{
b987e2
+  CoglContext *ctx = framebuffer->context;
b987e2
+  GLenum draw_buffer = GL_BACK;
b987e2
+
b987e2
+  if (framebuffer->type == COGL_FRAMEBUFFER_TYPE_OFFSCREEN)
b987e2
+    return;
b987e2
+
b987e2
+  switch (framebuffer->stereo_mode)
b987e2
+    {
b987e2
+    case COGL_STEREO_BOTH:
b987e2
+      draw_buffer = GL_BACK;
b987e2
+      break;
b987e2
+    case COGL_STEREO_LEFT:
b987e2
+      draw_buffer = GL_BACK_LEFT;
b987e2
+      break;
b987e2
+    case COGL_STEREO_RIGHT:
b987e2
+      draw_buffer = GL_BACK_RIGHT;
b987e2
+      break;
b987e2
+    }
b987e2
+
b987e2
+  if (ctx->current_gl_draw_buffer != draw_buffer)
b987e2
+    {
b987e2
+      GE (ctx, glDrawBuffer (draw_buffer));
b987e2
+      ctx->current_gl_draw_buffer = draw_buffer;
b987e2
+    }
b987e2
+}
b987e2
+
b987e2
 void
b987e2
 _cogl_framebuffer_gl_bind (CoglFramebuffer *framebuffer, GLenum target)
b987e2
 {
b987e2
@@ -365,6 +394,9 @@ _cogl_framebuffer_gl_flush_state (CoglFramebuffer *draw_buffer,
b987e2
         case COGL_FRAMEBUFFER_STATE_INDEX_FRONT_FACE_WINDING:
b987e2
           _cogl_framebuffer_gl_flush_front_face_winding_state (draw_buffer);
b987e2
           break;
b987e2
+        case COGL_FRAMEBUFFER_STATE_INDEX_STEREO_MODE:
b987e2
+          _cogl_framebuffer_gl_flush_stereo_mode_state (draw_buffer);
b987e2
+          break;
b987e2
         default:
b987e2
           g_warn_if_reached ();
b987e2
         }
b987e2
diff --git a/cogl/winsys/cogl-winsys-glx-feature-functions.h b/cogl/winsys/cogl-winsys-glx-feature-functions.h
b987e2
index 9e7b49d..1e56c66 100644
b987e2
--- a/cogl/winsys/cogl-winsys-glx-feature-functions.h
b987e2
+++ b/cogl/winsys/cogl-winsys-glx-feature-functions.h
b987e2
@@ -179,6 +179,7 @@ COGL_WINSYS_FEATURE_BEGIN (255, 255,
b987e2
                            0,
b987e2
                            COGL_WINSYS_FEATURE_SWAP_BUFFERS_EVENT |
b987e2
                            COGL_WINSYS_FEATURE_SYNC_AND_COMPLETE_EVENT)
b987e2
+
b987e2
 COGL_WINSYS_FEATURE_END ()
b987e2
 
b987e2
 COGL_WINSYS_FEATURE_BEGIN (255, 255,
b987e2
diff --git a/cogl/winsys/cogl-winsys-glx.c b/cogl/winsys/cogl-winsys-glx.c
b987e2
index a58a6ce..bff5178 100644
b987e2
--- a/cogl/winsys/cogl-winsys-glx.c
b987e2
+++ b/cogl/winsys/cogl-winsys-glx.c
b987e2
@@ -775,6 +775,11 @@ glx_attributes_from_framebuffer_config (CoglDisplay *display,
b987e2
   attributes[i++] = 1;
b987e2
   attributes[i++] = GLX_STENCIL_SIZE;
b987e2
   attributes[i++] = config->need_stencil ? 1: GLX_DONT_CARE;
b987e2
+  if (config->stereo_enabled)
b987e2
+    {
b987e2
+      attributes[i++] = GLX_STEREO;
b987e2
+      attributes[i++] = TRUE;
b987e2
+    }
b987e2
 
b987e2
   if (glx_renderer->glx_major == 1 && glx_renderer->glx_minor >= 4 &&
b987e2
       config->samples_per_pixel)
b987e2
@@ -814,6 +819,7 @@ find_fbconfig (CoglDisplay *display,
b987e2
                                              xscreen_num,
b987e2
                                              attributes,
b987e2
                                              &n_configs);
b987e2
+
b987e2
   if (!configs || n_configs == 0)
b987e2
     {
b987e2
       _cogl_set_error (error, COGL_WINSYS_ERROR,
b987e2
@@ -1722,7 +1728,7 @@ _cogl_winsys_onscreen_swap_region (CoglOnscreen *onscreen,
b987e2
                                       rect[0], rect[1], x2, y2,
b987e2
                                       GL_COLOR_BUFFER_BIT, GL_NEAREST);
b987e2
         }
b987e2
-      context->glDrawBuffer (GL_BACK);
b987e2
+      context->glDrawBuffer (context->current_gl_draw_buffer);
b987e2
     }
b987e2
 
b987e2
   /* NB: unlike glXSwapBuffers, glXCopySubBuffer and
b987e2
-- 
b987e2
1.9.3
b987e2