vrend: add support for exporting egl fences

Acked-by: Gert Wollny <gert.wollny@collabora.com>
macos/master
David Stevens 4 years ago committed by Gurchetan Singh
parent 16f8d896d0
commit 313f1cc887
  1. 6
      src/virglrenderer.c
  2. 3
      src/virglrenderer.h
  3. 52
      src/vrend_renderer.c
  4. 2
      src/vrend_renderer.h
  5. 23
      src/vrend_winsys_egl.c
  6. 2
      src/vrend_winsys_egl.h

@ -763,3 +763,9 @@ virgl_renderer_resource_export_blob(uint32_t res_id, uint32_t *fd_type, int *fd)
return 0; return 0;
} }
int
virgl_renderer_export_fence(uint32_t client_fence_id, uint32_t *fd)
{
return vrend_renderer_export_fence(client_fence_id, fd);
}

@ -297,6 +297,9 @@ VIRGL_EXPORT int virgl_renderer_resource_get_map_info(uint32_t res_handle, uint3
VIRGL_EXPORT int VIRGL_EXPORT int
virgl_renderer_resource_export_blob(uint32_t res_id, uint32_t *fd_type, int *fd); virgl_renderer_resource_export_blob(uint32_t res_id, uint32_t *fd_type, int *fd);
VIRGL_EXPORT int
virgl_renderer_export_fence(uint32_t client_fence_id, uint32_t *fd);
#endif /* VIRGL_RENDERER_UNSTABLE_APIS */ #endif /* VIRGL_RENDERER_UNSTABLE_APIS */
#endif #endif

@ -10645,3 +10645,55 @@ int vrend_renderer_resource_unmap(struct pipe_resource *pres)
glBindBufferARB(res->target, 0); glBindBufferARB(res->target, 0);
return 0; return 0;
} }
int vrend_renderer_export_fence(uint32_t fence_id, int* out_fd) {
#ifdef HAVE_EPOXY_EGL_H
if (!vrend_state.use_egl_fence) {
return -EINVAL;
}
if (vrend_state.sync_thread)
pipe_mutex_lock(vrend_state.fence_mutex);
struct vrend_fence *fence = NULL;
struct vrend_fence *iter;
uint32_t min_fence_id = UINT_MAX;
if (!LIST_IS_EMPTY(&vrend_state.fence_list)) {
min_fence_id = LIST_ENTRY(struct vrend_fence, vrend_state.fence_list.next, fences)->fence_id;
} else if (!LIST_IS_EMPTY(&vrend_state.fence_wait_list)) {
min_fence_id =
LIST_ENTRY(struct vrend_fence, vrend_state.fence_wait_list.next, fences)->fence_id;
}
if (fence_id < min_fence_id) {
if (vrend_state.sync_thread)
pipe_mutex_unlock(vrend_state.fence_mutex);
return virgl_egl_export_signaled_fence(egl, out_fd) ? 0 : -EINVAL;
}
LIST_FOR_EACH_ENTRY(iter, &vrend_state.fence_list, fences) {
if (iter->fence_id == fence_id) {
fence = iter;
break;
}
}
if (!fence) {
LIST_FOR_EACH_ENTRY(iter, &vrend_state.fence_wait_list, fences) {
if (iter->fence_id == fence_id) {
fence = iter;
break;
}
}
}
if (vrend_state.sync_thread)
pipe_mutex_unlock(vrend_state.fence_mutex);
if (fence && virgl_egl_export_fence(egl, fence->eglsyncobj, out_fd)) {
return 0;
}
#endif
return -EINVAL;
}

@ -347,6 +347,8 @@ int vrend_renderer_create_fence(int client_fence_id, uint32_t ctx_id);
void vrend_renderer_check_fences(void); void vrend_renderer_check_fences(void);
int vrend_renderer_export_fence(uint32_t fence_id, int* out_fd);
bool vrend_hw_switch_context(struct vrend_context *ctx, bool now); bool vrend_hw_switch_context(struct vrend_context *ctx, bool now);
uint32_t vrend_renderer_object_insert(struct vrend_context *ctx, void *data, uint32_t vrend_renderer_object_insert(struct vrend_context *ctx, void *data,
uint32_t handle, enum virgl_object_type type); uint32_t handle, enum virgl_object_type type);

