egl: Allow creation of per surface out fence

Add plumbing to allow creation of per display surface out fence.

This can be used to implement explicit sync. One user of which is
Android - which will be addressed with next commit.

Signed-off-by: Zhongmin Wu <zhongmin.wu@intel.com>
Signed-off-by: Yogesh Marathe <yogesh.marathe@intel.com>
Reviewed-by: Emil Velikov <emil.velikov@collabora.com>
Reviewed-by: Tomasz Figa <tfiga@chromium.org>
[Emil Velikov: reorder so there's no intermetent regressions, split]
Signed-off-by: Emil Velikov <emil.velikov@collabora.com>
This commit is contained in:
Zhongmin Wu 2017-09-15 18:32:42 +01:00 committed by Emil Velikov
parent 0b3fc8f305
commit e013ce8d0d
8 changed files with 93 additions and 6 deletions

View File

@ -1388,6 +1388,45 @@ dri2_destroy_context(_EGLDriver *drv, _EGLDisplay *disp, _EGLContext *ctx)
return EGL_TRUE;
}
EGLBoolean
dri2_init_surface(_EGLSurface *surf, _EGLDisplay *dpy, EGLint type,
_EGLConfig *conf, const EGLint *attrib_list, EGLBoolean enable_out_fence)
{
struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf);
struct dri2_egl_display *dri2_dpy = dri2_egl_display(dpy);
dri2_surf->out_fence_fd = -1;
dri2_surf->enable_out_fence = false;
if (dri2_dpy->fence && dri2_dpy->fence->base.version >= 2 &&
dri2_dpy->fence->get_capabilities &&
(dri2_dpy->fence->get_capabilities(dri2_dpy->dri_screen) &
__DRI_FENCE_CAP_NATIVE_FD)) {
dri2_surf->enable_out_fence = enable_out_fence;
}
return _eglInitSurface(surf, dpy, type, conf, attrib_list);
}
static void
dri2_surface_set_out_fence_fd( _EGLSurface *surf, int fence_fd)
{
struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf);
if (dri2_surf->out_fence_fd >= 0)
close(dri2_surf->out_fence_fd);
dri2_surf->out_fence_fd = fence_fd;
}
void
dri2_fini_surface(_EGLSurface *surf)
{
struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf);
dri2_surface_set_out_fence_fd(surf, -1);
dri2_surf->enable_out_fence = false;
}
static EGLBoolean
dri2_destroy_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf)
{
@ -1399,6 +1438,28 @@ dri2_destroy_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf)
return dri2_dpy->vtbl->destroy_surface(drv, dpy, surf);
}
static void
dri2_surf_update_fence_fd(_EGLContext *ctx,
_EGLDisplay *dpy, _EGLSurface *surf)
{
__DRIcontext *dri_ctx = dri2_egl_context(ctx)->dri_context;
struct dri2_egl_display *dri2_dpy = dri2_egl_display(dpy);
struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf);
int fence_fd = -1;
void *fence;
if (!dri2_surf->enable_out_fence)
return;
fence = dri2_dpy->fence->create_fence_fd(dri_ctx, -1);
if (fence) {
fence_fd = dri2_dpy->fence->get_fence_fd(dri2_dpy->dri_screen,
fence);
dri2_dpy->fence->destroy_fence(dri2_dpy->dri_screen, fence);
}
dri2_surface_set_out_fence_fd(surf, fence_fd);
}
/**
* Called via eglMakeCurrent(), drv->API.MakeCurrent().
*/
@ -1435,6 +1496,9 @@ dri2_make_current(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *dsurf,
if (old_ctx) {
__DRIcontext *old_cctx = dri2_egl_context(old_ctx)->dri_context;
if (old_dsurf)
dri2_surf_update_fence_fd(old_ctx, disp, old_dsurf);
dri2_dpy->core->unbindContext(old_cctx);
}
@ -1573,6 +1637,10 @@ static EGLBoolean
dri2_swap_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf)
{
struct dri2_egl_display *dri2_dpy = dri2_egl_display(dpy);
_EGLContext *ctx = _eglGetCurrentContext();
if (ctx && surf)
dri2_surf_update_fence_fd(ctx, dpy, surf);
return dri2_dpy->vtbl->swap_buffers(drv, dpy, surf);
}
@ -1582,6 +1650,10 @@ dri2_swap_buffers_with_damage(_EGLDriver *drv, _EGLDisplay *dpy,
const EGLint *rects, EGLint n_rects)
{
struct dri2_egl_display *dri2_dpy = dri2_egl_display(dpy);
_EGLContext *ctx = _eglGetCurrentContext();
if (ctx && surf)
dri2_surf_update_fence_fd(ctx, dpy, surf);
return dri2_dpy->vtbl->swap_buffers_with_damage(drv, dpy, surf,
rects, n_rects);
}

