Add support for setting up stereo CoglOnscreens
If we want to show quad-buffer stereo with Cogl, we need to pick an appropriate fbconfig for creating the CoglOnscreen objects. Add cogl_onscreen_template_set_stereo_enabled() to indicate whether stereo support is needed. Add cogl_framebuffer_get_stereo_mode() to see if a framebuffer was created with stereo support. Add cogl_framebuffer_get_stereo_mode() to pick whether to draw to the left, right, or both buffers. Reviewed-by: Robert Bragg <robert.bragg@intel.com>
This commit is contained in:
parent
775fcbaaaf
commit
d16df5a5aa
@ -270,6 +270,7 @@ struct _CoglContext
|
|||||||
|
|
||||||
CoglBool current_gl_dither_enabled;
|
CoglBool current_gl_dither_enabled;
|
||||||
CoglColorMask current_gl_color_mask;
|
CoglColorMask current_gl_color_mask;
|
||||||
|
GLenum current_gl_draw_buffer;
|
||||||
|
|
||||||
/* Clipping */
|
/* Clipping */
|
||||||
/* TRUE if we have a valid clipping stack flushed. In that case
|
/* TRUE if we have a valid clipping stack flushed. In that case
|
||||||
|
@ -61,6 +61,7 @@ typedef struct
|
|||||||
int samples_per_pixel;
|
int samples_per_pixel;
|
||||||
CoglBool swap_throttled;
|
CoglBool swap_throttled;
|
||||||
CoglBool depth_texture_enabled;
|
CoglBool depth_texture_enabled;
|
||||||
|
CoglBool stereo_enabled;
|
||||||
} CoglFramebufferConfig;
|
} CoglFramebufferConfig;
|
||||||
|
|
||||||
/* Flags to pass to _cogl_offscreen_new_with_texture_full */
|
/* Flags to pass to _cogl_offscreen_new_with_texture_full */
|
||||||
@ -86,7 +87,8 @@ typedef enum _CoglFramebufferStateIndex
|
|||||||
COGL_FRAMEBUFFER_STATE_INDEX_COLOR_MASK = 6,
|
COGL_FRAMEBUFFER_STATE_INDEX_COLOR_MASK = 6,
|
||||||
COGL_FRAMEBUFFER_STATE_INDEX_FRONT_FACE_WINDING = 7,
|
COGL_FRAMEBUFFER_STATE_INDEX_FRONT_FACE_WINDING = 7,
|
||||||
COGL_FRAMEBUFFER_STATE_INDEX_DEPTH_WRITE = 8,
|
COGL_FRAMEBUFFER_STATE_INDEX_DEPTH_WRITE = 8,
|
||||||
COGL_FRAMEBUFFER_STATE_INDEX_MAX = 9
|
COGL_FRAMEBUFFER_STATE_INDEX_STEREO_MODE = 9,
|
||||||
|
COGL_FRAMEBUFFER_STATE_INDEX_MAX = 10
|
||||||
} CoglFramebufferStateIndex;
|
} CoglFramebufferStateIndex;
|
||||||
|
|
||||||
typedef enum _CoglFramebufferState
|
typedef enum _CoglFramebufferState
|
||||||
@ -99,7 +101,8 @@ typedef enum _CoglFramebufferState
|
|||||||
COGL_FRAMEBUFFER_STATE_PROJECTION = 1<<5,
|
COGL_FRAMEBUFFER_STATE_PROJECTION = 1<<5,
|
||||||
COGL_FRAMEBUFFER_STATE_COLOR_MASK = 1<<6,
|
COGL_FRAMEBUFFER_STATE_COLOR_MASK = 1<<6,
|
||||||
COGL_FRAMEBUFFER_STATE_FRONT_FACE_WINDING = 1<<7,
|
COGL_FRAMEBUFFER_STATE_FRONT_FACE_WINDING = 1<<7,
|
||||||
COGL_FRAMEBUFFER_STATE_DEPTH_WRITE = 1<<8
|
COGL_FRAMEBUFFER_STATE_DEPTH_WRITE = 1<<8,
|
||||||
|
COGL_FRAMEBUFFER_STATE_STEREO_MODE = 1<<9
|
||||||
} CoglFramebufferState;
|
} CoglFramebufferState;
|
||||||
|
|
||||||
#define COGL_FRAMEBUFFER_STATE_ALL ((1<<COGL_FRAMEBUFFER_STATE_INDEX_MAX) - 1)
|
#define COGL_FRAMEBUFFER_STATE_ALL ((1<<COGL_FRAMEBUFFER_STATE_INDEX_MAX) - 1)
|
||||||
@ -154,6 +157,7 @@ struct _CoglFramebuffer
|
|||||||
CoglBool dither_enabled;
|
CoglBool dither_enabled;
|
||||||
CoglBool depth_writing_enabled;
|
CoglBool depth_writing_enabled;
|
||||||
CoglColorMask color_mask;
|
CoglColorMask color_mask;
|
||||||
|
CoglStereoMode stereo_mode;
|
||||||
|
|
||||||
/* We journal the textured rectangles we want to submit to OpenGL so
|
/* We journal the textured rectangles we want to submit to OpenGL so
|
||||||
* we have an oppertunity to batch them together into less draw
|
* we have an oppertunity to batch them together into less draw
|
||||||
|
@ -907,6 +907,14 @@ _cogl_framebuffer_compare_depth_write_state (CoglFramebuffer *a,
|
|||||||
COGL_FRAMEBUFFER_STATE_DEPTH_WRITE : 0;
|
COGL_FRAMEBUFFER_STATE_DEPTH_WRITE : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned long
|
||||||
|
_cogl_framebuffer_compare_stereo_mode (CoglFramebuffer *a,
|
||||||
|
CoglFramebuffer *b)
|
||||||
|
{
|
||||||
|
return a->stereo_mode != b->stereo_mode ?
|
||||||
|
COGL_FRAMEBUFFER_STATE_STEREO_MODE : 0;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned long
|
unsigned long
|
||||||
_cogl_framebuffer_compare (CoglFramebuffer *a,
|
_cogl_framebuffer_compare (CoglFramebuffer *a,
|
||||||
CoglFramebuffer *b,
|
CoglFramebuffer *b,
|
||||||
@ -959,6 +967,10 @@ _cogl_framebuffer_compare (CoglFramebuffer *a,
|
|||||||
differences |=
|
differences |=
|
||||||
_cogl_framebuffer_compare_depth_write_state (a, b);
|
_cogl_framebuffer_compare_depth_write_state (a, b);
|
||||||
break;
|
break;
|
||||||
|
case COGL_FRAMEBUFFER_STATE_INDEX_STEREO_MODE:
|
||||||
|
differences |=
|
||||||
|
_cogl_framebuffer_compare_stereo_mode (a, b);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
g_warn_if_reached ();
|
g_warn_if_reached ();
|
||||||
}
|
}
|
||||||
@ -1046,6 +1058,12 @@ _cogl_framebuffer_get_stencil_bits (CoglFramebuffer *framebuffer)
|
|||||||
return bits.stencil;
|
return bits.stencil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
cogl_framebuffer_get_is_stereo (CoglFramebuffer *framebuffer)
|
||||||
|
{
|
||||||
|
return framebuffer->config.stereo_enabled;
|
||||||
|
}
|
||||||
|
|
||||||
CoglColorMask
|
CoglColorMask
|
||||||
cogl_framebuffer_get_color_mask (CoglFramebuffer *framebuffer)
|
cogl_framebuffer_get_color_mask (CoglFramebuffer *framebuffer)
|
||||||
{
|
{
|
||||||
@ -1069,6 +1087,29 @@ cogl_framebuffer_set_color_mask (CoglFramebuffer *framebuffer,
|
|||||||
COGL_FRAMEBUFFER_STATE_COLOR_MASK;
|
COGL_FRAMEBUFFER_STATE_COLOR_MASK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CoglStereoMode
|
||||||
|
cogl_framebuffer_get_stereo_mode (CoglFramebuffer *framebuffer)
|
||||||
|
{
|
||||||
|
return framebuffer->stereo_mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cogl_framebuffer_set_stereo_mode (CoglFramebuffer *framebuffer,
|
||||||
|
CoglStereoMode stereo_mode)
|
||||||
|
{
|
||||||
|
if (framebuffer->stereo_mode == stereo_mode)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Stereo mode changes don't go through the journal */
|
||||||
|
_cogl_framebuffer_flush_journal (framebuffer);
|
||||||
|
|
||||||
|
framebuffer->stereo_mode = stereo_mode;
|
||||||
|
|
||||||
|
if (framebuffer->context->current_draw_buffer == framebuffer)
|
||||||
|
framebuffer->context->current_draw_buffer_changes |=
|
||||||
|
COGL_FRAMEBUFFER_STATE_STEREO_MODE;
|
||||||
|
}
|
||||||
|
|
||||||
CoglBool
|
CoglBool
|
||||||
cogl_framebuffer_get_depth_write_enabled (CoglFramebuffer *framebuffer)
|
cogl_framebuffer_get_depth_write_enabled (CoglFramebuffer *framebuffer)
|
||||||
{
|
{
|
||||||
|
@ -737,6 +737,23 @@ cogl_framebuffer_get_alpha_bits (CoglFramebuffer *framebuffer);
|
|||||||
int
|
int
|
||||||
cogl_framebuffer_get_depth_bits (CoglFramebuffer *framebuffer);
|
cogl_framebuffer_get_depth_bits (CoglFramebuffer *framebuffer);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* cogl_framebuffer_get_is_stereo:
|
||||||
|
* @framebuffer: a pointer to a #CoglFramebuffer
|
||||||
|
*
|
||||||
|
* Retrieves whether @framebuffer has separate left and right
|
||||||
|
* buffers for use with stereo drawing. See
|
||||||
|
* cogl_framebuffer_set_stereo_mode().
|
||||||
|
*
|
||||||
|
* Return value: %TRUE if @framebuffer has separate left and
|
||||||
|
* right buffers.
|
||||||
|
*
|
||||||
|
* Since: 1.20
|
||||||
|
* Stability: unstable
|
||||||
|
*/
|
||||||
|
CoglBool
|
||||||
|
cogl_framebuffer_get_is_stereo (CoglFramebuffer *framebuffer);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* cogl_framebuffer_get_dither_enabled:
|
* cogl_framebuffer_get_dither_enabled:
|
||||||
* @framebuffer: a pointer to a #CoglFramebuffer
|
* @framebuffer: a pointer to a #CoglFramebuffer
|
||||||
@ -846,6 +863,41 @@ void
|
|||||||
cogl_framebuffer_set_color_mask (CoglFramebuffer *framebuffer,
|
cogl_framebuffer_set_color_mask (CoglFramebuffer *framebuffer,
|
||||||
CoglColorMask color_mask);
|
CoglColorMask color_mask);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cogl_framebuffer_get_stereo_mode:
|
||||||
|
* @framebuffer: a pointer to a #CoglFramebuffer
|
||||||
|
*
|
||||||
|
* Gets the current #CoglStereoMode, which defines which stereo buffers
|
||||||
|
* should be drawn to. See cogl_framebuffer_set_stereo_mode().
|
||||||
|
*
|
||||||
|
* Returns: A #CoglStereoMode
|
||||||
|
* Since: 1.20
|
||||||
|
* Stability: unstable
|
||||||
|
*/
|
||||||
|
CoglStereoMode
|
||||||
|
cogl_framebuffer_get_stereo_mode (CoglFramebuffer *framebuffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cogl_framebuffer_set_stereo_mode:
|
||||||
|
* @framebuffer: a pointer to a #CoglFramebuffer
|
||||||
|
* @stereo_mode: A #CoglStereoMode specifying which stereo buffers
|
||||||
|
* should be drawn tow.
|
||||||
|
*
|
||||||
|
* Sets which stereo buffers should be drawn to. The default
|
||||||
|
* is %COGL_STEREO_BOTH, which means that both the left and
|
||||||
|
* right buffers will be affected by drawing. For this to have
|
||||||
|
* an effect, the display system must support stereo drawables,
|
||||||
|
* and the framebuffer must have been created with stereo
|
||||||
|
* enabled. (See cogl_onscreen_template_set_stereo_enabled(),
|
||||||
|
* cogl_framebuffer_get_is_stereo().)
|
||||||
|
*
|
||||||
|
* Since: 1.20
|
||||||
|
* Stability: unstable
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
cogl_framebuffer_set_stereo_mode (CoglFramebuffer *framebuffer,
|
||||||
|
CoglStereoMode stereo_mode);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* cogl_framebuffer_set_depth_texture_enabled:
|
* cogl_framebuffer_set_depth_texture_enabled:
|
||||||
* @framebuffer: A #CoglFramebuffer
|
* @framebuffer: A #CoglFramebuffer
|
||||||
|
@ -95,3 +95,11 @@ cogl_onscreen_template_set_swap_throttled (
|
|||||||
{
|
{
|
||||||
onscreen_template->config.swap_throttled = throttled;
|
onscreen_template->config.swap_throttled = throttled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cogl_onscreen_template_set_stereo_enabled (
|
||||||
|
CoglOnscreenTemplate *onscreen_template,
|
||||||
|
CoglBool enabled)
|
||||||
|
{
|
||||||
|
onscreen_template->config.stereo_enabled = enabled;
|
||||||
|
}
|
||||||
|
@ -106,6 +106,24 @@ cogl_onscreen_template_set_swap_throttled (
|
|||||||
CoglOnscreenTemplate *onscreen_template,
|
CoglOnscreenTemplate *onscreen_template,
|
||||||
CoglBool throttled);
|
CoglBool throttled);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cogl_onscreen_template_set_stereo_enabled:
|
||||||
|
* @onscreen_template: A #CoglOnscreenTemplate template framebuffer
|
||||||
|
* @enabled: Whether framebuffers are created with stereo buffers
|
||||||
|
*
|
||||||
|
* Sets whether future #CoglOnscreen framebuffers derived from this
|
||||||
|
* template are attempted to be created with both left and right
|
||||||
|
* buffers, for use with stereo display. If the display system
|
||||||
|
* does not support stereo, then creation of the framebuffer will
|
||||||
|
* fail.
|
||||||
|
*
|
||||||
|
* Since: 1.20
|
||||||
|
* Stability: unstable
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
cogl_onscreen_template_set_stereo_enabled (
|
||||||
|
CoglOnscreenTemplate *onscreen_template,
|
||||||
|
CoglBool enabled);
|
||||||
/**
|
/**
|
||||||
* cogl_is_onscreen_template:
|
* cogl_is_onscreen_template:
|
||||||
* @object: A #CoglObject pointer
|
* @object: A #CoglObject pointer
|
||||||
|
@ -920,6 +920,21 @@ typedef enum { /*< prefix=COGL_READ_PIXELS >*/
|
|||||||
COGL_READ_PIXELS_COLOR_BUFFER = 1L << 0
|
COGL_READ_PIXELS_COLOR_BUFFER = 1L << 0
|
||||||
} CoglReadPixelsFlags;
|
} CoglReadPixelsFlags;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CoglStereoMode:
|
||||||
|
* @COGL_STEREO_BOTH: draw to both stereo buffers
|
||||||
|
* @COGL_STEREO_LEFT: draw only to the left stereo buffer
|
||||||
|
* @COGL_STEREO_RIGHT: draw only to the left stereo buffer
|
||||||
|
*
|
||||||
|
* Represents how draw should affect the two buffers
|
||||||
|
* of a stereo framebuffer. See cogl_framebuffer_set_stereo_mode().
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
COGL_STEREO_BOTH,
|
||||||
|
COGL_STEREO_LEFT,
|
||||||
|
COGL_STEREO_RIGHT
|
||||||
|
} CoglStereoMode;
|
||||||
|
|
||||||
COGL_END_DECLS
|
COGL_END_DECLS
|
||||||
|
|
||||||
#endif /* __COGL_TYPES_H__ */
|
#endif /* __COGL_TYPES_H__ */
|
||||||
|
@ -236,6 +236,39 @@ _cogl_framebuffer_gl_flush_front_face_winding_state (CoglFramebuffer *framebuffe
|
|||||||
context->current_pipeline_age--;
|
context->current_pipeline_age--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_cogl_framebuffer_gl_flush_stereo_mode_state (CoglFramebuffer *framebuffer)
|
||||||
|
{
|
||||||
|
CoglContext *ctx = framebuffer->context;
|
||||||
|
GLenum draw_buffer = GL_BACK;
|
||||||
|
|
||||||
|
if (framebuffer->type == COGL_FRAMEBUFFER_TYPE_OFFSCREEN)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* The one-shot default draw buffer setting in _cogl_framebuffer_gl_bind
|
||||||
|
* must have already happened. If not it would override what we set here. */
|
||||||
|
g_assert (ctx->was_bound_to_onscreen);
|
||||||
|
|
||||||
|
switch (framebuffer->stereo_mode)
|
||||||
|
{
|
||||||
|
case COGL_STEREO_BOTH:
|
||||||
|
draw_buffer = GL_BACK;
|
||||||
|
break;
|
||||||
|
case COGL_STEREO_LEFT:
|
||||||
|
draw_buffer = GL_BACK_LEFT;
|
||||||
|
break;
|
||||||
|
case COGL_STEREO_RIGHT:
|
||||||
|
draw_buffer = GL_BACK_RIGHT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctx->current_gl_draw_buffer != draw_buffer)
|
||||||
|
{
|
||||||
|
GE (ctx, glDrawBuffer (draw_buffer));
|
||||||
|
ctx->current_gl_draw_buffer = draw_buffer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
_cogl_framebuffer_gl_bind (CoglFramebuffer *framebuffer, GLenum target)
|
_cogl_framebuffer_gl_bind (CoglFramebuffer *framebuffer, GLenum target)
|
||||||
{
|
{
|
||||||
@ -406,6 +439,9 @@ _cogl_framebuffer_gl_flush_state (CoglFramebuffer *draw_buffer,
|
|||||||
/* Nothing to do for depth write state change; the state will always
|
/* Nothing to do for depth write state change; the state will always
|
||||||
* be taken into account when flushing the pipeline's depth state. */
|
* be taken into account when flushing the pipeline's depth state. */
|
||||||
break;
|
break;
|
||||||
|
case COGL_FRAMEBUFFER_STATE_INDEX_STEREO_MODE:
|
||||||
|
_cogl_framebuffer_gl_flush_stereo_mode_state (draw_buffer);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
g_warn_if_reached ();
|
g_warn_if_reached ();
|
||||||
}
|
}
|
||||||
|
@ -184,6 +184,7 @@ COGL_WINSYS_FEATURE_BEGIN (255, 255,
|
|||||||
"swap_event\0",
|
"swap_event\0",
|
||||||
0,
|
0,
|
||||||
COGL_WINSYS_FEATURE_SYNC_AND_COMPLETE_EVENT)
|
COGL_WINSYS_FEATURE_SYNC_AND_COMPLETE_EVENT)
|
||||||
|
|
||||||
COGL_WINSYS_FEATURE_END ()
|
COGL_WINSYS_FEATURE_END ()
|
||||||
|
|
||||||
COGL_WINSYS_FEATURE_BEGIN (255, 255,
|
COGL_WINSYS_FEATURE_BEGIN (255, 255,
|
||||||
|
@ -909,6 +909,11 @@ glx_attributes_from_framebuffer_config (CoglDisplay *display,
|
|||||||
attributes[i++] = 1;
|
attributes[i++] = 1;
|
||||||
attributes[i++] = GLX_STENCIL_SIZE;
|
attributes[i++] = GLX_STENCIL_SIZE;
|
||||||
attributes[i++] = config->need_stencil ? 1: GLX_DONT_CARE;
|
attributes[i++] = config->need_stencil ? 1: GLX_DONT_CARE;
|
||||||
|
if (config->stereo_enabled)
|
||||||
|
{
|
||||||
|
attributes[i++] = GLX_STEREO;
|
||||||
|
attributes[i++] = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
if (glx_renderer->glx_major == 1 && glx_renderer->glx_minor >= 4 &&
|
if (glx_renderer->glx_major == 1 && glx_renderer->glx_minor >= 4 &&
|
||||||
config->samples_per_pixel)
|
config->samples_per_pixel)
|
||||||
@ -948,6 +953,7 @@ find_fbconfig (CoglDisplay *display,
|
|||||||
xscreen_num,
|
xscreen_num,
|
||||||
attributes,
|
attributes,
|
||||||
&n_configs);
|
&n_configs);
|
||||||
|
|
||||||
if (!configs || n_configs == 0)
|
if (!configs || n_configs == 0)
|
||||||
{
|
{
|
||||||
_cogl_set_error (error, COGL_WINSYS_ERROR,
|
_cogl_set_error (error, COGL_WINSYS_ERROR,
|
||||||
@ -1856,7 +1862,7 @@ _cogl_winsys_onscreen_swap_region (CoglOnscreen *onscreen,
|
|||||||
rect[0], rect[1], x2, y2,
|
rect[0], rect[1], x2, y2,
|
||||||
GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||||
}
|
}
|
||||||
context->glDrawBuffer (GL_BACK);
|
context->glDrawBuffer (context->current_gl_draw_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* NB: unlike glXSwapBuffers, glXCopySubBuffer and
|
/* NB: unlike glXSwapBuffers, glXCopySubBuffer and
|
||||||
|
Loading…
Reference in New Issue
Block a user