cogl/gl-framebuffer: Move stereo mode state flushing to backend

It's currently only handled by a surface backend framebuffer (assuming
the right GLX extensions are available). While it's theoretically
possible to do the same with the offcreen by having multiple textures,
it's not supported, so leave the FBO variant with a single warning if we
end up there.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1514>
This commit is contained in:
Jonas Ådahl 2020-10-20 11:55:57 +02:00 committed by Robert Mader
parent dd55c3699c
commit 102aa59ce3
4 changed files with 63 additions and 33 deletions

View File

@ -49,6 +49,8 @@ struct _CoglGlFramebufferClass
void (* bind) (CoglGlFramebuffer *gl_framebuffer, void (* bind) (CoglGlFramebuffer *gl_framebuffer,
GLenum target); GLenum target);
void (* flush_stereo_mode_state) (CoglGlFramebuffer *gl_framebuffer);
}; };
void void

View File

@ -194,40 +194,10 @@ cogl_gl_framebuffer_flush_front_face_winding_state (CoglGlFramebuffer *gl_frameb
static void static void
cogl_gl_framebuffer_flush_stereo_mode_state (CoglGlFramebuffer *gl_framebuffer) cogl_gl_framebuffer_flush_stereo_mode_state (CoglGlFramebuffer *gl_framebuffer)
{ {
CoglFramebufferDriver *driver = COGL_FRAMEBUFFER_DRIVER (gl_framebuffer); CoglGlFramebufferClass *klass =
CoglFramebuffer *framebuffer = COGL_GL_FRAMEBUFFER_GET_CLASS (gl_framebuffer);
cogl_framebuffer_driver_get_framebuffer (driver);
CoglContext *ctx = cogl_framebuffer_get_context (framebuffer);
GLenum draw_buffer = GL_BACK;
if (COGL_IS_OFFSCREEN (framebuffer)) klass->flush_stereo_mode_state (gl_framebuffer);
return;
if (!ctx->glDrawBuffer)
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 (cogl_framebuffer_get_stereo_mode (framebuffer))
{
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

View File

@ -227,6 +227,42 @@ cogl_gl_framebuffer_back_bind (CoglGlFramebuffer *gl_framebuffer,
} }
} }
static void
cogl_gl_framebuffer_back_flush_stereo_mode_state (CoglGlFramebuffer *gl_framebuffer)
{
CoglFramebufferDriver *driver = COGL_FRAMEBUFFER_DRIVER (gl_framebuffer);
CoglFramebuffer *framebuffer =
cogl_framebuffer_driver_get_framebuffer (driver);
CoglContext *ctx = cogl_framebuffer_get_context (framebuffer);
GLenum draw_buffer = GL_BACK;
if (!ctx->glDrawBuffer)
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 (cogl_framebuffer_get_stereo_mode (framebuffer))
{
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;
}
}
CoglGlFramebufferBack * CoglGlFramebufferBack *
cogl_gl_framebuffer_back_new (CoglFramebuffer *framebuffer, cogl_gl_framebuffer_back_new (CoglFramebuffer *framebuffer,
const CoglFramebufferDriverConfig *driver_config, const CoglFramebufferDriverConfig *driver_config,
@ -262,4 +298,6 @@ cogl_gl_framebuffer_back_class_init (CoglGlFramebufferBackClass *klass)
driver_class->discard_buffers = cogl_gl_framebuffer_back_discard_buffers; driver_class->discard_buffers = cogl_gl_framebuffer_back_discard_buffers;
gl_framebuffer_class->bind = cogl_gl_framebuffer_back_bind; gl_framebuffer_class->bind = cogl_gl_framebuffer_back_bind;
gl_framebuffer_class->flush_stereo_mode_state =
cogl_gl_framebuffer_back_flush_stereo_mode_state;
} }

View File

@ -214,6 +214,24 @@ cogl_gl_framebuffer_fbo_bind (CoglGlFramebuffer *gl_framebuffer,
GE (ctx, glBindFramebuffer (target, gl_framebuffer_fbo->gl_fbo.fbo_handle)); GE (ctx, glBindFramebuffer (target, gl_framebuffer_fbo->gl_fbo.fbo_handle));
} }
static void
cogl_gl_framebuffer_fbo_flush_stereo_mode_state (CoglGlFramebuffer *gl_framebuffer)
{
CoglFramebufferDriver *driver = COGL_FRAMEBUFFER_DRIVER (gl_framebuffer);
CoglFramebuffer *framebuffer =
cogl_framebuffer_driver_get_framebuffer (driver);
switch (cogl_framebuffer_get_stereo_mode (framebuffer))
{
case COGL_STEREO_BOTH:
break;
case COGL_STEREO_LEFT:
case COGL_STEREO_RIGHT:
g_warn_if_reached ();
break;
}
}
static GList * static GList *
try_creating_renderbuffers (CoglContext *ctx, try_creating_renderbuffers (CoglContext *ctx,
int width, int width,
@ -636,4 +654,6 @@ cogl_gl_framebuffer_fbo_class_init (CoglGlFramebufferFboClass *klass)
driver_class->discard_buffers = cogl_gl_framebuffer_fbo_discard_buffers; driver_class->discard_buffers = cogl_gl_framebuffer_fbo_discard_buffers;
gl_framebuffer_class->bind = cogl_gl_framebuffer_fbo_bind; gl_framebuffer_class->bind = cogl_gl_framebuffer_fbo_bind;
gl_framebuffer_class->flush_stereo_mode_state =
cogl_gl_framebuffer_fbo_flush_stereo_mode_state;
} }