@ -74,6 +74,7 @@ struct virgl_egl {
EGLConfig egl_conf; EGLConfig egl_conf;
EGLContext egl_ctx; EGLContext egl_ctx;
uint32_t extension_bits; uint32_t extension_bits;
EGLSyncKHR signaled_fence;
}; };
static bool virgl_egl_has_extension_in_string(const char *haystack, const char *needle) static bool virgl_egl_has_extension_in_string(const char *haystack, const char *needle)
@ -236,6 +237,16 @@ struct virgl_egl *virgl_egl_init(struct virgl_gbm *gbm, bool surfaceless, bool g
eglMakeCurrent(egl->egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, eglMakeCurrent(egl->egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE,
egl->egl_ctx); egl->egl_ctx);
if (virgl_egl_supports_fences(egl)) {
egl->signaled_fence = eglCreateSyncKHR(egl->egl_display,
EGL_SYNC_NATIVE_FENCE_ANDROID, NULL);
if (!egl->signaled_fence) {
vrend_printf("Failed to create signaled fence");
goto fail;
}
}
return egl; return egl;
fail: fail:
@ -245,6 +256,9 @@ struct virgl_egl *virgl_egl_init(struct virgl_gbm *gbm, bool surfaceless, bool g
void virgl_egl_destroy(struct virgl_egl *egl) void virgl_egl_destroy(struct virgl_egl *egl)
{ {
if (egl->signaled_fence) {
eglDestroySyncKHR(egl->egl_display, egl->signaled_fence);
}
eglMakeCurrent(egl->egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, eglMakeCurrent(egl->egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE,
EGL_NO_CONTEXT); EGL_NO_CONTEXT);
eglDestroyContext(egl->egl_display, egl->egl_ctx); eglDestroyContext(egl->egl_display, egl->egl_ctx);
@ -533,3 +547,12 @@ bool virgl_egl_client_wait_fence(struct virgl_egl *egl, EGLSyncKHR fence, uint64
} }
return ret != EGL_TIMEOUT_EXPIRED_KHR; return ret != EGL_TIMEOUT_EXPIRED_KHR;
} }
bool virgl_egl_export_signaled_fence(struct virgl_egl *egl, int *out_fd) {
return virgl_egl_export_fence(egl, egl->signaled_fence, out_fd);
}
bool virgl_egl_export_fence(struct virgl_egl *egl, EGLSyncKHR fence, int *out_fd) {
*out_fd = eglDupNativeFenceFDANDROID(egl->egl_display, fence);
return *out_fd != EGL_NO_NATIVE_FENCE_FD_ANDROID;
}

@ -64,4 +64,6 @@ bool virgl_egl_supports_fences(struct virgl_egl *egl);
EGLSyncKHR virgl_egl_fence_create(struct virgl_egl *egl); EGLSyncKHR virgl_egl_fence_create(struct virgl_egl *egl);
void virgl_egl_fence_destroy(struct virgl_egl *egl, EGLSyncKHR fence); void virgl_egl_fence_destroy(struct virgl_egl *egl, EGLSyncKHR fence);
bool virgl_egl_client_wait_fence(struct virgl_egl *egl, EGLSyncKHR fence, uint64_t timeout); bool virgl_egl_client_wait_fence(struct virgl_egl *egl, EGLSyncKHR fence, uint64_t timeout);
bool virgl_egl_export_signaled_fence(struct virgl_egl *egl, int *out_fd);
bool virgl_egl_export_fence(struct virgl_egl *egl, EGLSyncKHR fence, int *out_fd);
#endif #endif

Loading…
Cancel
Save