summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZhongmin Wu <[email protected]>2017-09-15 18:32:42 +0100
committerEmil Velikov <[email protected]>2017-09-19 12:12:25 +0100
commite013ce8d0d91f6558af50f285e6a96ab697ec90c (patch)
treefef4ec0e4afb6312a8ac3f4c65eade683112b73b
parent0b3fc8f3054fe88d5368f6c747289cdeceb1c5d7 (diff)
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 <[email protected]> Signed-off-by: Yogesh Marathe <[email protected]> Reviewed-by: Emil Velikov <[email protected]> Reviewed-by: Tomasz Figa <[email protected]> [Emil Velikov: reorder so there's no intermetent regressions, split] Signed-off-by: Emil Velikov <[email protected]>
-rw-r--r--src/egl/drivers/dri2/egl_dri2.c72
-rw-r--r--src/egl/drivers/dri2/egl_dri2.h9
-rw-r--r--src/egl/drivers/dri2/platform_android.c3
-rw-r--r--src/egl/drivers/dri2/platform_drm.c3
-rw-r--r--src/egl/drivers/dri2/platform_surfaceless.c3
-rw-r--r--src/egl/drivers/dri2/platform_wayland.c3
-rw-r--r--src/egl/drivers/dri2/platform_x11.c3
-rw-r--r--src/egl/drivers/dri2/platform_x11_dri3.c3
8 files changed, 93 insertions, 6 deletions
diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
index 2667aa5d647..42bca61cfda 100644
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -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);
}
diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h
index 4a52b490a87..10a41518172 100644
--- a/src/egl/drivers/dri2/egl_dri2.h
+++ b/src/egl/drivers/dri2/egl_dri2.h
@@ -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 */
diff --git a/src/egl/drivers/dri2/platform_android.c b/src/egl/drivers/dri2/platform_android.c
index a864a2af3d7..38c1122339f 100644
--- a/src/egl/drivers/dri2/platform_android.c
+++ b/src/egl/drivers/dri2/platform_android.c
@@ -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;
diff --git a/src/egl/drivers/dri2/platform_drm.c b/src/egl/drivers/dri2/platform_drm.c
index 0ccbd9a30a0..fbdf8b1672a 100644
--- a/src/egl/drivers/dri2/platform_drm.c
+++ b/src/egl/drivers/dri2/platform_drm.c
@@ -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;
diff --git a/src/egl/drivers/dri2/platform_surfaceless.c b/src/egl/drivers/dri2/platform_surfaceless.c
index 1091b4febdb..ff8f88d5375 100644
--- a/src/egl/drivers/dri2/platform_surfaceless.c
+++ b/src/egl/drivers/dri2/platform_surfaceless.c
@@ -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;
}
diff --git a/src/egl/drivers/dri2/platform_wayland.c b/src/egl/drivers/dri2/platform_wayland.c
index eb10a7dd137..dc6fcc1d072 100644
--- a/src/egl/drivers/dri2/platform_wayland.c
+++ b/src/egl/drivers/dri2/platform_wayland.c
@@ -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;
diff --git a/src/egl/drivers/dri2/platform_x11.c b/src/egl/drivers/dri2/platform_x11.c
index d80eee2969a..ab9a142f415 100644
--- a/src/egl/drivers/dri2/platform_x11.c
+++ b/src/egl/drivers/dri2/platform_x11.c
@@ -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;
diff --git a/src/egl/drivers/dri2/platform_x11_dri3.c b/src/egl/drivers/dri2/platform_x11_dri3.c
index a83e7839528..45bb56ca17e 100644
--- a/src/egl/drivers/dri2/platform_x11_dri3.c
+++ b/src/egl/drivers/dri2/platform_x11_dri3.c
@@ -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) {