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
|
void
|
||||||
_cogl_context_set_current_modelview_entry (CoglContext *context,
|
_cogl_context_set_current_modelview_entry (CoglContext *context,
|
||||||
CoglMatrixEntry *entry);
|
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;
|
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
|
CoglGraphicsResetStatus
|
||||||
cogl_get_graphics_reset_status (CoglContext *context)
|
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_EXPORT int64_t
|
||||||
cogl_context_get_gpu_time_ns (CoglContext *context);
|
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
|
G_END_DECLS
|
||||||
|
|
|
@ -309,6 +309,9 @@ cogl_onscreen_egl_swap_buffers_with_damage (CoglOnscreen *onscreen,
|
||||||
COGL_FRAMEBUFFER (onscreen),
|
COGL_FRAMEBUFFER (onscreen),
|
||||||
COGL_FRAMEBUFFER_STATE_BIND);
|
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))
|
if (cogl_has_feature (context, COGL_FEATURE_ID_TIMESTAMP_QUERY))
|
||||||
{
|
{
|
||||||
info->gpu_time_before_buffer_swap_ns =
|
info->gpu_time_before_buffer_swap_ns =
|
||||||
|
|
|
@ -162,6 +162,15 @@ COGL_WINSYS_FEATURE_FUNCTION (EGLBoolean, eglDestroySync,
|
||||||
(EGLDisplay dpy,
|
(EGLDisplay dpy,
|
||||||
EGLSyncKHR sync))
|
EGLSyncKHR sync))
|
||||||
COGL_WINSYS_FEATURE_END ()
|
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
|
#endif
|
||||||
|
|
||||||
COGL_WINSYS_FEATURE_BEGIN (surfaceless_context,
|
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_SURFACELESS_CONTEXT = 1L << 6,
|
||||||
COGL_EGL_WINSYS_FEATURE_CONTEXT_PRIORITY = 1L << 7,
|
COGL_EGL_WINSYS_FEATURE_CONTEXT_PRIORITY = 1L << 7,
|
||||||
COGL_EGL_WINSYS_FEATURE_NO_CONFIG_CONTEXT = 1L << 8,
|
COGL_EGL_WINSYS_FEATURE_NO_CONFIG_CONTEXT = 1L << 8,
|
||||||
|
COGL_EGL_WINSYS_FEATURE_NATIVE_FENCE_SYNC = 1L << 9,
|
||||||
} CoglEGLWinsysFeature;
|
} CoglEGLWinsysFeature;
|
||||||
|
|
||||||
typedef struct _CoglRendererEGL
|
typedef struct _CoglRendererEGL
|
||||||
|
@ -119,6 +120,9 @@ typedef struct _CoglRendererEGL
|
||||||
/* vtable for platform specific parts */
|
/* vtable for platform specific parts */
|
||||||
const CoglWinsysEGLVtable *platform_vtable;
|
const CoglWinsysEGLVtable *platform_vtable;
|
||||||
|
|
||||||
|
/* Sync for latest submitted work */
|
||||||
|
EGLSyncKHR sync;
|
||||||
|
|
||||||
/* Function pointers for EGL specific extensions */
|
/* Function pointers for EGL specific extensions */
|
||||||
#define COGL_WINSYS_FEATURE_BEGIN(a, b, c, d)
|
#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);
|
xlib_renderer = _cogl_xlib_renderer_get_data (renderer);
|
||||||
|
|
||||||
egl_renderer->platform_vtable = &_cogl_winsys_egl_vtable;
|
egl_renderer->platform_vtable = &_cogl_winsys_egl_vtable;
|
||||||
|
egl_renderer->sync = EGL_NO_SYNC_KHR;
|
||||||
|
|
||||||
if (!_cogl_xlib_renderer_connect (renderer, error))
|
if (!_cogl_xlib_renderer_connect (renderer, error))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
|
@ -441,6 +441,9 @@ _cogl_winsys_display_destroy (CoglDisplay *display)
|
||||||
|
|
||||||
g_return_if_fail (egl_display != NULL);
|
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);
|
cleanup_context (display);
|
||||||
|
|
||||||
if (egl_renderer->platform_vtable->display_destroy)
|
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);
|
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
|
#endif
|
||||||
|
|
||||||
static CoglWinsysVtable _cogl_winsys_vtable =
|
static CoglWinsysVtable _cogl_winsys_vtable =
|
||||||
|
@ -595,6 +629,8 @@ static CoglWinsysVtable _cogl_winsys_vtable =
|
||||||
.fence_add = _cogl_winsys_fence_add,
|
.fence_add = _cogl_winsys_fence_add,
|
||||||
.fence_is_complete = _cogl_winsys_fence_is_complete,
|
.fence_is_complete = _cogl_winsys_fence_is_complete,
|
||||||
.fence_destroy = _cogl_winsys_fence_destroy,
|
.fence_destroy = _cogl_winsys_fence_destroy,
|
||||||
|
.get_sync_fd = _cogl_winsys_get_sync_fd,
|
||||||
|
.update_sync = _cogl_winsys_update_sync,
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -141,6 +141,12 @@ typedef struct _CoglWinsysVtable
|
||||||
(*fence_destroy) (CoglContext *ctx,
|
(*fence_destroy) (CoglContext *ctx,
|
||||||
void *fence);
|
void *fence);
|
||||||
|
|
||||||
|
void
|
||||||
|
(*update_sync) (CoglContext *ctx);
|
||||||
|
|
||||||
|
int
|
||||||
|
(*get_sync_fd) (CoglContext *ctx);
|
||||||
|
|
||||||
} CoglWinsysVtable;
|
} CoglWinsysVtable;
|
||||||
|
|
||||||
typedef const CoglWinsysVtable *(*CoglWinsysVtableGetter) (void);
|
typedef const CoglWinsysVtable *(*CoglWinsysVtableGetter) (void);
|
||||||
|
|
Loading…
Reference in a new issue