View File

@ -327,6 +327,8 @@ struct dri2_egl_surface
__DRIimage *front;
unsigned int visual;
#endif
int out_fence_fd;
EGLBoolean enable_out_fence;
};
struct dri2_egl_config
@ -462,4 +464,11 @@ dri2_egl_surface_alloc_local_buffer(struct dri2_egl_surface *dri2_surf,
void
dri2_egl_surface_free_local_buffers(struct dri2_egl_surface *dri2_surf);
EGLBoolean
dri2_init_surface(_EGLSurface *surf, _EGLDisplay *dpy, EGLint type,
_EGLConfig *conf, const EGLint *attrib_list, EGLBoolean enable_out_fence);
void
dri2_fini_surface(_EGLSurface *surf);
#endif /* EGL_DRI2_INCLUDED */

View File

@ -289,7 +289,7 @@ droid_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type,
return NULL;
}
if (!_eglInitSurface(&dri2_surf->base, disp, type, conf, attrib_list))
if (!dri2_init_surface(&dri2_surf->base, disp, type, conf, attrib_list, false))
goto cleanup_surface;
if (type == EGL_WINDOW_BIT) {
@ -389,6 +389,7 @@ droid_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf)
dri2_dpy->core->destroyDrawable(dri2_surf->dri_drawable);
dri2_fini_surface(surf);
free(dri2_surf);
return EGL_TRUE;

View File

@ -110,7 +110,7 @@ dri2_drm_create_window_surface(_EGLDriver *drv, _EGLDisplay *disp,
return NULL;
}
if (!_eglInitSurface(&dri2_surf->base, disp, EGL_WINDOW_BIT, conf, attrib_list))
if (!dri2_init_surface(&dri2_surf->base, disp, EGL_WINDOW_BIT, conf, attrib_list, false))
goto cleanup_surf;
surf = gbm_dri_surface(surface);
@ -178,6 +178,7 @@ dri2_drm_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf)
dri2_egl_surface_free_local_buffers(dri2_surf);
dri2_fini_surface(surf);
free(surf);
return EGL_TRUE;

View File

@ -124,7 +124,7 @@ dri2_surfaceless_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type,
return NULL;
}
if (!_eglInitSurface(&dri2_surf->base, disp, type, conf, attrib_list))
if (!dri2_init_surface(&dri2_surf->base, disp, type, conf, attrib_list, false))
goto cleanup_surface;
config = dri2_get_dri_config(dri2_conf, type,
@ -165,6 +165,7 @@ surfaceless_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *sur
dri2_dpy->core->destroyDrawable(dri2_surf->dri_drawable);
dri2_fini_surface(surf);
free(dri2_surf);
return EGL_TRUE;
}

View File

@ -143,7 +143,7 @@ dri2_wl_create_window_surface(_EGLDriver *drv, _EGLDisplay *disp,
return NULL;
}
if (!_eglInitSurface(&dri2_surf->base, disp, EGL_WINDOW_BIT, conf, attrib_list))
if (!dri2_init_surface(&dri2_surf->base, disp, EGL_WINDOW_BIT, conf, attrib_list, false))
goto cleanup_surf;
if (dri2_dpy->wl_dmabuf || dri2_dpy->wl_drm) {
@ -296,6 +296,7 @@ dri2_wl_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf)
wl_proxy_wrapper_destroy(dri2_surf->wl_drm_wrapper);
wl_event_queue_destroy(dri2_surf->wl_queue);
dri2_fini_surface(surf);
free(surf);
return EGL_TRUE;

View File

@ -233,7 +233,7 @@ dri2_x11_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type,
return NULL;
}
if (!_eglInitSurface(&dri2_surf->base, disp, type, conf, attrib_list))
if (!dri2_init_surface(&dri2_surf->base, disp, type, conf, attrib_list, false))
goto cleanup_surf;
dri2_surf->region = XCB_NONE;
@ -395,6 +395,7 @@ dri2_x11_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf)
if (surf->Type == EGL_PBUFFER_BIT)
xcb_free_pixmap (dri2_dpy->conn, dri2_surf->drawable);
dri2_fini_surface(surf);
free(surf);
return EGL_TRUE;

View File

@ -101,6 +101,7 @@ dri3_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf)
loader_dri3_drawable_fini(&dri3_surf->loader_drawable);
dri2_fini_surface(surf);
free(surf);
return EGL_TRUE;
@ -137,7 +138,7 @@ dri3_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type,
return NULL;
}
if (!_eglInitSurface(&dri3_surf->surf.base, disp, type, conf, attrib_list))
if (!dri2_init_surface(&dri3_surf->surf.base, disp, type, conf, attrib_list, false))
goto cleanup_surf;
if (type == EGL_PBUFFER_BIT) {