1
0
mirror of https://github.com/brl/mutter.git synced 2025-06-08 14:33:59 +00:00

cogl/framebuffer: Add cogl_framebuffer_flush

In future patches, we'll create additional CoglFramebuffers that
will be shared via DMA-Buf with PipeWire. When recording frames,
we'll blit the current onscreen framebuffer into the shared one.

However, that presents a problem: cogl_framebuffer_blit() mimics
glBlitFramebuffer() semantics, and doesn't do an implicit flush
of the GPU command stream. As a consequence, clients may receive
unblitted or incomplete framebuffers.

We could use cogl_framebuffer_finish() to ensure the commands were
submitted to the GPU, but it is too harsh -- it blocks the CPU
completely until the commands are finished!

Add cogl_framebuffer_flush(), which ensures the command stream is
submitted to the GPU without blocking the CPU. Even though we don't
use the framebuffer specifically, it may be useful in the future
for e.g. a potential Vulkan backend to have access to the framebuffer.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1086
This commit is contained in:
Georges Basile Stavracas Neto 2020-02-24 12:44:52 -03:00
parent f27de9620a
commit 038a3170bf
10 changed files with 46 additions and 0 deletions

@ -93,6 +93,9 @@ struct _CoglDriverVtable
void void
(* framebuffer_finish) (CoglFramebuffer *framebuffer); (* framebuffer_finish) (CoglFramebuffer *framebuffer);
void
(* framebuffer_flush) (CoglFramebuffer *framebuffer);
void void
(* framebuffer_discard_buffers) (CoglFramebuffer *framebuffer, (* framebuffer_discard_buffers) (CoglFramebuffer *framebuffer,
unsigned long buffers); unsigned long buffers);

@ -1396,6 +1396,17 @@ cogl_framebuffer_finish (CoglFramebuffer *framebuffer)
ctx->driver_vtable->framebuffer_finish (framebuffer); ctx->driver_vtable->framebuffer_finish (framebuffer);
} }
void
cogl_framebuffer_flush (CoglFramebuffer *framebuffer)
{
CoglContext *ctx = framebuffer->context;
_cogl_framebuffer_flush_journal (framebuffer);
ctx->driver_vtable->framebuffer_flush (framebuffer);
}
void void
cogl_framebuffer_push_matrix (CoglFramebuffer *framebuffer) cogl_framebuffer_push_matrix (CoglFramebuffer *framebuffer)
{ {

@ -1555,6 +1555,18 @@ cogl_blit_framebuffer (CoglFramebuffer *src,
int height, int height,
GError **error); GError **error);
/**
* cogl_framebuffer_flush:
* @framebuffer: A #CoglFramebuffer pointer
*
* Flushes @framebuffer to ensure the current batch of commands is
* submitted to the GPU.
*
* Unlike cogl_framebuffer_finish(), this does not block the CPU.
*/
void
cogl_framebuffer_flush (CoglFramebuffer *framebuffer);
G_END_DECLS G_END_DECLS
#endif /* __COGL_FRAMEBUFFER_H */ #endif /* __COGL_FRAMEBUFFER_H */

@ -61,6 +61,9 @@ _cogl_framebuffer_gl_query_bits (CoglFramebuffer *framebuffer,
void void
_cogl_framebuffer_gl_finish (CoglFramebuffer *framebuffer); _cogl_framebuffer_gl_finish (CoglFramebuffer *framebuffer);
void
_cogl_framebuffer_gl_flush (CoglFramebuffer *framebuffer);
void void
_cogl_framebuffer_gl_discard_buffers (CoglFramebuffer *framebuffer, _cogl_framebuffer_gl_discard_buffers (CoglFramebuffer *framebuffer,
unsigned long buffers); unsigned long buffers);

@ -1031,6 +1031,12 @@ _cogl_framebuffer_gl_finish (CoglFramebuffer *framebuffer)
GE (framebuffer->context, glFinish ()); GE (framebuffer->context, glFinish ());
} }
void
_cogl_framebuffer_gl_flush (CoglFramebuffer *framebuffer)
{
GE (framebuffer->context, glFlush ());
}
void void
_cogl_framebuffer_gl_discard_buffers (CoglFramebuffer *framebuffer, _cogl_framebuffer_gl_discard_buffers (CoglFramebuffer *framebuffer,
unsigned long buffers) unsigned long buffers)

@ -554,6 +554,7 @@ _cogl_driver_gl =
_cogl_framebuffer_gl_clear, _cogl_framebuffer_gl_clear,
_cogl_framebuffer_gl_query_bits, _cogl_framebuffer_gl_query_bits,
_cogl_framebuffer_gl_finish, _cogl_framebuffer_gl_finish,
_cogl_framebuffer_gl_flush,
_cogl_framebuffer_gl_discard_buffers, _cogl_framebuffer_gl_discard_buffers,
_cogl_framebuffer_gl_draw_attributes, _cogl_framebuffer_gl_draw_attributes,
_cogl_framebuffer_gl_draw_indexed_attributes, _cogl_framebuffer_gl_draw_indexed_attributes,

@ -403,6 +403,7 @@ _cogl_driver_gles =
_cogl_framebuffer_gl_clear, _cogl_framebuffer_gl_clear,
_cogl_framebuffer_gl_query_bits, _cogl_framebuffer_gl_query_bits,
_cogl_framebuffer_gl_finish, _cogl_framebuffer_gl_finish,
_cogl_framebuffer_gl_flush,
_cogl_framebuffer_gl_discard_buffers, _cogl_framebuffer_gl_discard_buffers,
_cogl_framebuffer_gl_draw_attributes, _cogl_framebuffer_gl_draw_attributes,
_cogl_framebuffer_gl_draw_indexed_attributes, _cogl_framebuffer_gl_draw_indexed_attributes,

@ -78,6 +78,7 @@ _cogl_driver_nop =
_cogl_framebuffer_nop_clear, _cogl_framebuffer_nop_clear,
_cogl_framebuffer_nop_query_bits, _cogl_framebuffer_nop_query_bits,
_cogl_framebuffer_nop_finish, _cogl_framebuffer_nop_finish,
_cogl_framebuffer_nop_flush,
_cogl_framebuffer_nop_discard_buffers, _cogl_framebuffer_nop_discard_buffers,
_cogl_framebuffer_nop_draw_attributes, _cogl_framebuffer_nop_draw_attributes,
_cogl_framebuffer_nop_draw_indexed_attributes, _cogl_framebuffer_nop_draw_indexed_attributes,

@ -64,6 +64,9 @@ _cogl_framebuffer_nop_query_bits (CoglFramebuffer *framebuffer,
void void
_cogl_framebuffer_nop_finish (CoglFramebuffer *framebuffer); _cogl_framebuffer_nop_finish (CoglFramebuffer *framebuffer);
void
_cogl_framebuffer_nop_flush (CoglFramebuffer *framebuffer);
void void
_cogl_framebuffer_nop_discard_buffers (CoglFramebuffer *framebuffer, _cogl_framebuffer_nop_discard_buffers (CoglFramebuffer *framebuffer,
unsigned long buffers); unsigned long buffers);

@ -76,6 +76,11 @@ _cogl_framebuffer_nop_finish (CoglFramebuffer *framebuffer)
{ {
} }
void
_cogl_framebuffer_nop_flush (CoglFramebuffer *framebuffer)
{
}
void void
_cogl_framebuffer_nop_discard_buffers (CoglFramebuffer *framebuffer, _cogl_framebuffer_nop_discard_buffers (CoglFramebuffer *framebuffer,
unsigned long buffers) unsigned long buffers)