cogl: Store latest GPU work completed sync fd
This keeps an internal sync_fd for the latest work submitted to the GPU. This can then be fetched with cogl_context_get_latest_sync_fd for use. This is intended for use with linux-drm-syncobj-v1 Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3300>
This commit is contained in:
parent
3f5bf42ab6
commit
99209958b9
9 changed files with 98 additions and 0 deletions
|
@ -311,3 +311,6 @@ _cogl_context_set_current_projection_entry (CoglContext *context,
|
|||
void
|
||||
_cogl_context_set_current_modelview_entry (CoglContext *context,
|
||||
CoglMatrixEntry *entry);
|
||||
|
||||
void
|
||||
_cogl_context_update_sync (CoglContext *context);
|
||||
|
|
|
@ -463,6 +463,28 @@ _cogl_context_set_current_modelview_entry (CoglContext *context,
|
|||
context->current_modelview_entry = entry;
|
||||
}
|
||||
|
||||
void
|
||||
_cogl_context_update_sync (CoglContext *context)
|
||||
{
|
||||
const CoglWinsysVtable *winsys = _cogl_context_get_winsys (context);
|
||||
|
||||
if (!winsys->update_sync)
|
||||
return;
|
||||
|
||||
winsys->update_sync (context);
|
||||
}
|
||||
|
||||
int
|
||||
cogl_context_get_latest_sync_fd (CoglContext *context)
|
||||
{
|
||||
const CoglWinsysVtable *winsys = _cogl_context_get_winsys (context);
|
||||
|
||||
if (!winsys->get_sync_fd)
|
||||
return -1;
|
||||
|
||||
return winsys->get_sync_fd (context);
|
||||
}
|
||||
|
||||
CoglGraphicsResetStatus
|
||||
cogl_get_graphics_reset_status (CoglContext *context)
|
||||
{
|
||||
|
|
|
@ -367,4 +367,18 @@ cogl_context_timestamp_query_get_time_ns (CoglContext *context,
|
|||
COGL_EXPORT int64_t
|
||||
cogl_context_get_gpu_time_ns (CoglContext *context);
|
||||
|
||||
/**
|
||||
* cogl_context_get_latest_sync_fd
|
||||
* @context: a #CoglContext pointer
|
||||
*
|
||||
* This function is used to get support for waiting on previous
|
||||
* GPU work through sync fds. It will return a sync fd which will
|
||||
* signal when the previous work has completed.
|
||||
*
|
||||
* Return value: sync fd for latest GPU submission if available,
|
||||
* returns -1 if not.
|
||||
*/
|
||||
COGL_EXPORT int
|
||||
cogl_context_get_latest_sync_fd (CoglContext *context);
|
||||
|
||||
G_END_DECLS
|
||||
|
|
|
@ -309,6 +309,9 @@ cogl_onscreen_egl_swap_buffers_with_damage (CoglOnscreen *onscreen,
|
|||
COGL_FRAMEBUFFER (onscreen),
|
||||
COGL_FRAMEBUFFER_STATE_BIND);
|
||||
|
||||
/* Update our "latest" sync fd to contain all previous work */
|
||||
_cogl_context_update_sync (context);
|
||||
|
||||
if (cogl_has_feature (context, COGL_FEATURE_ID_TIMESTAMP_QUERY))
|
||||
{
|
||||
info->gpu_time_before_buffer_swap_ns =
|
||||
|
|
|
@ -162,6 +162,15 @@ COGL_WINSYS_FEATURE_FUNCTION (EGLBoolean, eglDestroySync,
|
|||
(EGLDisplay dpy,
|
||||
EGLSyncKHR sync))
|
||||
COGL_WINSYS_FEATURE_END ()
|
||||
|
||||
COGL_WINSYS_FEATURE_BEGIN (native_fence_sync,
|
||||
"ANDROID\0",
|
||||
"native_fence_sync\0",
|
||||
COGL_EGL_WINSYS_FEATURE_NATIVE_FENCE_SYNC)
|
||||
COGL_WINSYS_FEATURE_FUNCTION (EGLint, eglDupNativeFenceFD,
|
||||
(EGLDisplay dpy,
|
||||
EGLSyncKHR sync))
|
||||
COGL_WINSYS_FEATURE_END ()
|
||||
#endif
|
||||
|
||||
COGL_WINSYS_FEATURE_BEGIN (surfaceless_context,
|
||||
|
|
|
@ -101,6 +101,7 @@ typedef enum _CoglEGLWinsysFeature
|
|||
COGL_EGL_WINSYS_FEATURE_SURFACELESS_CONTEXT = 1L << 6,
|
||||
COGL_EGL_WINSYS_FEATURE_CONTEXT_PRIORITY = 1L << 7,
|
||||
COGL_EGL_WINSYS_FEATURE_NO_CONFIG_CONTEXT = 1L << 8,
|
||||
COGL_EGL_WINSYS_FEATURE_NATIVE_FENCE_SYNC = 1L << 9,
|
||||
} CoglEGLWinsysFeature;
|
||||
|
||||
typedef struct _CoglRendererEGL
|
||||
|
@ -119,6 +120,9 @@ typedef struct _CoglRendererEGL
|
|||
/* vtable for platform specific parts */
|
||||
const CoglWinsysEGLVtable *platform_vtable;
|
||||
|
||||
/* Sync for latest submitted work */
|
||||
EGLSyncKHR sync;
|
||||
|
||||
/* Function pointers for EGL specific extensions */
|
||||
#define COGL_WINSYS_FEATURE_BEGIN(a, b, c, d)
|
||||
|
||||
|
|
|
@ -243,6 +243,7 @@ _cogl_winsys_renderer_connect (CoglRenderer *renderer,
|
|||
xlib_renderer = _cogl_xlib_renderer_get_data (renderer);
|
||||
|
||||
egl_renderer->platform_vtable = &_cogl_winsys_egl_vtable;
|
||||
egl_renderer->sync = EGL_NO_SYNC_KHR;
|
||||
|
||||
if (!_cogl_xlib_renderer_connect (renderer, error))
|
||||
goto error;
|
||||
|
|
|
@ -441,6 +441,9 @@ _cogl_winsys_display_destroy (CoglDisplay *display)
|
|||
|
||||
g_return_if_fail (egl_display != NULL);
|
||||
|
||||
if (egl_renderer->sync != EGL_NO_SYNC_KHR)
|
||||
egl_renderer->pf_eglDestroySync (egl_renderer->edpy, egl_renderer->sync);
|
||||
|
||||
cleanup_context (display);
|
||||
|
||||
if (egl_renderer->platform_vtable->display_destroy)
|
||||
|
@ -573,6 +576,37 @@ _cogl_winsys_fence_destroy (CoglContext *context, void *fence)
|
|||
|
||||
renderer->pf_eglDestroySync (renderer->edpy, fence);
|
||||
}
|
||||
|
||||
static int
|
||||
_cogl_winsys_get_sync_fd (CoglContext *context)
|
||||
{
|
||||
CoglRendererEGL *renderer = context->display->renderer->winsys;
|
||||
int fd;
|
||||
|
||||
if (!renderer->pf_eglDupNativeFenceFD)
|
||||
return -1;
|
||||
|
||||
fd = renderer->pf_eglDupNativeFenceFD (renderer->edpy, renderer->sync);
|
||||
if (fd == EGL_NO_NATIVE_FENCE_FD_ANDROID)
|
||||
return -1;
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
static void
|
||||
_cogl_winsys_update_sync (CoglContext *context)
|
||||
{
|
||||
CoglRendererEGL *renderer = context->display->renderer->winsys;
|
||||
|
||||
if (!renderer->pf_eglDestroySync || !renderer->pf_eglCreateSync)
|
||||
return;
|
||||
|
||||
if (renderer->sync != EGL_NO_SYNC_KHR)
|
||||
renderer->pf_eglDestroySync (renderer->edpy, renderer->sync);
|
||||
|
||||
renderer->sync = renderer->pf_eglCreateSync (renderer->edpy,
|
||||
EGL_SYNC_NATIVE_FENCE_ANDROID, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
static CoglWinsysVtable _cogl_winsys_vtable =
|
||||
|
@ -595,6 +629,8 @@ static CoglWinsysVtable _cogl_winsys_vtable =
|
|||
.fence_add = _cogl_winsys_fence_add,
|
||||
.fence_is_complete = _cogl_winsys_fence_is_complete,
|
||||
.fence_destroy = _cogl_winsys_fence_destroy,
|
||||
.get_sync_fd = _cogl_winsys_get_sync_fd,
|
||||
.update_sync = _cogl_winsys_update_sync,
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
|
@ -141,6 +141,12 @@ typedef struct _CoglWinsysVtable
|
|||
(*fence_destroy) (CoglContext *ctx,
|
||||
void *fence);
|
||||
|
||||
void
|
||||
(*update_sync) (CoglContext *ctx);
|
||||
|
||||
int
|
||||
(*get_sync_fd) (CoglContext *ctx);
|
||||
|
||||
} CoglWinsysVtable;
|
||||
|
||||
typedef const CoglWinsysVtable *(*CoglWinsysVtableGetter) (void);
|
||||
|
|
Loading…
Reference in a new issue