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:
parent
0b3fc8f305
commit
e013ce8d0d
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue