From 038a3170bf971a68f132ba6c712a63713e67201d Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto Date: Mon, 24 Feb 2020 12:44:52 -0300 Subject: [PATCH] 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 --- cogl/cogl/cogl-driver.h | 3 +++ cogl/cogl/cogl-framebuffer.c | 11 +++++++++++ cogl/cogl/cogl-framebuffer.h | 12 ++++++++++++ cogl/cogl/driver/gl/cogl-framebuffer-gl-private.h | 3 +++ cogl/cogl/driver/gl/cogl-framebuffer-gl.c | 6 ++++++ cogl/cogl/driver/gl/gl/cogl-driver-gl.c | 1 + cogl/cogl/driver/gl/gles/cogl-driver-gles.c | 1 + cogl/cogl/driver/nop/cogl-driver-nop.c | 1 + cogl/cogl/driver/nop/cogl-framebuffer-nop-private.h | 3 +++ cogl/cogl/driver/nop/cogl-framebuffer-nop.c | 5 +++++ 10 files changed, 46 insertions(+) diff --git a/cogl/cogl/cogl-driver.h b/cogl/cogl/cogl-driver.h index f9b779fa7..9d0bc1b99 100644 --- a/cogl/cogl/cogl-driver.h +++ b/cogl/cogl/cogl-driver.h @@ -93,6 +93,9 @@ struct _CoglDriverVtable void (* framebuffer_finish) (CoglFramebuffer *framebuffer); + void + (* framebuffer_flush) (CoglFramebuffer *framebuffer); + void (* framebuffer_discard_buffers) (CoglFramebuffer *framebuffer, unsigned long buffers); diff --git a/cogl/cogl/cogl-framebuffer.c b/cogl/cogl/cogl-framebuffer.c index d10ae5cc5..6edb7f042 100644 --- a/cogl/cogl/cogl-framebuffer.c +++ b/cogl/cogl/cogl-framebuffer.c @@ -1396,6 +1396,17 @@ cogl_framebuffer_finish (CoglFramebuffer *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 cogl_framebuffer_push_matrix (CoglFramebuffer *framebuffer) { diff --git a/cogl/cogl/cogl-framebuffer.h b/cogl/cogl/cogl-framebuffer.h index 2046d459d..eef5089b0 100644 --- a/cogl/cogl/cogl-framebuffer.h +++ b/cogl/cogl/cogl-framebuffer.h @@ -1555,6 +1555,18 @@ cogl_blit_framebuffer (CoglFramebuffer *src, int height, 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 #endif /* __COGL_FRAMEBUFFER_H */ diff --git a/cogl/cogl/driver/gl/cogl-framebuffer-gl-private.h b/cogl/cogl/driver/gl/cogl-framebuffer-gl-private.h index 57c146b39..3e9333a24 100644 --- a/cogl/cogl/driver/gl/cogl-framebuffer-gl-private.h +++ b/cogl/cogl/driver/gl/cogl-framebuffer-gl-private.h @@ -61,6 +61,9 @@ _cogl_framebuffer_gl_query_bits (CoglFramebuffer *framebuffer, void _cogl_framebuffer_gl_finish (CoglFramebuffer *framebuffer); +void +_cogl_framebuffer_gl_flush (CoglFramebuffer *framebuffer); + void _cogl_framebuffer_gl_discard_buffers (CoglFramebuffer *framebuffer, unsigned long buffers); diff --git a/cogl/cogl/driver/gl/cogl-framebuffer-gl.c b/cogl/cogl/driver/gl/cogl-framebuffer-gl.c index 4eb914052..2848d7183 100644 --- a/cogl/cogl/driver/gl/cogl-framebuffer-gl.c +++ b/cogl/cogl/driver/gl/cogl-framebuffer-gl.c @@ -1031,6 +1031,12 @@ _cogl_framebuffer_gl_finish (CoglFramebuffer *framebuffer) GE (framebuffer->context, glFinish ()); } +void +_cogl_framebuffer_gl_flush (CoglFramebuffer *framebuffer) +{ + GE (framebuffer->context, glFlush ()); +} + void _cogl_framebuffer_gl_discard_buffers (CoglFramebuffer *framebuffer, unsigned long buffers) diff --git a/cogl/cogl/driver/gl/gl/cogl-driver-gl.c b/cogl/cogl/driver/gl/gl/cogl-driver-gl.c index 8b3ff64e2..f1b748118 100644 --- a/cogl/cogl/driver/gl/gl/cogl-driver-gl.c +++ b/cogl/cogl/driver/gl/gl/cogl-driver-gl.c @@ -554,6 +554,7 @@ _cogl_driver_gl = _cogl_framebuffer_gl_clear, _cogl_framebuffer_gl_query_bits, _cogl_framebuffer_gl_finish, + _cogl_framebuffer_gl_flush, _cogl_framebuffer_gl_discard_buffers, _cogl_framebuffer_gl_draw_attributes, _cogl_framebuffer_gl_draw_indexed_attributes, diff --git a/cogl/cogl/driver/gl/gles/cogl-driver-gles.c b/cogl/cogl/driver/gl/gles/cogl-driver-gles.c index 2f98b3bd8..e0c8ca1fa 100644 --- a/cogl/cogl/driver/gl/gles/cogl-driver-gles.c +++ b/cogl/cogl/driver/gl/gles/cogl-driver-gles.c @@ -403,6 +403,7 @@ _cogl_driver_gles = _cogl_framebuffer_gl_clear, _cogl_framebuffer_gl_query_bits, _cogl_framebuffer_gl_finish, + _cogl_framebuffer_gl_flush, _cogl_framebuffer_gl_discard_buffers, _cogl_framebuffer_gl_draw_attributes, _cogl_framebuffer_gl_draw_indexed_attributes, diff --git a/cogl/cogl/driver/nop/cogl-driver-nop.c b/cogl/cogl/driver/nop/cogl-driver-nop.c index 4fffd3686..7802803e2 100644 --- a/cogl/cogl/driver/nop/cogl-driver-nop.c +++ b/cogl/cogl/driver/nop/cogl-driver-nop.c @@ -78,6 +78,7 @@ _cogl_driver_nop = _cogl_framebuffer_nop_clear, _cogl_framebuffer_nop_query_bits, _cogl_framebuffer_nop_finish, + _cogl_framebuffer_nop_flush, _cogl_framebuffer_nop_discard_buffers, _cogl_framebuffer_nop_draw_attributes, _cogl_framebuffer_nop_draw_indexed_attributes, diff --git a/cogl/cogl/driver/nop/cogl-framebuffer-nop-private.h b/cogl/cogl/driver/nop/cogl-framebuffer-nop-private.h index c04da9d6a..95b636517 100644 --- a/cogl/cogl/driver/nop/cogl-framebuffer-nop-private.h +++ b/cogl/cogl/driver/nop/cogl-framebuffer-nop-private.h @@ -64,6 +64,9 @@ _cogl_framebuffer_nop_query_bits (CoglFramebuffer *framebuffer, void _cogl_framebuffer_nop_finish (CoglFramebuffer *framebuffer); +void +_cogl_framebuffer_nop_flush (CoglFramebuffer *framebuffer); + void _cogl_framebuffer_nop_discard_buffers (CoglFramebuffer *framebuffer, unsigned long buffers); diff --git a/cogl/cogl/driver/nop/cogl-framebuffer-nop.c b/cogl/cogl/driver/nop/cogl-framebuffer-nop.c index f94bab641..f9db69c91 100644 --- a/cogl/cogl/driver/nop/cogl-framebuffer-nop.c +++ b/cogl/cogl/driver/nop/cogl-framebuffer-nop.c @@ -76,6 +76,11 @@ _cogl_framebuffer_nop_finish (CoglFramebuffer *framebuffer) { } +void +_cogl_framebuffer_nop_flush (CoglFramebuffer *framebuffer) +{ +} + void _cogl_framebuffer_nop_discard_buffers (CoglFramebuffer *framebuffer, unsigned long buffers)